Get rid of another bunch of Lst_ForEach in favour of LST_FOREACH and

simplify code accordingly.
This commit is contained in:
Hartmut Brandt 2005-03-16 08:04:45 +00:00
parent 2a77000b75
commit 0bcd542606

View File

@ -227,14 +227,8 @@ static struct {
};
static int ParseFindKeyword(char *);
static int ParseDoOp(void *, void *);
static int ParseAddDep(void *, void *);
static void ParseDoSrc(int, char *, Lst *);
static int ParseFindMain(void *, void *);
static int ParseAddDir(void *, void *);
static int ParseClearPath(void *, void *);
static void ParseDoDependency(char *);
static int ParseAddCmd(void *, void *);
static int ParseReadc(void);
static void ParseUnreadc(int);
static void ParseHasCommands(void *);
@ -352,116 +346,80 @@ ParseLinkSrc(Lst *parents, GNode *cgn)
/*-
*---------------------------------------------------------------------
* ParseDoOp --
* Apply the parsed operator to the given target node. Used in a
* Lst_ForEach call by ParseDoDependency once all targets have
* been found and their operator parsed. If the previous and new
* operators are incompatible, a major error is taken.
*
* Results:
* Always 0
* Apply the parsed operator to all target nodes. Used in
* ParseDoDependency once all targets have been found and their
* operator parsed. If the previous and new operators are incompatible,
* a major error is taken.
*
* Side Effects:
* The type field of the node is altered to reflect any new bits in
* the op.
*---------------------------------------------------------------------
*/
static int
ParseDoOp(void *gnp, void *opp)
static void
ParseDoOp(int op)
{
GNode *gn = gnp;
int op = *(int *)opp;
GNode *cohort;
LstNode *ln;
GNode *gn;
/*
* If the dependency mask of the operator and the node don't match and
* the node has actually had an operator applied to it before, and
* the operator actually has some dependency information in it, complain.
*/
if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
!OP_NOP(gn->type) && !OP_NOP(op))
{
Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name);
return (1);
}
LST_FOREACH(ln, &targets) {
gn = Lst_Datum(ln);
if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {
/*
* If the node was the object of a :: operator, we need to create a
* new instance of it for the children and commands on this dependency
* line. The new instance is placed on the 'cohorts' list of the
* initial one (note the initial one is not on its own cohorts list)
* and the new instance is linked to all parents of the initial
* instance.
*/
GNode *cohort;
LstNode *ln;
/*
* If the dependency mask of the operator and the node don't
* match and the node has actually had an operator applied to
* it before, and the operator actually has some dependency
* information in it, complain.
*/
if ((op & OP_OPMASK) != (gn->type & OP_OPMASK) &&
!OP_NOP(gn->type) && !OP_NOP(op)) {
Parse_Error(PARSE_FATAL, "Inconsistent operator for %s",
gn->name);
return;
}
cohort = Targ_NewGN(gn->name);
/*
* Duplicate links to parents so graph traversal is simple. Perhaps
* some type bits should be duplicated?
*
* Make the cohort invisible as well to avoid duplicating it into
* other variables. True, parents of this target won't tend to do
* anything with their local variables, but better safe than
* sorry.
*/
ParseLinkSrc(&gn->parents, cohort);
cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
Lst_AtEnd(&gn->cohorts, cohort);
if (op == OP_DOUBLEDEP &&
(gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
/*
* If the node was the object of a :: operator, we need
* to create a new instance of it for the children and
* commands on this dependency line. The new instance
* is placed on the 'cohorts' list of the initial one
* (note the initial one is not on its own cohorts list)
* and the new instance is linked to all parents of the
* initial instance.
*/
cohort = Targ_NewGN(gn->name);
/*
* Replace the node in the targets list with the new copy
*/
ln = Lst_Member(&targets, gn);
Lst_Replace(ln, cohort);
gn = cohort;
}
/*
* We don't want to nuke any previous flags (whatever they were) so we
* just OR the new operator into the old
*/
gn->type |= op;
/*
* Duplicate links to parents so graph traversal is
* simple. Perhaps some type bits should be duplicated?
*
* Make the cohort invisible as well to avoid
* duplicating it into other variables. True, parents
* of this target won't tend to do anything with their
* local variables, but better safe than sorry.
*/
ParseLinkSrc(&gn->parents, cohort);
cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
Lst_AtEnd(&gn->cohorts, cohort);
return (0);
/*
* Replace the node in the targets list with the
* new copy
*/
Lst_Replace(ln, cohort);
gn = cohort;
}
/*
* We don't want to nuke any previous flags (whatever they were)
* so we just OR the new operator into the old
*/
gn->type |= op;
}
}
/*-
*---------------------------------------------------------------------
* ParseAddDep --
* Check if the pair of GNodes given needs to be synchronized.
* This has to be when two nodes are on different sides of a
* .WAIT directive.
*
* Results:
* Returns 1 if the two targets need to be ordered, 0 otherwise.
* If it returns 1, the search can stop
*
* Side Effects:
* A dependency can be added between the two nodes.
*
*---------------------------------------------------------------------
*/
static int
ParseAddDep(void *pp, void *sp)
{
GNode *p = pp;
GNode *s = sp;
if (p->order < s->order) {
/*
* XXX: This can cause loops, and loops can cause unmade targets,
* but checking is tedious, and the debugging output can show the
* problem
*/
Lst_AtEnd(&p->successors, s);
Lst_AtEnd(&s->preds, p);
return (0);
}
else
return (1);
}
/*-
*---------------------------------------------------------------------
* ParseDoSrc --
@ -487,9 +445,8 @@ ParseDoSrc(int tOp, char *src, Lst *allsrc)
if (*src == '.' && isupper ((unsigned char) src[1])) {
int keywd = ParseFindKeyword(src);
if (keywd != -1) {
int op = parseKeywords[keywd].op;
if (op != 0) {
Lst_ForEach(&targets, ParseDoOp, &op);
if(parseKeywords[keywd].op != 0) {
ParseDoOp(parseKeywords[keywd].op);
return;
}
if (parseKeywords[keywd].spec == Wait) {
@ -570,80 +527,30 @@ ParseDoSrc(int tOp, char *src, Lst *allsrc)
gn->order = waiting;
Lst_AtEnd(allsrc, gn);
if (waiting) {
Lst_ForEach(allsrc, ParseAddDep, gn);
LstNode *ln;
GNode *p;
/*
* Check if GNodes needs to be synchronized.
* This has to be when two nodes are on different sides of a
* .WAIT directive.
*/
LST_FOREACH(ln, allsrc) {
p = Lst_Datum(ln);
if (p->order >= gn->order)
break;
/*
* XXX: This can cause loops, and loops can cause
* unmade targets, but checking is tedious, and the
* debugging output can show the problem
*/
Lst_AtEnd(&p->successors, gn);
Lst_AtEnd(&gn->preds, p);
}
}
}
/*-
*-----------------------------------------------------------------------
* ParseFindMain --
* Find a real target in the list and set it to be the main one.
* Called by ParseDoDependency when a main target hasn't been found
* yet.
*
* Results:
* 0 if main not found yet, 1 if it is.
*
* Side Effects:
* mainNode is changed and Targ_SetMain is called.
*
*-----------------------------------------------------------------------
*/
static int
ParseFindMain(void *gnp, void *dummy __unused)
{
GNode *gn = gnp;
if ((gn->type & (OP_NOTMAIN | OP_USE | OP_EXEC | OP_TRANSFORM)) == 0) {
mainNode = gn;
Targ_SetMain(gn);
return (1);
} else {
return (0);
}
}
/*-
*-----------------------------------------------------------------------
* ParseAddDir --
* Front-end for Dir_AddDir to make sure Lst_ForEach keeps going
*
* Results:
* === 0
*
* Side Effects:
* See Dir_AddDir.
*
*-----------------------------------------------------------------------
*/
static int
ParseAddDir(void *path, void *name)
{
Dir_AddDir(path, name);
return(0);
}
/*-
*-----------------------------------------------------------------------
* ParseClearPath --
* Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going
*
* Results:
* === 0
*
* Side Effects:
* See Dir_ClearPath
*
*-----------------------------------------------------------------------
*/
static int
ParseClearPath(void *path, void *dummy __unused)
{
Dir_ClearPath(path);
return (0);
}
/*-
*---------------------------------------------------------------------
@ -688,6 +595,7 @@ ParseDoDependency(char *line)
char savec; /* a place to save a character */
Lst paths; /* Search paths to alter when parsing a list of .PATH targets */
int tOp; /* operator from special target */
LstNode *ln;
tOp = 0;
@ -998,7 +906,7 @@ ParseDoDependency(char *line)
cp++; /* Advance beyond operator */
Lst_ForEach(&targets, ParseDoOp, &op);
ParseDoOp(op);
/*
* Get to the first source
@ -1032,7 +940,8 @@ ParseDoDependency(char *line)
beSilent = TRUE;
break;
case ExPath:
Lst_ForEach(&paths, ParseClearPath, NULL);
LST_FOREACH(ln, &paths)
Dir_ClearPath(Lst_Datum(ln));
break;
case Posix:
Var_Set("%POSIX", "1003.2", VAR_GLOBAL);
@ -1101,7 +1010,8 @@ ParseDoDependency(char *line)
Suff_AddSuffix(line);
break;
case ExPath:
Lst_ForEach(&paths, ParseAddDir, line);
LST_FOREACH(ln, &paths)
Dir_AddDir(Lst_Datum(ln), line);
break;
case Includes:
Suff_AddInclude(line);
@ -1188,7 +1098,15 @@ ParseDoDependency(char *line)
* the first dependency line that is actually a real target
* (i.e. isn't a .USE or .EXEC rule) to be made.
*/
Lst_ForEach(&targets, ParseFindMain, NULL);
LST_FOREACH(ln, &targets) {
gn = Lst_Datum(ln);
if ((gn->type & (OP_NOTMAIN | OP_USE |
OP_EXEC | OP_TRANSFORM)) == 0) {
mainNode = gn;
Targ_SetMain(gn);
break;
}
}
}
}
@ -1469,31 +1387,6 @@ Parse_DoVar(char *line, GNode *ctxt)
}
}
/*-
* ParseAddCmd --
* Lst_ForEach function to add a command line to all targets
*
* Results:
* Always 0
*
* Side Effects:
* A new element is added to the commands list of the node.
*/
static int
ParseAddCmd(void *gnp, void *cmd)
{
GNode *gn = gnp;
/* if target already supplied, ignore commands */
if (!(gn->type & OP_HAS_COMMANDS))
Lst_AtEnd(&gn->commands, cmd);
else
Parse_Error(PARSE_WARNING,
"duplicate script for target \"%s\" ignored",
gn->name);
return (0);
}
/*-
*-----------------------------------------------------------------------
* ParseHasCommands --
@ -2465,12 +2358,24 @@ Parse_File(char *name, FILE *stream)
}
if (*cp) {
if (inLine) {
LstNode *ln;
GNode *gn;
/*
* So long as it's not a blank line and we're actually
* in a dependency spec, add the command to the list of
* commands of all targets in the dependency spec
*/
Lst_ForEach(&targets, ParseAddCmd, cp);
LST_FOREACH(ln, &targets) {
gn = Lst_Datum(ln);
/* if target already supplied, ignore commands */
if (!(gn->type & OP_HAS_COMMANDS))
Lst_AtEnd(&gn->commands, cp);
else
Parse_Error(PARSE_WARNING, "duplicate script "
"for target \"%s\" ignored", gn->name);
}
continue;
} else {
Parse_Error(PARSE_FATAL,