rename DONTCARE as OPTIONAL
[unix-history] / usr / src / usr.bin / make / parse.c
CommitLineData
9320ab9e
KB
1/*
2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3 * Copyright (c) 1988, 1989 by Adam de Boor
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms are permitted
11 * provided that the above copyright notice and this paragraph are
12 * duplicated in all such forms and that any documentation,
13 * advertising materials, and other materials related to such
14 * distribution and use acknowledge that the software was developed
15 * by the University of California, Berkeley. The name of the
16 * University may not be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23#ifndef lint
ac8c8bba 24static char sccsid[] = "@(#)parse.c 5.11 (Berkeley) %G%";
9320ab9e
KB
25#endif /* not lint */
26
ab950546
KB
27/*-
28 * parse.c --
29 * Functions to parse a makefile.
30 *
31 * One function, Parse_Init, must be called before any functions
32 * in this module are used. After that, the function Parse_File is the
33 * main entry point and controls most of the other functions in this
34 * module.
35 *
36 * Most important structures are kept in Lsts. Directories for
37 * the #include "..." function are kept in the 'parseIncPath' Lst, while
38 * those for the #include <...> are kept in the 'sysIncPath' Lst. The
39 * targets currently being defined are kept in the 'targets' Lst.
40 *
41 * The variables 'fname' and 'lineno' are used to track the name
42 * of the current file and the line number in that file so that error
43 * messages can be more meaningful.
44 *
ab950546
KB
45 * Interface:
46 * Parse_Init Initialization function which must be
47 * called before anything else in this module
48 * is used.
49 *
50 * Parse_File Function used to parse a makefile. It must
51 * be given the name of the file, which should
52 * already have been opened, and a function
53 * to call to read a character from the file.
54 *
55 * Parse_IsVar Returns TRUE if the given line is a
56 * variable assignment. Used by MainParseArgs
57 * to determine if an argument is a target
58 * or a variable assignment. Used internally
59 * for pretty much the same thing...
60 *
61 * Parse_Error Function called when an error occurs in
62 * parsing. Used by the variable and
63 * conditional modules.
64 * Parse_MainName Returns a Lst of the main target to create.
65 */
ab950546 66
b6cda174
KB
67#include <varargs.h>
68#include <stdio.h>
69#include <ctype.h>
70#include "make.h"
71#include "buf.h"
aabb6217 72#include "pathnames.h"
ab950546
KB
73
74/*
75 * These values are returned by ParseEOF to tell Parse_File whether to
76 * CONTINUE parsing, i.e. it had only reached the end of an include file,
77 * or if it's DONE.
78 */
79#define CONTINUE 1
80#define DONE 0
81static int ParseEOF();
82
83static Lst targets; /* targets we're working on */
84static Boolean inLine; /* true if currently in a dependency
85 * line or its commands */
86
87static char *fname; /* name of current file (for errors) */
88static int lineno; /* line number in current file */
89static FILE *curFILE; /* current makefile */
90
91static int fatals = 0;
92
93static GNode *mainNode; /* The main target to create. This is the
94 * first target on the first dependency
95 * line in the first makefile */
96/*
97 * Definitions for handling #include specifications
98 */
99typedef struct IFile {
100 char *fname; /* name of previous file */
101 int lineno; /* saved line number */
102 FILE * F; /* the open stream */
103} IFile;
104
105static Lst includes; /* stack of IFiles generated by
106 * #includes */
107Lst parseIncPath; /* list of directories for "..." includes */
108Lst sysIncPath; /* list of directories for <...> includes */
109
ab950546
KB
110/*-
111 * specType contains the SPECial TYPE of the current target. It is
112 * Not if the target is unspecial. If it *is* special, however, the children
113 * are linked as children of the parent but not vice versa. This variable is
114 * set in ParseDoDependency
115 */
116typedef enum {
117 Begin, /* .BEGIN */
118 Default, /* .DEFAULT */
119 End, /* .END */
ab950546
KB
120 Ignore, /* .IGNORE */
121 Includes, /* .INCLUDES */
122 Interrupt, /* .INTERRUPT */
123 Libs, /* .LIBS */
124 MFlags, /* .MFLAGS or .MAKEFLAGS */
125 Main, /* .MAIN and we don't have anything user-specified to
126 * make */
ab950546
KB
127 Not, /* Not special */
128 NotParallel, /* .NOTPARALELL */
129 Null, /* .NULL */
130 Order, /* .ORDER */
131 Path, /* .PATH */
132 Precious, /* .PRECIOUS */
133 Shell, /* .SHELL */
134 Silent, /* .SILENT */
135 SingleShell, /* .SINGLESHELL */
136 Suffixes, /* .SUFFIXES */
137 Attribute, /* Generic attribute */
138} ParseSpecial;
139
140ParseSpecial specType;
141
142/*
143 * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
144 * seen, then set to each successive source on the line.
145 */
146static GNode *predecessor;
147
148/*
149 * The parseKeywords table is searched using binary search when deciding
150 * if a target or source is special. The 'spec' field is the ParseSpecial
151 * type of the keyword ("Not" if the keyword isn't special as a target) while
152 * the 'op' field is the operator to apply to the list of targets if the
153 * keyword is used as a source ("0" if the keyword isn't special as a source)
154 */
155static struct {
156 char *name; /* Name of keyword */
157 ParseSpecial spec; /* Type when used as a target */
158 int op; /* Operator when used as a source */
159} parseKeywords[] = {
160{ ".BEGIN", Begin, 0 },
161{ ".DEFAULT", Default, 0 },
ac8c8bba 162{ ".OPTIONAL", Attribute, OP_OPTIONAL },
ab950546
KB
163{ ".END", End, 0 },
164{ ".EXEC", Attribute, OP_EXEC },
ab950546
KB
165{ ".IGNORE", Ignore, OP_IGNORE },
166{ ".INCLUDES", Includes, 0 },
167{ ".INTERRUPT", Interrupt, 0 },
168{ ".INVISIBLE", Attribute, OP_INVISIBLE },
169{ ".JOIN", Attribute, OP_JOIN },
170{ ".LIBS", Libs, 0 },
ab950546
KB
171{ ".MAIN", Main, 0 },
172{ ".MAKE", Attribute, OP_MAKE },
173{ ".MAKEFLAGS", MFlags, 0 },
174{ ".MFLAGS", MFlags, 0 },
ab950546
KB
175{ ".NOTMAIN", Attribute, OP_NOTMAIN },
176{ ".NOTPARALLEL", NotParallel, 0 },
177{ ".NULL", Null, 0 },
178{ ".ORDER", Order, 0 },
179{ ".PATH", Path, 0 },
180{ ".PRECIOUS", Precious, OP_PRECIOUS },
181{ ".RECURSIVE", Attribute, OP_MAKE },
182{ ".SHELL", Shell, 0 },
183{ ".SILENT", Silent, OP_SILENT },
184{ ".SINGLESHELL", SingleShell, 0 },
185{ ".SUFFIXES", Suffixes, 0 },
186{ ".USE", Attribute, OP_USE },
187};
182ca07d 188
ab950546
KB
189/*-
190 *----------------------------------------------------------------------
191 * ParseFindKeyword --
192 * Look in the table of keywords for one matching the given string.
193 *
194 * Results:
195 * The index of the keyword, or -1 if it isn't there.
196 *
197 * Side Effects:
198 * None
199 *----------------------------------------------------------------------
200 */
201static int
202ParseFindKeyword (str)
203 char *str; /* String to find */
204{
205 register int start,
206 end,
207 cur;
208 register int diff;
209
210 start = 0;
211 end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
212
213 do {
214 cur = start + ((end - start) / 2);
215 diff = strcmp (str, parseKeywords[cur].name);
216
217 if (diff == 0) {
218 return (cur);
219 } else if (diff < 0) {
220 end = cur - 1;
221 } else {
222 start = cur + 1;
223 }
224 } while (start <= end);
225 return (-1);
226}
182ca07d 227
ab950546 228/*-
ab950546
KB
229 * Parse_Error --
230 * Error message abort function for parsing. Prints out the context
231 * of the error (line number and file) as well as the message with
232 * two optional arguments.
233 *
234 * Results:
235 * None
236 *
237 * Side Effects:
238 * "fatals" is incremented if the level is PARSE_FATAL.
ab950546 239 */
b6cda174 240/* VARARGS */
ab950546 241void
b6cda174
KB
242Parse_Error(type, va_alist)
243 int type; /* Error type (PARSE_WARNING, PARSE_FATAL) */
244 va_dcl
ab950546 245{
b6cda174
KB
246 va_list ap;
247 char *fmt;
ab950546 248
b6cda174
KB
249 (void)fprintf(stderr, "\"%s\", line %d: ", fname, lineno);
250 if (type == PARSE_WARNING)
43bbd0a7 251 (void)fprintf(stderr, "warning: ");
8b2fa9f8 252 va_start(ap);
b6cda174
KB
253 fmt = va_arg(ap, char *);
254 (void)vfprintf(stderr, fmt, ap);
255 va_end(ap);
256 (void)fprintf(stderr, "\n");
257 (void)fflush(stderr);
258 if (type == PARSE_FATAL)
259 fatals += 1;
ab950546 260}
182ca07d 261
ab950546
KB
262/*-
263 *---------------------------------------------------------------------
264 * ParseLinkSrc --
265 * Link the parent node to its new child. Used in a Lst_ForEach by
266 * ParseDoDependency. If the specType isn't 'Not', the parent
267 * isn't linked as a parent of the child.
268 *
269 * Results:
270 * Always = 0
271 *
272 * Side Effects:
273 * New elements are added to the parents list of cgn and the
274 * children list of cgn. the unmade field of pgn is updated
275 * to reflect the additional child.
276 *---------------------------------------------------------------------
277 */
278static int
279ParseLinkSrc (pgn, cgn)
280 GNode *pgn; /* The parent node */
281 GNode *cgn; /* The child node */
282{
283 if (Lst_Member (pgn->children, (ClientData)cgn) == NILLNODE) {
284 (void)Lst_AtEnd (pgn->children, (ClientData)cgn);
285 if (specType == Not) {
286 (void)Lst_AtEnd (cgn->parents, (ClientData)pgn);
287 }
288 pgn->unmade += 1;
289 }
290 return (0);
291}
182ca07d 292
ab950546
KB
293/*-
294 *---------------------------------------------------------------------
295 * ParseDoOp --
296 * Apply the parsed operator to the given target node. Used in a
297 * Lst_ForEach call by ParseDoDependency once all targets have
298 * been found and their operator parsed. If the previous and new
299 * operators are incompatible, a major error is taken.
300 *
301 * Results:
302 * Always 0
303 *
304 * Side Effects:
305 * The type field of the node is altered to reflect any new bits in
306 * the op.
307 *---------------------------------------------------------------------
308 */
309static int
310ParseDoOp (gn, op)
311 GNode *gn; /* The node to which the operator is to be
312 * applied */
313 int op; /* The operator to apply */
314{
315 /*
316 * If the dependency mask of the operator and the node don't match and
317 * the node has actually had an operator applied to it before, and
318 * the operator actually has some dependency information in it, complain.
319 */
320 if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
321 !OP_NOP(gn->type) && !OP_NOP(op))
322 {
323 Parse_Error (PARSE_FATAL, "Inconsistent operator for %s", gn->name);
324 return (1);
325 }
326
327 if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {
328 /*
329 * If the node was the object of a :: operator, we need to create a
330 * new instance of it for the children and commands on this dependency
331 * line. The new instance is placed on the 'cohorts' list of the
332 * initial one (note the initial one is not on its own cohorts list)
333 * and the new instance is linked to all parents of the initial
334 * instance.
335 */
336 register GNode *cohort;
337 LstNode ln;
338
339 cohort = Targ_NewGN(gn->name);
340 /*
341 * Duplicate links to parents so graph traversal is simple. Perhaps
342 * some type bits should be duplicated?
343 *
344 * Make the cohort invisible as well to avoid duplicating it into
345 * other variables. True, parents of this target won't tend to do
346 * anything with their local variables, but better safe than
347 * sorry.
348 */
349 Lst_ForEach(gn->parents, ParseLinkSrc, (ClientData)cohort);
350 cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
351 (void)Lst_AtEnd(gn->cohorts, (ClientData)cohort);
352
353 /*
354 * Replace the node in the targets list with the new copy
355 */
356 ln = Lst_Member(targets, (ClientData)gn);
357 Lst_Replace(ln, (ClientData)cohort);
358 gn = cohort;
359 }
360 /*
361 * We don't want to nuke any previous flags (whatever they were) so we
362 * just OR the new operator into the old
363 */
364 gn->type |= op;
365
366 return (0);
367}
182ca07d 368
ab950546
KB
369/*-
370 *---------------------------------------------------------------------
371 * ParseDoSrc --
372 * Given the name of a source, figure out if it is an attribute
373 * and apply it to the targets if it is. Else decide if there is
374 * some attribute which should be applied *to* the source because
375 * of some special target and apply it if so. Otherwise, make the
376 * source be a child of the targets in the list 'targets'
377 *
378 * Results:
379 * None
380 *
381 * Side Effects:
382 * Operator bits may be added to the list of targets or to the source.
383 * The targets may have a new source added to their lists of children.
384 *---------------------------------------------------------------------
385 */
386static void
387ParseDoSrc (tOp, src)
388 int tOp; /* operator (if any) from special targets */
389 char *src; /* name of the source to handle */
390{
391 int op; /* operator (if any) from special source */
392 GNode *gn;
393
394 op = 0;
395 if (*src == '.' && isupper (src[1])) {
396 int keywd = ParseFindKeyword(src);
397 if (keywd != -1) {
398 op = parseKeywords[keywd].op;
399 }
400 }
401 if (op != 0) {
402 Lst_ForEach (targets, ParseDoOp, (ClientData)op);
ab950546
KB
403 } else if (specType == Main) {
404 /*
405 * If we have noted the existence of a .MAIN, it means we need
406 * to add the sources of said target to the list of things
407 * to create. The string 'src' is likely to be free, so we
408 * must make a new copy of it. Note that this will only be
409 * invoked if the user didn't specify a target on the command
410 * line. This is to allow #ifmake's to succeed, or something...
411 */
182ca07d 412 (void) Lst_AtEnd (create, (ClientData)strdup(src));
ab950546
KB
413 /*
414 * Add the name to the .TARGETS variable as well, so the user cna
415 * employ that, if desired.
416 */
417 Var_Append(".TARGETS", src, VAR_GLOBAL);
418 } else if (specType == Order) {
419 /*
420 * Create proper predecessor/successor links between the previous
421 * source and the current one.
422 */
423 gn = Targ_FindNode(src, TARG_CREATE);
424 if (predecessor != NILGNODE) {
425 (void)Lst_AtEnd(predecessor->successors, (ClientData)gn);
426 (void)Lst_AtEnd(gn->preds, (ClientData)predecessor);
427 }
428 /*
429 * The current source now becomes the predecessor for the next one.
430 */
431 predecessor = gn;
432 } else {
433 /*
434 * If the source is not an attribute, we need to find/create
435 * a node for it. After that we can apply any operator to it
436 * from a special target or link it to its parents, as
437 * appropriate.
438 *
439 * In the case of a source that was the object of a :: operator,
440 * the attribute is applied to all of its instances (as kept in
441 * the 'cohorts' list of the node) or all the cohorts are linked
442 * to all the targets.
443 */
444 gn = Targ_FindNode (src, TARG_CREATE);
445 if (tOp) {
446 gn->type |= tOp;
447 } else {
448 Lst_ForEach (targets, ParseLinkSrc, (ClientData)gn);
449 }
450 if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
451 register GNode *cohort;
452 register LstNode ln;
453
454 for (ln=Lst_First(gn->cohorts); ln != NILLNODE; ln = Lst_Succ(ln)){
455 cohort = (GNode *)Lst_Datum(ln);
456 if (tOp) {
457 cohort->type |= tOp;
458 } else {
459 Lst_ForEach(targets, ParseLinkSrc, (ClientData)cohort);
460 }
461 }
462 }
463 }
464}
182ca07d 465
ab950546
KB
466/*-
467 *-----------------------------------------------------------------------
468 * ParseFindMain --
469 * Find a real target in the list and set it to be the main one.
470 * Called by ParseDoDependency when a main target hasn't been found
471 * yet.
472 *
473 * Results:
474 * 0 if main not found yet, 1 if it is.
475 *
476 * Side Effects:
477 * mainNode is changed and Targ_SetMain is called.
478 *
479 *-----------------------------------------------------------------------
480 */
481static int
482ParseFindMain(gn)
483 GNode *gn; /* Node to examine */
484{
485 if ((gn->type & (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)) == 0) {
486 mainNode = gn;
487 Targ_SetMain(gn);
488 return (1);
489 } else {
490 return (0);
491 }
492}
182ca07d 493
ab950546
KB
494/*-
495 *-----------------------------------------------------------------------
496 * ParseAddDir --
497 * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going
498 *
499 * Results:
500 * === 0
501 *
502 * Side Effects:
503 * See Dir_AddDir.
504 *
505 *-----------------------------------------------------------------------
506 */
507static int
508ParseAddDir(path, name)
509 Lst path;
510 char *name;
511{
512 Dir_AddDir(path, name);
513 return(0);
514}
182ca07d 515
ab950546
KB
516/*-
517 *-----------------------------------------------------------------------
518 * ParseClearPath --
519 * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going
520 *
521 * Results:
522 * === 0
523 *
524 * Side Effects:
525 * See Dir_ClearPath
526 *
527 *-----------------------------------------------------------------------
528 */
529static int
530ParseClearPath(path)
531 Lst path;
532{
533 Dir_ClearPath(path);
534 return(0);
535}
182ca07d 536
ab950546
KB
537/*-
538 *---------------------------------------------------------------------
539 * ParseDoDependency --
540 * Parse the dependency line in line.
541 *
542 * Results:
543 * None
544 *
545 * Side Effects:
546 * The nodes of the sources are linked as children to the nodes of the
547 * targets. Some nodes may be created.
548 *
549 * We parse a dependency line by first extracting words from the line and
550 * finding nodes in the list of all targets with that name. This is done
551 * until a character is encountered which is an operator character. Currently
552 * these are only ! and :. At this point the operator is parsed and the
553 * pointer into the line advanced until the first source is encountered.
554 * The parsed operator is applied to each node in the 'targets' list,
555 * which is where the nodes found for the targets are kept, by means of
556 * the ParseDoOp function.
557 * The sources are read in much the same way as the targets were except
558 * that now they are expanded using the wildcarding scheme of the C-Shell
559 * and all instances of the resulting words in the list of all targets
560 * are found. Each of the resulting nodes is then linked to each of the
561 * targets as one of its children.
562 * Certain targets are handled specially. These are the ones detailed
563 * by the specType variable.
564 * The storing of transformation rules is also taken care of here.
565 * A target is recognized as a transformation rule by calling
566 * Suff_IsTransform. If it is a transformation rule, its node is gotten
567 * from the suffix module via Suff_AddTransform rather than the standard
568 * Targ_FindNode in the target module.
569 *---------------------------------------------------------------------
570 */
571static void
572ParseDoDependency (line)
573 char *line; /* the line to parse */
574{
575 register char *cp; /* our current position */
576 register GNode *gn; /* a general purpose temporary node */
577 register int op; /* the operator on the line */
578 char savec; /* a place to save a character */
579 Lst paths; /* List of search paths to alter when parsing
580 * a list of .PATH targets */
581 int tOp; /* operator from special target */
582 Lst sources; /* list of source names after expansion */
583 Lst curTargs; /* list of target names to be found and added
584 * to the targets list */
585
586 tOp = 0;
587
588 specType = Not;
589 paths = (Lst)NULL;
590
591 curTargs = Lst_Init(FALSE);
592
593 do {
594 for (cp = line;
595 *cp && !isspace (*cp) &&
596 (*cp != '!') && (*cp != ':') && (*cp != '(');
597 cp++)
598 {
599 if (*cp == '$') {
600 /*
601 * Must be a dynamic source (would have been expanded
602 * otherwise), so call the Var module to parse the puppy
603 * so we can safely advance beyond it...There should be
604 * no errors in this, as they would have been discovered
605 * in the initial Var_Subst and we wouldn't be here.
606 */
607 int length;
608 Boolean freeIt;
609 char *result;
610
611 result=Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
612
613 if (freeIt) {
614 free(result);
615 }
616 cp += length-1;
617 }
618 continue;
619 }
620 if (*cp == '(') {
621 /*
622 * Archives must be handled specially to make sure the OP_ARCHV
623 * flag is set in their 'type' field, for one thing, and because
624 * things like "archive(file1.o file2.o file3.o)" are permissible.
625 * Arch_ParseArchive will set 'line' to be the first non-blank
626 * after the archive-spec. It creates/finds nodes for the members
627 * and places them on the given list, returning SUCCESS if all
628 * went well and FAILURE if there was an error in the
629 * specification. On error, line should remain untouched.
630 */
631 if (Arch_ParseArchive (&line, targets, VAR_CMD) != SUCCESS) {
632 Parse_Error (PARSE_FATAL,
633 "Error in archive specification: \"%s\"", line);
634 return;
635 } else {
636 continue;
637 }
638 }
639 savec = *cp;
640
641 if (!*cp) {
642 /*
643 * Ending a dependency line without an operator is a Bozo
644 * no-no
645 */
646 Parse_Error (PARSE_FATAL, "Need an operator");
647 return;
648 }
649 *cp = '\0';
650 /*
651 * Have a word in line. See if it's a special target and set
652 * specType to match it.
653 */
654 if (*line == '.' && isupper (line[1])) {
655 /*
656 * See if the target is a special target that must have it
657 * or its sources handled specially.
658 */
659 int keywd = ParseFindKeyword(line);
660 if (keywd != -1) {
661 if (specType == Path && parseKeywords[keywd].spec != Path) {
662 Parse_Error(PARSE_FATAL, "Mismatched special targets");
663 return;
664 }
665
666 specType = parseKeywords[keywd].spec;
667 tOp = parseKeywords[keywd].op;
668
669 /*
670 * Certain special targets have special semantics:
671 * .PATH Have to set the dirSearchPath
672 * variable too
ab950546
KB
673 * .MAIN Its sources are only used if
674 * nothing has been specified to
675 * create.
676 * .DEFAULT Need to create a node to hang
677 * commands on, but we don't want
678 * it in the graph, nor do we want
679 * it to be the Main Target, so we
680 * create it, set OP_NOTMAIN and
681 * add it to the list, setting
682 * DEFAULT to the new node for
683 * later use. We claim the node is
684 * A transformation rule to make
685 * life easier later, when we'll
686 * use Make_HandleUse to actually
687 * apply the .DEFAULT commands.
688 * .BEGIN
689 * .END
690 * .INTERRUPT Are not to be considered the
691 * main target.
692 * .NOTPARALLEL Make only one target at a time.
693 * .SINGLESHELL Create a shell for each command.
694 * .ORDER Must set initial predecessor to NIL
695 */
696 switch (specType) {
697 case Path:
698 if (paths == NULL) {
699 paths = Lst_Init(FALSE);
700 }
701 (void)Lst_AtEnd(paths, (ClientData)dirSearchPath);
702 break;
ab950546
KB
703 case Main:
704 if (!Lst_IsEmpty(create)) {
705 specType = Not;
706 }
707 break;
708 case Begin:
709 case End:
710 case Interrupt:
711 gn = Targ_FindNode(line, TARG_CREATE);
712 gn->type |= OP_NOTMAIN;
713 (void)Lst_AtEnd(targets, (ClientData)gn);
714 break;
715 case Default:
716 gn = Targ_NewGN(".DEFAULT");
717 gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
718 (void)Lst_AtEnd(targets, (ClientData)gn);
719 DEFAULT = gn;
720 break;
721 case NotParallel:
722 {
723 extern int maxJobs;
724
725 maxJobs = 1;
726 break;
727 }
728 case SingleShell:
b6cda174 729 /* backwards = 1; */
ab950546
KB
730 break;
731 case Order:
732 predecessor = NILGNODE;
733 break;
734 }
735 } else if (strncmp (line, ".PATH", 5) == 0) {
736 /*
737 * .PATH<suffix> has to be handled specially.
738 * Call on the suffix module to give us a path to
739 * modify.
740 */
741 Lst path;
742
743 specType = Path;
744 path = Suff_GetPath (&line[5]);
745 if (path == NILLST) {
746 Parse_Error (PARSE_FATAL,
747 "Suffix '%s' not defined (yet)",
748 &line[5]);
749 return;
750 } else {
751 if (paths == (Lst)NULL) {
752 paths = Lst_Init(FALSE);
753 }
754 (void)Lst_AtEnd(paths, (ClientData)path);
755 }
756 }
757 }
758
759 /*
760 * Have word in line. Get or create its node and stick it at
761 * the end of the targets list
762 */
763 if ((specType == Not) && (*line != '\0')) {
764 if (Dir_HasWildcards(line)) {
765 /*
766 * Targets are to be sought only in the current directory,
767 * so create an empty path for the thing. Note we need to
768 * use Dir_Destroy in the destruction of the path as the
769 * Dir module could have added a directory to the path...
770 */
771 Lst emptyPath = Lst_Init(FALSE);
772
773 Dir_Expand(line, emptyPath, curTargs);
774
775 Lst_Destroy(emptyPath, Dir_Destroy);
776 } else {
777 /*
778 * No wildcards, but we want to avoid code duplication,
779 * so create a list with the word on it.
780 */
781 (void)Lst_AtEnd(curTargs, (ClientData)line);
782 }
783
784 while(!Lst_IsEmpty(curTargs)) {
785 char *targName = (char *)Lst_DeQueue(curTargs);
786
787 if (!Suff_IsTransform (targName)) {
788 gn = Targ_FindNode (targName, TARG_CREATE);
789 } else {
790 gn = Suff_AddTransform (targName);
791 }
792
793 (void)Lst_AtEnd (targets, (ClientData)gn);
794 }
795 } else if (specType == Path && *line != '.' && *line != '\0') {
796 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
797 }
798
799 *cp = savec;
800 /*
801 * If it is a special type and not .PATH, it's the only target we
802 * allow on this line...
803 */
804 if (specType != Not && specType != Path) {
805 Boolean warn = FALSE;
806
807 while ((*cp != '!') && (*cp != ':') && *cp) {
808 if (*cp != ' ' && *cp != '\t') {
809 warn = TRUE;
810 }
811 cp++;
812 }
813 if (warn) {
814 Parse_Error(PARSE_WARNING, "Extra target ignored");
815 }
816 } else {
817 while (*cp && isspace (*cp)) {
818 cp++;
819 }
820 }
821 line = cp;
822 } while ((*line != '!') && (*line != ':') && *line);
823
824 /*
825 * Don't need the list of target names anymore...
826 */
827 Lst_Destroy(curTargs, NOFREE);
828
829 if (!Lst_IsEmpty(targets)) {
830 switch(specType) {
831 default:
832 Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
833 break;
834 case Default:
835 case Begin:
836 case End:
837 case Interrupt:
838 /*
839 * These four create nodes on which to hang commands, so
840 * targets shouldn't be empty...
841 */
842 case Not:
843 /*
844 * Nothing special here -- targets can be empty if it wants.
845 */
846 break;
847 }
848 }
849
850 /*
851 * Have now parsed all the target names. Must parse the operator next. The
852 * result is left in op .
853 */
854 if (*cp == '!') {
855 op = OP_FORCE;
856 } else if (*cp == ':') {
857 if (cp[1] == ':') {
858 op = OP_DOUBLEDEP;
859 cp++;
860 } else {
861 op = OP_DEPENDS;
862 }
863 } else {
864 Parse_Error (PARSE_FATAL, "Missing dependency operator");
865 return;
866 }
867
868 cp++; /* Advance beyond operator */
869
870 Lst_ForEach (targets, ParseDoOp, (ClientData)op);
871
872 /*
873 * Get to the first source
874 */
875 while (*cp && isspace (*cp)) {
876 cp++;
877 }
878 line = cp;
879
880 /*
881 * Several special targets take different actions if present with no
882 * sources:
883 * a .SUFFIXES line with no sources clears out all old suffixes
884 * a .PRECIOUS line makes all targets precious
885 * a .IGNORE line ignores errors for all targets
886 * a .SILENT line creates silence when making all targets
887 * a .PATH removes all directories from the search path(s).
ab950546
KB
888 */
889 if (!*line) {
890 switch (specType) {
891 case Suffixes:
892 Suff_ClearSuffixes ();
893 break;
894 case Precious:
895 allPrecious = TRUE;
896 break;
897 case Ignore:
898 ignoreErrors = TRUE;
899 break;
900 case Silent:
901 beSilent = TRUE;
902 break;
903 case Path:
904 Lst_ForEach(paths, ParseClearPath, (ClientData)NULL);
905 break;
ab950546
KB
906 }
907 } else if (specType == MFlags) {
908 /*
909 * Call on functions in main.c to deal with these arguments and
910 * set the initial character to a null-character so the loop to
911 * get sources won't get anything
912 */
913 Main_ParseArgLine (line);
914 *line = '\0';
915 } else if (specType == Shell) {
916 if (Job_ParseShell (line) != SUCCESS) {
917 Parse_Error (PARSE_FATAL, "improper shell specification");
918 return;
919 }
920 *line = '\0';
921 } else if ((specType == NotParallel) || (specType == SingleShell)) {
922 *line = '\0';
923 }
924
925 /*
926 * NOW GO FOR THE SOURCES
927 */
928 if ((specType == Suffixes) || (specType == Path) ||
929 (specType == Includes) || (specType == Libs) ||
21859cc6 930 (specType == Null))
ab950546
KB
931 {
932 while (*line) {
933 /*
934 * If the target was one that doesn't take files as its sources
935 * but takes something like suffixes, we take each
936 * space-separated word on the line as a something and deal
937 * with it accordingly.
938 *
939 * If the target was .SUFFIXES, we take each source as a
940 * suffix and add it to the list of suffixes maintained by the
941 * Suff module.
942 *
943 * If the target was a .PATH, we add the source as a directory
944 * to search on the search path.
945 *
946 * If it was .INCLUDES, the source is taken to be the suffix of
947 * files which will be #included and whose search path should
948 * be present in the .INCLUDES variable.
949 *
950 * If it was .LIBS, the source is taken to be the suffix of
951 * files which are considered libraries and whose search path
952 * should be present in the .LIBS variable.
953 *
ab950546
KB
954 * If it was .NULL, the source is the suffix to use when a file
955 * has no valid suffix.
956 */
957 char savec;
958 while (*cp && !isspace (*cp)) {
959 cp++;
960 }
961 savec = *cp;
962 *cp = '\0';
963 switch (specType) {
964 case Suffixes:
965 Suff_AddSuffix (line);
966 break;
967 case Path:
968 Lst_ForEach(paths, ParseAddDir, (ClientData)line);
969 break;
970 case Includes:
971 Suff_AddInclude (line);
972 break;
973 case Libs:
974 Suff_AddLib (line);
975 break;
ab950546
KB
976 case Null:
977 Suff_SetNull (line);
978 break;
979 }
980 *cp = savec;
981 if (savec != '\0') {
982 cp++;
983 }
984 while (*cp && isspace (*cp)) {
985 cp++;
986 }
987 line = cp;
988 }
989 if (paths) {
990 Lst_Destroy(paths, NOFREE);
991 }
992 } else {
993 while (*line) {
994 /*
995 * The targets take real sources, so we must beware of archive
996 * specifications (i.e. things with left parentheses in them)
997 * and handle them accordingly.
998 */
999 while (*cp && !isspace (*cp)) {
1000 if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) {
1001 /*
1002 * Only stop for a left parenthesis if it isn't at the
1003 * start of a word (that'll be for variable changes
1004 * later) and isn't preceded by a dollar sign (a dynamic
1005 * source).
1006 */
1007 break;
1008 } else {
1009 cp++;
1010 }
1011 }
1012
1013 if (*cp == '(') {
1014 GNode *gn;
1015
1016 sources = Lst_Init (FALSE);
1017 if (Arch_ParseArchive (&line, sources, VAR_CMD) != SUCCESS) {
1018 Parse_Error (PARSE_FATAL,
1019 "Error in source archive spec \"%s\"", line);
1020 return;
1021 }
1022
1023 while (!Lst_IsEmpty (sources)) {
1024 gn = (GNode *) Lst_DeQueue (sources);
1025 ParseDoSrc (tOp, gn->name);
1026 }
1027 Lst_Destroy (sources, NOFREE);
1028 cp = line;
1029 } else {
1030 if (*cp) {
1031 *cp = '\0';
1032 cp += 1;
1033 }
1034
1035 ParseDoSrc (tOp, line);
1036 }
1037 while (*cp && isspace (*cp)) {
1038 cp++;
1039 }
1040 line = cp;
1041 }
1042 }
1043
1044 if (mainNode == NILGNODE) {
1045 /*
1046 * If we have yet to decide on a main target to make, in the
1047 * absence of any user input, we want the first target on
1048 * the first dependency line that is actually a real target
1049 * (i.e. isn't a .USE or .EXEC rule) to be made.
1050 */
1051 Lst_ForEach (targets, ParseFindMain, (ClientData)0);
1052 }
1053
1054}
182ca07d 1055
ab950546
KB
1056/*-
1057 *---------------------------------------------------------------------
1058 * Parse_IsVar --
1059 * Return TRUE if the passed line is a variable assignment. A variable
1060 * assignment consists of a single word followed by optional whitespace
1061 * followed by either a += or an = operator.
1062 * This function is used both by the Parse_File function and main when
1063 * parsing the command-line arguments.
1064 *
1065 * Results:
1066 * TRUE if it is. FALSE if it ain't
1067 *
1068 * Side Effects:
1069 * none
1070 *---------------------------------------------------------------------
1071 */
1072Boolean
1073Parse_IsVar (line)
1074 register char *line; /* the line to check */
1075{
1076 register Boolean wasSpace = FALSE; /* set TRUE if found a space */
1077 register Boolean haveName = FALSE; /* Set TRUE if have a variable name */
1078
1079 /*
1080 * Skip to variable name
1081 */
1082 while ((*line == ' ') || (*line == '\t')) {
1083 line++;
1084 }
1085
1086 while (*line != '=') {
1087 if (*line == '\0') {
1088 /*
1089 * end-of-line -- can't be a variable assignment.
1090 */
1091 return (FALSE);
1092 } else if ((*line == ' ') || (*line == '\t')) {
1093 /*
1094 * there can be as much white space as desired so long as there is
1095 * only one word before the operator
1096 */
1097 wasSpace = TRUE;
1098 } else if (wasSpace && haveName) {
1099 /*
1100 * Stop when an = operator is found.
1101 */
1102 if ((*line == '+') || (*line == ':') || (*line == '?') ||
1103 (*line == '!')) {
1104 break;
1105 }
1106
1107 /*
1108 * This is the start of another word, so not assignment.
1109 */
1110 return (FALSE);
1111 } else {
1112 haveName = TRUE;
1113 wasSpace = FALSE;
1114 }
1115 line++;
1116 }
1117
1118 /*
1119 * A final check: if we stopped on a +, ?, ! or :, the next character must
1120 * be an = or it ain't a valid assignment
1121 */
1122 if (((*line == '+') ||
1123 (*line == '?') ||
1124 (*line == ':') ||
1125 (*line == '!')) &&
1126 (line[1] != '='))
1127 {
1128 return (FALSE);
1129 } else {
1130 return (haveName);
1131 }
1132}
182ca07d 1133
ab950546
KB
1134/*-
1135 *---------------------------------------------------------------------
1136 * Parse_DoVar --
1137 * Take the variable assignment in the passed line and do it in the
1138 * global context.
1139 *
1140 * Note: There is a lexical ambiguity with assignment modifier characters
1141 * in variable names. This routine interprets the character before the =
1142 * as a modifier. Therefore, an assignment like
1143 * C++=/usr/bin/CC
1144 * is interpreted as "C+ +=" instead of "C++ =".
1145 *
1146 * Results:
1147 * none
1148 *
1149 * Side Effects:
1150 * the variable structure of the given variable name is altered in the
1151 * global context.
1152 *---------------------------------------------------------------------
1153 */
1154void
1155Parse_DoVar (line, ctxt)
1156 char *line; /* a line guaranteed to be a variable
1157 * assignment. This reduces error checks */
1158 GNode *ctxt; /* Context in which to do the assignment */
1159{
1160 register char *cp; /* pointer into line */
1161 enum {
1162 VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
1163 } type; /* Type of assignment */
1164 char *opc; /* ptr to operator character to
1165 * null-terminate the variable name */
1166
1167 /*
1168 * Skip to variable name
1169 */
1170 while ((*line == ' ') || (*line == '\t')) {
1171 line++;
1172 }
1173
1174 /*
1175 * Skip to operator character, nulling out whitespace as we go
1176 */
1177 for (cp = line + 1; *cp != '='; cp++) {
1178 if (isspace (*cp)) {
1179 *cp = '\0';
1180 }
1181 }
1182 opc = cp-1; /* operator is the previous character */
1183 *cp++ = '\0'; /* nuke the = */
1184
1185 /*
1186 * Check operator type
1187 */
1188 switch (*opc) {
1189 case '+':
1190 type = VAR_APPEND;
1191 *opc = '\0';
1192 break;
1193
1194 case '?':
1195 /*
1196 * If the variable already has a value, we don't do anything.
1197 */
1198 *opc = '\0';
1199 if (Var_Exists(line, ctxt)) {
1200 return;
1201 } else {
1202 type = VAR_NORMAL;
1203 }
1204 break;
1205
1206 case ':':
1207 type = VAR_SUBST;
1208 *opc = '\0';
1209 break;
1210
1211 case '!':
1212 type = VAR_SHELL;
1213 *opc = '\0';
1214 break;
1215
1216 default:
1217 type = VAR_NORMAL;
1218 break;
1219 }
1220
1221 while (isspace (*cp)) {
1222 cp++;
1223 }
1224
1225 if (type == VAR_APPEND) {
1226 Var_Append (line, cp, ctxt);
1227 } else if (type == VAR_SUBST) {
1228 /*
1229 * Allow variables in the old value to be undefined, but leave their
1230 * invocation alone -- this is done by forcing oldVars to be false.
1231 * XXX: This can cause recursive variables, but that's not hard to do,
1232 * and this allows someone to do something like
1233 *
1234 * CFLAGS = $(.INCLUDES)
1235 * CFLAGS := -I.. $(CFLAGS)
1236 *
1237 * And not get an error.
1238 */
1239 Boolean oldOldVars = oldVars;
1240
1241 oldVars = FALSE;
1242 cp = Var_Subst(cp, ctxt, FALSE);
1243 oldVars = oldOldVars;
1244
1245 Var_Set(line, cp, ctxt);
1246 free(cp);
1247 } else if (type == VAR_SHELL) {
1248 char result[BUFSIZ]; /* Result of command */
1249 char *args[4]; /* Args for invoking the shell */
1250 int fds[2]; /* Pipe streams */
1251 int cpid; /* Child PID */
1252 int pid; /* PID from wait() */
1253 Boolean freeCmd; /* TRUE if the command needs to be freed, i.e.
1254 * if any variable expansion was performed */
1255
1256 /*
1257 * Set up arguments for shell
1258 */
1259 args[0] = "sh";
1260 args[1] = "-c";
1261 if (index(cp, '$') != (char *)NULL) {
1262 /*
1263 * There's a dollar sign in the command, so perform variable
1264 * expansion on the whole thing. The resulting string will need
1265 * freeing when we're done, so set freeCmd to TRUE.
1266 */
1267 args[2] = Var_Subst(cp, VAR_CMD, TRUE);
1268 freeCmd = TRUE;
1269 } else {
1270 args[2] = cp;
1271 freeCmd = FALSE;
1272 }
1273 args[3] = (char *)NULL;
1274
1275 /*
1276 * Open a pipe for fetching its output
1277 */
1278 pipe(fds);
1279
1280 /*
1281 * Fork
1282 */
1283 cpid = vfork();
1284 if (cpid == 0) {
1285 /*
1286 * Close input side of pipe
1287 */
1288 close(fds[0]);
1289
1290 /*
1291 * Duplicate the output stream to the shell's output, then
1292 * shut the extra thing down. Note we don't fetch the error
1293 * stream...why not? Why?
1294 */
1295 dup2(fds[1], 1);
1296 close(fds[1]);
1297
1298 execv("/bin/sh", args);
1299 _exit(1);
1300 } else if (cpid < 0) {
1301 /*
1302 * Couldn't fork -- tell the user and make the variable null
1303 */
1304 Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp);
1305 Var_Set(line, "", ctxt);
1306 } else {
1307 int status;
1308 int cc;
1309
1310 /*
1311 * No need for the writing half
1312 */
1313 close(fds[1]);
1314
1315 /*
1316 * Wait for the process to exit.
1317 *
1318 * XXX: If the child writes more than a pipe's worth, we will
1319 * deadlock.
1320 */
1321 while(((pid = wait(&status)) != cpid) && (pid >= 0)) {
1322 ;
1323 }
1324
1325 /*
1326 * Read all the characters the child wrote.
1327 */
1328 cc = read(fds[0], result, sizeof(result));
1329
1330 if (cc < 0) {
1331 /*
1332 * Couldn't read the child's output -- tell the user and
1333 * set the variable to null
1334 */
1335 Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
1336 cc = 0;
1337 }
1338
1339 if (status) {
1340 /*
1341 * Child returned an error -- tell the user but still use
1342 * the result.
1343 */
1344 Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
1345 }
1346 /*
1347 * Null-terminate the result, convert newlines to spaces and
1348 * install it in the variable.
1349 */
1350 result[cc] = '\0';
1351 cp = &result[cc] - 1;
1352
1353 if (*cp == '\n') {
1354 /*
1355 * A final newline is just stripped
1356 */
1357 *cp-- = '\0';
1358 }
1359 while (cp >= result) {
1360 if (*cp == '\n') {
1361 *cp = ' ';
1362 }
1363 cp--;
1364 }
1365 Var_Set(line, result, ctxt);
1366
1367 /*
1368 * Close the input side of the pipe.
1369 */
1370 close(fds[0]);
1371 }
1372 if (freeCmd) {
1373 free(args[2]);
1374 }
1375 } else {
1376 /*
1377 * Normal assignment -- just do it.
1378 */
1379 Var_Set (line, cp, ctxt);
1380 }
1381}
182ca07d 1382
ab950546 1383/*-
ab950546
KB
1384 * ParseAddCmd --
1385 * Lst_ForEach function to add a command line to all targets
1386 *
1387 * Results:
1388 * Always 0
1389 *
1390 * Side Effects:
1391 * A new element is added to the commands list of the node.
ab950546 1392 */
8b2fa9f8
KB
1393static
1394ParseAddCmd(gn, cmd)
1395 GNode *gn; /* the node to which the command is to be added */
1396 char *cmd; /* the command to add */
ab950546 1397{
8b2fa9f8
KB
1398 /* if target already supplied, ignore commands */
1399 if (!(gn->type & OP_HAS_COMMANDS))
1400 (void)Lst_AtEnd(gn->commands, (ClientData)cmd);
1401 return(0);
ab950546 1402}
182ca07d 1403
ab950546
KB
1404/*-
1405 *-----------------------------------------------------------------------
1406 * ParseHasCommands --
1407 * Callback procedure for Parse_File when destroying the list of
1408 * targets on the last dependency line. Marks a target as already
1409 * having commands if it does, to keep from having shell commands
1410 * on multiple dependency lines.
1411 *
1412 * Results:
1413 * Always 0.
1414 *
1415 * Side Effects:
1416 * OP_HAS_COMMANDS may be set for the target.
1417 *
1418 *-----------------------------------------------------------------------
1419 */
1420static int
1421ParseHasCommands(gn)
1422 GNode *gn; /* Node to examine */
1423{
1424 if (!Lst_IsEmpty(gn->commands)) {
1425 gn->type |= OP_HAS_COMMANDS;
1426 }
1427 return(0);
1428}
182ca07d 1429
ab950546
KB
1430/*-
1431 *-----------------------------------------------------------------------
1432 * Parse_AddIncludeDir --
1433 * Add a directory to the path searched for included makefiles
1434 * bracketed by double-quotes. Used by functions in main.c
1435 *
1436 * Results:
1437 * None.
1438 *
1439 * Side Effects:
1440 * The directory is appended to the list.
1441 *
1442 *-----------------------------------------------------------------------
1443 */
1444void
1445Parse_AddIncludeDir (dir)
1446 char *dir; /* The name of the directory to add */
1447{
1448 Dir_AddDir (parseIncPath, dir);
1449}
182ca07d 1450
ab950546
KB
1451/*-
1452 *---------------------------------------------------------------------
1453 * ParseDoInclude --
1454 * Push to another file.
1455 *
1456 * The input is the line minus the #include. A file spec is a string
1457 * enclosed in <> or "". The former is looked for only in sysIncPath.
1458 * The latter in . and the directories specified by -I command line
1459 * options
1460 *
1461 * Results:
1462 * None
1463 *
1464 * Side Effects:
1465 * A structure is added to the includes Lst and readProc, lineno,
1466 * fname and curFILE are altered for the new file
1467 *---------------------------------------------------------------------
1468 */
1469static void
1470ParseDoInclude (file)
1471 char *file; /* file specification */
1472{
1473 char *fullname; /* full pathname of file */
1474 IFile *oldFile; /* state associated with current file */
1475 Lst path; /* the path to use to find the file */
1476 char endc; /* the character which ends the file spec */
1477 char *cp; /* current position in file spec */
1478 Boolean isSystem; /* TRUE if makefile is a system makefile */
1479
1480 /*
1481 * Skip to delimiter character so we know where to look
1482 */
1483 while ((*file == ' ') || (*file == '\t')) {
1484 file++;
1485 }
1486
1487 if ((*file != '"') && (*file != '<')) {
1488 /*
1489 * XXX: Should give some sort of error message, I suppose, but because
1490 * # is used for both comments and directives, we can't be sure if
1491 * the thing might not just be a comment, so we just return...
1492 */
1493 return;
1494 }
1495
1496 /*
1497 * Set the search path on which to find the include file based on the
1498 * characters which bracket its name. Angle-brackets imply it's
1499 * a system Makefile while double-quotes imply it's a user makefile
1500 */
1501 if (*file == '<') {
1502 isSystem = TRUE;
1503 endc = '>';
1504 } else {
1505 isSystem = FALSE;
1506 endc = '"';
1507 }
1508
1509 /*
1510 * Skip to matching delimiter
1511 */
1512 for (cp = ++file; *cp && *cp != endc; cp++) {
1513 continue;
1514 }
1515
1516 if (*cp != endc) {
1517 Parse_Error (PARSE_FATAL,
91783fd5 1518 "Unclosed .include filename. '%c' expected", endc);
ab950546
KB
1519 return;
1520 }
1521 *cp = '\0';
1522
1523 /*
1524 * Substitute for any variables in the file name before trying to
1525 * find the thing.
1526 */
1527 file = Var_Subst (file, VAR_CMD, FALSE);
1528
1529 /*
1530 * Now we know the file's name and its search path, we attempt to
1531 * find the durn thing. A return of NULL indicates the file don't
1532 * exist.
1533 */
1534 if (!isSystem) {
1535 /*
1536 * Include files contained in double-quotes are first searched for
1537 * relative to the including file's location. We don't want to
1538 * cd there, of course, so we just tack on the old file's
1539 * leading path components and call Dir_FindFile to see if
1540 * we can locate the beast.
1541 */
1542 char *prefEnd;
1543
1544 prefEnd = rindex (fname, '/');
1545 if (prefEnd != (char *)NULL) {
1546 char *newName;
1547
1548 *prefEnd = '\0';
1cffbb48 1549 newName = str_concat (fname, file, STR_ADDSLASH);
ab950546
KB
1550 fullname = Dir_FindFile (newName, parseIncPath);
1551 if (fullname == (char *)NULL) {
1552 fullname = Dir_FindFile(newName, dirSearchPath);
1553 }
1554 free (newName);
1555 *prefEnd = '/';
1556 } else {
1557 fullname = (char *)NULL;
1558 }
1559 } else {
1560 fullname = (char *)NULL;
1561 }
1562
1563 if (fullname == (char *)NULL) {
1564 /*
1565 * System makefile or makefile wasn't found in same directory as
1566 * included makefile. Search for it first on the -I search path,
1567 * then on the .PATH search path, if not found in a -I directory.
1568 * XXX: Suffix specific?
1569 */
1570 fullname = Dir_FindFile (file, parseIncPath);
1571 if (fullname == (char *)NULL) {
1572 fullname = Dir_FindFile(file, dirSearchPath);
1573 }
1574 }
1575
1576 if (fullname == (char *)NULL) {
1577 /*
1578 * Still haven't found the makefile. Look for it on the system
1579 * path as a last resort.
1580 */
1581 fullname = Dir_FindFile(file, sysIncPath);
1582 }
1583
1584 if (fullname == (char *) NULL) {
1585 *cp = endc;
1586 Parse_Error (PARSE_FATAL, "Could not find %s", file);
1587 return;
1588 }
1589
1590 /*
1591 * Once we find the absolute path to the file, we get to save all the
1592 * state from the current file before we can start reading this
1593 * include file. The state is stored in an IFile structure which
1594 * is placed on a list with other IFile structures. The list makes
1595 * a very nice stack to track how we got here...
1596 */
1cffbb48 1597 oldFile = (IFile *) emalloc (sizeof (IFile));
ab950546
KB
1598 oldFile->fname = fname;
1599
1600 oldFile->F = curFILE;
1601 oldFile->lineno = lineno;
1602
1603 (void) Lst_AtFront (includes, (ClientData)oldFile);
1604
1605 /*
1606 * Once the previous state has been saved, we can get down to reading
1607 * the new file. We set up the name of the file to be the absolute
1608 * name of the include file so error messages refer to the right
1609 * place. Naturally enough, we start reading at line number 0.
1610 */
1611 fname = fullname;
1612 lineno = 0;
1613
1614 curFILE = fopen (fullname, "r");
1615 if (curFILE == (FILE * ) NULL) {
1616 Parse_Error (PARSE_FATAL, "Cannot open %s", fullname);
1617 /*
1618 * Pop to previous file
1619 */
1620 (void) ParseEOF();
1621 }
1622}
182ca07d 1623
ab950546
KB
1624/*-
1625 *---------------------------------------------------------------------
1626 * ParseEOF --
1627 * Called when EOF is reached in the current file. If we were reading
1628 * an include file, the includes stack is popped and things set up
1629 * to go back to reading the previous file at the previous location.
1630 *
1631 * Results:
1632 * CONTINUE if there's more to do. DONE if not.
1633 *
1634 * Side Effects:
1635 * The old curFILE, is closed. The includes list is shortened.
1636 * lineno, curFILE, and fname are changed if CONTINUE is returned.
1637 *---------------------------------------------------------------------
1638 */
1639static int
1640ParseEOF ()
1641{
1642 IFile *ifile; /* the state on the top of the includes stack */
1643
1644 if (Lst_IsEmpty (includes)) {
1645 return (DONE);
1646 }
1647
1648 ifile = (IFile *) Lst_DeQueue (includes);
1649 free (fname);
1650 fname = ifile->fname;
1651 lineno = ifile->lineno;
1652 fclose (curFILE);
1653 curFILE = ifile->F;
1654 free ((Address)ifile);
1655 return (CONTINUE);
1656}
182ca07d 1657
ab950546
KB
1658/*-
1659 *---------------------------------------------------------------------
1660 * ParseReadc --
1661 * Read a character from the current file and update the line number
1662 * counter as necessary
1663 *
1664 * Results:
1665 * The character that was read
1666 *
1667 * Side Effects:
1668 * The lineno counter is incremented if the character is a newline
1669 *---------------------------------------------------------------------
1670 */
1671#ifdef notdef
1672static int parseReadChar;
1673
1674#define ParseReadc() (((parseReadChar = getc(curFILE)) == '\n') ? \
1675 (lineno++, '\n') : parseReadChar)
1676#else
1677#define ParseReadc() (getc(curFILE))
1678#endif /* notdef */
1679
182ca07d 1680
ab950546
KB
1681/*-
1682 *---------------------------------------------------------------------
1683 * ParseReadLine --
1684 * Read an entire line from the input file. Called only by Parse_File.
1685 * To facilitate escaped newlines and what have you, a character is
1686 * buffered in 'lastc', which is '\0' when no characters have been
1687 * read. When we break out of the loop, c holds the terminating
1688 * character and lastc holds a character that should be added to
1689 * the line (unless we don't read anything but a terminator).
1690 *
1691 * Results:
1692 * A line w/o its newline
1693 *
1694 * Side Effects:
1695 * Only those associated with reading a character
1696 *---------------------------------------------------------------------
1697 */
1698static char *
1699ParseReadLine ()
1700{
1701 Buffer buf; /* Buffer for current line */
1702 register int c; /* the current character */
1703 register int lastc; /* The most-recent character */
1704 Boolean semiNL; /* treat semi-colons as newlines */
1705 Boolean ignDepOp; /* TRUE if should ignore dependency operators
1706 * for the purposes of setting semiNL */
1707 Boolean ignComment; /* TRUE if should ignore comments (in a
1708 * shell command */
1709 char *line; /* Result */
1710 int lineLength; /* Length of result */
1711
1712 semiNL = FALSE;
1713 ignDepOp = FALSE;
1714 ignComment = FALSE;
1715
1716 /*
1717 * Handle special-characters at the beginning of the line. Either a
1718 * leading tab (shell command) or pound-sign (possible conditional)
1719 * forces us to ignore comments and dependency operators and treat
1720 * semi-colons as semi-colons (by leaving semiNL FALSE). This also
1721 * discards completely blank lines.
1722 */
1723 while(1) {
1724 c = ParseReadc();
1725
91783fd5 1726 if ((c == '\t') || (c == '.')) {
ab950546
KB
1727 ignComment = ignDepOp = TRUE;
1728 break;
1729 } else if (c == '\n') {
1730 lineno++;
1731 } else {
1732 /*
1733 * Anything else breaks out without doing anything
1734 */
1735 break;
1736 }
1737 }
1738
1739 if (c != EOF) {
1740 lastc = c;
1741 buf = Buf_Init(BSIZE);
1742
1743 while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&
1744 (c != EOF))
1745 {
1746test_char:
1747 switch(c) {
1748 case '\n':
1749 /*
1750 * Escaped newline: read characters until a non-space or an
1751 * unescaped newline and replace them all by a single space.
1752 * This is done by storing the space over the backslash and
1753 * dropping through with the next nonspace. If it is a
1754 * semi-colon and semiNL is TRUE, it will be recognized as a
1755 * newline in the code below this...
1756 */
1757 lineno++;
1758 lastc = ' ';
1759 while ((c = ParseReadc ()) == ' ' || c == '\t') {
1760 continue;
1761 }
1762 if (c == EOF || c == '\n') {
1763 goto line_read;
1764 } else {
1765 /*
1766 * Check for comments, semiNL's, etc. -- easier than
1767 * ungetc(c, curFILE); continue;
1768 */
1769 goto test_char;
1770 }
1771 break;
1772 case ';':
1773 /*
1774 * Semi-colon: Need to see if it should be interpreted as a
1775 * newline
1776 */
1777 if (semiNL) {
1778 /*
1779 * To make sure the command that may be following this
1780 * semi-colon begins with a tab, we push one back into the
1781 * input stream. This will overwrite the semi-colon in the
1782 * buffer. If there is no command following, this does no
1783 * harm, since the newline remains in the buffer and the
1784 * whole line is ignored.
1785 */
1786 ungetc('\t', curFILE);
1787 goto line_read;
1788 }
1789 break;
1790 case '=':
1791 if (!semiNL) {
1792 /*
1793 * Haven't seen a dependency operator before this, so this
1794 * must be a variable assignment -- don't pay attention to
1795 * dependency operators after this.
1796 */
1797 ignDepOp = TRUE;
1798 } else if (lastc == ':' || lastc == '!') {
1799 /*
1800 * Well, we've seen a dependency operator already, but it
1801 * was the previous character, so this is really just an
1802 * expanded variable assignment. Revert semi-colons to
1803 * being just semi-colons again and ignore any more
1804 * dependency operators.
1805 *
1806 * XXX: Note that a line like "foo : a:=b" will blow up,
1807 * but who'd write a line like that anyway?
1808 */
1809 ignDepOp = TRUE; semiNL = FALSE;
1810 }
1811 break;
1812 case '#':
1813 if (!ignComment) {
ab950546
KB
1814 /*
1815 * If the character is a hash mark and it isn't escaped
1816 * (or we're being compatible), the thing is a comment.
1817 * Skip to the end of the line.
1818 */
1819 do {
1820 c = ParseReadc();
1821 } while ((c != '\n') && (c != EOF));
1822 goto line_read;
ab950546
KB
1823 }
1824 break;
1825 case ':':
1826 case '!':
1827 if (!ignDepOp && (c == ':' || c == '!')) {
1828 /*
1829 * A semi-colon is recognized as a newline only on
1830 * dependency lines. Dependency lines are lines with a
1831 * colon or an exclamation point. Ergo...
1832 */
1833 semiNL = TRUE;
1834 }
1835 break;
1836 }
1837 /*
1838 * Copy in the previous character and save this one in lastc.
1839 */
1840 Buf_AddByte (buf, (Byte)lastc);
1841 lastc = c;
1842
1843 }
1844 line_read:
1845 lineno++;
1846
1847 if (lastc != '\0') {
1848 Buf_AddByte (buf, (Byte)lastc);
1849 }
1850 Buf_AddByte (buf, (Byte)'\0');
1851 line = (char *)Buf_GetAll (buf, &lineLength);
1852 Buf_Destroy (buf, FALSE);
1853
91783fd5 1854 if (line[0] == '.') {
ab950546
KB
1855 /*
1856 * The line might be a conditional. Ask the conditional module
1857 * about it and act accordingly
1858 */
1859 switch (Cond_Eval (line)) {
1860 case COND_SKIP:
1861 do {
1862 /*
1863 * Skip to next conditional that evaluates to COND_PARSE.
1864 */
1865 free (line);
1866 c = ParseReadc();
1867 /*
1868 * Skip lines until get to one that begins with a
1869 * special char.
1870 */
91783fd5 1871 while ((c != '.') && (c != EOF)) {
ab950546
KB
1872 while (((c != '\n') || (lastc == '\\')) &&
1873 (c != EOF))
1874 {
1875 /*
1876 * Advance to next unescaped newline
1877 */
1878 if ((lastc = c) == '\n') {
1879 lineno++;
1880 }
1881 c = ParseReadc();
1882 }
1883 lineno++;
1884
1885 lastc = c;
1886 c = ParseReadc ();
1887 }
1888
1889 if (c == EOF) {
1890 Parse_Error (PARSE_FATAL, "Unclosed conditional");
1891 return ((char *)NULL);
1892 }
1893
1894 /*
1895 * Read the entire line into buf
1896 */
1897 buf = Buf_Init (BSIZE);
1898 do {
1899 Buf_AddByte (buf, (Byte)c);
1900 c = ParseReadc();
1901 } while ((c != '\n') && (c != EOF));
1902 lineno++;
1903
1904 Buf_AddByte (buf, (Byte)'\0');
1905 line = (char *)Buf_GetAll (buf, &lineLength);
1906 Buf_Destroy (buf, FALSE);
1907 } while (Cond_Eval(line) != COND_PARSE);
1908 /*FALLTHRU*/
1909 case COND_PARSE:
1910 free (line);
1911 line = ParseReadLine();
1912 break;
1913 }
1914 }
1915
1916 return (line);
1917 } else {
1918 /*
1919 * Hit end-of-file, so return a NULL line to indicate this.
1920 */
1921 return((char *)NULL);
1922 }
1923}
182ca07d 1924
ab950546
KB
1925/*-
1926 *-----------------------------------------------------------------------
1927 * ParseFinishLine --
1928 * Handle the end of a dependency group.
1929 *
1930 * Results:
1931 * Nothing.
1932 *
1933 * Side Effects:
1934 * inLine set FALSE. 'targets' list destroyed.
1935 *
1936 *-----------------------------------------------------------------------
1937 */
1938static void
1939ParseFinishLine()
1940{
1941 extern int Suff_EndTransform();
1942
1943 if (inLine) {
1944 Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL);
1945 Lst_Destroy (targets, ParseHasCommands);
1946 inLine = FALSE;
1947 }
1948}
1949
182ca07d 1950
ab950546
KB
1951/*-
1952 *---------------------------------------------------------------------
1953 * Parse_File --
1954 * Parse a file into its component parts, incorporating it into the
1955 * current dependency graph. This is the main function and controls
1956 * almost every other function in this module
1957 *
1958 * Results:
1959 * None
1960 *
1961 * Side Effects:
1962 * Loads. Nodes are added to the list of all targets, nodes and links
1963 * are added to the dependency graph. etc. etc. etc.
1964 *---------------------------------------------------------------------
1965 */
1966void
1967Parse_File(name, stream)
1968 char *name; /* the name of the file being read */
1969 FILE * stream; /* Stream open to makefile to parse */
1970{
1971 register char *cp, /* pointer into the line */
1972 *line; /* the line we're working on */
1973
1974 inLine = FALSE;
1975 fname = name;
1976 curFILE = stream;
1977 lineno = 0;
1978 fatals = 0;
1979
1980 do {
1981 while (line = ParseReadLine ()) {
91783fd5 1982 if (*line == '.') {
ab950546
KB
1983 /*
1984 * Lines that begin with the special character are either
1985 * include or undef directives.
1986 */
1987 for (cp = line + 1; isspace (*cp); cp++) {
1988 continue;
1989 }
1990 if (strncmp (cp, "include", 7) == 0) {
1991 ParseDoInclude (cp + 7);
1992 goto nextLine;
1993 } else if (strncmp(cp, "undef", 5) == 0) {
1994 char *cp2;
1995 for (cp += 5; isspace(*cp); cp++) {
1996 continue;
1997 }
1998
1999 for (cp2 = cp; !isspace(*cp2) && (*cp2 != '\0'); cp2++) {
2000 continue;
2001 }
2002
2003 *cp2 = '\0';
2004
2005 Var_Delete(cp, VAR_GLOBAL);
2006 goto nextLine;
2007 }
2008 }
2009 if (*line == '#') {
91783fd5 2010 /* If we're this far, the line must be a comment. */
ab950546
KB
2011 goto nextLine;
2012 }
2013
2014 if (*line == '\t'
2015#ifdef POSIX
2016 || *line == ' '
2017#endif
2018 )
2019 {
2020 /*
2021 * If a line starts with a tab (or space in POSIX-land), it
2022 * can only hope to be a creation command.
2023 */
2024 shellCommand:
2025 for (cp = line + 1; isspace (*cp); cp++) {
2026 continue;
2027 }
2028 if (*cp) {
2029 if (inLine) {
2030 /*
2031 * So long as it's not a blank line and we're actually
2032 * in a dependency spec, add the command to the list of
2033 * commands of all targets in the dependency spec
2034 */
2035 Lst_ForEach (targets, ParseAddCmd, (ClientData)cp);
2036 continue;
2037 } else {
2038 Parse_Error (PARSE_FATAL,
2039 "Unassociated shell command \"%.20s\"",
2040 cp);
2041 }
2042 }
2043 } else if (Parse_IsVar (line)) {
2044 ParseFinishLine();
2045 Parse_DoVar (line, VAR_GLOBAL);
2046 } else {
2047 /*
2048 * We now know it's a dependency line so it needs to have all
2049 * variables expanded before being parsed. Tell the variable
2050 * module to complain if some variable is undefined...
2051 * To make life easier on novices, if the line is indented we
2052 * first make sure the line has a dependency operator in it.
2053 * If it doesn't have an operator and we're in a dependency
2054 * line's script, we assume it's actually a shell command
2055 * and add it to the current list of targets.
2056 *
2057 * Note that POSIX declares all lines that start with
2058 * whitespace are shell commands, so there's no need to check
2059 * here...
2060 */
2061 Boolean nonSpace = FALSE;
2062
2063 cp = line;
2064#ifndef POSIX
2065 if (line[0] == ' ') {
2066 while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) {
2067 if (!isspace(*cp)) {
2068 nonSpace = TRUE;
2069 }
2070 cp++;
2071 }
2072 }
2073
2074 if (*cp == '\0') {
2075 if (inLine) {
2076 Parse_Error (PARSE_WARNING,
2077 "Shell command needs a leading tab");
2078 goto shellCommand;
2079 } else if (nonSpace) {
2080 Parse_Error (PARSE_FATAL, "Missing operator");
2081 }
2082 } else {
2083#endif
2084 ParseFinishLine();
2085
2086 cp = Var_Subst (line, VAR_CMD, TRUE);
2087 free (line);
2088 line = cp;
2089
2090 /*
2091 * Need a non-circular list for the target nodes
2092 */
2093 targets = Lst_Init (FALSE);
2094 inLine = TRUE;
2095
2096 ParseDoDependency (line);
2097#ifndef POSIX
2098 }
2099#endif
2100 }
2101
2102 nextLine:
2103
2104 free (line);
2105 }
2106 /*
2107 * Reached EOF, but it may be just EOF of an include file...
2108 */
2109 } while (ParseEOF() == CONTINUE);
2110
2111 /*
2112 * Make sure conditionals are clean
2113 */
2114 Cond_End();
2115
2116 if (fatals) {
2117 fprintf (stderr, "Fatal errors encountered -- cannot continue\n");
2118 exit (1);
2119 }
2120}
182ca07d 2121
ab950546
KB
2122/*-
2123 *---------------------------------------------------------------------
2124 * Parse_Init --
2125 * initialize the parsing module
2126 *
2127 * Results:
2128 * none
2129 *
2130 * Side Effects:
2131 * the parseIncPath list is initialized...
2132 *---------------------------------------------------------------------
2133 */
2134Parse_Init ()
2135{
aabb6217
KB
2136 char *cp, *start;
2137 /* avoid faults on read-only strings */
2138 static char syspath[] = _PATH_DEFSYSPATH;
ab950546
KB
2139
2140 mainNode = NILGNODE;
2141 parseIncPath = Lst_Init (FALSE);
2142 sysIncPath = Lst_Init (FALSE);
2143 includes = Lst_Init (FALSE);
2144
2145 /*
2146 * Add the directories from the DEFSYSPATH (more than one may be given
2147 * as dir1:...:dirn) to the system include path.
2148 */
2149 for (start = syspath; *start != '\0'; start = cp) {
2150 for (cp = start; *cp != '\0' && *cp != ':'; cp++) {
2151 ;
2152 }
2153 if (*cp == '\0') {
2154 Dir_AddDir(sysIncPath, start);
2155 } else {
2156 *cp++ = '\0';
2157 Dir_AddDir(sysIncPath, start);
2158 }
2159 }
2160}
182ca07d 2161
ab950546
KB
2162/*-
2163 *-----------------------------------------------------------------------
2164 * Parse_MainName --
2165 * Return a Lst of the main target to create for main()'s sake. If
2166 * no such target exists, we Punt with an obnoxious error message.
2167 *
2168 * Results:
2169 * A Lst of the single node to create.
2170 *
2171 * Side Effects:
2172 * None.
2173 *
2174 *-----------------------------------------------------------------------
2175 */
2176Lst
2177Parse_MainName()
2178{
2179 Lst main; /* result list */
2180
2181 main = Lst_Init (FALSE);
2182
2183 if (mainNode == NILGNODE) {
2184 Punt ("I don't know what to DO!\n");
2185 /*NOTREACHED*/
2186 } else if (mainNode->type & OP_DOUBLEDEP) {
2187 Lst_Concat(main, mainNode->cohorts, LST_CONCNEW);
2188 }
2189 (void) Lst_AtEnd (main, (ClientData)mainNode);
2190 return (main);
2191}