* to create. The string 'src' is likely to be free, so we
* to create. The string 'src' is likely to be freed, so we
ParseDoSrc(tOp, src, allsrc)    int 	tOp;	/* operator (if any) from special targets */    const char	*src;	/* name of the source to handle */    Lst 	allsrc; /* List of all sources to wait for */{    GNode	*gn = NULL;    if (*src == '.' && isupper(src[1])) {	int keywd = ParseFindKeyword(src);	if (keywd != -1) {	    int op = parseKeywords[keywd].op;	    if (op != 0) {		Lst_Find(&targets, ParseDoOp, &op);		return;	    }	    if (parseKeywords[keywd].spec == Wait) {		waiting++;		return;	    }	}    }    switch (specType) {    case Main:	/*	 * If we have noted the existence of a .MAIN, it means we need	 * to add the sources of said target to the list of things	 * to create. The string 'src' is likely to be free, so we	 * must make a new copy of it. Note that this will only be	 * invoked if the user didn't specify a target on the command	 * line. This is to allow #ifmake's to succeed, or something...	 */	Lst_AtEnd(&create, estrdup(src));	/*	 * Add the name to the .TARGETS variable as well, so the user cna	 * employ that, if desired.	 */	Var_Append(".TARGETS", src, VAR_GLOBAL);	return;    case Order:	/*	 * Create proper predecessor/successor links between the previous	 * source and the current one.	 */	gn = Targ_FindNode(src, NULL, TARG_CREATE);	if (predecessor != NULL) {	    Lst_AtEnd(&predecessor->successors, gn);	    Lst_AtEnd(&gn->preds, predecessor);	}	/*	 * The current source now becomes the predecessor for the next one.	 */	predecessor = gn;	break;    default:	/*	 * If the source is not an attribute, we need to find/create	 * a node for it. After that we can apply any operator to it	 * from a special target or link it to its parents, as	 * appropriate.	 *	 * In the case of a source that was the object of a :: operator,	 * the attribute is applied to all of its instances (as kept in	 * the 'cohorts' list of the node) or all the cohorts are linked	 * to all the targets.	 */	gn = Targ_FindNode(src, NULL, TARG_CREATE);	if (tOp) {	    gn->type |= tOp;	} else {	    LstNode	ln;	    for (ln = Lst_First(&targets); ln != NULL; ln = Lst_Adv(ln))		ParseLinkSrc((GNode *)Lst_Datum(ln), gn);	}	if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {	    GNode	*cohort;	    LstNode	ln;	    for (ln=Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln)){		cohort = (GNode *)Lst_Datum(ln);		if (tOp) {		    cohort->type |= tOp;		} else {		    LstNode	ln;		    for (ln = Lst_First(&targets); ln != NULL; ln = Lst_Adv(ln))			ParseLinkSrc((GNode *)Lst_Datum(ln), cohort);		}	    }	}	break;    }    gn->order = waiting;    Lst_AtEnd(allsrc, gn);    if (waiting) {	Lst_Find(allsrc, ParseAddDep, gn);    }}