Hello,

Here’s an updated version of originally proposed at

  https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555271.html

with an extra documentation bit, as suggested by Armin’s
comment quoted below.

Re-tested with a couple of VxWorks builds.

Ok to commit ?

Thanks in advance!

Best Regards,

2020-10-14  Douglas Rupp  <r...@adacore.com>

        * gcc.c (if-exists-then-else): New built-in spec function.
        * doc/invoke.texi: Document it.

>> On 1 Oct 2020, at 18:20, Armin Brauns via Gcc-patches 
>> <gcc-patches@gcc.gnu.org> wrote:
>> 
>> could you please make sure to update the documentation around 
>> gcc/doc/invoke.texi:31574 accordingly?

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 47aa69530ab6..288792214e72 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -31665,6 +31665,19 @@ crt0%O%s %:if-exists(crti%O%s) \
 %:if-exists-else(crtbeginT%O%s crtbegin%O%s)
 @end smallexample
 
+@item @code{if-exists-then-else}
+The @code{if-exists-then-else} spec function takes at least two arguments
+and an optional third one. The first argument is an absolute pathname to a
+file.  If the file exists, the function returns the second argument.
+If the file does not exist, the function returns the third argument if there
+is one, or NULL otherwise. This can be used to expand one text, or optionally
+another, based on the existence of a file.  Here is a small example of its
+usage:
+
+@smallexample
+-l%:if-exists-then-else(%:getenv(VSB_DIR rtnet.h) rtnet net)
+@end smallexample
+
 @item @code{replace-outfile}
 The @code{replace-outfile} spec function takes two arguments.  It looks for the
 first argument in the outfiles array and replaces it with the second argument. 
 Here
diff --git a/gcc/gcc.c b/gcc/gcc.c
index ff7b6c4a3205..337c27442a39 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -416,6 +416,7 @@ static void try_generate_repro (const char **argv);
 static const char *getenv_spec_function (int, const char **);
 static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
+static const char *if_exists_then_else_spec_function (int, const char **);
 static const char *sanitize_spec_function (int, const char **);
 static const char *replace_outfile_spec_function (int, const char **);
 static const char *remove_outfile_spec_function (int, const char **);
@@ -1723,6 +1724,7 @@ static const struct spec_function static_spec_functions[] 
=
   { "getenv",                   getenv_spec_function },
   { "if-exists",               if_exists_spec_function },
   { "if-exists-else",          if_exists_else_spec_function },
+  { "if-exists-then-else",     if_exists_then_else_spec_function },
   { "sanitize",                        sanitize_spec_function },
   { "replace-outfile",         replace_outfile_spec_function },
   { "remove-outfile",          remove_outfile_spec_function },
@@ -10087,6 +10089,29 @@ if_exists_else_spec_function (int argc, const char 
**argv)
   return argv[1];
 }
 
+/* if-exists-then-else built-in spec function.
+
+   Checks to see if the file specified by the absolute pathname in
+   the first arg exists.  Returns the second arg if so, otherwise returns
+   the third arg if it is present.  */
+
+static const char *
+if_exists_then_else_spec_function (int argc, const char **argv)
+{
+
+  /* Must have two or three arguments.  */
+  if (argc != 2 && argc != 3)
+    return NULL;
+
+  if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
+    return argv[1];
+
+  if (argc == 3)
+    return argv[2];
+
+  return NULL;
+}
+
 /* sanitize built-in spec function.
 
    This returns non-NULL, if sanitizing address, thread or

Reply via email to