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 <okumoto@ucsd.edu>
This commit is contained in:
parent
6fab4fece2
commit
103823e628
@ -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--;
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user