From 5d7574a0b90fc18322efaeb7ade1d4da2b233ac3 Mon Sep 17 00:00:00 2001 From: dim Date: Mon, 13 Feb 2012 20:59:58 +0000 Subject: [PATCH] MFC r231079: Let rpcgen(1) support an environment variable RPCGEN_CPP to find the C preprocessor to run. Previously, it always ran /usr/bin/cpp, unless you used the -Y option, and even then you could not set the basename. It also attempted to run /usr/ccs/lib/cpp for SVR4 compatibility, but this is obsolete, and has been removed. Note that setting RPCGEN_CPP to a command with arguments is supported, though the command line parsing is simplistic. However, setting it to e.g. "gcc46 -E" or "clang -E" will lead to problems, because both gcc and clang in -E mode will consider files with unknown extensions (such as .x) as object files, and attempt to link them. This could be worked around by also adding "-x c", but it is much safer to set RPCGEN_CPP to e.g. "cpp46" or "clang-cpp" instead. MFC r231080: Amend r231079 by properly shifting up the existing arguments in rpc_main.c's insarg() function. I had forgotten to put this in my patch queue, sorry. Pointy hat to: me MFC r231101: In usr.bin/rpcgen/rpc_main.c, use execvp(3) instead of execv(3), so rpcgen will search the current PATH for the preprocessor. This makes it possible to run a preprocessor built during the cross-tools stage of buildworld. git-svn-id: svn://svn.freebsd.org/base/stable/8@231613 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- usr.bin/rpcgen/rpc_main.c | 75 +++++++++++++++++++++------------------ usr.bin/rpcgen/rpcgen.1 | 5 +++ 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/usr.bin/rpcgen/rpc_main.c b/usr.bin/rpcgen/rpc_main.c index 1125e1e71..01c9256fe 100644 --- a/usr.bin/rpcgen/rpc_main.c +++ b/usr.bin/rpcgen/rpc_main.c @@ -79,13 +79,8 @@ static void s_output(int, const char **, const char *, const char *, int, const #define EXTEND 1 /* alias for TRUE */ #define DONT_EXTEND 0 /* alias for FALSE */ -#define SVR4_CPP "/usr/ccs/lib/cpp" -#define SUNOS_CPP "/usr/bin/cpp" - -static int cppDefined = 0; /* explicit path for C preprocessor */ - static const char *svcclosetime = "120"; -static const char *CPP = SVR4_CPP; +static const char *CPP = NULL; static const char CPPFLAGS[] = "-C"; static char pathbuf[MAXPATHLEN + 1]; static const char *allv[] = { @@ -101,7 +96,7 @@ static int allnc = sizeof (allnv)/sizeof (allnv[0]); * machinations for handling expanding argument list */ static void addarg(const char *); /* add another argument to the list */ -static void putarg(int, const char *); /* put argument at specified location */ +static void insarg(int, const char *); /* insert arg at specified location */ static void clear_args(void); /* clear argument list */ static void checkfiles(const char *, const char *); /* check if out file already exists */ @@ -109,7 +104,7 @@ static void checkfiles(const char *, const char *); #define ARGLISTLEN 20 -#define FIXEDARGS 2 +#define FIXEDARGS 0 static char *arglist[ARGLISTLEN]; static int argcount = FIXEDARGS; @@ -292,24 +287,29 @@ clear_args(void) argcount = FIXEDARGS; } -/* make sure that a CPP exists */ +/* prepend C-preprocessor and flags before arguments */ static void -find_cpp(void) +prepend_cpp(void) { - struct stat buf; - - if (stat(CPP, &buf) < 0) { /* SVR4 or explicit cpp does not exist */ - if (cppDefined) { - warnx("cannot find C preprocessor: %s", CPP); - crash(); - } else { /* try the other one */ - CPP = SUNOS_CPP; - if (stat(CPP, &buf) < 0) { /* can't find any cpp */ - warnx("cannot find C preprocessor: %s", CPP); - crash(); - } + int idx = 1; + const char *var; + char *dupvar, *s, *t; + + if (CPP != NULL) + insarg(0, CPP); + else if ((var = getenv("RPCGEN_CPP")) == NULL) + insarg(0, "/usr/bin/cpp"); + else { + /* Parse command line in a rudimentary way */ + dupvar = xstrdup(var); + for (s = dupvar, idx = 0; (t = strsep(&s, " \t")) != NULL; ) { + if (t[0]) + insarg(idx++, t); } + free(dupvar); } + + insarg(idx, CPPFLAGS); } /* @@ -324,9 +324,7 @@ open_input(const char *infile, const char *define) (void) pipe(pd); switch (childpid = fork()) { case 0: - find_cpp(); - putarg(0, CPP); - putarg(1, CPPFLAGS); + prepend_cpp(); addarg(define); if (infile) addarg(infile); @@ -334,8 +332,8 @@ open_input(const char *infile, const char *define) (void) close(1); (void) dup2(pd[1], 1); (void) close(pd[0]); - execv(arglist[0], arglist); - err(1, "execv"); + execvp(arglist[0], arglist); + err(1, "execvp %s", arglist[0]); case -1: err(1, "fork"); } @@ -938,18 +936,26 @@ addarg(const char *cp) } +/* + * Insert an argument at the specified location + */ static void -putarg(int place, const char *cp) +insarg(int place, const char *cp) { - if (place >= ARGLISTLEN) { - warnx("arglist coding error"); + int i; + + if (argcount >= ARGLISTLEN) { + warnx("too many defines"); crash(); /*NOTREACHED*/ } - if (cp != NULL) - arglist[place] = xstrdup(cp); - else - arglist[place] = NULL; + + /* Move up existing arguments */ + for (i = argcount - 1; i >= place; i--) + arglist[i + 1] = arglist[i]; + + arglist[place] = xstrdup(cp); + argcount++; } /* @@ -1138,7 +1144,6 @@ parseargs(int argc, const char *argv[], struct commandline *cmd) return (0); } CPP = pathbuf; - cppDefined = 1; goto nextarg; diff --git a/usr.bin/rpcgen/rpcgen.1 b/usr.bin/rpcgen/rpcgen.1 index 2a4a25ecc..1389adf00 100644 --- a/usr.bin/rpcgen/rpcgen.1 +++ b/usr.bin/rpcgen/rpcgen.1 @@ -490,6 +490,11 @@ Give the name of the directory where .Nm will start looking for the C-preprocessor. .El +.Sh ENVIRONMENT +If the +.Ev RPCGEN_CPP +environment variable is set, its value is used as the command line of the +C preprocessor to be run on the input file. .Sh EXAMPLES The following example: .Dl example% rpcgen -T prot.x -- 2.45.0