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