From 103823e628cdb04649ce6a85637b31452d277244 Mon Sep 17 00:00:00 2001 From: Hartmut Brandt Date: Tue, 10 May 2005 08:06:13 +0000 Subject: [PATCH] Make make a little bit more POSIXish with regard to option parsing: take everything after -- as either a macro assignment or a target. Note that make still reorders arguments before --: anything starting with a dash is considered an option, anything which contains an equal sign is considered a macro assignment and everything else a target. This still is not POSIX with regard to the options, but it will probably not change because it has been make's behaviour for ages. Add a new function Var_Match() that correctly skips a macro call by just doing the same as Var_Subst() but without producing output. This will help making the parser more robust. Patches: 7.190,7.191 Submitted by: Max Okumoto --- usr.bin/make/main.c | 22 +++++++++++++++---- usr.bin/make/var.c | 53 ++++++++++++++++++++++++++++++++++++++------- usr.bin/make/var.h | 1 + 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index d93628a4cf75..4059ecb06a65 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -241,12 +241,19 @@ static void MainParseArgs(int argc, char **argv) { int c; + Boolean found_dd = FALSE; rearg: optind = 1; /* since we're called more than once */ optreset = 1; #define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:" - while((c = getopt(argc, argv, OPTFLAGS)) != -1) { + for (;;) { + if ((optind < argc) && strcmp(argv[optind], "--") == 0) { + found_dd = TRUE; + } + if ((c = getopt(argc, argv, OPTFLAGS)) == -1) { + break; + } switch(c) { case 'A': @@ -438,11 +445,18 @@ MainParseArgs(int argc, char **argv) * (*argv) is a single dash, so we * just ignore it. */ + } else if (found_dd) { + /* + * Double dash has been found, ignore + * any more options. But what do we do + * with it? For now treat it like a target. + */ + Lst_AtEnd(&create, estrdup(*argv)); } else { /* - * (*argv) is a -flag, so backup argv - * and argc, since getopt() expects - * options to start in the 2nd position. + * (*argv) is a -flag, so backup argv and + * argc. getopt() expects options to start + * in the 2nd position. */ argc++; argv--; diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index cb62da790e82..1ca3e4c10aa4 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -108,6 +108,7 @@ typedef struct VarParser { const char *ptr; /* current parser pos in input str */ GNode *ctxt; Boolean err; + Boolean execute; } VarParser; static char *VarParse(VarParser *, Boolean *); @@ -764,7 +765,8 @@ VarGetPattern(VarParser *vp, int delim, int *flags, VarPattern *patt) vp->ptr, vp->ptr, vp->ctxt, - vp->err + vp->err, + vp->execute }; char *rval; Boolean rfree; @@ -1229,10 +1231,13 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult) (vp->ptr[1] == 'h') && (vp->ptr[2] == endc || vp->ptr[2] == ':')) { const char *error; - Buffer *buf; - buf = Cmd_Exec(value, &error); - newStr = Buf_Peel(buf); + if (vp->execute) { + newStr = Buf_Peel( + Cmd_Exec(value, &error)); + } else { + newStr = estrdup(""); + } if (error) Error(error, value); @@ -1560,7 +1565,8 @@ VarParseLong(VarParser *vp, Boolean *freeResult) vp->ptr, vp->ptr, vp->ctxt, - vp->err + vp->err, + vp->execute }; char *rval; Boolean rfree; @@ -1691,7 +1697,8 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err, input, input, ctxt, - err + err, + TRUE }; char *value; @@ -1700,6 +1707,34 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err, return (value); } +/* + * + * Results: + * The number of characters in the specification. For invalid + * specifications, this is just 2 to skip the '$' and the + * following letter, or 1 if '$' was the last character in the + * string. + */ +size_t +Var_Match(const char input[], GNode *ctxt) +{ + VarParser vp = { + input, + input, + ctxt, + FALSE, + FALSE + }; + char *value; + Boolean freeResult; + + value = VarParse(&vp, &freeResult); + if (freeResult) { + free(value); + } + return (vp.ptr - vp.input); +} + /*- *----------------------------------------------------------------------- * Var_Subst -- @@ -1746,7 +1781,8 @@ Var_Subst(const char *str, GNode *ctxt, Boolean err) str, str, ctxt, - err + err, + TRUE }; char *rval; Boolean rfree; @@ -1883,7 +1919,8 @@ Var_SubstOnly(const char *var, const char *str, GNode *ctxt, Boolean err) str, str, ctxt, - err + err, + TRUE }; char *rval; Boolean rfree; diff --git a/usr.bin/make/var.h b/usr.bin/make/var.h index a81e74345a3c..dbc41dbef793 100644 --- a/usr.bin/make/var.h +++ b/usr.bin/make/var.h @@ -94,6 +94,7 @@ void Var_Delete(const char *, struct GNode *); void Var_Dump(const struct GNode *); Boolean Var_Exists(const char *, struct GNode *); void Var_Init(char **); +size_t Var_Match(const char [], struct GNode *); char *Var_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *); char *Var_Quote(const char *); void Var_Set(const char *, const char *, struct GNode *);