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:
Hartmut Brandt 2005-05-10 08:06:13 +00:00
parent 6fab4fece2
commit 103823e628
3 changed files with 64 additions and 12 deletions

View File

@ -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--;

View File

@ -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;

View File

@ -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 *);