Annotation of src/usr.bin/make/parse.c, Revision 1.57
1.57 ! espie 1: /* $OpenBSD: parse.c,v 1.56 2000/09/14 13:43:31 espie Exp $ */
1.13 millert 2: /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */
1.1 deraadt 3:
4: /*
1.11 millert 5: * Copyright (c) 1988, 1989, 1990, 1993
6: * The Regents of the University of California. All rights reserved.
1.1 deraadt 7: * Copyright (c) 1989 by Berkeley Softworks
8: * All rights reserved.
9: *
10: * This code is derived from software contributed to Berkeley by
11: * Adam de Boor.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by the University of
24: * California, Berkeley and its contributors.
25: * 4. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: */
41:
42: /*-
43: * parse.c --
44: * Functions to parse a makefile.
45: *
46: * One function, Parse_Init, must be called before any functions
47: * in this module are used. After that, the function Parse_File is the
48: * main entry point and controls most of the other functions in this
49: * module.
50: *
51: * Most important structures are kept in Lsts. Directories for
52: * the #include "..." function are kept in the 'parseIncPath' Lst, while
53: * those for the #include <...> are kept in the 'sysIncPath' Lst. The
54: * targets currently being defined are kept in the 'targets' Lst.
55: *
56: * The variables 'fname' and 'lineno' are used to track the name
57: * of the current file and the line number in that file so that error
58: * messages can be more meaningful.
59: *
60: * Interface:
61: * Parse_Init Initialization function which must be
62: * called before anything else in this module
63: * is used.
64: *
65: * Parse_End Cleanup the module
66: *
67: * Parse_File Function used to parse a makefile. It must
68: * be given the name of the file, which should
69: * already have been opened, and a function
70: * to call to read a character from the file.
71: *
72: * Parse_IsVar Returns TRUE if the given line is a
73: * variable assignment. Used by MainParseArgs
74: * to determine if an argument is a target
75: * or a variable assignment. Used internally
76: * for pretty much the same thing...
77: *
78: * Parse_Error Function called when an error occurs in
79: * parsing. Used by the variable and
80: * conditional modules.
81: * Parse_MainName Returns a Lst of the main target to create.
82: */
83:
1.15 mickey 84: #ifdef __STDC__
1.1 deraadt 85: #include <stdarg.h>
86: #else
87: #include <varargs.h>
88: #endif
1.57 ! espie 89: #include <stddef.h>
1.1 deraadt 90: #include <stdio.h>
91: #include <ctype.h>
92: #include <errno.h>
93: #include "make.h"
1.57 ! espie 94: #include "ohash.h"
1.1 deraadt 95: #include "dir.h"
96: #include "job.h"
97: #include "buf.h"
98: #include "pathnames.h"
1.50 espie 99: #include "lowparse.h"
1.1 deraadt 100:
1.53 espie 101: #ifndef lint
102: #if 0
103: static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
104: #else
105: UNUSED
1.57 ! espie 106: static char rcsid[] = "$OpenBSD: parse.c,v 1.56 2000/09/14 13:43:31 espie Exp $";
1.53 espie 107: #endif
108: #endif /* not lint */
109:
1.45 espie 110: static LIST targets; /* targets we're working on */
1.20 espie 111: #ifdef CLEANUP
1.45 espie 112: static LIST targCmds; /* command lines for targets */
1.20 espie 113: #endif
1.45 espie 114: static Boolean inLine; /* true if currently in a dependency
115: * line or its commands */
1.1 deraadt 116: static GNode *mainNode; /* The main target to create. This is the
117: * first target on the first dependency
118: * line in the first makefile */
1.43 espie 119: LIST parseIncPath; /* list of directories for "..." includes */
120: LIST sysIncPath; /* list of directories for <...> includes */
1.1 deraadt 121:
122: /*-
123: * specType contains the SPECial TYPE of the current target. It is
124: * Not if the target is unspecial. If it *is* special, however, the children
125: * are linked as children of the parent but not vice versa. This variable is
126: * set in ParseDoDependency
127: */
128: typedef enum {
129: Begin, /* .BEGIN */
130: Default, /* .DEFAULT */
131: End, /* .END */
132: Ignore, /* .IGNORE */
133: Includes, /* .INCLUDES */
134: Interrupt, /* .INTERRUPT */
135: Libs, /* .LIBS */
136: MFlags, /* .MFLAGS or .MAKEFLAGS */
137: Main, /* .MAIN and we don't have anything user-specified to
138: * make */
139: NoExport, /* .NOEXPORT */
1.17 espie 140: NoPath, /* .NOPATH */
1.1 deraadt 141: Not, /* Not special */
142: NotParallel, /* .NOTPARALELL */
143: Null, /* .NULL */
144: Order, /* .ORDER */
1.3 deraadt 145: Parallel, /* .PARALLEL */
1.1 deraadt 146: ExPath, /* .PATH */
1.7 niklas 147: Phony, /* .PHONY */
1.1 deraadt 148: Precious, /* .PRECIOUS */
149: ExShell, /* .SHELL */
150: Silent, /* .SILENT */
151: SingleShell, /* .SINGLESHELL */
152: Suffixes, /* .SUFFIXES */
1.3 deraadt 153: Wait, /* .WAIT */
1.1 deraadt 154: Attribute /* Generic attribute */
155: } ParseSpecial;
156:
157: static ParseSpecial specType;
1.3 deraadt 158: static int waiting;
1.1 deraadt 159:
160: /*
1.33 espie 161: * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
1.1 deraadt 162: * seen, then set to each successive source on the line.
163: */
164: static GNode *predecessor;
165:
166: /*
167: * The parseKeywords table is searched using binary search when deciding
168: * if a target or source is special. The 'spec' field is the ParseSpecial
169: * type of the keyword ("Not" if the keyword isn't special as a target) while
170: * the 'op' field is the operator to apply to the list of targets if the
171: * keyword is used as a source ("0" if the keyword isn't special as a source)
172: */
173: static struct {
174: char *name; /* Name of keyword */
175: ParseSpecial spec; /* Type when used as a target */
176: int op; /* Operator when used as a source */
177: } parseKeywords[] = {
178: { ".BEGIN", Begin, 0 },
179: { ".DEFAULT", Default, 0 },
180: { ".END", End, 0 },
181: { ".EXEC", Attribute, OP_EXEC },
182: { ".IGNORE", Ignore, OP_IGNORE },
183: { ".INCLUDES", Includes, 0 },
184: { ".INTERRUPT", Interrupt, 0 },
185: { ".INVISIBLE", Attribute, OP_INVISIBLE },
186: { ".JOIN", Attribute, OP_JOIN },
187: { ".LIBS", Libs, 0 },
1.13 millert 188: { ".MADE", Attribute, OP_MADE },
1.1 deraadt 189: { ".MAIN", Main, 0 },
190: { ".MAKE", Attribute, OP_MAKE },
191: { ".MAKEFLAGS", MFlags, 0 },
192: { ".MFLAGS", MFlags, 0 },
1.17 espie 193: #if 0 /* basic scaffolding for NOPATH, not working yet */
194: { ".NOPATH", NoPath, OP_NOPATH },
195: #endif
1.1 deraadt 196: { ".NOTMAIN", Attribute, OP_NOTMAIN },
197: { ".NOTPARALLEL", NotParallel, 0 },
1.3 deraadt 198: { ".NO_PARALLEL", NotParallel, 0 },
1.1 deraadt 199: { ".NULL", Null, 0 },
200: { ".OPTIONAL", Attribute, OP_OPTIONAL },
201: { ".ORDER", Order, 0 },
1.3 deraadt 202: { ".PARALLEL", Parallel, 0 },
1.1 deraadt 203: { ".PATH", ExPath, 0 },
1.7 niklas 204: { ".PHONY", Phony, OP_PHONY },
1.1 deraadt 205: { ".PRECIOUS", Precious, OP_PRECIOUS },
206: { ".RECURSIVE", Attribute, OP_MAKE },
207: { ".SHELL", ExShell, 0 },
208: { ".SILENT", Silent, OP_SILENT },
209: { ".SINGLESHELL", SingleShell, 0 },
210: { ".SUFFIXES", Suffixes, 0 },
211: { ".USE", Attribute, OP_USE },
1.3 deraadt 212: { ".WAIT", Wait, 0 },
1.1 deraadt 213: };
214:
215: static int ParseFindKeyword __P((char *));
1.42 espie 216: static void ParseLinkSrc __P((void *, void *));
217: static int ParseDoOp __P((void *, void *));
218: static int ParseAddDep __P((void *, void *));
1.3 deraadt 219: static void ParseDoSrc __P((int, char *, Lst));
1.42 espie 220: static int ParseFindMain __P((void *, void *));
221: static void ParseAddDir __P((void *, void *));
222: static void ParseClearPath __P((void *));
1.1 deraadt 223: static void ParseDoDependency __P((char *));
1.42 espie 224: static void ParseAddCmd __P((void *, void *));
225: static void ParseHasCommands __P((void *));
1.1 deraadt 226: static void ParseDoInclude __P((char *));
227: #ifdef SYSVINCLUDE
228: static void ParseTraditionalInclude __P((char *));
229: #endif
1.50 espie 230: static void ParseLookupIncludeFile __P((char *, char *, Boolean));
1.1 deraadt 231: static void ParseFinishLine __P((void));
232:
233: /*-
234: *----------------------------------------------------------------------
235: * ParseFindKeyword --
236: * Look in the table of keywords for one matching the given string.
237: *
238: * Results:
239: * The index of the keyword, or -1 if it isn't there.
240: *
241: * Side Effects:
242: * None
243: *----------------------------------------------------------------------
244: */
245: static int
246: ParseFindKeyword (str)
247: char *str; /* String to find */
248: {
249: register int start,
250: end,
251: cur;
252: register int diff;
1.11 millert 253:
1.1 deraadt 254: start = 0;
255: end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
256:
257: do {
258: cur = start + ((end - start) / 2);
259: diff = strcmp (str, parseKeywords[cur].name);
260:
261: if (diff == 0) {
262: return (cur);
263: } else if (diff < 0) {
264: end = cur - 1;
265: } else {
266: start = cur + 1;
267: }
268: } while (start <= end);
269: return (-1);
270: }
271:
272: /*-
273: *---------------------------------------------------------------------
274: * ParseLinkSrc --
275: * Link the parent node to its new child. Used in a Lst_ForEach by
276: * ParseDoDependency. If the specType isn't 'Not', the parent
277: * isn't linked as a parent of the child.
278: *
279: * Side Effects:
280: * New elements are added to the parents list of cgn and the
281: * children list of cgn. the unmade field of pgn is updated
282: * to reflect the additional child.
283: *---------------------------------------------------------------------
284: */
1.41 espie 285: static void
286: ParseLinkSrc(pgnp, cgnp)
1.42 espie 287: void *pgnp; /* The parent node */
288: void *cgnp; /* The child node */
1.1 deraadt 289: {
1.41 espie 290: GNode *pgn = (GNode *)pgnp;
291: GNode *cgn = (GNode *)cgnp;
1.43 espie 292: if (Lst_Member(&pgn->children, cgn) == NULL) {
293: Lst_AtEnd(&pgn->children, cgn);
1.41 espie 294: if (specType == Not)
1.43 espie 295: Lst_AtEnd(&cgn->parents, pgn);
1.1 deraadt 296: pgn->unmade += 1;
297: }
298: }
299:
300: /*-
301: *---------------------------------------------------------------------
302: * ParseDoOp --
303: * Apply the parsed operator to the given target node. Used in a
1.41 espie 304: * Lst_Find call by ParseDoDependency once all targets have
1.1 deraadt 305: * been found and their operator parsed. If the previous and new
306: * operators are incompatible, a major error is taken.
307: *
308: * Results:
1.40 espie 309: * 0 if a problem, 1 if ok.
1.1 deraadt 310: *
311: * Side Effects:
312: * The type field of the node is altered to reflect any new bits in
313: * the op.
314: *---------------------------------------------------------------------
315: */
316: static int
317: ParseDoOp (gnp, opp)
1.42 espie 318: void *gnp; /* The node to which the operator is to be
319: * applied */
320: void *opp; /* The operator to apply */
1.1 deraadt 321: {
322: GNode *gn = (GNode *) gnp;
323: int op = *(int *) opp;
324: /*
325: * If the dependency mask of the operator and the node don't match and
326: * the node has actually had an operator applied to it before, and
1.11 millert 327: * the operator actually has some dependency information in it, complain.
1.1 deraadt 328: */
329: if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
1.40 espie 330: !OP_NOP(gn->type) && !OP_NOP(op)) {
331: Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name);
332: return 0;
1.1 deraadt 333: }
334:
335: if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {
336: /*
337: * If the node was the object of a :: operator, we need to create a
338: * new instance of it for the children and commands on this dependency
339: * line. The new instance is placed on the 'cohorts' list of the
340: * initial one (note the initial one is not on its own cohorts list)
341: * and the new instance is linked to all parents of the initial
342: * instance.
343: */
344: register GNode *cohort;
345: LstNode ln;
1.11 millert 346:
1.55 espie 347: cohort = Targ_NewGN(gn->name, NULL);
1.1 deraadt 348: /*
349: * Duplicate links to parents so graph traversal is simple. Perhaps
350: * some type bits should be duplicated?
351: *
352: * Make the cohort invisible as well to avoid duplicating it into
353: * other variables. True, parents of this target won't tend to do
354: * anything with their local variables, but better safe than
355: * sorry.
356: */
1.43 espie 357: Lst_ForEach(&gn->parents, ParseLinkSrc, cohort);
1.1 deraadt 358: cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
1.43 espie 359: Lst_AtEnd(&gn->cohorts, cohort);
1.1 deraadt 360:
361: /*
362: * Replace the node in the targets list with the new copy
363: */
1.45 espie 364: ln = Lst_Member(&targets, gn);
1.37 espie 365: Lst_Replace(ln, cohort);
1.1 deraadt 366: gn = cohort;
367: }
368: /*
369: * We don't want to nuke any previous flags (whatever they were) so we
1.11 millert 370: * just OR the new operator into the old
1.1 deraadt 371: */
372: gn->type |= op;
373:
1.40 espie 374: return 1;
1.1 deraadt 375: }
376:
1.11 millert 377: /*-
1.3 deraadt 378: *---------------------------------------------------------------------
379: * ParseAddDep --
380: * Check if the pair of GNodes given needs to be synchronized.
381: * This has to be when two nodes are on different sides of a
382: * .WAIT directive.
383: *
384: * Results:
1.40 espie 385: * Returns 0 if the two targets need to be ordered, 1 otherwise.
386: * If it returns 0, the search can stop
1.3 deraadt 387: *
388: * Side Effects:
389: * A dependency can be added between the two nodes.
1.11 millert 390: *
1.3 deraadt 391: *---------------------------------------------------------------------
392: */
1.13 millert 393: static int
1.3 deraadt 394: ParseAddDep(pp, sp)
1.42 espie 395: void *pp;
396: void *sp;
1.3 deraadt 397: {
398: GNode *p = (GNode *) pp;
399: GNode *s = (GNode *) sp;
400:
401: if (p->order < s->order) {
402: /*
403: * XXX: This can cause loops, and loops can cause unmade targets,
404: * but checking is tedious, and the debugging output can show the
405: * problem
406: */
1.43 espie 407: Lst_AtEnd(&p->successors, s);
408: Lst_AtEnd(&s->preds, p);
1.40 espie 409: return 1;
1.3 deraadt 410: }
411: else
1.40 espie 412: return 0;
1.3 deraadt 413: }
414:
415:
1.1 deraadt 416: /*-
417: *---------------------------------------------------------------------
418: * ParseDoSrc --
419: * Given the name of a source, figure out if it is an attribute
420: * and apply it to the targets if it is. Else decide if there is
421: * some attribute which should be applied *to* the source because
422: * of some special target and apply it if so. Otherwise, make the
423: * source be a child of the targets in the list 'targets'
424: *
425: * Results:
426: * None
427: *
428: * Side Effects:
429: * Operator bits may be added to the list of targets or to the source.
430: * The targets may have a new source added to their lists of children.
431: *---------------------------------------------------------------------
432: */
433: static void
1.3 deraadt 434: ParseDoSrc (tOp, src, allsrc)
1.1 deraadt 435: int tOp; /* operator (if any) from special targets */
436: char *src; /* name of the source to handle */
1.3 deraadt 437: Lst allsrc; /* List of all sources to wait for */
438:
1.1 deraadt 439: {
1.3 deraadt 440: GNode *gn = NULL;
1.1 deraadt 441:
442: if (*src == '.' && isupper (src[1])) {
443: int keywd = ParseFindKeyword(src);
444: if (keywd != -1) {
1.3 deraadt 445: int op = parseKeywords[keywd].op;
446: if (op != 0) {
1.45 espie 447: Lst_Find(&targets, ParseDoOp, &op);
1.3 deraadt 448: return;
449: }
450: if (parseKeywords[keywd].spec == Wait) {
451: waiting++;
452: return;
453: }
1.1 deraadt 454: }
455: }
1.3 deraadt 456:
457: switch (specType) {
458: case Main:
1.1 deraadt 459: /*
460: * If we have noted the existence of a .MAIN, it means we need
461: * to add the sources of said target to the list of things
462: * to create. The string 'src' is likely to be free, so we
463: * must make a new copy of it. Note that this will only be
464: * invoked if the user didn't specify a target on the command
465: * line. This is to allow #ifmake's to succeed, or something...
466: */
1.43 espie 467: Lst_AtEnd(&create, estrdup(src));
1.1 deraadt 468: /*
469: * Add the name to the .TARGETS variable as well, so the user cna
470: * employ that, if desired.
471: */
472: Var_Append(".TARGETS", src, VAR_GLOBAL);
1.3 deraadt 473: return;
474:
475: case Order:
1.1 deraadt 476: /*
477: * Create proper predecessor/successor links between the previous
478: * source and the current one.
479: */
480: gn = Targ_FindNode(src, TARG_CREATE);
1.33 espie 481: if (predecessor != NULL) {
1.43 espie 482: Lst_AtEnd(&predecessor->successors, gn);
483: Lst_AtEnd(&gn->preds, predecessor);
1.1 deraadt 484: }
485: /*
486: * The current source now becomes the predecessor for the next one.
487: */
488: predecessor = gn;
1.3 deraadt 489: break;
490:
491: default:
1.1 deraadt 492: /*
493: * If the source is not an attribute, we need to find/create
494: * a node for it. After that we can apply any operator to it
495: * from a special target or link it to its parents, as
496: * appropriate.
497: *
498: * In the case of a source that was the object of a :: operator,
499: * the attribute is applied to all of its instances (as kept in
500: * the 'cohorts' list of the node) or all the cohorts are linked
501: * to all the targets.
502: */
503: gn = Targ_FindNode (src, TARG_CREATE);
504: if (tOp) {
505: gn->type |= tOp;
506: } else {
1.45 espie 507: Lst_ForEach(&targets, ParseLinkSrc, gn);
1.1 deraadt 508: }
509: if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
510: register GNode *cohort;
511: register LstNode ln;
512:
1.46 espie 513: for (ln=Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln)){
1.1 deraadt 514: cohort = (GNode *)Lst_Datum(ln);
515: if (tOp) {
516: cohort->type |= tOp;
517: } else {
1.45 espie 518: Lst_ForEach(&targets, ParseLinkSrc, cohort);
1.1 deraadt 519: }
520: }
521: }
1.3 deraadt 522: break;
523: }
524:
525: gn->order = waiting;
1.37 espie 526: Lst_AtEnd(allsrc, gn);
1.40 espie 527: if (waiting)
528: Lst_Find(allsrc, ParseAddDep, gn);
1.1 deraadt 529: }
530:
531: /*-
532: *-----------------------------------------------------------------------
533: * ParseFindMain --
534: * Find a real target in the list and set it to be the main one.
535: * Called by ParseDoDependency when a main target hasn't been found
536: * yet.
537: *
538: * Results:
1.40 espie 539: * 1 if main not found yet, 0 if it is.
1.1 deraadt 540: *
541: * Side Effects:
542: * mainNode is changed and Targ_SetMain is called.
543: *
544: *-----------------------------------------------------------------------
545: */
546: static int
547: ParseFindMain(gnp, dummy)
1.54 espie 548: void *gnp; /* Node to examine */
549: void *dummy UNUSED;
1.1 deraadt 550: {
551: GNode *gn = (GNode *) gnp;
1.17 espie 552: if ((gn->type & OP_NOTARGET) == 0) {
1.1 deraadt 553: mainNode = gn;
554: Targ_SetMain(gn);
1.54 espie 555: return 0;
556: } else
557: return 1;
1.1 deraadt 558: }
559:
560: /*-
561: *-----------------------------------------------------------------------
562: * ParseAddDir --
563: * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going
564: *
565: * Side Effects:
566: * See Dir_AddDir.
567: *
568: *-----------------------------------------------------------------------
569: */
1.41 espie 570: static void
1.1 deraadt 571: ParseAddDir(path, name)
1.42 espie 572: void *path;
573: void *name;
1.1 deraadt 574: {
1.56 espie 575: Dir_AddDir((Lst)path, (char *)name, NULL);
1.1 deraadt 576: }
577:
578: /*-
579: *-----------------------------------------------------------------------
580: * ParseClearPath --
581: * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going
582: *
583: * Side Effects:
584: * See Dir_ClearPath
585: *
586: *-----------------------------------------------------------------------
587: */
1.41 espie 588: static void
589: ParseClearPath(path)
1.42 espie 590: void *path;
1.1 deraadt 591: {
1.41 espie 592: Dir_ClearPath((Lst)path);
1.1 deraadt 593: }
594:
595: /*-
596: *---------------------------------------------------------------------
597: * ParseDoDependency --
598: * Parse the dependency line in line.
599: *
600: * Results:
601: * None
602: *
603: * Side Effects:
604: * The nodes of the sources are linked as children to the nodes of the
605: * targets. Some nodes may be created.
606: *
607: * We parse a dependency line by first extracting words from the line and
608: * finding nodes in the list of all targets with that name. This is done
609: * until a character is encountered which is an operator character. Currently
610: * these are only ! and :. At this point the operator is parsed and the
611: * pointer into the line advanced until the first source is encountered.
612: * The parsed operator is applied to each node in the 'targets' list,
613: * which is where the nodes found for the targets are kept, by means of
614: * the ParseDoOp function.
615: * The sources are read in much the same way as the targets were except
616: * that now they are expanded using the wildcarding scheme of the C-Shell
617: * and all instances of the resulting words in the list of all targets
618: * are found. Each of the resulting nodes is then linked to each of the
619: * targets as one of its children.
620: * Certain targets are handled specially. These are the ones detailed
621: * by the specType variable.
622: * The storing of transformation rules is also taken care of here.
623: * A target is recognized as a transformation rule by calling
624: * Suff_IsTransform. If it is a transformation rule, its node is gotten
625: * from the suffix module via Suff_AddTransform rather than the standard
626: * Targ_FindNode in the target module.
627: *---------------------------------------------------------------------
628: */
629: static void
630: ParseDoDependency (line)
631: char *line; /* the line to parse */
632: {
633: char *cp; /* our current position */
634: GNode *gn; /* a general purpose temporary node */
635: int op; /* the operator on the line */
636: char savec; /* a place to save a character */
1.45 espie 637: LIST paths; /* List of search paths to alter when parsing
1.1 deraadt 638: * a list of .PATH targets */
639: int tOp; /* operator from special target */
1.43 espie 640: LIST curTargs; /* list of target names to be found and added
1.1 deraadt 641: * to the targets list */
1.43 espie 642: LIST curSrcs; /* list of sources in order */
1.1 deraadt 643:
644: tOp = 0;
645:
646: specType = Not;
1.3 deraadt 647: waiting = 0;
1.45 espie 648: Lst_Init(&paths);
1.1 deraadt 649:
1.43 espie 650: Lst_Init(&curTargs);
651: Lst_Init(&curSrcs);
1.11 millert 652:
1.1 deraadt 653: do {
654: for (cp = line;
1.18 millert 655: *cp && !isspace (*cp) && (*cp != '(');
1.1 deraadt 656: cp++)
657: {
1.19 millert 658: /*
659: * We don't want to end a word on ':' or '!' if there is a
660: * better match later on in the string. By "better" I mean
661: * one that is followed by whitespace. This allows the user
662: * to have targets like:
663: * fie::fi:fo: fum
664: * where "fie::fi:fo" is the target. In real life this is used
665: * for perl5 library man pages where "::" separates an object
666: * from its class. Ie: "File::Spec::Unix". This behaviour
667: * is also consistent with other versions of make.
668: */
1.18 millert 669: if (*cp == '!' || *cp == ':') {
670: char *p = cp + 1;
671:
672: if (*p == '\0')
673: break; /* no chance, not enough room */
674: /*
675: * Only end the word on ':' or '!' if there is not
1.19 millert 676: * a match later on followed by whitespace.
1.18 millert 677: */
678: while ((p = strchr(p + 1, *cp)) && !isspace(*(p + 1)))
679: ;
680: if (!p || !isspace(*(p + 1)))
681: break;
682: } else if (*cp == '$') {
1.1 deraadt 683: /*
684: * Must be a dynamic source (would have been expanded
685: * otherwise), so call the Var module to parse the puppy
686: * so we can safely advance beyond it...There should be
687: * no errors in this, as they would have been discovered
688: * in the initial Var_Subst and we wouldn't be here.
689: */
1.36 espie 690: size_t length;
1.1 deraadt 691: Boolean freeIt;
692: char *result;
693:
1.48 espie 694: result=Var_Parse(cp, NULL, TRUE, &length, &freeIt);
1.1 deraadt 695:
696: if (freeIt) {
697: free(result);
698: }
699: cp += length-1;
700: }
701: continue;
702: }
703: if (*cp == '(') {
704: /*
705: * Archives must be handled specially to make sure the OP_ARCHV
706: * flag is set in their 'type' field, for one thing, and because
707: * things like "archive(file1.o file2.o file3.o)" are permissible.
708: * Arch_ParseArchive will set 'line' to be the first non-blank
709: * after the archive-spec. It creates/finds nodes for the members
710: * and places them on the given list, returning SUCCESS if all
711: * went well and FAILURE if there was an error in the
712: * specification. On error, line should remain untouched.
713: */
1.48 espie 714: if (Arch_ParseArchive(&line, &targets, NULL) != SUCCESS) {
1.1 deraadt 715: Parse_Error (PARSE_FATAL,
716: "Error in archive specification: \"%s\"", line);
717: return;
718: } else {
719: continue;
720: }
721: }
722: savec = *cp;
1.11 millert 723:
1.1 deraadt 724: if (!*cp) {
725: /*
726: * Ending a dependency line without an operator is a Bozo
1.11 millert 727: * no-no
1.1 deraadt 728: */
729: Parse_Error (PARSE_FATAL, "Need an operator");
730: return;
731: }
732: *cp = '\0';
733: /*
734: * Have a word in line. See if it's a special target and set
735: * specType to match it.
736: */
737: if (*line == '.' && isupper (line[1])) {
738: /*
739: * See if the target is a special target that must have it
1.11 millert 740: * or its sources handled specially.
1.1 deraadt 741: */
742: int keywd = ParseFindKeyword(line);
743: if (keywd != -1) {
744: if (specType == ExPath && parseKeywords[keywd].spec != ExPath) {
745: Parse_Error(PARSE_FATAL, "Mismatched special targets");
746: return;
747: }
1.11 millert 748:
1.1 deraadt 749: specType = parseKeywords[keywd].spec;
750: tOp = parseKeywords[keywd].op;
751:
752: /*
753: * Certain special targets have special semantics:
754: * .PATH Have to set the dirSearchPath
755: * variable too
756: * .MAIN Its sources are only used if
757: * nothing has been specified to
758: * create.
759: * .DEFAULT Need to create a node to hang
760: * commands on, but we don't want
761: * it in the graph, nor do we want
762: * it to be the Main Target, so we
763: * create it, set OP_NOTMAIN and
764: * add it to the list, setting
765: * DEFAULT to the new node for
766: * later use. We claim the node is
767: * A transformation rule to make
768: * life easier later, when we'll
769: * use Make_HandleUse to actually
770: * apply the .DEFAULT commands.
1.7 niklas 771: * .PHONY The list of targets
1.17 espie 772: * .NOPATH Don't search for file in the path
1.1 deraadt 773: * .BEGIN
774: * .END
775: * .INTERRUPT Are not to be considered the
776: * main target.
777: * .NOTPARALLEL Make only one target at a time.
778: * .SINGLESHELL Create a shell for each command.
1.33 espie 779: * .ORDER Must set initial predecessor to NULL
1.1 deraadt 780: */
781: switch (specType) {
782: case ExPath:
1.45 espie 783: Lst_AtEnd(&paths, &dirSearchPath);
1.1 deraadt 784: break;
785: case Main:
1.43 espie 786: if (!Lst_IsEmpty(&create)) {
1.1 deraadt 787: specType = Not;
788: }
789: break;
790: case Begin:
791: case End:
792: case Interrupt:
793: gn = Targ_FindNode(line, TARG_CREATE);
794: gn->type |= OP_NOTMAIN;
1.45 espie 795: Lst_AtEnd(&targets, gn);
1.1 deraadt 796: break;
797: case Default:
1.55 espie 798: gn = Targ_NewGN(".DEFAULT", NULL);
1.1 deraadt 799: gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
1.45 espie 800: Lst_AtEnd(&targets, gn);
1.1 deraadt 801: DEFAULT = gn;
802: break;
803: case NotParallel:
804: {
805: extern int maxJobs;
1.11 millert 806:
1.1 deraadt 807: maxJobs = 1;
808: break;
809: }
810: case SingleShell:
811: compatMake = 1;
812: break;
813: case Order:
1.33 espie 814: predecessor = NULL;
1.1 deraadt 815: break;
816: default:
817: break;
818: }
819: } else if (strncmp (line, ".PATH", 5) == 0) {
820: /*
821: * .PATH<suffix> has to be handled specially.
822: * Call on the suffix module to give us a path to
823: * modify.
824: */
825: Lst path;
1.11 millert 826:
1.1 deraadt 827: specType = ExPath;
1.45 espie 828: path = Suff_GetPath(&line[5]);
1.33 espie 829: if (path == NULL) {
1.45 espie 830: Parse_Error(PARSE_FATAL,
1.1 deraadt 831: "Suffix '%s' not defined (yet)",
832: &line[5]);
833: return;
1.45 espie 834: } else
835: Lst_AtEnd(&paths, path);
1.1 deraadt 836: }
837: }
1.11 millert 838:
1.1 deraadt 839: /*
840: * Have word in line. Get or create its node and stick it at
1.11 millert 841: * the end of the targets list
1.1 deraadt 842: */
843: if ((specType == Not) && (*line != '\0')) {
1.34 espie 844: char *targName;
845:
1.1 deraadt 846: if (Dir_HasWildcards(line)) {
847: /*
848: * Targets are to be sought only in the current directory,
849: * so create an empty path for the thing. Note we need to
850: * use Dir_Destroy in the destruction of the path as the
851: * Dir module could have added a directory to the path...
852: */
1.43 espie 853: LIST emptyPath;
854:
855: Lst_Init(&emptyPath);
1.11 millert 856:
1.43 espie 857: Dir_Expand(line, &emptyPath, &curTargs);
1.11 millert 858:
1.43 espie 859: Lst_Destroy(&emptyPath, Dir_Destroy);
1.1 deraadt 860: } else {
861: /*
862: * No wildcards, but we want to avoid code duplication,
863: * so create a list with the word on it.
864: */
1.43 espie 865: Lst_AtEnd(&curTargs, line);
1.1 deraadt 866: }
1.11 millert 867:
1.43 espie 868: while((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) {
1.1 deraadt 869: if (!Suff_IsTransform (targName)) {
870: gn = Targ_FindNode (targName, TARG_CREATE);
871: } else {
872: gn = Suff_AddTransform (targName);
873: }
1.11 millert 874:
1.16 millert 875: if (gn != NULL)
1.45 espie 876: Lst_AtEnd(&targets, gn);
1.1 deraadt 877: }
878: } else if (specType == ExPath && *line != '.' && *line != '\0') {
879: Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
880: }
1.11 millert 881:
1.1 deraadt 882: *cp = savec;
883: /*
884: * If it is a special type and not .PATH, it's the only target we
885: * allow on this line...
886: */
887: if (specType != Not && specType != ExPath) {
888: Boolean warn = FALSE;
1.11 millert 889:
1.1 deraadt 890: while ((*cp != '!') && (*cp != ':') && *cp) {
891: if (*cp != ' ' && *cp != '\t') {
892: warn = TRUE;
893: }
894: cp++;
895: }
896: if (warn) {
897: Parse_Error(PARSE_WARNING, "Extra target ignored");
898: }
899: } else {
900: while (*cp && isspace (*cp)) {
901: cp++;
902: }
903: }
904: line = cp;
905: } while ((*line != '!') && (*line != ':') && *line);
906:
1.43 espie 907: /* Don't need the list of target names any more */
908: Lst_Destroy(&curTargs, NOFREE);
1.1 deraadt 909:
1.45 espie 910: if (!Lst_IsEmpty(&targets)) {
1.1 deraadt 911: switch(specType) {
912: default:
913: Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
914: break;
915: case Default:
916: case Begin:
917: case End:
918: case Interrupt:
919: /*
920: * These four create nodes on which to hang commands, so
921: * targets shouldn't be empty...
922: */
923: case Not:
924: /*
925: * Nothing special here -- targets can be empty if it wants.
926: */
927: break;
928: }
929: }
930:
931: /*
932: * Have now parsed all the target names. Must parse the operator next. The
933: * result is left in op .
934: */
935: if (*cp == '!') {
936: op = OP_FORCE;
937: } else if (*cp == ':') {
938: if (cp[1] == ':') {
939: op = OP_DOUBLEDEP;
940: cp++;
941: } else {
942: op = OP_DEPENDS;
943: }
944: } else {
945: Parse_Error (PARSE_FATAL, "Missing dependency operator");
946: return;
947: }
948:
949: cp++; /* Advance beyond operator */
950:
1.45 espie 951: Lst_Find(&targets, ParseDoOp, &op);
1.1 deraadt 952:
953: /*
1.11 millert 954: * Get to the first source
1.1 deraadt 955: */
956: while (*cp && isspace (*cp)) {
957: cp++;
958: }
959: line = cp;
960:
961: /*
962: * Several special targets take different actions if present with no
963: * sources:
964: * a .SUFFIXES line with no sources clears out all old suffixes
965: * a .PRECIOUS line makes all targets precious
966: * a .IGNORE line ignores errors for all targets
967: * a .SILENT line creates silence when making all targets
968: * a .PATH removes all directories from the search path(s).
969: */
970: if (!*line) {
971: switch (specType) {
972: case Suffixes:
973: Suff_ClearSuffixes ();
974: break;
975: case Precious:
976: allPrecious = TRUE;
977: break;
978: case Ignore:
979: ignoreErrors = TRUE;
980: break;
981: case Silent:
982: beSilent = TRUE;
983: break;
984: case ExPath:
1.45 espie 985: Lst_Every(&paths, ParseClearPath);
1.1 deraadt 986: break;
987: default:
988: break;
989: }
990: } else if (specType == MFlags) {
991: /*
992: * Call on functions in main.c to deal with these arguments and
993: * set the initial character to a null-character so the loop to
994: * get sources won't get anything
995: */
996: Main_ParseArgLine (line);
997: *line = '\0';
998: } else if (specType == ExShell) {
999: if (Job_ParseShell (line) != SUCCESS) {
1000: Parse_Error (PARSE_FATAL, "improper shell specification");
1001: return;
1002: }
1003: *line = '\0';
1004: } else if ((specType == NotParallel) || (specType == SingleShell)) {
1005: *line = '\0';
1006: }
1.11 millert 1007:
1.1 deraadt 1008: /*
1.11 millert 1009: * NOW GO FOR THE SOURCES
1.1 deraadt 1010: */
1011: if ((specType == Suffixes) || (specType == ExPath) ||
1012: (specType == Includes) || (specType == Libs) ||
1013: (specType == Null))
1014: {
1015: while (*line) {
1016: /*
1017: * If the target was one that doesn't take files as its sources
1018: * but takes something like suffixes, we take each
1019: * space-separated word on the line as a something and deal
1020: * with it accordingly.
1021: *
1022: * If the target was .SUFFIXES, we take each source as a
1023: * suffix and add it to the list of suffixes maintained by the
1024: * Suff module.
1025: *
1026: * If the target was a .PATH, we add the source as a directory
1027: * to search on the search path.
1028: *
1029: * If it was .INCLUDES, the source is taken to be the suffix of
1030: * files which will be #included and whose search path should
1031: * be present in the .INCLUDES variable.
1032: *
1033: * If it was .LIBS, the source is taken to be the suffix of
1034: * files which are considered libraries and whose search path
1035: * should be present in the .LIBS variable.
1036: *
1037: * If it was .NULL, the source is the suffix to use when a file
1038: * has no valid suffix.
1039: */
1040: char savec;
1041: while (*cp && !isspace (*cp)) {
1042: cp++;
1043: }
1044: savec = *cp;
1045: *cp = '\0';
1046: switch (specType) {
1047: case Suffixes:
1048: Suff_AddSuffix (line);
1049: break;
1050: case ExPath:
1.45 espie 1051: Lst_ForEach(&paths, ParseAddDir, line);
1.1 deraadt 1052: break;
1053: case Includes:
1054: Suff_AddInclude (line);
1055: break;
1056: case Libs:
1057: Suff_AddLib (line);
1058: break;
1059: case Null:
1060: Suff_SetNull (line);
1061: break;
1062: default:
1063: break;
1064: }
1065: *cp = savec;
1066: if (savec != '\0') {
1067: cp++;
1068: }
1069: while (*cp && isspace (*cp)) {
1070: cp++;
1071: }
1072: line = cp;
1073: }
1.45 espie 1074: Lst_Destroy(&paths, NOFREE);
1.1 deraadt 1075: } else {
1076: while (*line) {
1077: /*
1078: * The targets take real sources, so we must beware of archive
1079: * specifications (i.e. things with left parentheses in them)
1080: * and handle them accordingly.
1081: */
1082: while (*cp && !isspace (*cp)) {
1083: if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) {
1084: /*
1085: * Only stop for a left parenthesis if it isn't at the
1086: * start of a word (that'll be for variable changes
1087: * later) and isn't preceded by a dollar sign (a dynamic
1088: * source).
1089: */
1090: break;
1091: } else {
1092: cp++;
1093: }
1094: }
1095:
1096: if (*cp == '(') {
1097: GNode *gn;
1.43 espie 1098: LIST sources; /* list of archive source names after
1099: * expansion */
1.1 deraadt 1100:
1.43 espie 1101: Lst_Init(&sources);
1.48 espie 1102: if (Arch_ParseArchive(&line, &sources, NULL) != SUCCESS) {
1.1 deraadt 1103: Parse_Error (PARSE_FATAL,
1104: "Error in source archive spec \"%s\"", line);
1105: return;
1106: }
1107:
1.43 espie 1108: while ((gn = (GNode *)Lst_DeQueue(&sources)) != NULL)
1109: ParseDoSrc(tOp, gn->name, &curSrcs);
1110: Lst_Destroy(&sources, NOFREE);
1.1 deraadt 1111: cp = line;
1112: } else {
1113: if (*cp) {
1114: *cp = '\0';
1115: cp += 1;
1116: }
1117:
1.43 espie 1118: ParseDoSrc(tOp, line, &curSrcs);
1.1 deraadt 1119: }
1120: while (*cp && isspace (*cp)) {
1121: cp++;
1122: }
1123: line = cp;
1124: }
1125: }
1.11 millert 1126:
1.33 espie 1127: if (mainNode == NULL) {
1.1 deraadt 1128: /*
1129: * If we have yet to decide on a main target to make, in the
1130: * absence of any user input, we want the first target on
1131: * the first dependency line that is actually a real target
1132: * (i.e. isn't a .USE or .EXEC rule) to be made.
1133: */
1.45 espie 1134: Lst_Find(&targets, ParseFindMain, NULL);
1.1 deraadt 1135: }
1136:
1.43 espie 1137: /* Finally, destroy the list of sources. */
1138: Lst_Destroy(&curSrcs, NOFREE);
1.1 deraadt 1139: }
1140:
1141: /*-
1142: *---------------------------------------------------------------------
1143: * Parse_IsVar --
1144: * Return TRUE if the passed line is a variable assignment. A variable
1145: * assignment consists of a single word followed by optional whitespace
1146: * followed by either a += or an = operator.
1147: * This function is used both by the Parse_File function and main when
1148: * parsing the command-line arguments.
1149: *
1150: * Results:
1151: * TRUE if it is. FALSE if it ain't
1152: *
1153: * Side Effects:
1154: * none
1155: *---------------------------------------------------------------------
1156: */
1157: Boolean
1158: Parse_IsVar (line)
1159: register char *line; /* the line to check */
1160: {
1161: register Boolean wasSpace = FALSE; /* set TRUE if found a space */
1162: register Boolean haveName = FALSE; /* Set TRUE if have a variable name */
1163: int level = 0;
1164: #define ISEQOPERATOR(c) \
1165: (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!'))
1166:
1167: /*
1168: * Skip to variable name
1169: */
1.11 millert 1170: for (;(*line == ' ') || (*line == '\t'); line++)
1.1 deraadt 1171: continue;
1172:
1173: for (; *line != '=' || level != 0; line++)
1174: switch (*line) {
1175: case '\0':
1176: /*
1177: * end-of-line -- can't be a variable assignment.
1178: */
1179: return FALSE;
1180:
1181: case ' ':
1182: case '\t':
1183: /*
1184: * there can be as much white space as desired so long as there is
1.11 millert 1185: * only one word before the operator
1.1 deraadt 1186: */
1187: wasSpace = TRUE;
1188: break;
1189:
1190: case '(':
1191: case '{':
1192: level++;
1193: break;
1194:
1195: case '}':
1196: case ')':
1197: level--;
1198: break;
1.11 millert 1199:
1.1 deraadt 1200: default:
1201: if (wasSpace && haveName) {
1202: if (ISEQOPERATOR(*line)) {
1203: /*
1.9 briggs 1204: * We must have a finished word
1205: */
1206: if (level != 0)
1207: return FALSE;
1208:
1209: /*
1.1 deraadt 1210: * When an = operator [+?!:] is found, the next
1.9 briggs 1211: * character must be an = or it ain't a valid
1.1 deraadt 1212: * assignment.
1213: */
1.9 briggs 1214: if (line[1] == '=')
1.1 deraadt 1215: return haveName;
1.9 briggs 1216: #ifdef SUNSHCMD
1.1 deraadt 1217: /*
1.9 briggs 1218: * This is a shell command
1.1 deraadt 1219: */
1.9 briggs 1220: if (strncmp(line, ":sh", 3) == 0)
1221: return haveName;
1222: #endif
1.1 deraadt 1223: }
1.9 briggs 1224: /*
1225: * This is the start of another word, so not assignment.
1226: */
1227: return FALSE;
1.1 deraadt 1228: }
1229: else {
1.11 millert 1230: haveName = TRUE;
1.1 deraadt 1231: wasSpace = FALSE;
1232: }
1233: break;
1234: }
1235:
1236: return haveName;
1237: }
1238:
1239: /*-
1240: *---------------------------------------------------------------------
1241: * Parse_DoVar --
1242: * Take the variable assignment in the passed line and do it in the
1243: * global context.
1244: *
1245: * Note: There is a lexical ambiguity with assignment modifier characters
1246: * in variable names. This routine interprets the character before the =
1247: * as a modifier. Therefore, an assignment like
1248: * C++=/usr/bin/CC
1249: * is interpreted as "C+ +=" instead of "C++ =".
1250: *
1251: * Results:
1252: * none
1253: *
1254: * Side Effects:
1255: * the variable structure of the given variable name is altered in the
1256: * global context.
1257: *---------------------------------------------------------------------
1258: */
1259: void
1260: Parse_DoVar (line, ctxt)
1261: char *line; /* a line guaranteed to be a variable
1262: * assignment. This reduces error checks */
1.49 espie 1263: GSymT *ctxt; /* Context in which to do the assignment */
1.1 deraadt 1264: {
1265: char *cp; /* pointer into line */
1266: enum {
1267: VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
1268: } type; /* Type of assignment */
1.11 millert 1269: char *opc; /* ptr to operator character to
1.1 deraadt 1270: * null-terminate the variable name */
1.11 millert 1271: /*
1.1 deraadt 1272: * Avoid clobbered variable warnings by forcing the compiler
1273: * to ``unregister'' variables
1274: */
1275: #if __GNUC__
1276: (void) &cp;
1277: (void) &line;
1278: #endif
1279:
1280: /*
1281: * Skip to variable name
1282: */
1283: while ((*line == ' ') || (*line == '\t')) {
1284: line++;
1285: }
1286:
1287: /*
1288: * Skip to operator character, nulling out whitespace as we go
1289: */
1290: for (cp = line + 1; *cp != '='; cp++) {
1291: if (isspace (*cp)) {
1292: *cp = '\0';
1293: }
1294: }
1295: opc = cp-1; /* operator is the previous character */
1296: *cp++ = '\0'; /* nuke the = */
1297:
1298: /*
1299: * Check operator type
1300: */
1301: switch (*opc) {
1302: case '+':
1303: type = VAR_APPEND;
1304: *opc = '\0';
1305: break;
1306:
1307: case '?':
1308: /*
1309: * If the variable already has a value, we don't do anything.
1310: */
1311: *opc = '\0';
1312: if (Var_Exists(line, ctxt)) {
1313: return;
1314: } else {
1315: type = VAR_NORMAL;
1316: }
1317: break;
1318:
1319: case ':':
1320: type = VAR_SUBST;
1321: *opc = '\0';
1322: break;
1323:
1324: case '!':
1325: type = VAR_SHELL;
1326: *opc = '\0';
1327: break;
1328:
1329: default:
1.9 briggs 1330: #ifdef SUNSHCMD
1331: while (*opc != ':')
1332: if (--opc < line)
1333: break;
1334:
1335: if (strncmp(opc, ":sh", 3) == 0) {
1336: type = VAR_SHELL;
1337: *opc = '\0';
1338: break;
1339: }
1340: #endif
1.1 deraadt 1341: type = VAR_NORMAL;
1342: break;
1343: }
1344:
1345: while (isspace (*cp)) {
1346: cp++;
1347: }
1348:
1349: if (type == VAR_APPEND) {
1350: Var_Append (line, cp, ctxt);
1351: } else if (type == VAR_SUBST) {
1352: /*
1353: * Allow variables in the old value to be undefined, but leave their
1354: * invocation alone -- this is done by forcing oldVars to be false.
1355: * XXX: This can cause recursive variables, but that's not hard to do,
1356: * and this allows someone to do something like
1357: *
1358: * CFLAGS = $(.INCLUDES)
1359: * CFLAGS := -I.. $(CFLAGS)
1360: *
1361: * And not get an error.
1362: */
1363: Boolean oldOldVars = oldVars;
1364:
1365: oldVars = FALSE;
1.49 espie 1366: cp = Var_Subst(cp, (SymTable *)ctxt, FALSE);
1.1 deraadt 1367: oldVars = oldOldVars;
1368:
1369: Var_Set(line, cp, ctxt);
1370: free(cp);
1371: } else if (type == VAR_SHELL) {
1.9 briggs 1372: Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e.
1373: * if any variable expansion was performed */
1374: char *res, *err;
1.1 deraadt 1375:
1.9 briggs 1376: if (strchr(cp, '$') != NULL) {
1.1 deraadt 1377: /*
1378: * There's a dollar sign in the command, so perform variable
1379: * expansion on the whole thing. The resulting string will need
1380: * freeing when we're done, so set freeCmd to TRUE.
1381: */
1.48 espie 1382: cp = Var_Subst(cp, NULL, TRUE);
1.1 deraadt 1383: freeCmd = TRUE;
1384: }
1385:
1.9 briggs 1386: res = Cmd_Exec(cp, &err);
1387: Var_Set(line, res, ctxt);
1388: free(res);
1.1 deraadt 1389:
1.9 briggs 1390: if (err)
1391: Parse_Error(PARSE_WARNING, err, cp);
1.1 deraadt 1392:
1.9 briggs 1393: if (freeCmd)
1394: free(cp);
1.1 deraadt 1395: } else {
1396: /*
1397: * Normal assignment -- just do it.
1398: */
1.9 briggs 1399: Var_Set(line, cp, ctxt);
1.1 deraadt 1400: }
1401: }
1402:
1.9 briggs 1403:
1.1 deraadt 1404: /*-
1405: * ParseAddCmd --
1406: * Lst_ForEach function to add a command line to all targets
1407: *
1408: * Side Effects:
1409: * A new element is added to the commands list of the node.
1410: */
1.41 espie 1411: static void
1.1 deraadt 1412: ParseAddCmd(gnp, cmd)
1.42 espie 1413: void *gnp; /* the node to which the command is to be added */
1414: void *cmd; /* the command to add */
1.1 deraadt 1415: {
1.41 espie 1416: GNode *gn = (GNode *)gnp;
1.1 deraadt 1417: /* if target already supplied, ignore commands */
1.39 espie 1418: if (!(gn->type & OP_HAS_COMMANDS)) {
1.43 espie 1419: Lst_AtEnd(&gn->commands, cmd);
1.39 espie 1420: if (!gn->lineno) {
1421: gn->lineno = Parse_Getlineno();
1422: gn->fname = Parse_Getfilename();
1423: }
1424: }
1.1 deraadt 1425: }
1426:
1427: /*-
1428: *-----------------------------------------------------------------------
1429: * ParseHasCommands --
1430: * Callback procedure for Parse_File when destroying the list of
1431: * targets on the last dependency line. Marks a target as already
1432: * having commands if it does, to keep from having shell commands
1433: * on multiple dependency lines.
1434: *
1435: * Results:
1436: * None
1437: *
1438: * Side Effects:
1439: * OP_HAS_COMMANDS may be set for the target.
1440: *
1441: *-----------------------------------------------------------------------
1442: */
1443: static void
1444: ParseHasCommands(gnp)
1.42 espie 1445: void *gnp; /* Node to examine */
1.1 deraadt 1446: {
1447: GNode *gn = (GNode *) gnp;
1.43 espie 1448: if (!Lst_IsEmpty(&gn->commands)) {
1.1 deraadt 1449: gn->type |= OP_HAS_COMMANDS;
1450: }
1451: }
1452:
1453: /*-
1454: *-----------------------------------------------------------------------
1455: * Parse_AddIncludeDir --
1456: * Add a directory to the path searched for included makefiles
1457: * bracketed by double-quotes. Used by functions in main.c
1458: *
1459: * Results:
1460: * None.
1461: *
1462: * Side Effects:
1463: * The directory is appended to the list.
1464: *
1465: *-----------------------------------------------------------------------
1466: */
1467: void
1.43 espie 1468: Parse_AddIncludeDir(dir)
1.1 deraadt 1469: char *dir; /* The name of the directory to add */
1470: {
1.56 espie 1471: Dir_AddDir(&parseIncPath, dir, NULL);
1.1 deraadt 1472: }
1473:
1474: /*-
1475: *---------------------------------------------------------------------
1476: * ParseDoInclude --
1477: * Push to another file.
1.11 millert 1478: *
1.1 deraadt 1479: * The input is the line minus the #include. A file spec is a string
1480: * enclosed in <> or "". The former is looked for only in sysIncPath.
1481: * The latter in . and the directories specified by -I command line
1482: * options
1483: *
1484: * Side Effects:
1.50 espie 1485: * old parse context is pushed on the stack, new file becomes
1486: * current context.
1.1 deraadt 1487: *---------------------------------------------------------------------
1488: */
1489: static void
1.50 espie 1490: ParseDoInclude(file)
1.1 deraadt 1491: char *file; /* file specification */
1492: {
1493: char endc; /* the character which ends the file spec */
1494: char *cp; /* current position in file spec */
1495: Boolean isSystem; /* TRUE if makefile is a system makefile */
1496:
1.50 espie 1497: /* Skip to delimiter character so we know where to look */
1498: while (*file == ' ' || *file == '\t')
1.1 deraadt 1499: file++;
1500:
1.50 espie 1501: if (*file != '"' && *file != '<') {
1.1 deraadt 1502: Parse_Error (PARSE_FATAL,
1503: ".include filename must be delimited by '\"' or '<'");
1504: return;
1505: }
1506:
1.50 espie 1507: /* Set the search path on which to find the include file based on the
1.1 deraadt 1508: * characters which bracket its name. Angle-brackets imply it's
1.50 espie 1509: * a system Makefile while double-quotes imply it's a user makefile */
1.1 deraadt 1510: if (*file == '<') {
1511: isSystem = TRUE;
1512: endc = '>';
1513: } else {
1514: isSystem = FALSE;
1515: endc = '"';
1516: }
1517:
1.50 espie 1518: /* Skip to matching delimiter */
1.1 deraadt 1519: for (cp = ++file; *cp && *cp != endc; cp++) {
1.50 espie 1520: if (*cp == '\0') {
1521: Parse_Error(PARSE_FATAL,
1.1 deraadt 1522: "Unclosed %cinclude filename. '%c' expected",
1523: '.', endc);
1.50 espie 1524: return;
1.1 deraadt 1525: }
1526: }
1.50 espie 1527: ParseLookupIncludeFile(file, cp, isSystem);
1.1 deraadt 1528: }
1529:
1530: #ifdef SYSVINCLUDE
1531: /*-
1532: *---------------------------------------------------------------------
1533: * ParseTraditionalInclude --
1534: * Push to another file.
1.11 millert 1535: *
1.1 deraadt 1536: * The input is the line minus the "include". The file name is
1537: * the string following the "include".
1538: *
1539: * Side Effects:
1.50 espie 1540: * old parse context is pushed on the stack, new file becomes
1541: * current context.
1.1 deraadt 1542: *---------------------------------------------------------------------
1543: */
1544: static void
1.50 espie 1545: ParseTraditionalInclude(file)
1.1 deraadt 1546: char *file; /* file specification */
1547: {
1548: char *cp; /* current position in file spec */
1549:
1.50 espie 1550: /* Skip over whitespace */
1551: while (*file == ' ' || *file == '\t')
1.1 deraadt 1552: file++;
1553:
1554: if (*file == '\0') {
1555: Parse_Error (PARSE_FATAL,
1556: "Filename missing from \"include\"");
1557: return;
1558: }
1559:
1.50 espie 1560: /* Skip to end of line or next whitespace */
1561: for (cp = file; *cp != '\0' && !isspace(*cp);)
1562: cp++;
1.1 deraadt 1563:
1.50 espie 1564: ParseLookupIncludeFile(file, cp, TRUE);
1565: }
1566: #endif
1.1 deraadt 1567:
1.50 espie 1568: /* Common part to lookup and read an include file. */
1569: static void
1570: ParseLookupIncludeFile(spec, endSpec, isSystem)
1571: char *spec;
1572: char *endSpec;
1573: Boolean isSystem;
1574: {
1575: char *file;
1576: char *fullname;
1577: char endc;
1578:
1579: /* Substitute for any variables in the file name before trying to
1580: * find the thing. */
1581: endc = *endSpec;
1582: *endSpec = '\0';
1583: file = Var_Subst(spec, NULL, FALSE);
1584: *endSpec = endc;
1585:
1586: /* Now that we know the file name and its search path, we attempt to
1587: * find the durn thing. NULL indicates the file still hasn't been
1588: * found. */
1589: fullname = NULL;
1590:
1591: /* Handle non-system non-absolute files... */
1592: if (!isSystem && file[0] != '/') {
1593: /* ... by first searching relative to the including file's
1594: * location. We don't want to cd there, of course, so we
1595: * just tack on the old file's leading path components
1596: * and call Dir_FindFile to see if we can locate the beast. */
1597: char *slash;
1598:
1599: slash = strrchr(Parse_Getfilename(), '/');
1600: if (slash != NULL) {
1601: char *base, *newName;
1602:
1603: base = interval_dup(Parse_Getfilename(), slash);
1.52 espie 1604: newName = str_concat(base, file, '/');
1.50 espie 1605: free(base);
1606: fullname = Dir_FindFile(newName, &parseIncPath);
1607: if (fullname == NULL)
1608: fullname = Dir_FindFile(newName, &dirSearchPath);
1609: free(newName);
1610: }
1.1 deraadt 1611: }
1612:
1.50 espie 1613: /* Now look first on the -I search path, then on the .PATH
1614: * search path, if not found in a -I directory.
1615: * XXX: Suffix specific? */
1616: if (fullname == NULL)
1.43 espie 1617: fullname = Dir_FindFile(file, &parseIncPath);
1.50 espie 1618: if (fullname == NULL)
1619: fullname = Dir_FindFile(file, &dirSearchPath);
1.1 deraadt 1620:
1.50 espie 1621: /* Still haven't found the makefile. Look for it on the system
1622: * path as a last resort. */
1623: if (fullname == NULL)
1.43 espie 1624: fullname = Dir_FindFile(file, &sysIncPath);
1.1 deraadt 1625:
1.50 espie 1626: if (fullname == NULL)
1627: Parse_Error(PARSE_FATAL, "Could not find %s", file);
1.1 deraadt 1628:
1.50 espie 1629: free(file);
1.1 deraadt 1630:
1.50 espie 1631: if (fullname != NULL) {
1632: FILE *f;
1.1 deraadt 1633:
1.50 espie 1634: f = fopen(fullname, "r");
1635: if (f == NULL) {
1636: Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
1637: } else {
1638: /* Once we find the absolute path to the file, we push the current
1639: * stream to the includes stack, and start reading from the new
1640: * file. We set up the file name to be its absolute name so that
1641: * error messages are informative. */
1642: Parse_FromFile(fullname, f);
1643: }
1.1 deraadt 1644: }
1645: }
1646:
1647: /*-
1648: *-----------------------------------------------------------------------
1649: * ParseFinishLine --
1650: * Handle the end of a dependency group.
1651: *
1652: * Side Effects:
1653: * inLine set FALSE. 'targets' list destroyed.
1654: *
1655: *-----------------------------------------------------------------------
1656: */
1657: static void
1658: ParseFinishLine()
1659: {
1660: if (inLine) {
1.45 espie 1661: Lst_Every(&targets, Suff_EndTransform);
1662: Lst_Destroy(&targets, ParseHasCommands);
1663: Lst_Init(&targets);
1.1 deraadt 1664: inLine = FALSE;
1665: }
1666: }
1.11 millert 1667:
1.1 deraadt 1668:
1669: /*-
1670: *---------------------------------------------------------------------
1671: * Parse_File --
1672: * Parse a file into its component parts, incorporating it into the
1673: * current dependency graph. This is the main function and controls
1674: * almost every other function in this module
1675: *
1676: * Results:
1677: * None
1678: *
1679: * Side Effects:
1680: * Loads. Nodes are added to the list of all targets, nodes and links
1681: * are added to the dependency graph. etc. etc. etc.
1682: *---------------------------------------------------------------------
1683: */
1684: void
1685: Parse_File(name, stream)
1686: char *name; /* the name of the file being read */
1687: FILE * stream; /* Stream open to makefile to parse */
1688: {
1689: register char *cp, /* pointer into the line */
1690: *line; /* the line we're working on */
1691:
1692: inLine = FALSE;
1.50 espie 1693: Parse_FromFile(name, stream);
1.1 deraadt 1694: do {
1695: while ((line = ParseReadLine ()) != NULL) {
1696: if (*line == '.') {
1697: /*
1698: * Lines that begin with the special character are either
1699: * include or undef directives.
1700: */
1701: for (cp = line + 1; isspace (*cp); cp++) {
1702: continue;
1703: }
1704: if (strncmp (cp, "include", 7) == 0) {
1705: ParseDoInclude (cp + 7);
1706: goto nextLine;
1707: } else if (strncmp(cp, "undef", 5) == 0) {
1708: char *cp2;
1709: for (cp += 5; isspace((unsigned char) *cp); cp++) {
1710: continue;
1711: }
1712:
1713: for (cp2 = cp; !isspace((unsigned char) *cp2) &&
1714: (*cp2 != '\0'); cp2++) {
1715: continue;
1716: }
1717:
1718: *cp2 = '\0';
1719:
1720: Var_Delete(cp, VAR_GLOBAL);
1721: goto nextLine;
1722: }
1723: }
1.11 millert 1724: if (*line == '#') {
1725: /* If we're this far, the line must be a comment. */
1.1 deraadt 1726: goto nextLine;
1727: }
1.11 millert 1728:
1.1 deraadt 1729: if (*line == '\t') {
1730: /*
1731: * If a line starts with a tab, it can only hope to be
1732: * a creation command.
1733: */
1734: #ifndef POSIX
1735: shellCommand:
1736: #endif
1737: for (cp = line + 1; isspace (*cp); cp++) {
1738: continue;
1739: }
1740: if (*cp) {
1741: if (inLine) {
1742: /*
1743: * So long as it's not a blank line and we're actually
1744: * in a dependency spec, add the command to the list of
1.11 millert 1745: * commands of all targets in the dependency spec
1.1 deraadt 1746: */
1.45 espie 1747: Lst_ForEach(&targets, ParseAddCmd, cp);
1.20 espie 1748: #ifdef CLEANUP
1.43 espie 1749: Lst_AtEnd(&targCmds, line);
1.20 espie 1750: #endif
1.1 deraadt 1751: continue;
1752: } else {
1753: Parse_Error (PARSE_FATAL,
1.10 briggs 1754: "Unassociated shell command \"%s\"",
1.1 deraadt 1755: cp);
1756: }
1757: }
1758: #ifdef SYSVINCLUDE
1.11 millert 1759: } else if (strncmp (line, "include", 7) == 0 &&
1.6 tholo 1760: isspace((unsigned char) line[7]) &&
1.1 deraadt 1761: strchr(line, ':') == NULL) {
1762: /*
1763: * It's an S3/S5-style "include".
1764: */
1765: ParseTraditionalInclude (line + 7);
1766: goto nextLine;
1767: #endif
1768: } else if (Parse_IsVar (line)) {
1769: ParseFinishLine();
1770: Parse_DoVar (line, VAR_GLOBAL);
1771: } else {
1772: /*
1773: * We now know it's a dependency line so it needs to have all
1774: * variables expanded before being parsed. Tell the variable
1775: * module to complain if some variable is undefined...
1776: * To make life easier on novices, if the line is indented we
1777: * first make sure the line has a dependency operator in it.
1778: * If it doesn't have an operator and we're in a dependency
1779: * line's script, we assume it's actually a shell command
1780: * and add it to the current list of targets.
1781: */
1782: #ifndef POSIX
1783: Boolean nonSpace = FALSE;
1784: #endif
1.11 millert 1785:
1.1 deraadt 1786: cp = line;
1787: if (isspace((unsigned char) line[0])) {
1788: while ((*cp != '\0') && isspace((unsigned char) *cp)) {
1789: cp++;
1790: }
1791: if (*cp == '\0') {
1792: goto nextLine;
1793: }
1794: #ifndef POSIX
1795: while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) {
1796: nonSpace = TRUE;
1797: cp++;
1798: }
1799: #endif
1800: }
1.11 millert 1801:
1.1 deraadt 1802: #ifndef POSIX
1803: if (*cp == '\0') {
1804: if (inLine) {
1805: Parse_Error (PARSE_WARNING,
1806: "Shell command needs a leading tab");
1807: goto shellCommand;
1808: } else if (nonSpace) {
1809: Parse_Error (PARSE_FATAL, "Missing operator");
1810: }
1811: } else {
1812: #endif
1813: ParseFinishLine();
1814:
1.48 espie 1815: cp = Var_Subst(line, NULL, TRUE);
1.1 deraadt 1816: free (line);
1817: line = cp;
1.11 millert 1818:
1.45 espie 1819: /* Need a new list for the target nodes */
1820: Lst_Destroy(&targets, NOFREE);
1821: Lst_Init(&targets);
1.1 deraadt 1822: inLine = TRUE;
1.11 millert 1823:
1.1 deraadt 1824: ParseDoDependency (line);
1825: #ifndef POSIX
1826: }
1827: #endif
1828: }
1829:
1830: nextLine:
1831:
1832: free (line);
1833: }
1.50 espie 1834: } while (Parse_NextFile());
1.1 deraadt 1835:
1.50 espie 1836: /* Make sure conditionals are clean */
1.1 deraadt 1837: Cond_End();
1838:
1.50 espie 1839: Finish_Errors();
1.1 deraadt 1840: }
1841:
1842: /*-
1843: *---------------------------------------------------------------------
1844: * Parse_Init --
1845: * initialize the parsing module
1846: *
1847: * Side Effects:
1848: * the parseIncPath list is initialized...
1849: *---------------------------------------------------------------------
1850: */
1851: void
1.43 espie 1852: Parse_Init()
1.1 deraadt 1853: {
1.33 espie 1854: mainNode = NULL;
1.43 espie 1855: Lst_Init(&parseIncPath);
1856: Lst_Init(&sysIncPath);
1.45 espie 1857: Lst_Init(&targets);
1.20 espie 1858: #ifdef CLEANUP
1.50 espie 1859: LowParse_Init();
1.43 espie 1860: Lst_Init(&targCmds);
1861: Lst_Init(&fileNames);
1.20 espie 1862: #endif
1.1 deraadt 1863: }
1864:
1865: void
1866: Parse_End()
1867: {
1.20 espie 1868: #ifdef CLEANUP
1.43 espie 1869: Lst_Destroy(&targCmds, (SimpleProc)free);
1870: Lst_Destroy(&fileNames, (void (*) __P((ClientData))) free);
1.45 espie 1871: Lst_Delete(&targets, NOFREE);
1.43 espie 1872: Lst_Destroy(&sysIncPath, Dir_Destroy);
1873: Lst_Destroy(&parseIncPath, Dir_Destroy);
1.50 espie 1874: LowParse_End();
1.20 espie 1875: #endif
1.1 deraadt 1876: }
1.11 millert 1877:
1.1 deraadt 1878:
1879: /*-
1880: *-----------------------------------------------------------------------
1881: * Parse_MainName --
1882: * Return a Lst of the main target to create for main()'s sake. If
1883: * no such target exists, we Punt with an obnoxious error message.
1884: *
1885: * Side Effects:
1.44 espie 1886: * Add the node to create to the list.
1.1 deraadt 1887: *
1888: *-----------------------------------------------------------------------
1889: */
1.44 espie 1890: void
1891: Parse_MainName(listmain)
1892: Lst listmain; /* result list */
1.1 deraadt 1893: {
1894:
1.44 espie 1895: if (mainNode == NULL)
1.8 deraadt 1896: Punt ("no target to make.");
1.1 deraadt 1897: /*NOTREACHED*/
1.44 espie 1898: else if (mainNode->type & OP_DOUBLEDEP) {
1.37 espie 1899: Lst_AtEnd(listmain, mainNode);
1.45 espie 1900: Lst_Concat(listmain, &mainNode->cohorts);
1.1 deraadt 1901: }
1902: else
1.37 espie 1903: Lst_AtEnd(listmain, mainNode);
1.1 deraadt 1904: }