PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/usr.bin/make/parse.c

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