gn = Targ_FindNode(line, NULL, TARG_CREATE);
gn = Targ_FindNode(line, TARG_CREATE);
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 */    LIST	    paths;	/* List of search paths to alter when parsing				 * a list of .PATH targets */    int 	    tOp;	/* operator from special target */    LIST	    curTargs;	/* list of target names to be found and added				 * to the targets list */    LIST	    curSrcs;	/* list of sources in order */    tOp = 0;    specType = Not;    waiting = 0;    Lst_Init(&paths);    Lst_Init(&curTargs);    Lst_Init(&curSrcs);    do {	for (cp = line; *cp && !isspace(*cp) && *cp != '(';)	    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.  */		cp += Var_ParseSkip(cp, NULL, NULL);	    else {		/* 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 (*cp == ':' && *p == ':')			p++;		    /* Found the best match already. */		    if (isspace(*p) || *p == '\0')			break;		    do {			p += strcspn(p, "!:");			if (*p == '\0')			    break;			p++;		    } while (!isspace(*p));		    /* No better match later on... */		    if (*p == '\0')			break;		}		cp++;	    }	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, NULL) != SUCCESS) {		Parse_Error(PARSE_FATAL,			     "Error in archive specification: \"%s\"", line);		return;	    } else {		continue;	    }	}	savec = *cp;	if (*cp == '\0') {	    /* 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:			Lst_AtEnd(&paths, &dirSearchPath);			break;		    case Main:			if (!Lst_IsEmpty(&create)) {			    specType = Not;			}			break;		    case Begin:		    case End:		    case Interrupt:			gn = Targ_FindNode(line, NULL, TARG_CREATE);			gn->type |= OP_NOTMAIN;			Lst_AtEnd(&targets, gn);			break;		    case Default:			gn = Targ_NewGN(".DEFAULT", NULL);			gn->type |= OP_NOTMAIN|OP_TRANSFORM;			Lst_AtEnd(&targets, 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 {		    Lst_AtEnd(&paths, 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...		 */		LIST	    emptyPath;		Lst_Init(&emptyPath);		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, line);	    }	    while ((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) {		if (!Suff_IsTransform(targName)) {		    gn = Targ_FindNode(targName, NULL, TARG_CREATE);		} else {		    gn = Suff_AddTransform(targName);		}		if (gn != NULL)		    Lst_AtEnd(&targets, 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_Find(&targets, ParseDoOp, &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_Every(&paths, ParseClearPath);		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, 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;	}	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;		LIST	  sources; /* list of archive source names after				    * expansion */		Lst_Init(&sources);		if (Arch_ParseArchive(&line, &sources, NULL) != 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);		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_Find(&targets, ParseFindMain, NULL);    }    /* Finally, destroy the list of sources.  */    Lst_Destroy(&curSrcs, NOFREE);}