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)
|
MainParseArgs(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
Boolean found_dd = FALSE;
|
||||||
|
|
||||||
rearg:
|
rearg:
|
||||||
optind = 1; /* since we're called more than once */
|
optind = 1; /* since we're called more than once */
|
||||||
optreset = 1;
|
optreset = 1;
|
||||||
#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
|
#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) {
|
switch(c) {
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -438,11 +445,18 @@ MainParseArgs(int argc, char **argv)
|
|||||||
* (*argv) is a single dash, so we
|
* (*argv) is a single dash, so we
|
||||||
* just ignore it.
|
* 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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* (*argv) is a -flag, so backup argv
|
* (*argv) is a -flag, so backup argv and
|
||||||
* and argc, since getopt() expects
|
* argc. getopt() expects options to start
|
||||||
* options to start in the 2nd position.
|
* in the 2nd position.
|
||||||
*/
|
*/
|
||||||
argc++;
|
argc++;
|
||||||
argv--;
|
argv--;
|
||||||
|
@ -108,6 +108,7 @@ typedef struct VarParser {
|
|||||||
const char *ptr; /* current parser pos in input str */
|
const char *ptr; /* current parser pos in input str */
|
||||||
GNode *ctxt;
|
GNode *ctxt;
|
||||||
Boolean err;
|
Boolean err;
|
||||||
|
Boolean execute;
|
||||||
} VarParser;
|
} VarParser;
|
||||||
static char *VarParse(VarParser *, Boolean *);
|
static char *VarParse(VarParser *, Boolean *);
|
||||||
|
|
||||||
@ -764,7 +765,8 @@ VarGetPattern(VarParser *vp, int delim, int *flags, VarPattern *patt)
|
|||||||
vp->ptr,
|
vp->ptr,
|
||||||
vp->ptr,
|
vp->ptr,
|
||||||
vp->ctxt,
|
vp->ctxt,
|
||||||
vp->err
|
vp->err,
|
||||||
|
vp->execute
|
||||||
};
|
};
|
||||||
char *rval;
|
char *rval;
|
||||||
Boolean rfree;
|
Boolean rfree;
|
||||||
@ -1229,10 +1231,13 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult)
|
|||||||
(vp->ptr[1] == 'h') &&
|
(vp->ptr[1] == 'h') &&
|
||||||
(vp->ptr[2] == endc || vp->ptr[2] == ':')) {
|
(vp->ptr[2] == endc || vp->ptr[2] == ':')) {
|
||||||
const char *error;
|
const char *error;
|
||||||
Buffer *buf;
|
|
||||||
|
|
||||||
buf = Cmd_Exec(value, &error);
|
if (vp->execute) {
|
||||||
newStr = Buf_Peel(buf);
|
newStr = Buf_Peel(
|
||||||
|
Cmd_Exec(value, &error));
|
||||||
|
} else {
|
||||||
|
newStr = estrdup("");
|
||||||
|
}
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
Error(error, value);
|
Error(error, value);
|
||||||
@ -1560,7 +1565,8 @@ VarParseLong(VarParser *vp, Boolean *freeResult)
|
|||||||
vp->ptr,
|
vp->ptr,
|
||||||
vp->ptr,
|
vp->ptr,
|
||||||
vp->ctxt,
|
vp->ctxt,
|
||||||
vp->err
|
vp->err,
|
||||||
|
vp->execute
|
||||||
};
|
};
|
||||||
char *rval;
|
char *rval;
|
||||||
Boolean rfree;
|
Boolean rfree;
|
||||||
@ -1691,7 +1697,8 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err,
|
|||||||
input,
|
input,
|
||||||
input,
|
input,
|
||||||
ctxt,
|
ctxt,
|
||||||
err
|
err,
|
||||||
|
TRUE
|
||||||
};
|
};
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
@ -1700,6 +1707,34 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err,
|
|||||||
return (value);
|
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 --
|
* Var_Subst --
|
||||||
@ -1746,7 +1781,8 @@ Var_Subst(const char *str, GNode *ctxt, Boolean err)
|
|||||||
str,
|
str,
|
||||||
str,
|
str,
|
||||||
ctxt,
|
ctxt,
|
||||||
err
|
err,
|
||||||
|
TRUE
|
||||||
};
|
};
|
||||||
char *rval;
|
char *rval;
|
||||||
Boolean rfree;
|
Boolean rfree;
|
||||||
@ -1883,7 +1919,8 @@ Var_SubstOnly(const char *var, const char *str, GNode *ctxt, Boolean err)
|
|||||||
str,
|
str,
|
||||||
str,
|
str,
|
||||||
ctxt,
|
ctxt,
|
||||||
err
|
err,
|
||||||
|
TRUE
|
||||||
};
|
};
|
||||||
char *rval;
|
char *rval;
|
||||||
Boolean rfree;
|
Boolean rfree;
|
||||||
|
@ -94,6 +94,7 @@ void Var_Delete(const char *, struct GNode *);
|
|||||||
void Var_Dump(const struct GNode *);
|
void Var_Dump(const struct GNode *);
|
||||||
Boolean Var_Exists(const char *, struct GNode *);
|
Boolean Var_Exists(const char *, struct GNode *);
|
||||||
void Var_Init(char **);
|
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_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *);
|
||||||
char *Var_Quote(const char *);
|
char *Var_Quote(const char *);
|
||||||
void Var_Set(const char *, const char *, struct GNode *);
|
void Var_Set(const char *, const char *, struct GNode *);
|
||||||
|
Loading…
Reference in New Issue
Block a user