Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

944 lines
30 KiB

  1. // ACTION.C -- routines called by the parser
  2. //
  3. // Copyright (c) 1988-1990, Microsoft Corporation. All rights reserved.
  4. //
  5. // Purpose:
  6. // This module contains the routines called during parsing of a makefile.
  7. //
  8. // Revision History:
  9. // 15-Oct-1993 HV Use tchar.h instead of mbstring.h directly, change STR*() to _ftcs*()
  10. // 10-May-1993 HV Add include file mbstring.h
  11. // Change the str* functions to STR*
  12. // 13-Feb-1990 SB nextComponent() missed out mixed case of quoted/non-quote list
  13. // 02-Feb-1990 SB Add nextComponent() for Longfilename handling
  14. // 08-Dec-1989 SB removed local used without initialization warnings for -Oes
  15. // 07-Dec-1989 SB removed register to compile using C6 -Oes (warning gone)
  16. // 06-Dec-1989 SB changed expandFileNames() type to void instead of void *
  17. // 22-Nov-1989 SB Changed free() to FREE()
  18. // 13-Nov-1989 SB Removed an unreferenced local in endNameList()
  19. // 02-Oct-1989 SB add dynamic inline file handling support
  20. // 04-Sep-1989 SB Add A_DEPENDENT and fix macro inheritance
  21. // 24-Aug-1989 SB Allow $* on dependency lines
  22. // 14-Jul-1989 SB Environment macro was getting updated even when CMDLINE
  23. // macro was present
  24. // 29-Jun-1989 SB addItemToList() now maintains Global inline file List
  25. // 26-Jun-1989 SB Fixed -e for recursive NMAKE
  26. // 22-May-1989 SB NZ options work independently. -NZ does both stuff now
  27. // 13-May-1989 SB Changed delList to contain just names of files and no "del "
  28. // 14-Apr-1989 SB made targetList NEAR, no 'del inlinefile' cmd for -n now
  29. // 05-Apr-1989 SB Added parameters to makeRule() & makeTarget(); this get rid
  30. // of globals
  31. // 03-Apr-1989 SB changed all functions to NEAR to get them into one module
  32. // 21-Mar-1989 SB changed assignDependents() and assignCommands() to handle
  33. // multiple target case correctly.
  34. // 20-Mar-1989 SB startNamelist() doesn't flag error if target macro is null
  35. // and >1 target given; commented startNameList()
  36. // 16-Feb-1989 SB addItemToList() now appends to delList instead of List so
  37. // that all 'del scriptFile' cmds can be at the end of the make
  38. // 29-Jan-1989 SB added targList but not used as yet
  39. // 19-Jan-1989 SB changed startNameList() to avoid GP fault, bug# 162
  40. // 18-Jan-1989 SB modified endNameList(), added makeList() and makeBuildList()
  41. // and added a parameter to makeTarget() for bug# 161
  42. // 21-Dec-1988 SB use scriptFileList to handle multiple scriptFiles
  43. // Improve KEEP/NOKEEP;each file can have its own action
  44. // 16-Dec-1988 SB addItemToList() is now equipped for KEEP/NOKEEP
  45. // 14-Dec-1988 SB addItemToList() modified for 'Z' option -- adds a delete
  46. // command for deleting temporary script files
  47. // 5-Nov-1988 RB Fixed macro inheritance for recursive definitions.
  48. // 27-Oct-1988 SB put malloc for allocate in putEnvStr() -- error checking
  49. // 23-Oct-1988 SB Using putEnvStr() for putenv() to simplify code
  50. // 21-Oct-1988 SB Added fInheritUserEnv flag modifications to makeMacro()
  51. // and putMacro() for macro inheritance
  52. // 19-Sep-1988 RB Remove warning for MAKE redefinition.
  53. // 22-Aug-1988 RB Clean up for !UNDEF'ed macros.
  54. // 17-Aug-1988 RB Clean up.
  55. // 14-Jul-1988 rj Added initialization of dateTime field of BUILDBLOCKs.
  56. // 7-Jul-1988 rj Added targetFlag parameter to hash() calls.
  57. // Fixed bug: redefined macros didn't get flags reset.
  58. // 09-May-1988 rb Don't swallow no-match wildcards.
  59. #include "precomp.h"
  60. #pragma hdrstop
  61. void startNameList(void);
  62. void makeRule(STRINGLIST *, BOOL fBatch);
  63. void makeTarget(char*, BOOL, BUILDBLOCK**);
  64. void appendPseudoTargetList(STRINGLIST**, STRINGLIST*);
  65. void clearSuffixes(void);
  66. BOOL doSpecial(char*);
  67. BUILDLIST * makeBuildList(BUILDBLOCK *);
  68. char * nextComponent(char **);
  69. // created by endNameList() & freed by assignBuildCommands(). In use because
  70. // although global 'list' has this list is used by too many routines and the
  71. // complete sequence of actions on 'list' is unknown
  72. STRINGLIST * targetList; // corr to a dependency block
  73. // makeName -- create copy of a name seen by lexer
  74. //
  75. // Purpose:
  76. // Create a copy of a macro or 1st name in a target/dependency list. It also
  77. // does the groundwork for expansion of macros in name and saves values.
  78. //
  79. // Assumes: That the lexical routines save the token in buf
  80. //
  81. // Modifies Globals:
  82. // name -- the pointer to the copy created, gets allocated memory
  83. // macros -- the list of macro values in name. Used later by startNameList()
  84. // to expand macros in name and get expanded target name.
  85. //
  86. // Uses Globals:
  87. // buf -- the lexical routines return a token in this
  88. //
  89. // Notes:
  90. // The token in buf could be part of a macrodefinition or a target list. The
  91. // next token determines if it is a macrodefn or a targetlist we are parsing.
  92. // The next token would overwrite the current token and so it is saved in name.
  93. void
  94. makeName()
  95. {
  96. findMacroValues(buf, &macros, NULL, NULL, 0, 0, 0);
  97. name = makeString(buf);
  98. }
  99. // don't expand build lines for rules now -- expand after everything read in
  100. // that way CC and CFLAGS used in rules from tools.ini but not defined until
  101. // the makefile will have appropriate values. Redefining macros for use
  102. // in targets w/o explicit build commands doesn't work. Macros in rules have
  103. // the value of their last definition in the makefile.
  104. void
  105. addItemToList()
  106. {
  107. STRINGLIST *p; // from lexer
  108. STRINGLIST *NewList;
  109. if (name) {
  110. SET(actionFlags, A_TARGET);
  111. startNameList();
  112. name = NULL;
  113. }
  114. if (ON(actionFlags, A_TARGET)) {
  115. if (isRule(buf)) {
  116. if (ON(actionFlags, A_RULE))
  117. makeError(currentLine, TOO_MANY_RULE_NAMES);
  118. makeError(currentLine, MIXED_RULES);
  119. }
  120. }
  121. p = makeNewStrListElement();
  122. if (ON(actionFlags, A_STRING)) { // we collect macros
  123. p->text = string; // for dependents &
  124. string = NULL; // build lines for
  125. } else // non-implicit rules
  126. p->text = makeString(buf);
  127. NewList = p; // build lines for
  128. if (OFF(actionFlags, A_RULE) // rules get expanded
  129. || ON(actionFlags, A_TARGET)) // after entire make-
  130. {
  131. findMacroValues(p->text, &macros, NULL, NULL, 0, 0, 0); // file parsed
  132. }
  133. if (ON(actionFlags, A_TARGET)) {
  134. p = macros;
  135. expandFileNames("$", &NewList, &macros);
  136. expandFileNames("*?", &NewList, NULL);
  137. while (macros = p) {
  138. p = p->next;
  139. FREE_STRINGLIST(macros);
  140. }
  141. }
  142. appendItem(&list, NewList);
  143. }
  144. // startNameList -- puts in the first element into list
  145. //
  146. // Scope: Local.
  147. //
  148. // Purpose: Puts in the first name seen into a list
  149. //
  150. // Errors/Warnings: TARGET_MACRO_IS_NULL -- if the macro used as a target expands to null
  151. //
  152. // Assumes:
  153. // The global 'list' is originally a null list, & the global 'macro' points to
  154. // a list of values used for expanding the macros in global 'name'.
  155. //
  156. // Modifies Globals:
  157. // list -- the list of names; set to contain the first name here or to a
  158. // list of values if 'name' contains a macro invocation.
  159. // macros -- the list of values reqd for macro expansion; the list is
  160. // freed and macros is made NULL
  161. // currentFlags -- the flags for current target; set to global flags
  162. // actionFlags -- determine actions to be done; if the name is a rule then set
  163. // the rule bit
  164. //
  165. // Uses Globals:
  166. // name -- the first name seen in a list of names.
  167. // flags -- the global flags setup by the options specified
  168. // actionFlags -- if handling targets then no error as we have > 1 target
  169. //
  170. // Notes:
  171. // If there is more than one target then actionFlags has A_TARGET flag set and
  172. // startNameList() is called from addItemToList. In this case don't flag error.
  173. void
  174. startNameList()
  175. {
  176. STRINGLIST *p;
  177. currentFlags = flags; // set flags for cur target
  178. p = makeNewStrListElement();
  179. p->text = name;
  180. list = p; // list contains name
  181. p = macros;
  182. expandFileNames("$", &list, &macros); // expand macros in name
  183. expandFileNames("*?", &list, NULL); // expand wildcards
  184. while (macros = p) { // free macro list
  185. p = p->next;
  186. FREE_STRINGLIST(macros);
  187. }
  188. if (!list && OFF(actionFlags, A_TARGET))
  189. makeError(line, TARGET_MACRO_IS_NULL, name); // target null & 1 target
  190. if (list && isRule(list->text))
  191. SET(actionFlags, A_RULE);
  192. }
  193. // endNameList -- semantic actions when a list is fully seen
  194. //
  195. // Purpose:
  196. // When the parser has seen an entire list then it needs to do some semantic
  197. // actions. It calls endNameList() to do these actions. The action depends on
  198. // the values in certain globals.
  199. //
  200. // Modifies Globals: actionFlags --
  201. //
  202. // Uses Globals:
  203. // name -- The first element seen (if non null)
  204. // actionFlags -- The flag determining semantic & data structure actions
  205. // buf -- The delimiter seen after list
  206. // list -- The list of elements seen
  207. void
  208. endNameList()
  209. {
  210. if (name) { // if only one name to left of :
  211. startNameList(); // it hasn't been put in list yet
  212. name = NULL;
  213. } else
  214. CLEAR(actionFlags, A_TARGET); // clear target flag
  215. if (buf[1])
  216. SET(currentFlags, F2_DOUBLECOLON); // so addItemToList()
  217. if (!list) // won't expand names
  218. makeError(currentLine, SYNTAX_NO_TARGET_NAME); // of dependents
  219. if (ON(actionFlags, A_RULE)) {
  220. BOOL fBatch;
  221. // A rule with a doublecolon on the dependency line
  222. // is a "batch rule", i.e., a rule that applies the
  223. // command block in batch mode for all affected
  224. // dependents.
  225. fBatch = !!(ON(currentFlags, F2_DOUBLECOLON));
  226. makeRule(list, fBatch);
  227. FREE_STRINGLIST(list);
  228. }
  229. else if (!(list->next) && doSpecial(list->text)) { // special pseudotarget ...
  230. FREE(list->text); // don't need ".SUFFIXES" etc
  231. FREE_STRINGLIST(list);
  232. }
  233. else // regular target
  234. targetList = list;
  235. list = NULL;
  236. // We are now looking for a dependent
  237. SET(actionFlags, A_DEPENDENT);
  238. }
  239. BOOL
  240. doSpecial(
  241. char *s)
  242. {
  243. BOOL status = FALSE;
  244. if (!_tcsicmp(s, silent)) {
  245. SET(actionFlags, A_SILENT);
  246. setFlags('s', TRUE);
  247. status = TRUE;
  248. }
  249. if (!_tcsicmp(s, ignore)) {
  250. SET(actionFlags, A_IGNORE);
  251. setFlags('i', TRUE);
  252. status = TRUE;
  253. }
  254. else if (!_tcscmp(s, suffixes)) {
  255. SET(actionFlags, A_SUFFIX);
  256. status = TRUE;
  257. }
  258. else if (!_tcscmp(s, precious)) {
  259. SET(actionFlags, A_PRECIOUS);
  260. status = TRUE;
  261. }
  262. return(status);
  263. }
  264. void
  265. expandFileNames(
  266. char *string,
  267. STRINGLIST **sourceList,
  268. STRINGLIST **macroList
  269. )
  270. {
  271. char *s,
  272. *t = NULL;
  273. STRINGLIST *p; // Main list pointer
  274. STRINGLIST *pNew, // Pointer to new list
  275. *pBack; // Pointer to one element back
  276. char *saveText = NULL;
  277. for (pBack = NULL, p = *sourceList; p;) {
  278. // If no expand-character is found, continue to next list element.
  279. if (!_tcspbrk(p->text, string)) {
  280. pBack = p;
  281. p = pBack->next;
  282. continue;
  283. }
  284. // Either expand macros or wildcards.
  285. if (*string == '$') {
  286. t = expandMacros(p->text, macroList);
  287. FREE(p->text);
  288. } else {
  289. // If the wildcard string does not expand to anything, go to
  290. // next list elment. Do not remove p from the original list
  291. // else we must check for null elsewhere.
  292. // CAVIAR 3912 -- do not attempt to expand wildcards that
  293. // occur in inference rules [rm]
  294. if (isRule(p->text) || (pNew = expandWildCards(p->text)) == NULL) {
  295. pBack = p;
  296. p = pBack->next;
  297. continue;
  298. }
  299. saveText = p->text;
  300. }
  301. // At this point we have a list of expanded names to replace p with.
  302. if (pBack) {
  303. pBack->next = p->next;
  304. FREE_STRINGLIST(p);
  305. p = pBack->next;
  306. } else {
  307. *sourceList = p->next;
  308. FREE_STRINGLIST(p);
  309. p = *sourceList;
  310. }
  311. if (*string == '$') { // if expanding macros
  312. char *str = t;
  313. if (s = nextComponent(&str)) {
  314. do { // put expanded names
  315. pNew = makeNewStrListElement(); // at front of list
  316. pNew->text = makeString(s); // so we won't try to
  317. prependItem(sourceList, pNew); // re-expand them
  318. if (!pBack)
  319. pBack = pNew;
  320. } while (s = nextComponent(&str));
  321. }
  322. FREE(t);
  323. continue;
  324. }
  325. else if (pNew) { // if matches for * ?
  326. // Wild cards within Quoted strings will fail
  327. if (!pBack)
  328. for (pBack = pNew; pBack->next; pBack = pBack->next)
  329. ;
  330. appendItem(&pNew, *sourceList); // put at front of old list
  331. *sourceList = pNew;
  332. }
  333. FREE(saveText);
  334. }
  335. }
  336. // nextComponent - returns next component from expanded name
  337. //
  338. // Scope: Local (used by expandFilenames)
  339. //
  340. // Purpose:
  341. // Given a target string (target with macros expanded) this function returns a
  342. // name component. Previously _tcstok(s, " \t") was used but with the advent of
  343. // quoted filenames this is no good.
  344. //
  345. // Input: szExpStr - the target name with macros expanded
  346. //
  347. // Output: Returns pointer to next Component; NULL means no more components left.
  348. //
  349. // Assumes: That that two quoted strings are seperated by whitespace.
  350. char *
  351. nextComponent(
  352. char **szExpStr
  353. )
  354. {
  355. char *t, *next;
  356. t = *szExpStr;
  357. while (WHITESPACE(*t))
  358. t++;
  359. next = t;
  360. if (!*t)
  361. return(NULL);
  362. if (*t == '"') {
  363. for (; *++t && *t != '"';)
  364. ;
  365. } else {
  366. for (; *t && *t != ' ' && *t != '\t'; t++)
  367. ;
  368. }
  369. if (WHITESPACE(*t)) {
  370. *t = '\0';
  371. } else if (*t == '"') {
  372. t++;
  373. if(*t=='\0') t--; // If this is the end of the string, backup a byte, so we don't go past next time
  374. else *t = '\0'; // else stop here for this time.
  375. } else if (!*t) {
  376. // If at end of string then backup a byte so that next time we don't go past
  377. t--;
  378. }
  379. *szExpStr = t+1;
  380. return(next);
  381. }
  382. // append dependents to existing ones (if any)
  383. void
  384. assignDependents()
  385. {
  386. const char *which = NULL;
  387. if (ON(actionFlags, A_DEPENDENT))
  388. CLEAR(actionFlags, A_DEPENDENT);
  389. if (ON(actionFlags, A_RULE)) {
  390. if (list)
  391. makeError(currentLine, DEPENDENTS_ON_RULE);
  392. }
  393. else if (ON(actionFlags, A_SILENT) || ON(actionFlags, A_IGNORE)) {
  394. if (list) {
  395. if (ON(actionFlags, A_SILENT))
  396. which = silent;
  397. else if (ON(actionFlags, A_IGNORE))
  398. which = ignore;
  399. makeError(currentLine, DEPS_ON_PSEUDO, which);
  400. }
  401. }
  402. else if (ON(actionFlags, A_SUFFIX)) {
  403. if (!list)
  404. clearSuffixes();
  405. else
  406. appendPseudoTargetList(&dotSuffixList, list);
  407. }
  408. else if (ON(actionFlags, A_PRECIOUS)) {
  409. if (list)
  410. appendPseudoTargetList(&dotPreciousList, list);
  411. }
  412. else {
  413. block = makeNewBuildBlock();
  414. block->dependents = list;
  415. block->dependentMacros = macros;
  416. }
  417. list = NULL;
  418. macros = NULL;
  419. SET(actionFlags, A_STRING); // expecting build cmd
  420. }
  421. void
  422. assignBuildCommands()
  423. {
  424. BOOL okToFreeList = TRUE;
  425. BOOL fFirstTarg = (BOOL)TRUE;
  426. STRINGLIST *p;
  427. const char *which = NULL;
  428. if (ON(actionFlags, A_RULE)) // no macros found yet for inference rules
  429. rules->buildCommands = list;
  430. else if (ON(actionFlags, A_SILENT) ||
  431. ON(actionFlags, A_IGNORE) ||
  432. ON(actionFlags, A_PRECIOUS) ||
  433. ON(actionFlags, A_SUFFIX)
  434. ) {
  435. if (list) {
  436. if (ON(actionFlags, A_SILENT))
  437. which = silent;
  438. else if (ON(actionFlags, A_IGNORE))
  439. which = ignore;
  440. else if (ON(actionFlags, A_PRECIOUS))
  441. which = precious;
  442. else if (ON(actionFlags, A_SUFFIX))
  443. which = suffixes;
  444. makeError(currentLine, CMDS_ON_PSEUDO, which);
  445. }
  446. } else {
  447. block->buildCommands = list;
  448. block->buildMacros = macros;
  449. block->flags = currentFlags;
  450. while (p = targetList) { // make a struct for each targ
  451. if (doSpecial(p->text)) // in list, freeing list when
  452. makeError(currentLine, MIXED_TARGETS);
  453. makeTarget(p->text, fFirstTarg, &block); // done, don't free name
  454. if (!makeTargets) { // field -- it's still in use
  455. makeTargets = p; // if no targs given on cmdlin
  456. okToFreeList = FALSE; // put first target(s) from
  457. } // mkfile in makeTargets list
  458. targetList = p->next; // (makeTargets defined in
  459. if (okToFreeList) // nmake.c)
  460. FREE_STRINGLIST(p);
  461. if (fFirstTarg)
  462. fFirstTarg = (BOOL)FALSE;
  463. }
  464. }
  465. targetList = NULL;
  466. list = NULL;
  467. macros = NULL;
  468. block = NULL;
  469. actionFlags = 0;
  470. }
  471. // makeMacro -- define macro with name and string taken from global variables
  472. //
  473. // Modifies:
  474. // fInheritUserEnv set to TRUE
  475. //
  476. // Notes:
  477. // Calls putMacro() to place expanded Macros in the NMAKE table. By setting
  478. // fInheritUserEnv those definitions that change Environment variables are
  479. // inherited by the environment.
  480. void
  481. makeMacro()
  482. {
  483. STRINGLIST *q;
  484. char *t;
  485. if (_tcschr(name, '$')) { // expand name
  486. q = macros;
  487. t = expandMacros(name, &macros); // name holds result
  488. if (!*t) // error if macro to left of = is undefined
  489. makeError(currentLine, SYNTAX_NO_MACRO_NAME);
  490. while (macros = q) {
  491. q = q->next;
  492. FREE_STRINGLIST(macros);
  493. }
  494. FREE(name);
  495. name = t;
  496. }
  497. for (t = name; *t && MACRO_CHAR(*t); t = _tcsinc (t)) // Check for illegal chars
  498. ;
  499. if (*t)
  500. makeError(currentLine, SYNTAX_BAD_CHAR, *t);
  501. fInheritUserEnv = (BOOL)TRUE;
  502. // Put Env Var in Env & macros in table.
  503. if (!putMacro(name, string, 0)) {
  504. FREE(name);
  505. FREE(string);
  506. }
  507. name = string = NULL;
  508. }
  509. // defineMacro -- check macro's syntax for illegal chars., then define it
  510. //
  511. // actions: check all of macro's characters
  512. // if one's bad and it's an environment macro, bag it
  513. // else flag error
  514. // call putMacro to do the real work
  515. //
  516. // can't use macro invocation to left of = in macro def from commandline
  517. // it doesn't make sense to do that, because we're not in a makefile
  518. // the only way to get a comment char into the makefile w/o having it really
  519. // mark a comment is to define a macro A=# on the command line
  520. BOOL
  521. defineMacro(
  522. char *s, // commandline or env definitions
  523. char *t,
  524. UCHAR flags
  525. )
  526. {
  527. char *u;
  528. for (u = s; *u && MACRO_CHAR(*u); u = _tcsinc(u)) // check for illegal
  529. ;
  530. if (*u) {
  531. if (ON(flags, M_ENVIRONMENT_DEF)) { // ignore bad macros
  532. return(FALSE);
  533. }
  534. makeError(currentLine, SYNTAX_BAD_CHAR, *u); // chars, bad syntax
  535. }
  536. return(putMacro(s, t, flags)); // put macro in table
  537. }
  538. // putMacro - Put the macro definition into the Macro Table / Environmnet
  539. //
  540. // Scope:
  541. // Global.
  542. //
  543. // Purpose:
  544. // putMacro() inserts a macro definition into NMAKE's macro table and also into
  545. // the environment. If a macro name is also an environment variable than its
  546. // value is inherited into the environment. While replacing older values by new
  547. // values NMAKE needs to follow the precedence of macro definitions which is
  548. // as per the notes below.
  549. //
  550. // Input:
  551. // name - Name of the macro
  552. // value - Value of the macro
  553. // flags - Flags determining Precedence of Macro definitions (see Notes)
  554. //
  555. // Output:
  556. //
  557. // Errors/Warnings:
  558. // OUT_OF_ENV_SPACE - If putenv() returns failure in adding to the environment.
  559. //
  560. // Assumes:
  561. // Whatever it assumes
  562. //
  563. // Modifies Globals:
  564. // fInheritUserEnv - Set to False.
  565. //
  566. // Uses Globals:
  567. // fInheritUserEnv - If True then Inherit definition to the Environment.
  568. // gFlags - Global Options Flag. If -e specified then Environment Vars
  569. // take precedence.
  570. // macroTable - NMAKE's internal table of Macro Definitions.
  571. //
  572. // Notes:
  573. // 1> If the same macro is defined in more than one place then NMAKE uses the
  574. // following order of Precedence (highest to lowest) --
  575. //
  576. // -1- Command line definitions
  577. // -2- Description file/Include file definitions
  578. // -3- Environment definitions
  579. // -4- TOOLS.INI definitions
  580. // -5- Predefined Values (e.g. for CC, AS, BC, RC)
  581. // If -e option is specified then -3- precedes -2-.
  582. //
  583. // 2> Check if the macro already exists in the Macro Table. If the macro is not
  584. // redefinable (use order of precedence) then return. Make a new string
  585. // element to hold macro's new value. If the macro does not exist then create
  586. // new entry in the Macro table. Set Macro's flag to be union of Old and new
  587. // values. Add the new value to macro's value entry. If a new macro then add
  588. // it to the macro table. Test for Cyclic definitions.
  589. //
  590. // Undone/Incomplete:
  591. // 1> Investigate into possibility of removing fInheritUserEnv variable.
  592. // Can be done. Use CANT_REDEFINE(p) || OFF((A)->flags,M_ENVIRONMENT_DEF)
  593. // 2> Probably should warn when $(MAKE) is being changed.
  594. BOOL
  595. putMacro(
  596. char *name,
  597. char *value,
  598. UCHAR flags
  599. )
  600. {
  601. MACRODEF *p;
  602. STRINGLIST *q;
  603. BOOL defined = FALSE;
  604. BOOL fSyntax = TRUE;
  605. // Inherit macro definitions. Call removeMacros() to expand sub-macro
  606. // definitions. Must be done before macro is put in table, else
  607. // recursive definitions won't work.
  608. if (ON(flags, M_NON_RESETTABLE)) {
  609. if (*value)
  610. if ((putEnvStr(name,removeMacros(value)) == -1))
  611. makeError(currentLine, OUT_OF_ENV_SPACE);
  612. } else
  613. if (fInheritUserEnv &&
  614. OFF(gFlags, F1_USE_ENVIRON_VARS) &&
  615. getenv(name)
  616. ) {
  617. if (p = findMacro(name)) { // don't let user
  618. if (CANT_REDEFINE(p)) // redefine cmdline
  619. return(FALSE); // macros, MAKE, etc.
  620. }
  621. if ((putEnvStr(name,removeMacros(value)) == -1))
  622. makeError(currentLine, OUT_OF_ENV_SPACE);
  623. }
  624. fInheritUserEnv = (BOOL)FALSE;
  625. if (p = findMacro(name)) { // don't let user
  626. if (CANT_REDEFINE(p)) // redefine cmdline
  627. return(FALSE); // macros, MAKE, etc.
  628. }
  629. q = makeNewStrListElement();
  630. q->text = value;
  631. if (!p) {
  632. p = makeNewMacro();
  633. p->name = name;
  634. assert(p->flags == 0);
  635. assert(p->values == NULL);
  636. } else
  637. defined = TRUE;
  638. p->flags &= ~M_UNDEFINED; // Is no longer undefined
  639. p->flags |= flags; // Set flags to union of old and new
  640. prependItem((STRINGLIST**)&(p->values), (STRINGLIST*)q);
  641. if (!defined)
  642. insertMacro((STRINGLIST*)p);
  643. if (OFF(flags, M_LITERAL) && _tcschr(value, '$')) { // Check for cyclic Macro Definitions
  644. SET(p->flags, M_EXPANDING_THIS_ONE);
  645. // NULL -> don't build list
  646. fSyntax = findMacroValues(value, NULL, NULL, name, 1, 0, flags);
  647. CLEAR(p->flags, M_EXPANDING_THIS_ONE);
  648. }
  649. if (!fSyntax) {
  650. p->values = NULL;
  651. p->flags |= M_UNDEFINED;
  652. //return(FALSE);
  653. // return TRUE since p has been added to the macro table
  654. // Otherwise the caller may free name and value leaving
  655. // dangling pointers in the macro table. [DS 18040]
  656. return(TRUE);
  657. }
  658. return(TRUE);
  659. }
  660. // makeRule -- makes an inference rule
  661. //
  662. // Scope:
  663. // Local
  664. //
  665. // Purpose:
  666. // Allocates space for an inference rule and adds rule to the beginning of the
  667. // doubly linked inference rule list. The name of the rule is also added.
  668. //
  669. // Input:
  670. // rule -- The name of the inference rule
  671. // fBatch -- True if command block should be executed in batch mode
  672. //
  673. // Output:
  674. //
  675. // Errors/Warnings:
  676. //
  677. // Assumes:
  678. //
  679. // Modifies Globals:
  680. // rules -- The doubly linked inference rule list to which the rule is added
  681. //
  682. // Uses Globals:
  683. //
  684. // Notes:
  685. // The syntax of an inference rule is --
  686. //
  687. // {frompath}.fromext{topath}.toext: # Name of the inference rule
  688. // command ... # command block of the inference rule
  689. void
  690. makeRule(
  691. STRINGLIST *rule,
  692. BOOL fBatch
  693. )
  694. {
  695. RULELIST *rList;
  696. rList = makeNewRule();
  697. rList->name = rule->text;
  698. rList->fBatch = fBatch;
  699. prependItem((STRINGLIST**)&rules, (STRINGLIST*)rList);
  700. if (rList->next)
  701. rList->next->back = rList;
  702. }
  703. // makeTarget -- add target to targetTable
  704. //
  705. // actions: if no block defined, create one and initialize it
  706. // make new build list entry for this target
  707. // if the target's already in the table,
  708. // flag error if : and :: mixed
  709. // else add new buildlist object to target's current buildlist
  710. // else allocate new object, initialize it, and stick it in table
  711. void
  712. makeTarget(
  713. char *s,
  714. BOOL firstTarg,
  715. BUILDBLOCK **block
  716. )
  717. {
  718. BUILDLIST *build;
  719. MAKEOBJECT *object;
  720. if (!*block)
  721. *block = makeNewBuildBlock();
  722. if (firstTarg) {
  723. build = makeNewBldListElement();
  724. build->buildBlock = *block;
  725. } else
  726. build = makeBuildList(*block);
  727. if (object = findTarget(s)) {
  728. if (ON(object->flags2, F2_DOUBLECOLON) != ON(currentFlags, F2_DOUBLECOLON))
  729. makeError(currentLine, MIXED_SEPARATORS);
  730. appendItem((STRINGLIST**)&(object->buildList), (STRINGLIST*)build);
  731. FREE(s);
  732. } else {
  733. build->next = NULL;
  734. object = makeNewObject();
  735. object->name = s;
  736. object->buildList = build;
  737. object->flags2 = currentFlags;
  738. prependItem((STRINGLIST**)targetTable+hash(s, MAXTARGET, (BOOL)TRUE),
  739. (STRINGLIST*)object);
  740. }
  741. }
  742. void
  743. clearSuffixes()
  744. {
  745. STRINGLIST *p;
  746. while (p = dotSuffixList) {
  747. dotSuffixList = dotSuffixList->next;
  748. FREE(p->text);
  749. FREE_STRINGLIST(p);
  750. }
  751. }
  752. void
  753. appendPseudoTargetList(
  754. STRINGLIST **pseudo,
  755. STRINGLIST *list
  756. )
  757. {
  758. STRINGLIST *p, *q, *r;
  759. char *t, *u;
  760. while (p = list) {
  761. if (!_tcschr(p->text, '$')) {
  762. list = list->next;
  763. p->next = NULL;
  764. appendItem(pseudo, p);
  765. } else {
  766. r = macros;
  767. t = expandMacros(p->text, &macros);
  768. while (r != macros) {
  769. q = r->next;
  770. FREE_STRINGLIST(r);
  771. r = q;
  772. }
  773. for (u = _tcstok(t, " \t"); u; u = _tcstok(NULL, " \t")) {
  774. q = makeNewStrListElement();
  775. q->text = makeString(u);
  776. appendItem(pseudo, q);
  777. }
  778. FREE(t);
  779. FREE(p->text);
  780. list = list->next;
  781. FREE_STRINGLIST(p);
  782. }
  783. }
  784. }
  785. // putEnvStr -- Extends putenv() standard function
  786. //
  787. // Purpose:
  788. // Library function putenv() expects one string argument of the form
  789. // "NAME=value"
  790. // Most of the times when putenv() is to be used we have two strings
  791. // name -- of the variable to add to the environment, and
  792. // value -- to be set
  793. // putEnvStr takes these 2 parameters and calls putenv with the reqd
  794. // format
  795. //
  796. // Input:
  797. // name -- of var to add to the env
  798. // value -- reqd to be set
  799. //
  800. // Output:
  801. // Same as putenv()
  802. int
  803. putEnvStr(
  804. char *name,
  805. char *value
  806. )
  807. {
  808. char *envPtr;
  809. envPtr = (char *)rallocate(_tcslen(name)+1+_tcslen(value)+1);
  810. // ^ ^
  811. // for '=' for '\0'
  812. return(PutEnv(_tcscat(_tcscat(_tcscpy(envPtr, name), "="), value)));
  813. }
  814. // makeBuildList -- takes a build block and copies into a buildlist
  815. //
  816. // Purpose:
  817. // Routine creates a copy of a buildlist and returns a pointer to a copy.
  818. // When multiple targets have the same description block then there is a
  819. // need for each of them to get seperate build blocks. makeBuildList()
  820. // helps achieve this by creating a copy for each target.
  821. //
  822. // Input:
  823. // bBlock -- the build block whose copy is to be added to a build block
  824. //
  825. // Output:
  826. // Returns a pointer to the copy of buildlist it creates
  827. BUILDLIST *
  828. makeBuildList(
  829. BUILDBLOCK *bBlock
  830. )
  831. {
  832. BUILDLIST *tList = makeNewBldListElement();
  833. BUILDBLOCK *tBlock = makeNewBuildBlock();
  834. tBlock->dependents = bBlock->dependents;
  835. tBlock->dependentMacros = bBlock->dependentMacros;
  836. tBlock->buildCommands = bBlock->buildCommands;
  837. tBlock->buildMacros = bBlock->buildMacros;
  838. tBlock->flags = bBlock->flags;
  839. tBlock->dateTime = bBlock->dateTime;
  840. tList->buildBlock = tBlock;
  841. return(tList);
  842. }