From 081dc85073da351470b2851e8a93c769cb74f341 Mon Sep 17 00:00:00 2001 From: Douglas Rupp Date: Tue, 7 Apr 2020 14:05:57 -0700 Subject: [PATCH] Add a if-exists-then-else built-in spec function This patch adds an if-exists-then-else builtin spec function, which tests for the existence of a file and returns one or the other of the following arguments depending on the result of the test. This differs from the existing if-exists or if-exists-else function which return the name of the tested file if it exists. This new function is of help to a forthcoming change for VxWorks where we check for the presence of a specific header file to decide the name of a library to include in the link closure. 2020-10-23 Douglas Rupp gcc/ * gcc.c (if-exists-then-else): New built-in spec function. * doc/invoke.texi: Document it. --- gcc/doc/invoke.texi | 13 +++++++++++++ gcc/gcc.c | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0b87822..3c3c51c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -31685,6 +31685,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 ff7b6c4..337c274 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 -- 2.7.4