Lst_ForEach(paths, ParseAddDir, (ClientData)line);
Lst_ForEach(paths, ParseAddDir, line);
ParseDoDependency (line)    char           *line;	/* the line to parse */{    char  	   *cp;		/* our current position */    GNode 	   *gn;		/* a general purpose temporary node */    int             op;		/* the operator on the line */    char            savec;	/* a place to save a character */    Lst    	    paths;   	/* List of search paths to alter when parsing				 * a list of .PATH targets */    int	    	    tOp;    	/* operator from special target */    Lst	    	    sources;	/* list of archive source names after				 * expansion */    Lst 	    curTargs;	/* list of target names to be found and added				 * to the targets list */    Lst		    curSrcs;	/* list of sources in order */    tOp = 0;    specType = Not;    waiting = 0;    paths = (Lst)NULL;    curTargs = Lst_Init();    curSrcs = Lst_Init();    do {	for (cp = line;	     *cp && !isspace (*cp) && (*cp != '(');	     cp++)	{	    /*	     * We don't want to end a word on ':' or '!' if there is a	     * better match later on in the string.  By "better" I mean	     * one that is followed by whitespace.  This allows the user	     * to have targets like:	     *    fie::fi:fo: fum	     * where "fie::fi:fo" is the target.  In real life this is used	     * for perl5 library man pages where "::" separates an object	     * from its class.  Ie: "File::Spec::Unix".  This behaviour	     * is also consistent with other versions of make.	     */	    if (*cp == '!' || *cp == ':') {		char *p = cp + 1;		if (*p == '\0')		    break;			/* no chance, not enough room */		/*		 * Only end the word on ':' or '!' if there is not		 * a match later on followed by whitespace.		 */		while ((p = strchr(p + 1, *cp)) && !isspace(*(p + 1)))		    ;		if (!p || !isspace(*(p + 1)))		    break;	    } else if (*cp == '$') {		/*		 * Must be a dynamic source (would have been expanded		 * otherwise), so call the Var module to parse the puppy		 * so we can safely advance beyond it...There should be		 * no errors in this, as they would have been discovered		 * in the initial Var_Subst and we wouldn't be here.		 */		size_t 	length;		Boolean	freeIt;		char	*result;		result=Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);		if (freeIt) {		    free(result);		}		cp += length-1;	    }	    continue;	}	if (*cp == '(') {	    /*	     * Archives must be handled specially to make sure the OP_ARCHV	     * flag is set in their 'type' field, for one thing, and because	     * things like "archive(file1.o file2.o file3.o)" are permissible.	     * Arch_ParseArchive will set 'line' to be the first non-blank	     * after the archive-spec. It creates/finds nodes for the members	     * and places them on the given list, returning SUCCESS if all	     * went well and FAILURE if there was an error in the	     * specification. On error, line should remain untouched.	     */	    if (Arch_ParseArchive (&line, targets, VAR_CMD) != SUCCESS) {		Parse_Error (PARSE_FATAL,			     "Error in archive specification: \"%s\"", line);		return;	    } else {		continue;	    }	}	savec = *cp;	if (!*cp) {	    /*	     * Ending a dependency line without an operator is a Bozo	     * no-no	     */	    Parse_Error (PARSE_FATAL, "Need an operator");	    return;	}	*cp = '\0';	/*	 * Have a word in line. See if it's a special target and set	 * specType to match it.	 */	if (*line == '.' && isupper (line[1])) {	    /*	     * See if the target is a special target that must have it	     * or its sources handled specially.	     */	    int keywd = ParseFindKeyword(line);	    if (keywd != -1) {		if (specType == ExPath && parseKeywords[keywd].spec != ExPath) {		    Parse_Error(PARSE_FATAL, "Mismatched special targets");		    return;		}		specType = parseKeywords[keywd].spec;		tOp = parseKeywords[keywd].op;		/*		 * Certain special targets have special semantics:		 *	.PATH		Have to set the dirSearchPath		 *			variable too		 *	.MAIN		Its sources are only used if		 *			nothing has been specified to		 *			create.		 *	.DEFAULT    	Need to create a node to hang		 *			commands on, but we don't want		 *			it in the graph, nor do we want		 *			it to be the Main Target, so we		 *			create it, set OP_NOTMAIN and		 *			add it to the list, setting		 *			DEFAULT to the new node for		 *			later use. We claim the node is		 *	    	    	A transformation rule to make		 *	    	    	life easier later, when we'll		 *	    	    	use Make_HandleUse to actually		 *	    	    	apply the .DEFAULT commands.		 *	.PHONY		The list of targets		 *	.NOPATH		Don't search for file in the path		 *	.BEGIN		 *	.END		 *	.INTERRUPT  	Are not to be considered the		 *			main target.		 *  	.NOTPARALLEL	Make only one target at a time.		 *  	.SINGLESHELL	Create a shell for each command.		 *  	.ORDER	    	Must set initial predecessor to NULL		 */		switch (specType) {		    case ExPath:			if (paths == NULL) {			    paths = Lst_Init();			}			Lst_AtEnd(paths, (ClientData)dirSearchPath);			break;		    case Main:			if (!Lst_IsEmpty(create)) {			    specType = Not;			}			break;		    case Begin:		    case End:		    case Interrupt:			gn = Targ_FindNode(line, TARG_CREATE);			gn->type |= OP_NOTMAIN;			Lst_AtEnd(targets, (ClientData)gn);			break;		    case Default:			gn = Targ_NewGN(".DEFAULT");			gn->type |= (OP_NOTMAIN|OP_TRANSFORM);			Lst_AtEnd(targets, (ClientData)gn);			DEFAULT = gn;			break;		    case NotParallel:		    {			extern int  maxJobs;			maxJobs = 1;			break;		    }		    case SingleShell:			compatMake = 1;			break;		    case Order:			predecessor = NULL;			break;		    default:			break;		}	    } else if (strncmp (line, ".PATH", 5) == 0) {		/*		 * .PATH<suffix> has to be handled specially.		 * Call on the suffix module to give us a path to		 * modify.		 */		Lst 	path;		specType = ExPath;		path = Suff_GetPath (&line[5]);		if (path == NULL) {		    Parse_Error (PARSE_FATAL,				 "Suffix '%s' not defined (yet)",				 &line[5]);		    return;		} else {		    if (paths == NULL) {			paths = Lst_Init();		    }		    Lst_AtEnd(paths, (ClientData)path);		}	    }	}	/*	 * Have word in line. Get or create its node and stick it at	 * the end of the targets list	 */	if ((specType == Not) && (*line != '\0')) {	    char *targName;	    if (Dir_HasWildcards(line)) {		/*		 * Targets are to be sought only in the current directory,		 * so create an empty path for the thing. Note we need to		 * use Dir_Destroy in the destruction of the path as the		 * Dir module could have added a directory to the path...		 */		Lst	    emptyPath = Lst_Init();		Dir_Expand(line, emptyPath, curTargs);		Lst_Destroy(emptyPath, Dir_Destroy);	    } else {		/*		 * No wildcards, but we want to avoid code duplication,		 * so create a list with the word on it.		 */		Lst_AtEnd(curTargs, (ClientData)line);	    }	    while((targName = (char *)Lst_DeQueue(curTargs)) != NULL) {		if (!Suff_IsTransform (targName)) {		    gn = Targ_FindNode (targName, TARG_CREATE);		} else {		    gn = Suff_AddTransform (targName);		}		if (gn != NULL)		    Lst_AtEnd(targets, (ClientData)gn);	    }	} else if (specType == ExPath && *line != '.' && *line != '\0') {	    Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);	}	*cp = savec;	/*	 * If it is a special type and not .PATH, it's the only target we	 * allow on this line...	 */	if (specType != Not && specType != ExPath) {	    Boolean warn = FALSE;	    while ((*cp != '!') && (*cp != ':') && *cp) {		if (*cp != ' ' && *cp != '\t') {		    warn = TRUE;		}		cp++;	    }	    if (warn) {		Parse_Error(PARSE_WARNING, "Extra target ignored");	    }	} else {	    while (*cp && isspace (*cp)) {		cp++;	    }	}	line = cp;    } while ((*line != '!') && (*line != ':') && *line);    /*     * Don't need the list of target names anymore...     */    Lst_Destroy(curTargs, NOFREE);    if (!Lst_IsEmpty(targets)) {	switch(specType) {	    default:		Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");		break;	    case Default:	    case Begin:	    case End:	    case Interrupt:		/*		 * These four create nodes on which to hang commands, so		 * targets shouldn't be empty...		 */	    case Not:		/*		 * Nothing special here -- targets can be empty if it wants.		 */		break;	}    }    /*     * Have now parsed all the target names. Must parse the operator next. The     * result is left in  op .     */    if (*cp == '!') {	op = OP_FORCE;    } else if (*cp == ':') {	if (cp[1] == ':') {	    op = OP_DOUBLEDEP;	    cp++;	} else {	    op = OP_DEPENDS;	}    } else {	Parse_Error (PARSE_FATAL, "Missing dependency operator");	return;    }    cp++;			/* Advance beyond operator */    Lst_ForEach (targets, ParseDoOp, (ClientData)&op);    /*     * Get to the first source     */    while (*cp && isspace (*cp)) {	cp++;    }    line = cp;    /*     * Several special targets take different actions if present with no     * sources:     *	a .SUFFIXES line with no sources clears out all old suffixes     *	a .PRECIOUS line makes all targets precious     *	a .IGNORE line ignores errors for all targets     *	a .SILENT line creates silence when making all targets     *	a .PATH removes all directories from the search path(s).     */    if (!*line) {	switch (specType) {	    case Suffixes:		Suff_ClearSuffixes ();		break;	    case Precious:		allPrecious = TRUE;		break;	    case Ignore:		ignoreErrors = TRUE;		break;	    case Silent:		beSilent = TRUE;		break;	    case ExPath:		Lst_ForEach(paths, ParseClearPath, (ClientData)NULL);		break;	    default:		break;	}    } else if (specType == MFlags) {	/*	 * Call on functions in main.c to deal with these arguments and	 * set the initial character to a null-character so the loop to	 * get sources won't get anything	 */	Main_ParseArgLine (line);	*line = '\0';    } else if (specType == ExShell) {	if (Job_ParseShell (line) != SUCCESS) {	    Parse_Error (PARSE_FATAL, "improper shell specification");	    return;	}	*line = '\0';    } else if ((specType == NotParallel) || (specType == SingleShell)) {	*line = '\0';    }    /*     * NOW GO FOR THE SOURCES     */    if ((specType == Suffixes) || (specType == ExPath) ||	(specType == Includes) || (specType == Libs) ||	(specType == Null))    {	while (*line) {	    /*	     * If the target was one that doesn't take files as its sources	     * but takes something like suffixes, we take each	     * space-separated word on the line as a something and deal	     * with it accordingly.	     *	     * If the target was .SUFFIXES, we take each source as a	     * suffix and add it to the list of suffixes maintained by the	     * Suff module.	     *	     * If the target was a .PATH, we add the source as a directory	     * to search on the search path.	     *	     * If it was .INCLUDES, the source is taken to be the suffix of	     * files which will be #included and whose search path should	     * be present in the .INCLUDES variable.	     *	     * If it was .LIBS, the source is taken to be the suffix of	     * files which are considered libraries and whose search path	     * should be present in the .LIBS variable.	     *	     * If it was .NULL, the source is the suffix to use when a file	     * has no valid suffix.	     */	    char  savec;	    while (*cp && !isspace (*cp)) {		cp++;	    }	    savec = *cp;	    *cp = '\0';	    switch (specType) {		case Suffixes:		    Suff_AddSuffix (line);		    break;		case ExPath:		    Lst_ForEach(paths, ParseAddDir, (ClientData)line);		    break;		case Includes:		    Suff_AddInclude (line);		    break;		case Libs:		    Suff_AddLib (line);		    break;		case Null:		    Suff_SetNull (line);		    break;		default:		    break;	    }	    *cp = savec;	    if (savec != '\0') {		cp++;	    }	    while (*cp && isspace (*cp)) {		cp++;	    }	    line = cp;	}	if (paths) {	    Lst_Destroy(paths, NOFREE);	}    } else {	while (*line) {	    /*	     * The targets take real sources, so we must beware of archive	     * specifications (i.e. things with left parentheses in them)	     * and handle them accordingly.	     */	    while (*cp && !isspace (*cp)) {		if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) {		    /*		     * Only stop for a left parenthesis if it isn't at the		     * start of a word (that'll be for variable changes		     * later) and isn't preceded by a dollar sign (a dynamic		     * source).		     */		    break;		} else {		    cp++;		}	    }	    if (*cp == '(') {		GNode	  *gn;		sources = Lst_Init();		if (Arch_ParseArchive (&line, sources, VAR_CMD) != SUCCESS) {		    Parse_Error (PARSE_FATAL,				 "Error in source archive spec \"%s\"", line);		    return;		}		while ((gn = (GNode *)Lst_DeQueue(sources)) != NULL)		    ParseDoSrc(tOp, gn->name, curSrcs);		Lst_Destroy (sources, NOFREE);		cp = line;	    } else {		if (*cp) {		    *cp = '\0';		    cp += 1;		}		ParseDoSrc (tOp, line, curSrcs);	    }	    while (*cp && isspace (*cp)) {		cp++;	    }	    line = cp;	}    }    if (mainNode == NULL) {	/*	 * If we have yet to decide on a main target to make, in the	 * absence of any user input, we want the first target on	 * 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, (ClientData)0);    }    /*     * Finally, destroy the list of sources     */    Lst_Destroy(curSrcs, NOFREE);}