PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/commands/make/var.c

http://github.com/vivekp/minix-nbsd
C | 4032 lines | 2402 code | 275 blank | 1355 comment | 914 complexity | 5f97aa9cba085dd1cec3ef59b48a2dc7 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause
  1. /* $NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $ */
  2. /*
  3. * Copyright (c) 1988, 1989, 1990, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Adam de Boor.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. /*
  34. * Copyright (c) 1989 by Berkeley Softworks
  35. * All rights reserved.
  36. *
  37. * This code is derived from software contributed to Berkeley by
  38. * Adam de Boor.
  39. *
  40. * Redistribution and use in source and binary forms, with or without
  41. * modification, are permitted provided that the following conditions
  42. * are met:
  43. * 1. Redistributions of source code must retain the above copyright
  44. * notice, this list of conditions and the following disclaimer.
  45. * 2. Redistributions in binary form must reproduce the above copyright
  46. * notice, this list of conditions and the following disclaimer in the
  47. * documentation and/or other materials provided with the distribution.
  48. * 3. All advertising materials mentioning features or use of this software
  49. * must display the following acknowledgement:
  50. * This product includes software developed by the University of
  51. * California, Berkeley and its contributors.
  52. * 4. Neither the name of the University nor the names of its contributors
  53. * may be used to endorse or promote products derived from this software
  54. * without specific prior written permission.
  55. *
  56. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  57. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  58. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  59. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  60. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  61. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  62. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  63. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  64. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  65. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  66. * SUCH DAMAGE.
  67. */
  68. #ifndef MAKE_NATIVE
  69. static char rcsid[] = "$NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $";
  70. #else
  71. #include <sys/cdefs.h>
  72. #ifndef lint
  73. #if 0
  74. static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
  75. #else
  76. __RCSID("$NetBSD: var.c,v 1.159 2010/06/06 01:13:12 sjg Exp $");
  77. #endif
  78. #endif /* not lint */
  79. #endif
  80. /*-
  81. * var.c --
  82. * Variable-handling functions
  83. *
  84. * Interface:
  85. * Var_Set Set the value of a variable in the given
  86. * context. The variable is created if it doesn't
  87. * yet exist. The value and variable name need not
  88. * be preserved.
  89. *
  90. * Var_Append Append more characters to an existing variable
  91. * in the given context. The variable needn't
  92. * exist already -- it will be created if it doesn't.
  93. * A space is placed between the old value and the
  94. * new one.
  95. *
  96. * Var_Exists See if a variable exists.
  97. *
  98. * Var_Value Return the value of a variable in a context or
  99. * NULL if the variable is undefined.
  100. *
  101. * Var_Subst Substitute named variable, or all variables if
  102. * NULL in a string using
  103. * the given context as the top-most one. If the
  104. * third argument is non-zero, Parse_Error is
  105. * called if any variables are undefined.
  106. *
  107. * Var_Parse Parse a variable expansion from a string and
  108. * return the result and the number of characters
  109. * consumed.
  110. *
  111. * Var_Delete Delete a variable in a context.
  112. *
  113. * Var_Init Initialize this module.
  114. *
  115. * Debugging:
  116. * Var_Dump Print out all variables defined in the given
  117. * context.
  118. *
  119. * XXX: There's a lot of duplication in these functions.
  120. */
  121. #include <sys/stat.h>
  122. #ifndef NO_REGEX
  123. #include <sys/types.h>
  124. #include <regex.h>
  125. #endif
  126. #include <ctype.h>
  127. #include <stdlib.h>
  128. #include <limits.h>
  129. #include "make.h"
  130. #include "buf.h"
  131. #include "dir.h"
  132. #include "job.h"
  133. /*
  134. * This is a harmless return value for Var_Parse that can be used by Var_Subst
  135. * to determine if there was an error in parsing -- easier than returning
  136. * a flag, as things outside this module don't give a hoot.
  137. */
  138. char var_Error[] = "";
  139. /*
  140. * Similar to var_Error, but returned when the 'errnum' flag for Var_Parse is
  141. * set false. Why not just use a constant? Well, gcc likes to condense
  142. * identical string instances...
  143. */
  144. static char varNoError[] = "";
  145. /*
  146. * Internally, variables are contained in four different contexts.
  147. * 1) the environment. They may not be changed. If an environment
  148. * variable is appended-to, the result is placed in the global
  149. * context.
  150. * 2) the global context. Variables set in the Makefile are located in
  151. * the global context. It is the penultimate context searched when
  152. * substituting.
  153. * 3) the command-line context. All variables set on the command line
  154. * are placed in this context. They are UNALTERABLE once placed here.
  155. * 4) the local context. Each target has associated with it a context
  156. * list. On this list are located the structures describing such
  157. * local variables as $(@) and $(*)
  158. * The four contexts are searched in the reverse order from which they are
  159. * listed.
  160. */
  161. GNode *VAR_GLOBAL; /* variables from the makefile */
  162. GNode *VAR_CMD; /* variables defined on the command-line */
  163. #define FIND_CMD 0x1 /* look in VAR_CMD when searching */
  164. #define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
  165. #define FIND_ENV 0x4 /* look in the environment also */
  166. typedef struct Var {
  167. char *name; /* the variable's name */
  168. Buffer val; /* its value */
  169. int flags; /* miscellaneous status flags */
  170. #define VAR_IN_USE 1 /* Variable's value currently being used.
  171. * Used to avoid recursion */
  172. #define VAR_FROM_ENV 2 /* Variable comes from the environment */
  173. #define VAR_JUNK 4 /* Variable is a junk variable that
  174. * should be destroyed when done with
  175. * it. Used by Var_Parse for undefined,
  176. * modified variables */
  177. #define VAR_KEEP 8 /* Variable is VAR_JUNK, but we found
  178. * a use for it in some modifier and
  179. * the value is therefore valid */
  180. #define VAR_EXPORTED 16 /* Variable is exported */
  181. #define VAR_REEXPORT 32 /* Indicate if var needs re-export.
  182. * This would be true if it contains $'s
  183. */
  184. #define VAR_FROM_CMD 64 /* Variable came from command line */
  185. } Var;
  186. /*
  187. * Exporting vars is expensive so skip it if we can
  188. */
  189. #define VAR_EXPORTED_NONE 0
  190. #define VAR_EXPORTED_YES 1
  191. #define VAR_EXPORTED_ALL 2
  192. static int var_exportedVars = VAR_EXPORTED_NONE;
  193. /*
  194. * We pass this to Var_Export when doing the initial export
  195. * or after updating an exported var.
  196. */
  197. #define VAR_EXPORT_PARENT 1
  198. /* Var*Pattern flags */
  199. #define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
  200. #define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
  201. #define VAR_SUB_MATCHED 0x04 /* There was a match */
  202. #define VAR_MATCH_START 0x08 /* Match at start of word */
  203. #define VAR_MATCH_END 0x10 /* Match at end of word */
  204. #define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */
  205. /* Var_Set flags */
  206. #define VAR_NO_EXPORT 0x01 /* do not export */
  207. typedef struct {
  208. /*
  209. * The following fields are set by Var_Parse() when it
  210. * encounters modifiers that need to keep state for use by
  211. * subsequent modifiers within the same variable expansion.
  212. */
  213. Byte varSpace; /* Word separator in expansions */
  214. Boolean oneBigWord; /* TRUE if we will treat the variable as a
  215. * single big word, even if it contains
  216. * embedded spaces (as opposed to the
  217. * usual behaviour of treating it as
  218. * several space-separated words). */
  219. } Var_Parse_State;
  220. /* struct passed as 'void *' to VarSubstitute() for ":S/lhs/rhs/",
  221. * to VarSYSVMatch() for ":lhs=rhs". */
  222. typedef struct {
  223. const char *lhs; /* String to match */
  224. int leftLen; /* Length of string */
  225. const char *rhs; /* Replacement string (w/ &'s removed) */
  226. int rightLen; /* Length of replacement */
  227. int flags;
  228. } VarPattern;
  229. /* struct passed as 'void *' to VarLoopExpand() for ":@tvar@str@" */
  230. typedef struct {
  231. GNode *ctxt; /* variable context */
  232. char *tvar; /* name of temp var */
  233. int tvarLen;
  234. char *str; /* string to expand */
  235. int strLen;
  236. int errnum; /* errnum for not defined */
  237. } VarLoop_t;
  238. #ifndef NO_REGEX
  239. /* struct passed as 'void *' to VarRESubstitute() for ":C///" */
  240. typedef struct {
  241. regex_t re;
  242. int nsub;
  243. regmatch_t *matches;
  244. char *replace;
  245. int flags;
  246. } VarREPattern;
  247. #endif
  248. /* struct passed to VarSelectWords() for ":[start..end]" */
  249. typedef struct {
  250. int start; /* first word to select */
  251. int end; /* last word to select */
  252. } VarSelectWords_t;
  253. static Var *VarFind(const char *, GNode *, int);
  254. static void VarAdd(const char *, const char *, GNode *);
  255. static Boolean VarHead(GNode *, Var_Parse_State *,
  256. char *, Boolean, Buffer *, void *);
  257. static Boolean VarTail(GNode *, Var_Parse_State *,
  258. char *, Boolean, Buffer *, void *);
  259. static Boolean VarSuffix(GNode *, Var_Parse_State *,
  260. char *, Boolean, Buffer *, void *);
  261. static Boolean VarRoot(GNode *, Var_Parse_State *,
  262. char *, Boolean, Buffer *, void *);
  263. static Boolean VarMatch(GNode *, Var_Parse_State *,
  264. char *, Boolean, Buffer *, void *);
  265. #ifdef SYSVVARSUB
  266. static Boolean VarSYSVMatch(GNode *, Var_Parse_State *,
  267. char *, Boolean, Buffer *, void *);
  268. #endif
  269. static Boolean VarNoMatch(GNode *, Var_Parse_State *,
  270. char *, Boolean, Buffer *, void *);
  271. #ifndef NO_REGEX
  272. static void VarREError(int, regex_t *, const char *);
  273. static Boolean VarRESubstitute(GNode *, Var_Parse_State *,
  274. char *, Boolean, Buffer *, void *);
  275. #endif
  276. static Boolean VarSubstitute(GNode *, Var_Parse_State *,
  277. char *, Boolean, Buffer *, void *);
  278. static Boolean VarLoopExpand(GNode *, Var_Parse_State *,
  279. char *, Boolean, Buffer *, void *);
  280. static char *VarGetPattern(GNode *, Var_Parse_State *,
  281. int, const char **, int, int *, int *,
  282. VarPattern *);
  283. static char *VarQuote(char *);
  284. static char *VarChangeCase(char *, int);
  285. static char *VarModify(GNode *, Var_Parse_State *,
  286. const char *,
  287. Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
  288. void *);
  289. static char *VarOrder(const char *, const char);
  290. static char *VarUniq(const char *);
  291. static int VarWordCompare(const void *, const void *);
  292. static void VarPrintVar(void *);
  293. #define BROPEN '{'
  294. #define BRCLOSE '}'
  295. #define PROPEN '('
  296. #define PRCLOSE ')'
  297. /*-
  298. *-----------------------------------------------------------------------
  299. * VarFind --
  300. * Find the given variable in the given context and any other contexts
  301. * indicated.
  302. *
  303. * Input:
  304. * name name to find
  305. * ctxt context in which to find it
  306. * flags FIND_GLOBAL set means to look in the
  307. * VAR_GLOBAL context as well. FIND_CMD set means
  308. * to look in the VAR_CMD context also. FIND_ENV
  309. * set means to look in the environment
  310. *
  311. * Results:
  312. * A pointer to the structure describing the desired variable or
  313. * NULL if the variable does not exist.
  314. *
  315. * Side Effects:
  316. * None
  317. *-----------------------------------------------------------------------
  318. */
  319. static Var *
  320. VarFind(const char *name, GNode *ctxt, int flags)
  321. {
  322. Hash_Entry *var;
  323. Var *v;
  324. /*
  325. * If the variable name begins with a '.', it could very well be one of
  326. * the local ones. We check the name against all the local variables
  327. * and substitute the short version in for 'name' if it matches one of
  328. * them.
  329. */
  330. if (*name == '.' && isupper((unsigned char) name[1]))
  331. switch (name[1]) {
  332. case 'A':
  333. if (!strcmp(name, ".ALLSRC"))
  334. name = ALLSRC;
  335. if (!strcmp(name, ".ARCHIVE"))
  336. name = ARCHIVE;
  337. break;
  338. case 'I':
  339. if (!strcmp(name, ".IMPSRC"))
  340. name = IMPSRC;
  341. break;
  342. case 'M':
  343. if (!strcmp(name, ".MEMBER"))
  344. name = MEMBER;
  345. break;
  346. case 'O':
  347. if (!strcmp(name, ".OODATE"))
  348. name = OODATE;
  349. break;
  350. case 'P':
  351. if (!strcmp(name, ".PREFIX"))
  352. name = PREFIX;
  353. break;
  354. case 'T':
  355. if (!strcmp(name, ".TARGET"))
  356. name = TARGET;
  357. break;
  358. }
  359. /*
  360. * First look for the variable in the given context. If it's not there,
  361. * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
  362. * depending on the FIND_* flags in 'flags'
  363. */
  364. var = Hash_FindEntry(&ctxt->context, name);
  365. if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
  366. var = Hash_FindEntry(&VAR_CMD->context, name);
  367. }
  368. if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) &&
  369. (ctxt != VAR_GLOBAL))
  370. {
  371. var = Hash_FindEntry(&VAR_GLOBAL->context, name);
  372. }
  373. if ((var == NULL) && (flags & FIND_ENV)) {
  374. char *env;
  375. if ((env = getenv(name)) != NULL) {
  376. int len;
  377. v = bmake_malloc(sizeof(Var));
  378. v->name = bmake_strdup(name);
  379. len = strlen(env);
  380. Buf_Init(&v->val, len + 1);
  381. Buf_AddBytes(&v->val, len, env);
  382. v->flags = VAR_FROM_ENV;
  383. return (v);
  384. } else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
  385. (ctxt != VAR_GLOBAL))
  386. {
  387. var = Hash_FindEntry(&VAR_GLOBAL->context, name);
  388. if (var == NULL) {
  389. return NULL;
  390. } else {
  391. return ((Var *)Hash_GetValue(var));
  392. }
  393. } else {
  394. return NULL;
  395. }
  396. } else if (var == NULL) {
  397. return NULL;
  398. } else {
  399. return ((Var *)Hash_GetValue(var));
  400. }
  401. }
  402. /*-
  403. *-----------------------------------------------------------------------
  404. * VarFreeEnv --
  405. * If the variable is an environment variable, free it
  406. *
  407. * Input:
  408. * v the variable
  409. * destroy true if the value buffer should be destroyed.
  410. *
  411. * Results:
  412. * 1 if it is an environment variable 0 ow.
  413. *
  414. * Side Effects:
  415. * The variable is free'ed if it is an environent variable.
  416. *-----------------------------------------------------------------------
  417. */
  418. static Boolean
  419. VarFreeEnv(Var *v, Boolean destroy)
  420. {
  421. if ((v->flags & VAR_FROM_ENV) == 0)
  422. return FALSE;
  423. free(v->name);
  424. Buf_Destroy(&v->val, destroy);
  425. free(v);
  426. return TRUE;
  427. }
  428. /*-
  429. *-----------------------------------------------------------------------
  430. * VarAdd --
  431. * Add a new variable of name name and value val to the given context
  432. *
  433. * Input:
  434. * name name of variable to add
  435. * val value to set it to
  436. * ctxt context in which to set it
  437. *
  438. * Results:
  439. * None
  440. *
  441. * Side Effects:
  442. * The new variable is placed at the front of the given context
  443. * The name and val arguments are duplicated so they may
  444. * safely be freed.
  445. *-----------------------------------------------------------------------
  446. */
  447. static void
  448. VarAdd(const char *name, const char *val, GNode *ctxt)
  449. {
  450. Var *v;
  451. int len;
  452. Hash_Entry *h;
  453. v = bmake_malloc(sizeof(Var));
  454. len = val ? strlen(val) : 0;
  455. Buf_Init(&v->val, len+1);
  456. Buf_AddBytes(&v->val, len, val);
  457. v->flags = 0;
  458. h = Hash_CreateEntry(&ctxt->context, name, NULL);
  459. Hash_SetValue(h, v);
  460. v->name = h->name;
  461. if (DEBUG(VAR)) {
  462. fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
  463. }
  464. }
  465. /*-
  466. *-----------------------------------------------------------------------
  467. * Var_Delete --
  468. * Remove a variable from a context.
  469. *
  470. * Results:
  471. * None.
  472. *
  473. * Side Effects:
  474. * The Var structure is removed and freed.
  475. *
  476. *-----------------------------------------------------------------------
  477. */
  478. void
  479. Var_Delete(const char *name, GNode *ctxt)
  480. {
  481. Hash_Entry *ln;
  482. ln = Hash_FindEntry(&ctxt->context, name);
  483. if (DEBUG(VAR)) {
  484. fprintf(debug_file, "%s:delete %s%s\n",
  485. ctxt->name, name, ln ? "" : " (not found)");
  486. }
  487. if (ln != NULL) {
  488. Var *v;
  489. v = (Var *)Hash_GetValue(ln);
  490. if ((v->flags & VAR_EXPORTED)) {
  491. unsetenv(v->name);
  492. }
  493. if (strcmp(MAKE_EXPORTED, v->name) == 0) {
  494. var_exportedVars = VAR_EXPORTED_NONE;
  495. }
  496. if (v->name != ln->name)
  497. free(v->name);
  498. Hash_DeleteEntry(&ctxt->context, ln);
  499. Buf_Destroy(&v->val, TRUE);
  500. free(v);
  501. }
  502. }
  503. /*
  504. * Export a var.
  505. * We ignore make internal variables (those which start with '.')
  506. * Also we jump through some hoops to avoid calling setenv
  507. * more than necessary since it can leak.
  508. * We only manipulate flags of vars if 'parent' is set.
  509. */
  510. static int
  511. Var_Export1(const char *name, int parent)
  512. {
  513. char tmp[BUFSIZ];
  514. Var *v;
  515. char *val = NULL;
  516. int n;
  517. if (*name == '.')
  518. return 0; /* skip internals */
  519. if (!name[1]) {
  520. /*
  521. * A single char.
  522. * If it is one of the vars that should only appear in
  523. * local context, skip it, else we can get Var_Subst
  524. * into a loop.
  525. */
  526. switch (name[0]) {
  527. case '@':
  528. case '%':
  529. case '*':
  530. case '!':
  531. return 0;
  532. }
  533. }
  534. v = VarFind(name, VAR_GLOBAL, 0);
  535. if (v == NULL) {
  536. return 0;
  537. }
  538. if (!parent &&
  539. (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
  540. return 0; /* nothing to do */
  541. }
  542. val = Buf_GetAll(&v->val, NULL);
  543. if (strchr(val, '$')) {
  544. if (parent) {
  545. /*
  546. * Flag this as something we need to re-export.
  547. * No point actually exporting it now though,
  548. * the child can do it at the last minute.
  549. */
  550. v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
  551. return 1;
  552. }
  553. if (v->flags & VAR_IN_USE) {
  554. /*
  555. * We recursed while exporting in a child.
  556. * This isn't going to end well, just skip it.
  557. */
  558. return 0;
  559. }
  560. n = snprintf(tmp, sizeof(tmp), "${%s}", name);
  561. if (n < (int)sizeof(tmp)) {
  562. val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
  563. setenv(name, val, 1);
  564. free(val);
  565. }
  566. } else {
  567. if (parent) {
  568. v->flags &= ~VAR_REEXPORT; /* once will do */
  569. }
  570. if (parent || !(v->flags & VAR_EXPORTED)) {
  571. setenv(name, val, 1);
  572. }
  573. }
  574. /*
  575. * This is so Var_Set knows to call Var_Export again...
  576. */
  577. if (parent) {
  578. v->flags |= VAR_EXPORTED;
  579. }
  580. return 1;
  581. }
  582. /*
  583. * This gets called from our children.
  584. */
  585. void
  586. Var_ExportVars(void)
  587. {
  588. char tmp[BUFSIZ];
  589. Hash_Entry *var;
  590. Hash_Search state;
  591. Var *v;
  592. char *val;
  593. int n;
  594. if (VAR_EXPORTED_NONE == var_exportedVars)
  595. return;
  596. if (VAR_EXPORTED_ALL == var_exportedVars) {
  597. /*
  598. * Ouch! This is crazy...
  599. */
  600. for (var = Hash_EnumFirst(&VAR_GLOBAL->context, &state);
  601. var != NULL;
  602. var = Hash_EnumNext(&state)) {
  603. v = (Var *)Hash_GetValue(var);
  604. Var_Export1(v->name, 0);
  605. }
  606. return;
  607. }
  608. /*
  609. * We have a number of exported vars,
  610. */
  611. n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
  612. if (n < (int)sizeof(tmp)) {
  613. char **av;
  614. char *as;
  615. int ac;
  616. int i;
  617. val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
  618. av = brk_string(val, &ac, FALSE, &as);
  619. for (i = 0; i < ac; i++) {
  620. Var_Export1(av[i], 0);
  621. }
  622. free(val);
  623. free(as);
  624. free(av);
  625. }
  626. }
  627. /*
  628. * This is called when .export is seen or
  629. * .MAKE.EXPORTED is modified.
  630. * It is also called when any exported var is modified.
  631. */
  632. void
  633. Var_Export(char *str, int isExport)
  634. {
  635. char *name;
  636. char *val;
  637. char **av;
  638. char *as;
  639. int track;
  640. int ac;
  641. int i;
  642. if (isExport && (!str || !str[0])) {
  643. var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
  644. return;
  645. }
  646. if (strncmp(str, "-env", 4) == 0) {
  647. track = 0;
  648. str += 4;
  649. } else {
  650. track = VAR_EXPORT_PARENT;
  651. }
  652. val = Var_Subst(NULL, str, VAR_GLOBAL, 0);
  653. av = brk_string(val, &ac, FALSE, &as);
  654. for (i = 0; i < ac; i++) {
  655. name = av[i];
  656. if (!name[1]) {
  657. /*
  658. * A single char.
  659. * If it is one of the vars that should only appear in
  660. * local context, skip it, else we can get Var_Subst
  661. * into a loop.
  662. */
  663. switch (name[0]) {
  664. case '@':
  665. case '%':
  666. case '*':
  667. case '!':
  668. continue;
  669. }
  670. }
  671. if (Var_Export1(name, track)) {
  672. if (VAR_EXPORTED_ALL != var_exportedVars)
  673. var_exportedVars = VAR_EXPORTED_YES;
  674. if (isExport && track) {
  675. Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
  676. }
  677. }
  678. }
  679. free(val);
  680. free(as);
  681. free(av);
  682. }
  683. /*
  684. * This is called when .unexport[-env] is seen.
  685. */
  686. void
  687. Var_UnExport(char *str)
  688. {
  689. char tmp[BUFSIZ];
  690. char *vlist;
  691. char *cp;
  692. Boolean unexport_env;
  693. int n;
  694. if (!str || !str[0]) {
  695. return; /* assert? */
  696. }
  697. vlist = NULL;
  698. str += 8;
  699. unexport_env = (strncmp(str, "-env", 4) == 0);
  700. if (unexport_env) {
  701. extern char **environ;
  702. static char **savenv;
  703. char **newenv;
  704. cp = getenv(MAKE_LEVEL); /* we should preserve this */
  705. if (environ == savenv) {
  706. /* we have been here before! */
  707. newenv = bmake_realloc(environ, 2 * sizeof(char *));
  708. } else {
  709. if (savenv) {
  710. free(savenv);
  711. savenv = NULL;
  712. }
  713. newenv = bmake_malloc(2 * sizeof(char *));
  714. }
  715. if (!newenv)
  716. return;
  717. /* Note: we cannot safely free() the original environ. */
  718. environ = savenv = newenv;
  719. newenv[0] = NULL;
  720. newenv[1] = NULL;
  721. setenv(MAKE_LEVEL, cp, 1);
  722. } else {
  723. for (; *str != '\n' && isspace((unsigned char) *str); str++)
  724. continue;
  725. if (str[0] && str[0] != '\n') {
  726. vlist = str;
  727. }
  728. }
  729. if (!vlist) {
  730. /* Using .MAKE.EXPORTED */
  731. n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
  732. if (n < (int)sizeof(tmp)) {
  733. vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
  734. }
  735. }
  736. if (vlist) {
  737. Var *v;
  738. char **av;
  739. char *as;
  740. int ac;
  741. int i;
  742. av = brk_string(vlist, &ac, FALSE, &as);
  743. for (i = 0; i < ac; i++) {
  744. v = VarFind(av[i], VAR_GLOBAL, 0);
  745. if (!v)
  746. continue;
  747. if (!unexport_env &&
  748. (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
  749. unsetenv(v->name);
  750. }
  751. v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT);
  752. /*
  753. * If we are unexporting a list,
  754. * remove each one from .MAKE.EXPORTED.
  755. * If we are removing them all,
  756. * just delete .MAKE.EXPORTED below.
  757. */
  758. if (vlist == str) {
  759. n = snprintf(tmp, sizeof(tmp),
  760. "${" MAKE_EXPORTED ":N%s}", v->name);
  761. if (n < (int)sizeof(tmp)) {
  762. cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
  763. Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
  764. free(cp);
  765. }
  766. }
  767. }
  768. free(as);
  769. free(av);
  770. if (vlist != str) {
  771. Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
  772. free(vlist);
  773. }
  774. }
  775. }
  776. /*-
  777. *-----------------------------------------------------------------------
  778. * Var_Set --
  779. * Set the variable name to the value val in the given context.
  780. *
  781. * Input:
  782. * name name of variable to set
  783. * val value to give to the variable
  784. * ctxt context in which to set it
  785. *
  786. * Results:
  787. * None.
  788. *
  789. * Side Effects:
  790. * If the variable doesn't yet exist, a new record is created for it.
  791. * Else the old value is freed and the new one stuck in its place
  792. *
  793. * Notes:
  794. * The variable is searched for only in its context before being
  795. * created in that context. I.e. if the context is VAR_GLOBAL,
  796. * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
  797. * VAR_CMD->context is searched. This is done to avoid the literally
  798. * thousands of unnecessary strcmp's that used to be done to
  799. * set, say, $(@) or $(<).
  800. * If the context is VAR_GLOBAL though, we check if the variable
  801. * was set in VAR_CMD from the command line and skip it if so.
  802. *-----------------------------------------------------------------------
  803. */
  804. void
  805. Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
  806. {
  807. Var *v;
  808. char *expanded_name = NULL;
  809. /*
  810. * We only look for a variable in the given context since anything set
  811. * here will override anything in a lower context, so there's not much
  812. * point in searching them all just to save a bit of memory...
  813. */
  814. if (strchr(name, '$') != NULL) {
  815. expanded_name = Var_Subst(NULL, name, ctxt, 0);
  816. if (expanded_name[0] == 0) {
  817. if (DEBUG(VAR)) {
  818. fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
  819. "name expands to empty string - ignored\n",
  820. name, val);
  821. }
  822. free(expanded_name);
  823. return;
  824. }
  825. name = expanded_name;
  826. }
  827. if (ctxt == VAR_GLOBAL) {
  828. v = VarFind(name, VAR_CMD, 0);
  829. if (v != NULL) {
  830. if ((v->flags & VAR_FROM_CMD)) {
  831. if (DEBUG(VAR)) {
  832. fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val);
  833. }
  834. goto out;
  835. }
  836. VarFreeEnv(v, TRUE);
  837. }
  838. }
  839. v = VarFind(name, ctxt, 0);
  840. if (v == NULL) {
  841. VarAdd(name, val, ctxt);
  842. } else {
  843. Buf_Empty(&v->val);
  844. Buf_AddBytes(&v->val, strlen(val), val);
  845. if (DEBUG(VAR)) {
  846. fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
  847. }
  848. if ((v->flags & VAR_EXPORTED)) {
  849. Var_Export1(name, VAR_EXPORT_PARENT);
  850. }
  851. }
  852. /*
  853. * Any variables given on the command line are automatically exported
  854. * to the environment (as per POSIX standard)
  855. */
  856. if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
  857. if (v == NULL) {
  858. /* we just added it */
  859. v = VarFind(name, ctxt, 0);
  860. }
  861. if (v != NULL)
  862. v->flags |= VAR_FROM_CMD;
  863. /*
  864. * If requested, don't export these in the environment
  865. * individually. We still put them in MAKEOVERRIDES so
  866. * that the command-line settings continue to override
  867. * Makefile settings.
  868. */
  869. if (varNoExportEnv != TRUE)
  870. setenv(name, val, 1);
  871. Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
  872. }
  873. /*
  874. * Another special case.
  875. * Several make's support this sort of mechanism for tracking
  876. * recursion - but each uses a different name.
  877. * We allow the makefiles to update .MAKE.LEVEL and ensure
  878. * children see a correctly incremented value.
  879. */
  880. if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
  881. char tmp[64];
  882. int level;
  883. level = atoi(val);
  884. snprintf(tmp, sizeof(tmp), "%u", level + 1);
  885. setenv(MAKE_LEVEL, tmp, 1);
  886. }
  887. out:
  888. if (expanded_name != NULL)
  889. free(expanded_name);
  890. if (v != NULL)
  891. VarFreeEnv(v, TRUE);
  892. }
  893. /*-
  894. *-----------------------------------------------------------------------
  895. * Var_Append --
  896. * The variable of the given name has the given value appended to it in
  897. * the given context.
  898. *
  899. * Input:
  900. * name name of variable to modify
  901. * val String to append to it
  902. * ctxt Context in which this should occur
  903. *
  904. * Results:
  905. * None
  906. *
  907. * Side Effects:
  908. * If the variable doesn't exist, it is created. Else the strings
  909. * are concatenated (with a space in between).
  910. *
  911. * Notes:
  912. * Only if the variable is being sought in the global context is the
  913. * environment searched.
  914. * XXX: Knows its calling circumstances in that if called with ctxt
  915. * an actual target, it will only search that context since only
  916. * a local variable could be being appended to. This is actually
  917. * a big win and must be tolerated.
  918. *-----------------------------------------------------------------------
  919. */
  920. void
  921. Var_Append(const char *name, const char *val, GNode *ctxt)
  922. {
  923. Var *v;
  924. Hash_Entry *h;
  925. char *expanded_name = NULL;
  926. if (strchr(name, '$') != NULL) {
  927. expanded_name = Var_Subst(NULL, name, ctxt, 0);
  928. if (expanded_name[0] == 0) {
  929. if (DEBUG(VAR)) {
  930. fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
  931. "name expands to empty string - ignored\n",
  932. name, val);
  933. }
  934. free(expanded_name);
  935. return;
  936. }
  937. name = expanded_name;
  938. }
  939. v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
  940. if (v == NULL) {
  941. VarAdd(name, val, ctxt);
  942. } else {
  943. Buf_AddByte(&v->val, ' ');
  944. Buf_AddBytes(&v->val, strlen(val), val);
  945. if (DEBUG(VAR)) {
  946. fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
  947. Buf_GetAll(&v->val, NULL));
  948. }
  949. if (v->flags & VAR_FROM_ENV) {
  950. /*
  951. * If the original variable came from the environment, we
  952. * have to install it in the global context (we could place
  953. * it in the environment, but then we should provide a way to
  954. * export other variables...)
  955. */
  956. v->flags &= ~VAR_FROM_ENV;
  957. h = Hash_CreateEntry(&ctxt->context, name, NULL);
  958. Hash_SetValue(h, v);
  959. }
  960. }
  961. if (expanded_name != NULL)
  962. free(expanded_name);
  963. }
  964. /*-
  965. *-----------------------------------------------------------------------
  966. * Var_Exists --
  967. * See if the given variable exists.
  968. *
  969. * Input:
  970. * name Variable to find
  971. * ctxt Context in which to start search
  972. *
  973. * Results:
  974. * TRUE if it does, FALSE if it doesn't
  975. *
  976. * Side Effects:
  977. * None.
  978. *
  979. *-----------------------------------------------------------------------
  980. */
  981. Boolean
  982. Var_Exists(const char *name, GNode *ctxt)
  983. {
  984. Var *v;
  985. char *cp;
  986. if ((cp = strchr(name, '$')) != NULL) {
  987. cp = Var_Subst(NULL, name, ctxt, FALSE);
  988. }
  989. v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
  990. if (cp != NULL) {
  991. free(cp);
  992. }
  993. if (v == NULL) {
  994. return(FALSE);
  995. } else {
  996. (void)VarFreeEnv(v, TRUE);
  997. }
  998. return(TRUE);
  999. }
  1000. /*-
  1001. *-----------------------------------------------------------------------
  1002. * Var_Value --
  1003. * Return the value of the named variable in the given context
  1004. *
  1005. * Input:
  1006. * name name to find
  1007. * ctxt context in which to search for it
  1008. *
  1009. * Results:
  1010. * The value if the variable exists, NULL if it doesn't
  1011. *
  1012. * Side Effects:
  1013. * None
  1014. *-----------------------------------------------------------------------
  1015. */
  1016. char *
  1017. Var_Value(const char *name, GNode *ctxt, char **frp)
  1018. {
  1019. Var *v;
  1020. v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
  1021. *frp = NULL;
  1022. if (v != NULL) {
  1023. char *p = (Buf_GetAll(&v->val, NULL));
  1024. if (VarFreeEnv(v, FALSE))
  1025. *frp = p;
  1026. return p;
  1027. } else {
  1028. return NULL;
  1029. }
  1030. }
  1031. /*-
  1032. *-----------------------------------------------------------------------
  1033. * VarHead --
  1034. * Remove the tail of the given word and place the result in the given
  1035. * buffer.
  1036. *
  1037. * Input:
  1038. * word Word to trim
  1039. * addSpace True if need to add a space to the buffer
  1040. * before sticking in the head
  1041. * buf Buffer in which to store it
  1042. *
  1043. * Results:
  1044. * TRUE if characters were added to the buffer (a space needs to be
  1045. * added to the buffer before the next word).
  1046. *
  1047. * Side Effects:
  1048. * The trimmed word is added to the buffer.
  1049. *
  1050. *-----------------------------------------------------------------------
  1051. */
  1052. static Boolean
  1053. VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
  1054. char *word, Boolean addSpace, Buffer *buf,
  1055. void *dummy)
  1056. {
  1057. char *slash;
  1058. slash = strrchr(word, '/');
  1059. if (slash != NULL) {
  1060. if (addSpace && vpstate->varSpace) {
  1061. Buf_AddByte(buf, vpstate->varSpace);
  1062. }
  1063. *slash = '\0';
  1064. Buf_AddBytes(buf, strlen(word), word);
  1065. *slash = '/';
  1066. return (TRUE);
  1067. } else {
  1068. /*
  1069. * If no directory part, give . (q.v. the POSIX standard)
  1070. */
  1071. if (addSpace && vpstate->varSpace)
  1072. Buf_AddByte(buf, vpstate->varSpace);
  1073. Buf_AddByte(buf, '.');
  1074. }
  1075. return(dummy ? TRUE : TRUE);
  1076. }
  1077. /*-
  1078. *-----------------------------------------------------------------------
  1079. * VarTail --
  1080. * Remove the head of the given word and place the result in the given
  1081. * buffer.
  1082. *
  1083. * Input:
  1084. * word Word to trim
  1085. * addSpace True if need to add a space to the buffer
  1086. * before adding the tail
  1087. * buf Buffer in which to store it
  1088. *
  1089. * Results:
  1090. * TRUE if characters were added to the buffer (a space needs to be
  1091. * added to the buffer before the next word).
  1092. *
  1093. * Side Effects:
  1094. * The trimmed word is added to the buffer.
  1095. *
  1096. *-----------------------------------------------------------------------
  1097. */
  1098. static Boolean
  1099. VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
  1100. char *word, Boolean addSpace, Buffer *buf,
  1101. void *dummy)
  1102. {
  1103. char *slash;
  1104. if (addSpace && vpstate->varSpace) {
  1105. Buf_AddByte(buf, vpstate->varSpace);
  1106. }
  1107. slash = strrchr(word, '/');
  1108. if (slash != NULL) {
  1109. *slash++ = '\0';
  1110. Buf_AddBytes(buf, strlen(slash), slash);
  1111. slash[-1] = '/';
  1112. } else {
  1113. Buf_AddBytes(buf, strlen(word), word);
  1114. }
  1115. return (dummy ? TRUE : TRUE);
  1116. }
  1117. /*-
  1118. *-----------------------------------------------------------------------
  1119. * VarSuffix --
  1120. * Place the suffix of the given word in the given buffer.
  1121. *
  1122. * Input:
  1123. * word Word to trim
  1124. * addSpace TRUE if need to add a space before placing the
  1125. * suffix in the buffer
  1126. * buf Buffer in which to store it
  1127. *
  1128. * Results:
  1129. * TRUE if characters were added to the buffer (a space needs to be
  1130. * added to the buffer before the next word).
  1131. *
  1132. * Side Effects:
  1133. * The suffix from the word is placed in the buffer.
  1134. *
  1135. *-----------------------------------------------------------------------
  1136. */
  1137. static Boolean
  1138. VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
  1139. char *word, Boolean addSpace, Buffer *buf,
  1140. void *dummy)
  1141. {
  1142. char *dot;
  1143. dot = strrchr(word, '.');
  1144. if (dot != NULL) {
  1145. if (addSpace && vpstate->varSpace) {
  1146. Buf_AddByte(buf, vpstate->varSpace);
  1147. }
  1148. *dot++ = '\0';
  1149. Buf_AddBytes(buf, strlen(dot), dot);
  1150. dot[-1] = '.';
  1151. addSpace = TRUE;
  1152. }
  1153. return (dummy ? addSpace : addSpace);
  1154. }
  1155. /*-
  1156. *-----------------------------------------------------------------------
  1157. * VarRoot --
  1158. * Remove the suffix of the given word and place the result in the
  1159. * buffer.
  1160. *
  1161. * Input:
  1162. * word Word to trim
  1163. * addSpace TRUE if need to add a space to the buffer
  1164. * before placing the root in it
  1165. * buf Buffer in which to store it
  1166. *
  1167. * Results:
  1168. * TRUE if characters were added to the buffer (a space needs to be
  1169. * added to the buffer before the next word).
  1170. *
  1171. * Side Effects:
  1172. * The trimmed word is added to the buffer.
  1173. *
  1174. *-----------------------------------------------------------------------
  1175. */
  1176. static Boolean
  1177. VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
  1178. char *word, Boolean addSpace, Buffer *buf,
  1179. void *dummy)
  1180. {
  1181. char *dot;
  1182. if (addSpace && vpstate->varSpace) {
  1183. Buf_AddByte(buf, vpstate->varSpace);
  1184. }
  1185. dot = strrchr(word, '.');
  1186. if (dot != NULL) {
  1187. *dot = '\0';
  1188. Buf_AddBytes(buf, strlen(word), word);
  1189. *dot = '.';
  1190. } else {
  1191. Buf_AddBytes(buf, strlen(word), word);
  1192. }
  1193. return (dummy ? TRUE : TRUE);
  1194. }
  1195. /*-
  1196. *-----------------------------------------------------------------------
  1197. * VarMatch --
  1198. * Place the word in the buffer if it matches the given pattern.
  1199. * Callback function for VarModify to implement the :M modifier.
  1200. *
  1201. * Input:
  1202. * word Word to examine
  1203. * addSpace TRUE if need to add a space to the buffer
  1204. * before adding the word, if it matches
  1205. * buf Buffer in which to store it
  1206. * pattern Pattern the word must match
  1207. *
  1208. * Results:
  1209. * TRUE if a space should be placed in the buffer before the next
  1210. * word.
  1211. *
  1212. * Side Effects:
  1213. * The word may be copied to the buffer.
  1214. *
  1215. *-----------------------------------------------------------------------
  1216. */
  1217. static Boolean
  1218. VarMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
  1219. char *word, Boolean addSpace, Buffer *buf,
  1220. void *pattern)
  1221. {
  1222. if (DEBUG(VAR))
  1223. fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *)pattern);
  1224. if (Str_Match(word, (char *)pattern)) {
  1225. if (addSpace && vpstate->varSpace) {
  1226. Buf_AddByte(buf, vpstate->varSpace);
  1227. }
  1228. addSpace = TRUE;
  1229. Buf_AddBytes(buf, strlen(word), word);
  1230. }
  1231. return(addSpace);
  1232. }
  1233. #ifdef SYSVVARSUB
  1234. /*-
  1235. *-----------------------------------------------------------------------
  1236. * VarSYSVMatch --
  1237. * Place the word in the buffer if it matches the given pattern.
  1238. * Callback function for VarModify to implement the System V %
  1239. * modifiers.
  1240. *
  1241. * Input:
  1242. * word Word to examine
  1243. * addSpace TRUE if need to add a space to the buffer
  1244. * before adding the word, if it matches
  1245. * buf Buffer in which to store it
  1246. * patp Pattern the word must match
  1247. *
  1248. * Results:
  1249. * TRUE if a space should be placed in the buffer before the next
  1250. * word.
  1251. *
  1252. * Side Effects:
  1253. * The word may be copied to the buffer.
  1254. *
  1255. *-----------------------------------------------------------------------
  1256. */
  1257. static Boolean
  1258. VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
  1259. char *word, Boolean addSpace, Buffer *buf,
  1260. void *patp)
  1261. {
  1262. int len;
  1263. char *ptr;
  1264. VarPattern *pat = (VarPattern *)patp;
  1265. char *varexp;
  1266. if (addSpace && vpstate->varSpace)
  1267. Buf_AddByte(buf, vpstate->varSpace);
  1268. addSpace = TRUE;
  1269. if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) {
  1270. varexp = Var_Subst(NULL, pat->rhs, ctx, 0);
  1271. Str_SYSVSubst(buf, varexp, ptr, len);
  1272. free(varexp);
  1273. } else {
  1274. Buf_AddBytes(buf, strlen(word), word);
  1275. }
  1276. return(addSpace);
  1277. }
  1278. #endif
  1279. /*-
  1280. *-----------------------------------------------------------------------
  1281. * VarNoMatch --
  1282. * Place the word in the buffer if it doesn't match the given pattern.
  1283. * Callback function for VarModify to implement the :N modifier.
  1284. *
  1285. * Input:
  1286. * word Word to examine
  1287. * addSpace TRUE if need to add a space to the buffer
  1288. * before adding the word, if it matches
  1289. * buf Buffer in which to store it
  1290. * pattern Pattern the word must match
  1291. *
  1292. * Results:
  1293. * TRUE if a space should be placed in the buffer before the next
  1294. * word.
  1295. *
  1296. * Side Effects:
  1297. * The word may be copied to the buffer.
  1298. *
  1299. *-----------------------------------------------------------------------
  1300. */
  1301. static Boolean
  1302. VarNoMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
  1303. char *word, Boolean addSpace, Buffer *buf,
  1304. void *pattern)
  1305. {
  1306. if (!Str_Match(word, (char *)pattern)) {
  1307. if (addSpace && vpstate->varSpace) {
  1308. Buf_AddByte(buf, vpstate->varSpace);
  1309. }
  1310. addSpace = TRUE;
  1311. Buf_AddBytes(buf, strlen(word), word);
  1312. }
  1313. return(addSpace);
  1314. }
  1315. /*-
  1316. *-----------------------------------------------------------------------
  1317. * VarSubstitute --
  1318. * Perform a string-substitution on the given word, placing the
  1319. * result in the passed buffer.
  1320. *
  1321. * Input:
  1322. * word Word to modify
  1323. * addSpace True if space should be added before
  1324. * other characters
  1325. * buf Buffer for result
  1326. * patternp Pattern for substitution
  1327. *
  1328. * Results:
  1329. * TRUE if a space is needed before more characters are added.
  1330. *
  1331. * Side Effects:
  1332. * None.
  1333. *
  1334. *-----------------------------------------------------------------------
  1335. */
  1336. static Boolean
  1337. VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
  1338. char *word, Boolean addSpace, Buffer *buf,
  1339. void *patternp)
  1340. {
  1341. int wordLen; /* Length of word */
  1342. char *cp; /* General pointer */
  1343. VarPattern *pattern = (VarPattern *)patternp;
  1344. wordLen = strlen(word);
  1345. if ((pattern->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) !=
  1346. (VAR_SUB_ONE|VAR_SUB_MATCHED)) {
  1347. /*
  1348. * Still substituting -- break it down into simple anchored cases
  1349. * and if none of them fits, perform the general substitution case.
  1350. */
  1351. if ((pattern->flags & VAR_MATCH_START) &&
  1352. (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
  1353. /*
  1354. * Anchored at start and beginning of word matches pattern
  1355. */
  1356. if ((pattern->flags & VAR_MATCH_END) &&
  1357. (wordLen == pattern->leftLen)) {
  1358. /*
  1359. * Also anchored at end and matches to the end (word
  1360. * is same length as pattern) add space and rhs only
  1361. * if rhs is non-null.
  1362. */
  1363. if (pattern->rightLen != 0) {
  1364. if (addSpace && vpstate->varSpace) {
  1365. Buf_AddByte(buf, vpstate->varSpace);
  1366. }
  1367. addSpace = TRUE;
  1368. Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
  1369. }
  1370. pattern->flags |= VAR_SUB_MATCHED;
  1371. } else if (pattern->flags & VAR_MATCH_END) {
  1372. /*
  1373. * Doesn't match to end -- copy word wholesale
  1374. */
  1375. goto nosub;
  1376. } else {
  1377. /*
  1378. * Matches at start but need to copy in trailing characters
  1379. */
  1380. if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
  1381. if (addSpace && vpstate->varSpace) {
  1382. Buf_AddByte(buf, vpstate->varSpace);
  1383. }
  1384. addSpace = TRUE;
  1385. }
  1386. Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
  1387. Buf_AddBytes(buf, wordLen - pattern->leftLen,
  1388. (word + pattern->leftLen));
  1389. pattern->flags |= VAR_SUB_MATCHED;
  1390. }
  1391. } else if (pattern->flags & VAR_MATCH_START) {
  1392. /*
  1393. * Had to match at start of word and didn't -- copy whole word.
  1394. */
  1395. goto nosub;
  1396. } else if (pattern->flags & VAR_MATCH_END) {
  1397. /*
  1398. * Anchored at end, Find only place match could occur (leftLen
  1399. * characters from the end of the word) and see if it does. Note
  1400. * that because the $ will be left at the end of the lhs, we have
  1401. * to use strncmp.
  1402. */
  1403. cp = word + (wordLen - pattern->leftLen);
  1404. if ((cp >= word) &&
  1405. (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
  1406. /*
  1407. * Match found. If we will place characters in the buffer,
  1408. * add a space before hand as indicated by addSpace, then
  1409. * stuff in the initial, unmatched part of the word followed
  1410. * by the right-hand-side.
  1411. */
  1412. if (((cp - word) + pattern->rightLen) != 0) {
  1413. if (addSpace && vpstate->varSpace) {
  1414. Buf_AddByte(buf, vpstate->varSpace);
  1415. }
  1416. addSpace = TRUE;
  1417. }
  1418. Buf_AddBytes(buf, cp - word, word);
  1419. Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
  1420. pattern->flags |= VAR_SUB_MATCHED;
  1421. } else {
  1422. /*
  1423. * Had to match at end and didn't. Copy entire word.
  1424. */
  1425. goto nosub;
  1426. }
  1427. } else {
  1428. /*
  1429. * Pattern is unanchored: search for the pattern in the word using
  1430. * String_FindSubstring, copying unmatched portions and the
  1431. * right-hand-side for each match found, handling non-global
  1432. * substitutions correctly, etc. When the loop is done, any
  1433. * remaining part of the word (word and wordLen are adjusted
  1434. * accordingly through the loop) is copied straight into the
  1435. * buffer.
  1436. * addSpace is set FALSE as soon as a space is added to the
  1437. * buffer.
  1438. */
  1439. Boolean done;
  1440. int origSize;
  1441. done = FALSE;
  1442. origSize = Buf_Size(buf);
  1443. while (!done) {
  1444. cp = Str_FindSubstring(word, pattern->lhs);
  1445. if (cp != NULL) {
  1446. if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
  1447. Buf_AddByte(buf, vpstate->varSpace);
  1448. addSpace = FALSE;
  1449. }
  1450. Buf_AddBytes(buf, cp-word, word);
  1451. Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
  1452. wordLen -= (cp - word) + pattern->leftLen;
  1453. word = cp + pattern->leftLen;
  1454. if (wordLen == 0) {
  1455. done = TRUE;
  1456. }
  1457. if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
  1458. done = TRUE;
  1459. }
  1460. pattern->flags |= VAR_SUB_MATCHED;
  1461. } else {
  1462. done = TRUE;
  1463. }
  1464. }
  1465. if (wordLen != 0) {
  1466. if (addSpace && vpstate->varSpace) {
  1467. Buf_AddByte(buf, vpstate->varSpace);
  1468. }
  1469. Buf_AddBytes(buf, wordLen, word);
  1470. }
  1471. /*
  1472. * If added characters to the buffer, need to add a space
  1473. * before we add any more. If we didn't add any, just return
  1474. * the previous value of addSpace.
  1475. */
  1476. return ((Buf_Size(buf) != origSize) || addSpace);
  1477. }
  1478. return (addSpace);
  1479. }
  1480. nosub:
  1481. if (addSpace && vpstate->varSpace) {
  1482. Buf_AddByte(buf, vpstate->varSpace);
  1483. }
  1484. Buf_AddBytes(buf, wordLen, word);
  1485. return(TRUE);
  1486. }
  1487. #ifndef NO_REGEX
  1488. /*-
  1489. *-----------------------------------------------------------------------
  1490. * VarREError --
  1491. * Print the error caused by a regcomp or regexec call.
  1492. *
  1493. * Results:
  1494. * None.
  1495. *
  1496. * Side Effects:
  1497. * An error gets printed.
  1498. *
  1499. *-----------------------------------------------------------------------
  1500. */
  1501. static void
  1502. VarREError(int errnum, regex_t *pat, const char *str)
  1503. {
  1504. char *errbuf;
  1505. int errlen;
  1506. errlen = regerror(errnum, pat, 0, 0);
  1507. errbuf = bmake_malloc(errlen);
  1508. regerror(errnum, pat, errbuf, errlen);
  1509. Error("%s: %s", str, errbuf);
  1510. free(errbuf);
  1511. }
  1512. /*-
  1513. *-----------------------------------------------------------------------
  1514. * VarRESubstitute --
  1515. * Perform a regex substitution on the given word, placing the
  1516. * result in the passed buffer.
  1517. *
  1518. * Results:
  1519. * TRUE if a space is needed before more characters are added.
  1520. *
  1521. * Side Effects:
  1522. * None.
  1523. *
  1524. *-----------------------------------------------------------------------
  1525. */
  1526. static Boolean
  1527. VarRESubstitute(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
  1528. char *word, Boolean addSpace, Buffer *buf,
  1529. void *patternp)
  1530. {
  1531. VarREPattern *pat;
  1532. int xrv;
  1533. char *wp;
  1534. char *rp;
  1535. int added;
  1536. int flags = 0;
  1537. #define MAYBE_ADD_SPACE() \
  1538. if (addSpace && !added) \
  1539. Buf_AddByte(buf, ' '); \
  1540. added = 1
  1541. added = 0;
  1542. wp = word;
  1543. pat = patternp;
  1544. if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
  1545. (VAR_SUB_ONE|VAR_SUB_MATCHED))
  1546. xrv = REG_NOMATCH;
  1547. else {
  1548. tryagain:
  1549. xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
  1550. }
  1551. switch (xrv) {
  1552. case 0:
  1553. pat->flags |= VAR_SUB_MATCHED;
  1554. if (pat->matches[0].rm_so > 0) {
  1555. MAYBE_ADD_SPACE();
  1556. Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
  1557. }
  1558. for (rp = pat->replace; *rp; rp++) {
  1559. if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
  1560. MAYBE_ADD_SPACE();
  1561. Buf_AddByte(buf,rp[1]);
  1562. rp++;
  1563. }
  1564. else if ((*rp == '&') ||
  1565. ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
  1566. int n;
  1567. const char *subbuf;
  1568. int sublen;
  1569. char errstr[3];
  1570. if (*rp == '&') {
  1571. n = 0;
  1572. errstr[0] = '&';
  1573. errstr[1] = '\0';
  1574. } else {
  1575. n = rp[1] - '0';
  1576. errstr[0] = '\\';
  1577. errstr[1] = rp[1];
  1578. errstr[2] = '\0';
  1579. rp++;
  1580. }
  1581. if (n > pat->nsub) {
  1582. Error("No subexpression %s", &errstr[0]);
  1583. subbuf = "";
  1584. sublen = 0;
  1585. } else if ((pat->matches[n].rm_so == -1) &&
  1586. (pat->matches[n].rm_eo == -1)) {
  1587. Error("No match for subexpression %s", &errstr[0]);
  1588. subbuf = "";
  1589. sublen = 0;
  1590. } else {
  1591. subbuf = wp + pat->matches[n].rm_so;
  1592. sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
  1593. }
  1594. if (sublen > 0) {
  1595. MAYBE_ADD_SPACE();
  1596. Buf_AddBytes(buf, sublen, subbuf);
  1597. }
  1598. } else {
  1599. MAYBE_ADD_SPACE();
  1600. Buf_AddByte(buf, *rp);
  1601. }
  1602. }
  1603. wp += pat->matches[0].rm_eo;
  1604. if (pat->flags & VAR_SUB_GLOBAL) {
  1605. flags |= REG_NOTBOL;
  1606. if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
  1607. MAYBE_ADD_SPACE();
  1608. Buf_AddByte(buf, *wp);
  1609. wp++;
  1610. }
  1611. if (*wp)
  1612. goto tryagain;
  1613. }
  1614. if (*wp) {
  1615. MAYBE_ADD_SPACE();
  1616. Buf_AddBytes(buf, strlen(wp), wp);
  1617. }
  1618. break;
  1619. default:
  1620. VarREError(xrv, &pat->re, "Unexpected regex error");
  1621. /* fall through */
  1622. case REG_NOMATCH:
  1623. if (*wp) {
  1624. MAYBE_ADD_SPACE();
  1625. Buf_AddBytes(buf,strlen(wp),wp);
  1626. }
  1627. break;
  1628. }
  1629. return(addSpace||added);
  1630. }
  1631. #endif
  1632. /*-
  1633. *-----------------------------------------------------------------------
  1634. * VarLoopExpand --
  1635. * Implements the :@<temp>@<string>@ modifier of ODE make.
  1636. * We set the temp variable named in pattern.lhs to word and expand
  1637. * pattern.rhs storing the result in the passed buffer.
  1638. *
  1639. * Input:
  1640. * word Word to modify
  1641. * addSpace True if space should be added before
  1642. * other characters
  1643. * buf Buffer for result
  1644. * pattern Datafor substitution
  1645. *
  1646. * Results:
  1647. * TRUE if a space is needed before more characters are added.
  1648. *
  1649. * Side Effects:
  1650. * None.
  1651. *
  1652. *-----------------------------------------------------------------------
  1653. */
  1654. static Boolean
  1655. VarLoopExpand(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
  1656. char *word, Boolean addSpace, Buffer *buf,
  1657. void *loopp)
  1658. {
  1659. VarLoop_t *loop = (VarLoop_t *)loopp;
  1660. char *s;
  1661. int slen;
  1662. if (word && *word) {
  1663. Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT);
  1664. s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum);
  1665. if (s != NULL && *s != '\0') {
  1666. if (addSpace && *s != '\n')
  1667. Buf_AddByte(buf, ' ');
  1668. Buf_AddBytes(buf, (slen = strlen(s)), s);
  1669. addSpace = (slen > 0 && s[slen - 1] != '\n');
  1670. free(s);
  1671. }
  1672. }
  1673. return addSpace;
  1674. }
  1675. /*-
  1676. *-----------------------------------------------------------------------
  1677. * VarSelectWords --
  1678. * Implements the :[start..end] modifier.
  1679. * This is a special case of VarModify since we want to be able
  1680. * to scan the list backwards if start > end.
  1681. *
  1682. * Input:
  1683. * str String whose words should be trimmed
  1684. * seldata words to select
  1685. *
  1686. * Results:
  1687. * A string of all the words selected.
  1688. *
  1689. * Side Effects:
  1690. * None.
  1691. *
  1692. *-----------------------------------------------------------------------
  1693. */
  1694. static char *
  1695. VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
  1696. const char *str, VarSelectWords_t *seldata)
  1697. {
  1698. Buffer buf; /* Buffer for the new string */
  1699. Boolean addSpace; /* TRUE if need to add a space to the
  1700. * buffer before adding the trimmed
  1701. * word */
  1702. char **av; /* word list */
  1703. char *as; /* word list memory */
  1704. int ac, i;
  1705. int start, end, step;
  1706. Buf_Init(&buf, 0);
  1707. addSpace = FALSE;
  1708. if (vpstate->oneBigWord) {
  1709. /* fake what brk_string() would do if there were only one word */
  1710. ac = 1;
  1711. av = bmake_malloc((ac + 1) * sizeof(char *));
  1712. as = bmake_strdup(str);
  1713. av[0] = as;
  1714. av[1] = NULL;
  1715. } else {
  1716. av = brk_string(str, &ac, FALSE, &as);
  1717. }
  1718. /*
  1719. * Now sanitize seldata.
  1720. * If seldata->start or seldata->end are negative, convert them to
  1721. * the positive equivalents (-1 gets converted to argc, -2 gets
  1722. * converted to (argc-1), etc.).
  1723. */
  1724. if (seldata->start < 0)
  1725. seldata->start = ac + seldata->start + 1;
  1726. if (seldata->end < 0)
  1727. seldata->end = ac + seldata->end + 1;
  1728. /*
  1729. * We avoid scanning more of the list than we need to.
  1730. */
  1731. if (seldata->start > seldata->end) {
  1732. start = MIN(ac, seldata->start) - 1;
  1733. end = MAX(0, seldata->end - 1);
  1734. step = -1;
  1735. } else {
  1736. start = MAX(0, seldata->start - 1);
  1737. end = MIN(ac, seldata->end);
  1738. step = 1;
  1739. }
  1740. for (i = start;
  1741. (step < 0 && i >= end) || (step > 0 && i < end);
  1742. i += step) {
  1743. if (av[i] && *av[i]) {
  1744. if (addSpace && vpstate->varSpace) {
  1745. Buf_AddByte(&buf, vpstate->varSpace);
  1746. }
  1747. Buf_AddBytes(&buf, strlen(av[i]), av[i]);
  1748. addSpace = TRUE;
  1749. }
  1750. }
  1751. free(as);
  1752. free(av);
  1753. return Buf_Destroy(&buf, FALSE);
  1754. }
  1755. /*-
  1756. * VarRealpath --
  1757. * Replace each word with the result of realpath()
  1758. * if successful.
  1759. */
  1760. static Boolean
  1761. VarRealpath(GNode *ctx __unused, Var_Parse_State *vpstate,
  1762. char *word, Boolean addSpace, Buffer *buf,
  1763. void *patternp __unused)
  1764. {
  1765. struct stat st;
  1766. char rbuf[MAXPATHLEN];
  1767. char *rp;
  1768. if (addSpace && vpstate->varSpace) {
  1769. Buf_AddByte(buf, vpstate->varSpace);
  1770. }
  1771. addSpace = TRUE;
  1772. rp = realpath(word, rbuf);
  1773. if (rp && *rp == '/' && stat(rp, &st) == 0)
  1774. word = rp;
  1775. Buf_AddBytes(buf, strlen(word), word);
  1776. return(addSpace);
  1777. }
  1778. /*-
  1779. *-----------------------------------------------------------------------
  1780. * VarModify --
  1781. * Modify each of the words of the passed string using the given
  1782. * function. Used to implement all modifiers.
  1783. *
  1784. * Input:
  1785. * str String whose words should be trimmed
  1786. * modProc Function to use to modify them
  1787. * datum Datum to pass it
  1788. *
  1789. * Results:
  1790. * A string of all the words modified appropriately.
  1791. *
  1792. * Side Effects:
  1793. * None.
  1794. *
  1795. *-----------------------------------------------------------------------
  1796. */
  1797. static char *
  1798. VarModify(GNode *ctx, Var_Parse_State *vpstate,
  1799. const char *str,
  1800. Boolean (*modProc)(GNode *, Var_Parse_State *, char *,
  1801. Boolean, Buffer *, void *),
  1802. void *datum)
  1803. {
  1804. Buffer buf; /* Buffer for the new string */
  1805. Boolean addSpace; /* TRUE if need to add a space to the
  1806. * buffer before adding the trimmed
  1807. * word */
  1808. char **av; /* word list */
  1809. char *as; /* word list memory */
  1810. int ac, i;
  1811. Buf_Init(&buf, 0);
  1812. addSpace = FALSE;
  1813. if (vpstate->oneBigWord) {
  1814. /* fake what brk_string() would do if there were only one word */
  1815. ac = 1;
  1816. av = bmake_malloc((ac + 1) * sizeof(char *));
  1817. as = bmake_strdup(str);
  1818. av[0] = as;
  1819. av[1] = NULL;
  1820. } else {
  1821. av = brk_string(str, &ac, FALSE, &as);
  1822. }
  1823. for (i = 0; i < ac; i++) {
  1824. addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum);
  1825. }
  1826. free(as);
  1827. free(av);
  1828. return Buf_Destroy(&buf, FALSE);
  1829. }
  1830. static int
  1831. VarWordCompare(const void *a, const void *b)
  1832. {
  1833. int r = strcmp(*(const char * const *)a, *(const char * const *)b);
  1834. return r;
  1835. }
  1836. /*-
  1837. *-----------------------------------------------------------------------
  1838. * VarOrder --
  1839. * Order the words in the string.
  1840. *
  1841. * Input:
  1842. * str String whose words should be sorted.
  1843. * otype How to order: s - sort, x - random.
  1844. *
  1845. * Results:
  1846. * A string containing the words ordered.
  1847. *
  1848. * Side Effects:
  1849. * None.
  1850. *
  1851. *-----------------------------------------------------------------------
  1852. */
  1853. static char *
  1854. VarOrder(const char *str, const char otype)
  1855. {
  1856. Buffer buf; /* Buffer for the new string */
  1857. char **av; /* word list [first word does not count] */
  1858. char *as; /* word list memory */
  1859. int ac, i;
  1860. Buf_Init(&buf, 0);
  1861. av = brk_string(str, &ac, FALSE, &as);
  1862. if (ac > 0)
  1863. switch (otype) {
  1864. case 's': /* sort alphabetically */
  1865. qsort(av, ac, sizeof(char *), VarWordCompare);
  1866. break;
  1867. case 'x': /* randomize */
  1868. {
  1869. int rndidx;
  1870. char *t;
  1871. /*
  1872. * We will use [ac..2] range for mod factors. This will produce
  1873. * random numbers in [(ac-1)..0] interval, and minimal
  1874. * reasonable value for mod factor is 2 (the mod 1 will produce
  1875. * 0 with probability 1).
  1876. */
  1877. for (i = ac-1; i > 0; i--) {
  1878. rndidx = random() % (i + 1);
  1879. if (i != rndidx) {
  1880. t = av[i];
  1881. av[i] = av[rndidx];
  1882. av[rndidx] = t;
  1883. }
  1884. }
  1885. }
  1886. } /* end of switch */
  1887. for (i = 0; i < ac; i++) {
  1888. Buf_AddBytes(&buf, strlen(av[i]), av[i]);
  1889. if (i != ac - 1)
  1890. Buf_AddByte(&buf, ' ');
  1891. }
  1892. free(as);
  1893. free(av);
  1894. return Buf_Destroy(&buf, FALSE);
  1895. }
  1896. /*-
  1897. *-----------------------------------------------------------------------
  1898. * VarUniq --
  1899. * Remove adjacent duplicate words.
  1900. *
  1901. * Input:
  1902. * str String whose words should be sorted
  1903. *
  1904. * Results:
  1905. * A string containing the resulting words.
  1906. *
  1907. * Side Effects:
  1908. * None.
  1909. *
  1910. *-----------------------------------------------------------------------
  1911. */
  1912. static char *
  1913. VarUniq(const char *str)
  1914. {
  1915. Buffer buf; /* Buffer for new string */
  1916. char **av; /* List of words to affect */
  1917. char *as; /* Word list memory */
  1918. int ac, i, j;
  1919. Buf_Init(&buf, 0);
  1920. av = brk_string(str, &ac, FALSE, &as);
  1921. if (ac > 1) {
  1922. for (j = 0, i = 1; i < ac; i++)
  1923. if (strcmp(av[i], av[j]) != 0 && (++j != i))
  1924. av[j] = av[i];
  1925. ac = j + 1;
  1926. }
  1927. for (i = 0; i < ac; i++) {
  1928. Buf_AddBytes(&buf, strlen(av[i]), av[i]);
  1929. if (i != ac - 1)
  1930. Buf_AddByte(&buf, ' ');
  1931. }
  1932. free(as);
  1933. free(av);
  1934. return Buf_Destroy(&buf, FALSE);
  1935. }
  1936. /*-
  1937. *-----------------------------------------------------------------------
  1938. * VarGetPattern --
  1939. * Pass through the tstr looking for 1) escaped delimiters,
  1940. * '$'s and backslashes (place the escaped character in
  1941. * uninterpreted) and 2) unescaped $'s that aren't before
  1942. * the delimiter (expand the variable substitution unless flags
  1943. * has VAR_NOSUBST set).
  1944. * Return the expanded string or NULL if the delimiter was missing
  1945. * If pattern is specified, handle escaped ampersands, and replace
  1946. * unescaped ampersands with the lhs of the pattern.
  1947. *
  1948. * Results:
  1949. * A string of all the words modified appropriately.
  1950. * If length is specified, return the string length of the buffer
  1951. * If flags is specified and the last character of the pattern is a
  1952. * $ set the VAR_MATCH_END bit of flags.
  1953. *
  1954. * Side Effects:
  1955. * None.
  1956. *-----------------------------------------------------------------------
  1957. */
  1958. static char *
  1959. VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
  1960. int errnum, const char **tstr, int delim, int *flags,
  1961. int *length, VarPattern *pattern)
  1962. {
  1963. const char *cp;
  1964. char *rstr;
  1965. Buffer buf;
  1966. int junk;
  1967. Buf_Init(&buf, 0);
  1968. if (length == NULL)
  1969. length = &junk;
  1970. #define IS_A_MATCH(cp, delim) \
  1971. ((cp[0] == '\\') && ((cp[1] == delim) || \
  1972. (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
  1973. /*
  1974. * Skim through until the matching delimiter is found;
  1975. * pick up variable substitutions on the way. Also allow
  1976. * backslashes to quote the delimiter, $, and \, but don't
  1977. * touch other backslashes.
  1978. */
  1979. for (cp = *tstr; *cp && (*cp != delim); cp++) {
  1980. if (IS_A_MATCH(cp, delim)) {
  1981. Buf_AddByte(&buf, cp[1]);
  1982. cp++;
  1983. } else if (*cp == '$') {
  1984. if (cp[1] == delim) {
  1985. if (flags == NULL)
  1986. Buf_AddByte(&buf, *cp);
  1987. else
  1988. /*
  1989. * Unescaped $ at end of pattern => anchor
  1990. * pattern at end.
  1991. */
  1992. *flags |= VAR_MATCH_END;
  1993. } else {
  1994. if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
  1995. char *cp2;
  1996. int len;
  1997. void *freeIt;
  1998. /*
  1999. * If unescaped dollar sign not before the
  2000. * delimiter, assume it's a variable
  2001. * substitution and recurse.
  2002. */
  2003. cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
  2004. Buf_AddBytes(&buf, strlen(cp2), cp2);
  2005. if (freeIt)
  2006. free(freeIt);
  2007. cp += len - 1;
  2008. } else {
  2009. const char *cp2 = &cp[1];
  2010. if (*cp2 == PROPEN || *cp2 == BROPEN) {
  2011. /*
  2012. * Find the end of this variable reference
  2013. * and suck it in without further ado.
  2014. * It will be interperated later.
  2015. */
  2016. int have = *cp2;
  2017. int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
  2018. int depth = 1;
  2019. for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
  2020. if (cp2[-1] != '\\') {
  2021. if (*cp2 == have)
  2022. ++depth;
  2023. if (*cp2 == want)
  2024. --depth;
  2025. }
  2026. }
  2027. Buf_AddBytes(&buf, cp2 - cp, cp);
  2028. cp = --cp2;
  2029. } else
  2030. Buf_AddByte(&buf, *cp);
  2031. }
  2032. }
  2033. }
  2034. else if (pattern && *cp == '&')
  2035. Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs);
  2036. else
  2037. Buf_AddByte(&buf, *cp);
  2038. }
  2039. if (*cp != delim) {
  2040. *tstr = cp;
  2041. *length = 0;
  2042. return NULL;
  2043. }
  2044. *tstr = ++cp;
  2045. *length = Buf_Size(&buf);
  2046. rstr = Buf_Destroy(&buf, FALSE);
  2047. if (DEBUG(VAR))
  2048. fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr);
  2049. return rstr;
  2050. }
  2051. /*-
  2052. *-----------------------------------------------------------------------
  2053. * VarQuote --
  2054. * Quote shell meta-characters in the string
  2055. *
  2056. * Results:
  2057. * The quoted string
  2058. *
  2059. * Side Effects:
  2060. * None.
  2061. *
  2062. *-----------------------------------------------------------------------
  2063. */
  2064. static char *
  2065. VarQuote(char *str)
  2066. {
  2067. Buffer buf;
  2068. /* This should cover most shells :-( */
  2069. static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
  2070. const char *newline;
  2071. size_t len, nlen;
  2072. if ((newline = Shell_GetNewline()) == NULL)
  2073. newline = "\\\n";
  2074. nlen = strlen(newline);
  2075. Buf_Init(&buf, 0);
  2076. while (*str != '\0') {
  2077. if ((len = strcspn(str, meta)) != 0) {
  2078. Buf_AddBytes(&buf, len, str);
  2079. str += len;
  2080. } else if (*str == '\n') {
  2081. Buf_AddBytes(&buf, nlen, newline);
  2082. ++str;
  2083. } else {
  2084. Buf_AddByte(&buf, '\\');
  2085. Buf_AddByte(&buf, *str);
  2086. ++str;
  2087. }
  2088. }
  2089. str = Buf_Destroy(&buf, FALSE);
  2090. if (DEBUG(VAR))
  2091. fprintf(debug_file, "QuoteMeta: [%s]\n", str);
  2092. return str;
  2093. }
  2094. /*-
  2095. *-----------------------------------------------------------------------
  2096. * VarChangeCase --
  2097. * Change the string to all uppercase or all lowercase
  2098. *
  2099. * Input:
  2100. * str String to modify
  2101. * upper TRUE -> uppercase, else lowercase
  2102. *
  2103. * Results:
  2104. * The string with case changed
  2105. *
  2106. * Side Effects:
  2107. * None.
  2108. *
  2109. *-----------------------------------------------------------------------
  2110. */
  2111. static char *
  2112. VarChangeCase(char *str, int upper)
  2113. {
  2114. Buffer buf;
  2115. int (*modProc)(int);
  2116. modProc = (upper ? toupper : tolower);
  2117. Buf_Init(&buf, 0);
  2118. for (; *str ; str++) {
  2119. Buf_AddByte(&buf, modProc(*str));
  2120. }
  2121. return Buf_Destroy(&buf, FALSE);
  2122. }
  2123. /*
  2124. * Now we need to apply any modifiers the user wants applied.
  2125. * These are:
  2126. * :M<pattern> words which match the given <pattern>.
  2127. * <pattern> is of the standard file
  2128. * wildcarding form.
  2129. * :N<pattern> words which do not match the given <pattern>.
  2130. * :S<d><pat1><d><pat2><d>[1gW]
  2131. * Substitute <pat2> for <pat1> in the value
  2132. * :C<d><pat1><d><pat2><d>[1gW]
  2133. * Substitute <pat2> for regex <pat1> in the value
  2134. * :H Substitute the head of each word
  2135. * :T Substitute the tail of each word
  2136. * :E Substitute the extension (minus '.') of
  2137. * each word
  2138. * :R Substitute the root of each word
  2139. * (pathname minus the suffix).
  2140. * :O ("Order") Alphabeticaly sort words in variable.
  2141. * :Ox ("intermiX") Randomize words in variable.
  2142. * :u ("uniq") Remove adjacent duplicate words.
  2143. * :tu Converts the variable contents to uppercase.
  2144. * :tl Converts the variable contents to lowercase.
  2145. * :ts[c] Sets varSpace - the char used to
  2146. * separate words to 'c'. If 'c' is
  2147. * omitted then no separation is used.
  2148. * :tW Treat the variable contents as a single
  2149. * word, even if it contains spaces.
  2150. * (Mnemonic: one big 'W'ord.)
  2151. * :tw Treat the variable contents as multiple
  2152. * space-separated words.
  2153. * (Mnemonic: many small 'w'ords.)
  2154. * :[index] Select a single word from the value.
  2155. * :[start..end] Select multiple words from the value.
  2156. * :[*] or :[0] Select the entire value, as a single
  2157. * word. Equivalent to :tW.
  2158. * :[@] Select the entire value, as multiple
  2159. * words. Undoes the effect of :[*].
  2160. * Equivalent to :tw.
  2161. * :[#] Returns the number of words in the value.
  2162. *
  2163. * :?<true-value>:<false-value>
  2164. * If the variable evaluates to true, return
  2165. * true value, else return the second value.
  2166. * :lhs=rhs Like :S, but the rhs goes to the end of
  2167. * the invocation.
  2168. * :sh Treat the current value as a command
  2169. * to be run, new value is its output.
  2170. * The following added so we can handle ODE makefiles.
  2171. * :@<tmpvar>@<newval>@
  2172. * Assign a temporary local variable <tmpvar>
  2173. * to the current value of each word in turn
  2174. * and replace each word with the result of
  2175. * evaluating <newval>
  2176. * :D<newval> Use <newval> as value if variable defined
  2177. * :U<newval> Use <newval> as value if variable undefined
  2178. * :L Use the name of the variable as the value.
  2179. * :P Use the path of the node that has the same
  2180. * name as the variable as the value. This
  2181. * basically includes an implied :L so that
  2182. * the common method of refering to the path
  2183. * of your dependent 'x' in a rule is to use
  2184. * the form '${x:P}'.
  2185. * :!<cmd>! Run cmd much the same as :sh run's the
  2186. * current value of the variable.
  2187. * The ::= modifiers, actually assign a value to the variable.
  2188. * Their main purpose is in supporting modifiers of .for loop
  2189. * iterators and other obscure uses. They always expand to
  2190. * nothing. In a target rule that would otherwise expand to an
  2191. * empty line they can be preceded with @: to keep make happy.
  2192. * Eg.
  2193. *
  2194. * foo: .USE
  2195. * .for i in ${.TARGET} ${.TARGET:R}.gz
  2196. * @: ${t::=$i}
  2197. * @echo blah ${t:T}
  2198. * .endfor
  2199. *
  2200. * ::=<str> Assigns <str> as the new value of variable.
  2201. * ::?=<str> Assigns <str> as value of variable if
  2202. * it was not already set.
  2203. * ::+=<str> Appends <str> to variable.
  2204. * ::!=<cmd> Assigns output of <cmd> as the new value of
  2205. * variable.
  2206. */
  2207. static char *
  2208. ApplyModifiers(char *nstr, const char *tstr,
  2209. int startc, int endc,
  2210. Var *v, GNode *ctxt, Boolean errnum,
  2211. int *lengthPtr, void **freePtr)
  2212. {
  2213. const char *start;
  2214. const char *cp; /* Secondary pointer into str (place marker
  2215. * for tstr) */
  2216. char *newStr; /* New value to return */
  2217. char termc; /* Character which terminated scan */
  2218. int cnt; /* Used to count brace pairs when variable in
  2219. * in parens or braces */
  2220. char delim;
  2221. int modifier; /* that we are processing */
  2222. Var_Parse_State parsestate; /* Flags passed to helper functions */
  2223. delim = '\0';
  2224. parsestate.oneBigWord = FALSE;
  2225. parsestate.varSpace = ' '; /* word separator */
  2226. start = cp = tstr;
  2227. while (*tstr && *tstr != endc) {
  2228. if (*tstr == '$') {
  2229. /*
  2230. * We have some complex modifiers in a variable.
  2231. */
  2232. void *freeIt;
  2233. char *rval;
  2234. int rlen;
  2235. rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt);
  2236. if (DEBUG(VAR)) {
  2237. fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
  2238. rval, rlen, tstr, rlen, tstr + rlen);
  2239. }
  2240. tstr += rlen;
  2241. if (rval != NULL && *rval) {
  2242. int used;
  2243. nstr = ApplyModifiers(nstr, rval,
  2244. 0, 0,
  2245. v, ctxt, errnum, &used, freePtr);
  2246. if (nstr == var_Error
  2247. || (nstr == varNoError && errnum == 0)
  2248. || strlen(rval) != (size_t) used) {
  2249. if (freeIt)
  2250. free(freeIt);
  2251. goto out; /* error already reported */
  2252. }
  2253. }
  2254. if (freeIt)
  2255. free(freeIt);
  2256. if (*tstr == ':')
  2257. tstr++;
  2258. else if (!*tstr && endc) {
  2259. Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name);
  2260. goto out;
  2261. }
  2262. continue;
  2263. }
  2264. if (DEBUG(VAR)) {
  2265. fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr);
  2266. }
  2267. newStr = var_Error;
  2268. switch ((modifier = *tstr)) {
  2269. case ':':
  2270. {
  2271. if (tstr[1] == '=' ||
  2272. (tstr[2] == '=' &&
  2273. (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) {
  2274. /*
  2275. * "::=", "::!=", "::+=", or "::?="
  2276. */
  2277. GNode *v_ctxt; /* context where v belongs */
  2278. const char *emsg;
  2279. char *sv_name;
  2280. VarPattern pattern;
  2281. int how;
  2282. if (v->name[0] == 0)
  2283. goto bad_modifier;
  2284. v_ctxt = ctxt;
  2285. sv_name = NULL;
  2286. ++tstr;
  2287. if (v->flags & VAR_JUNK) {
  2288. /*
  2289. * We need to bmake_strdup() it incase
  2290. * VarGetPattern() recurses.
  2291. */
  2292. sv_name = v->name;
  2293. v->name = bmake_strdup(v->name);
  2294. } else if (ctxt != VAR_GLOBAL) {
  2295. Var *gv = VarFind(v->name, ctxt, 0);
  2296. if (gv == NULL)
  2297. v_ctxt = VAR_GLOBAL;
  2298. else
  2299. VarFreeEnv(gv, TRUE);
  2300. }
  2301. switch ((how = *tstr)) {
  2302. case '+':
  2303. case '?':
  2304. case '!':
  2305. cp = &tstr[2];
  2306. break;
  2307. default:
  2308. cp = ++tstr;
  2309. break;
  2310. }
  2311. delim = BRCLOSE;
  2312. pattern.flags = 0;
  2313. pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
  2314. &cp, delim, NULL,
  2315. &pattern.rightLen,
  2316. NULL);
  2317. if (v->flags & VAR_JUNK) {
  2318. /* restore original name */
  2319. free(v->name);
  2320. v->name = sv_name;
  2321. }
  2322. if (pattern.rhs == NULL)
  2323. goto cleanup;
  2324. termc = *--cp;
  2325. delim = '\0';
  2326. switch (how) {
  2327. case '+':
  2328. Var_Append(v->name, pattern.rhs, v_ctxt);
  2329. break;
  2330. case '!':
  2331. newStr = Cmd_Exec(pattern.rhs, &emsg);
  2332. if (emsg)
  2333. Error(emsg, nstr);
  2334. else
  2335. Var_Set(v->name, newStr, v_ctxt, 0);
  2336. if (newStr)
  2337. free(newStr);
  2338. break;
  2339. case '?':
  2340. if ((v->flags & VAR_JUNK) == 0)
  2341. break;
  2342. /* FALLTHROUGH */
  2343. default:
  2344. Var_Set(v->name, pattern.rhs, v_ctxt, 0);
  2345. break;
  2346. }
  2347. free(UNCONST(pattern.rhs));
  2348. newStr = var_Error;
  2349. break;
  2350. }
  2351. goto default_case; /* "::<unrecognised>" */
  2352. }
  2353. case '@':
  2354. {
  2355. VarLoop_t loop;
  2356. int flags = VAR_NOSUBST;
  2357. cp = ++tstr;
  2358. delim = '@';
  2359. if ((loop.tvar = VarGetPattern(ctxt, &parsestate, errnum,
  2360. &cp, delim,
  2361. &flags, &loop.tvarLen,
  2362. NULL)) == NULL)
  2363. goto cleanup;
  2364. if ((loop.str = VarGetPattern(ctxt, &parsestate, errnum,
  2365. &cp, delim,
  2366. &flags, &loop.strLen,
  2367. NULL)) == NULL)
  2368. goto cleanup;
  2369. termc = *cp;
  2370. delim = '\0';
  2371. loop.errnum = errnum;
  2372. loop.ctxt = ctxt;
  2373. newStr = VarModify(ctxt, &parsestate, nstr, VarLoopExpand,
  2374. &loop);
  2375. free(loop.tvar);
  2376. free(loop.str);
  2377. break;
  2378. }
  2379. case 'D':
  2380. case 'U':
  2381. {
  2382. Buffer buf; /* Buffer for patterns */
  2383. int wantit; /* want data in buffer */
  2384. /*
  2385. * Pass through tstr looking for 1) escaped delimiters,
  2386. * '$'s and backslashes (place the escaped character in
  2387. * uninterpreted) and 2) unescaped $'s that aren't before
  2388. * the delimiter (expand the variable substitution).
  2389. * The result is left in the Buffer buf.
  2390. */
  2391. Buf_Init(&buf, 0);
  2392. for (cp = tstr + 1;
  2393. *cp != endc && *cp != ':' && *cp != '\0';
  2394. cp++) {
  2395. if ((*cp == '\\') &&
  2396. ((cp[1] == ':') ||
  2397. (cp[1] == '$') ||
  2398. (cp[1] == endc) ||
  2399. (cp[1] == '\\')))
  2400. {
  2401. Buf_AddByte(&buf, cp[1]);
  2402. cp++;
  2403. } else if (*cp == '$') {
  2404. /*
  2405. * If unescaped dollar sign, assume it's a
  2406. * variable substitution and recurse.
  2407. */
  2408. char *cp2;
  2409. int len;
  2410. void *freeIt;
  2411. cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
  2412. Buf_AddBytes(&buf, strlen(cp2), cp2);
  2413. if (freeIt)
  2414. free(freeIt);
  2415. cp += len - 1;
  2416. } else {
  2417. Buf_AddByte(&buf, *cp);
  2418. }
  2419. }
  2420. termc = *cp;
  2421. if (*tstr == 'U')
  2422. wantit = ((v->flags & VAR_JUNK) != 0);
  2423. else
  2424. wantit = ((v->flags & VAR_JUNK) == 0);
  2425. if ((v->flags & VAR_JUNK) != 0)
  2426. v->flags |= VAR_KEEP;
  2427. if (wantit) {
  2428. newStr = Buf_Destroy(&buf, FALSE);
  2429. } else {
  2430. newStr = nstr;
  2431. Buf_Destroy(&buf, TRUE);
  2432. }
  2433. break;
  2434. }
  2435. case 'L':
  2436. {
  2437. if ((v->flags & VAR_JUNK) != 0)
  2438. v->flags |= VAR_KEEP;
  2439. newStr = bmake_strdup(v->name);
  2440. cp = ++tstr;
  2441. termc = *tstr;
  2442. break;
  2443. }
  2444. case 'P':
  2445. {
  2446. GNode *gn;
  2447. if ((v->flags & VAR_JUNK) != 0)
  2448. v->flags |= VAR_KEEP;
  2449. gn = Targ_FindNode(v->name, TARG_NOCREATE);
  2450. if (gn == NULL || gn->type & OP_NOPATH) {
  2451. newStr = NULL;
  2452. } else if (gn->path) {
  2453. newStr = bmake_strdup(gn->path);
  2454. } else {
  2455. newStr = Dir_FindFile(v->name, Suff_FindPath(gn));
  2456. }
  2457. if (!newStr) {
  2458. newStr = bmake_strdup(v->name);
  2459. }
  2460. cp = ++tstr;
  2461. termc = *tstr;
  2462. break;
  2463. }
  2464. case '!':
  2465. {
  2466. const char *emsg;
  2467. VarPattern pattern;
  2468. pattern.flags = 0;
  2469. delim = '!';
  2470. cp = ++tstr;
  2471. if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
  2472. &cp, delim,
  2473. NULL, &pattern.rightLen,
  2474. NULL)) == NULL)
  2475. goto cleanup;
  2476. newStr = Cmd_Exec(pattern.rhs, &emsg);
  2477. free(UNCONST(pattern.rhs));
  2478. if (emsg)
  2479. Error(emsg, nstr);
  2480. termc = *cp;
  2481. delim = '\0';
  2482. if (v->flags & VAR_JUNK) {
  2483. v->flags |= VAR_KEEP;
  2484. }
  2485. break;
  2486. }
  2487. case '[':
  2488. {
  2489. /*
  2490. * Look for the closing ']', recursively
  2491. * expanding any embedded variables.
  2492. *
  2493. * estr is a pointer to the expanded result,
  2494. * which we must free().
  2495. */
  2496. char *estr;
  2497. cp = tstr+1; /* point to char after '[' */
  2498. delim = ']'; /* look for closing ']' */
  2499. estr = VarGetPattern(ctxt, &parsestate,
  2500. errnum, &cp, delim,
  2501. NULL, NULL, NULL);
  2502. if (estr == NULL)
  2503. goto cleanup; /* report missing ']' */
  2504. /* now cp points just after the closing ']' */
  2505. delim = '\0';
  2506. if (cp[0] != ':' && cp[0] != endc) {
  2507. /* Found junk after ']' */
  2508. free(estr);
  2509. goto bad_modifier;
  2510. }
  2511. if (estr[0] == '\0') {
  2512. /* Found empty square brackets in ":[]". */
  2513. free(estr);
  2514. goto bad_modifier;
  2515. } else if (estr[0] == '#' && estr[1] == '\0') {
  2516. /* Found ":[#]" */
  2517. /*
  2518. * We will need enough space for the decimal
  2519. * representation of an int. We calculate the
  2520. * space needed for the octal representation,
  2521. * and add enough slop to cope with a '-' sign
  2522. * (which should never be needed) and a '\0'
  2523. * string terminator.
  2524. */
  2525. int newStrSize =
  2526. (sizeof(int) * CHAR_BIT + 2) / 3 + 2;
  2527. newStr = bmake_malloc(newStrSize);
  2528. if (parsestate.oneBigWord) {
  2529. strncpy(newStr, "1", newStrSize);
  2530. } else {
  2531. /* XXX: brk_string() is a rather expensive
  2532. * way of counting words. */
  2533. char **av;
  2534. char *as;
  2535. int ac;
  2536. av = brk_string(nstr, &ac, FALSE, &as);
  2537. snprintf(newStr, newStrSize, "%d", ac);
  2538. free(as);
  2539. free(av);
  2540. }
  2541. termc = *cp;
  2542. free(estr);
  2543. break;
  2544. } else if (estr[0] == '*' && estr[1] == '\0') {
  2545. /* Found ":[*]" */
  2546. parsestate.oneBigWord = TRUE;
  2547. newStr = nstr;
  2548. termc = *cp;
  2549. free(estr);
  2550. break;
  2551. } else if (estr[0] == '@' && estr[1] == '\0') {
  2552. /* Found ":[@]" */
  2553. parsestate.oneBigWord = FALSE;
  2554. newStr = nstr;
  2555. termc = *cp;
  2556. free(estr);
  2557. break;
  2558. } else {
  2559. /*
  2560. * We expect estr to contain a single
  2561. * integer for :[N], or two integers
  2562. * separated by ".." for :[start..end].
  2563. */
  2564. char *ep;
  2565. VarSelectWords_t seldata = { 0, 0 };
  2566. seldata.start = strtol(estr, &ep, 0);
  2567. if (ep == estr) {
  2568. /* Found junk instead of a number */
  2569. free(estr);
  2570. goto bad_modifier;
  2571. } else if (ep[0] == '\0') {
  2572. /* Found only one integer in :[N] */
  2573. seldata.end = seldata.start;
  2574. } else if (ep[0] == '.' && ep[1] == '.' &&
  2575. ep[2] != '\0') {
  2576. /* Expecting another integer after ".." */
  2577. ep += 2;
  2578. seldata.end = strtol(ep, &ep, 0);
  2579. if (ep[0] != '\0') {
  2580. /* Found junk after ".." */
  2581. free(estr);
  2582. goto bad_modifier;
  2583. }
  2584. } else {
  2585. /* Found junk instead of ".." */
  2586. free(estr);
  2587. goto bad_modifier;
  2588. }
  2589. /*
  2590. * Now seldata is properly filled in,
  2591. * but we still have to check for 0 as
  2592. * a special case.
  2593. */
  2594. if (seldata.start == 0 && seldata.end == 0) {
  2595. /* ":[0]" or perhaps ":[0..0]" */
  2596. parsestate.oneBigWord = TRUE;
  2597. newStr = nstr;
  2598. termc = *cp;
  2599. free(estr);
  2600. break;
  2601. } else if (seldata.start == 0 ||
  2602. seldata.end == 0) {
  2603. /* ":[0..N]" or ":[N..0]" */
  2604. free(estr);
  2605. goto bad_modifier;
  2606. }
  2607. /*
  2608. * Normal case: select the words
  2609. * described by seldata.
  2610. */
  2611. newStr = VarSelectWords(ctxt, &parsestate,
  2612. nstr, &seldata);
  2613. termc = *cp;
  2614. free(estr);
  2615. break;
  2616. }
  2617. }
  2618. case 't':
  2619. {
  2620. cp = tstr + 1; /* make sure it is set */
  2621. if (tstr[1] != endc && tstr[1] != ':') {
  2622. if (tstr[1] == 's') {
  2623. /*
  2624. * Use the char (if any) at tstr[2]
  2625. * as the word separator.
  2626. */
  2627. VarPattern pattern;
  2628. if (tstr[2] != endc &&
  2629. (tstr[3] == endc || tstr[3] == ':')) {
  2630. /* ":ts<unrecognised><endc>" or
  2631. * ":ts<unrecognised>:" */
  2632. parsestate.varSpace = tstr[2];
  2633. cp = tstr + 3;
  2634. } else if (tstr[2] == endc || tstr[2] == ':') {
  2635. /* ":ts<endc>" or ":ts:" */
  2636. parsestate.varSpace = 0; /* no separator */
  2637. cp = tstr + 2;
  2638. } else if (tstr[2] == '\\') {
  2639. switch (tstr[3]) {
  2640. case 'n':
  2641. parsestate.varSpace = '\n';
  2642. cp = tstr + 4;
  2643. break;
  2644. case 't':
  2645. parsestate.varSpace = '\t';
  2646. cp = tstr + 4;
  2647. break;
  2648. default:
  2649. if (isdigit((unsigned char)tstr[3])) {
  2650. char *ep;
  2651. parsestate.varSpace =
  2652. strtoul(&tstr[3], &ep, 0);
  2653. if (*ep != ':' && *ep != endc)
  2654. goto bad_modifier;
  2655. cp = ep;
  2656. } else {
  2657. /*
  2658. * ":ts<backslash><unrecognised>".
  2659. */
  2660. goto bad_modifier;
  2661. }
  2662. break;
  2663. }
  2664. } else {
  2665. /*
  2666. * Found ":ts<unrecognised><unrecognised>".
  2667. */
  2668. goto bad_modifier;
  2669. }
  2670. termc = *cp;
  2671. /*
  2672. * We cannot be certain that VarModify
  2673. * will be used - even if there is a
  2674. * subsequent modifier, so do a no-op
  2675. * VarSubstitute now to for str to be
  2676. * re-expanded without the spaces.
  2677. */
  2678. pattern.flags = VAR_SUB_ONE;
  2679. pattern.lhs = pattern.rhs = "\032";
  2680. pattern.leftLen = pattern.rightLen = 1;
  2681. newStr = VarModify(ctxt, &parsestate, nstr,
  2682. VarSubstitute,
  2683. &pattern);
  2684. } else if (tstr[2] == endc || tstr[2] == ':') {
  2685. /*
  2686. * Check for two-character options:
  2687. * ":tu", ":tl"
  2688. */
  2689. if (tstr[1] == 'A') { /* absolute path */
  2690. newStr = VarModify(ctxt, &parsestate, nstr,
  2691. VarRealpath, NULL);
  2692. cp = tstr + 2;
  2693. termc = *cp;
  2694. } else if (tstr[1] == 'u' || tstr[1] == 'l') {
  2695. newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
  2696. cp = tstr + 2;
  2697. termc = *cp;
  2698. } else if (tstr[1] == 'W' || tstr[1] == 'w') {
  2699. parsestate.oneBigWord = (tstr[1] == 'W');
  2700. newStr = nstr;
  2701. cp = tstr + 2;
  2702. termc = *cp;
  2703. } else {
  2704. /* Found ":t<unrecognised>:" or
  2705. * ":t<unrecognised><endc>". */
  2706. goto bad_modifier;
  2707. }
  2708. } else {
  2709. /*
  2710. * Found ":t<unrecognised><unrecognised>".
  2711. */
  2712. goto bad_modifier;
  2713. }
  2714. } else {
  2715. /*
  2716. * Found ":t<endc>" or ":t:".
  2717. */
  2718. goto bad_modifier;
  2719. }
  2720. break;
  2721. }
  2722. case 'N':
  2723. case 'M':
  2724. {
  2725. char *pattern;
  2726. const char *endpat; /* points just after end of pattern */
  2727. char *cp2;
  2728. Boolean copy; /* pattern should be, or has been, copied */
  2729. Boolean needSubst;
  2730. int nest;
  2731. copy = FALSE;
  2732. needSubst = FALSE;
  2733. nest = 1;
  2734. /*
  2735. * In the loop below, ignore ':' unless we are at
  2736. * (or back to) the original brace level.
  2737. * XXX This will likely not work right if $() and ${}
  2738. * are intermixed.
  2739. */
  2740. for (cp = tstr + 1;
  2741. *cp != '\0' && !(*cp == ':' && nest == 1);
  2742. cp++)
  2743. {
  2744. if (*cp == '\\' &&
  2745. (cp[1] == ':' ||
  2746. cp[1] == endc || cp[1] == startc)) {
  2747. if (!needSubst) {
  2748. copy = TRUE;
  2749. }
  2750. cp++;
  2751. continue;
  2752. }
  2753. if (*cp == '$') {
  2754. needSubst = TRUE;
  2755. }
  2756. if (*cp == '(' || *cp == '{')
  2757. ++nest;
  2758. if (*cp == ')' || *cp == '}') {
  2759. --nest;
  2760. if (nest == 0)
  2761. break;
  2762. }
  2763. }
  2764. termc = *cp;
  2765. endpat = cp;
  2766. if (copy) {
  2767. /*
  2768. * Need to compress the \:'s out of the pattern, so
  2769. * allocate enough room to hold the uncompressed
  2770. * pattern (note that cp started at tstr+1, so
  2771. * cp - tstr takes the null byte into account) and
  2772. * compress the pattern into the space.
  2773. */
  2774. pattern = bmake_malloc(cp - tstr);
  2775. for (cp2 = pattern, cp = tstr + 1;
  2776. cp < endpat;
  2777. cp++, cp2++)
  2778. {
  2779. if ((*cp == '\\') && (cp+1 < endpat) &&
  2780. (cp[1] == ':' || cp[1] == endc)) {
  2781. cp++;
  2782. }
  2783. *cp2 = *cp;
  2784. }
  2785. *cp2 = '\0';
  2786. endpat = cp2;
  2787. } else {
  2788. /*
  2789. * Either Var_Subst or VarModify will need a
  2790. * nul-terminated string soon, so construct one now.
  2791. */
  2792. pattern = bmake_strndup(tstr+1, endpat - (tstr + 1));
  2793. }
  2794. if (needSubst) {
  2795. /*
  2796. * pattern contains embedded '$', so use Var_Subst to
  2797. * expand it.
  2798. */
  2799. cp2 = pattern;
  2800. pattern = Var_Subst(NULL, cp2, ctxt, errnum);
  2801. free(cp2);
  2802. }
  2803. if (DEBUG(VAR))
  2804. fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
  2805. pattern);
  2806. if (*tstr == 'M') {
  2807. newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
  2808. pattern);
  2809. } else {
  2810. newStr = VarModify(ctxt, &parsestate, nstr, VarNoMatch,
  2811. pattern);
  2812. }
  2813. free(pattern);
  2814. break;
  2815. }
  2816. case 'S':
  2817. {
  2818. VarPattern pattern;
  2819. Var_Parse_State tmpparsestate;
  2820. pattern.flags = 0;
  2821. tmpparsestate = parsestate;
  2822. delim = tstr[1];
  2823. tstr += 2;
  2824. /*
  2825. * If pattern begins with '^', it is anchored to the
  2826. * start of the word -- skip over it and flag pattern.
  2827. */
  2828. if (*tstr == '^') {
  2829. pattern.flags |= VAR_MATCH_START;
  2830. tstr += 1;
  2831. }
  2832. cp = tstr;
  2833. if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
  2834. &cp, delim,
  2835. &pattern.flags,
  2836. &pattern.leftLen,
  2837. NULL)) == NULL)
  2838. goto cleanup;
  2839. if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
  2840. &cp, delim, NULL,
  2841. &pattern.rightLen,
  2842. &pattern)) == NULL)
  2843. goto cleanup;
  2844. /*
  2845. * Check for global substitution. If 'g' after the final
  2846. * delimiter, substitution is global and is marked that
  2847. * way.
  2848. */
  2849. for (;; cp++) {
  2850. switch (*cp) {
  2851. case 'g':
  2852. pattern.flags |= VAR_SUB_GLOBAL;
  2853. continue;
  2854. case '1':
  2855. pattern.flags |= VAR_SUB_ONE;
  2856. continue;
  2857. case 'W':
  2858. tmpparsestate.oneBigWord = TRUE;
  2859. continue;
  2860. }
  2861. break;
  2862. }
  2863. termc = *cp;
  2864. newStr = VarModify(ctxt, &tmpparsestate, nstr,
  2865. VarSubstitute,
  2866. &pattern);
  2867. /*
  2868. * Free the two strings.
  2869. */
  2870. free(UNCONST(pattern.lhs));
  2871. free(UNCONST(pattern.rhs));
  2872. delim = '\0';
  2873. break;
  2874. }
  2875. case '?':
  2876. {
  2877. VarPattern pattern;
  2878. Boolean value;
  2879. /* find ':', and then substitute accordingly */
  2880. pattern.flags = 0;
  2881. cp = ++tstr;
  2882. delim = ':';
  2883. if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
  2884. &cp, delim, NULL,
  2885. &pattern.leftLen,
  2886. NULL)) == NULL)
  2887. goto cleanup;
  2888. /* BROPEN or PROPEN */
  2889. delim = endc;
  2890. if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
  2891. &cp, delim, NULL,
  2892. &pattern.rightLen,
  2893. NULL)) == NULL)
  2894. goto cleanup;
  2895. termc = *--cp;
  2896. delim = '\0';
  2897. if (Cond_EvalExpression(NULL, v->name, &value, 0)
  2898. == COND_INVALID) {
  2899. Error("Bad conditional expression `%s' in %s?%s:%s",
  2900. v->name, v->name, pattern.lhs, pattern.rhs);
  2901. goto cleanup;
  2902. }
  2903. if (value) {
  2904. newStr = UNCONST(pattern.lhs);
  2905. free(UNCONST(pattern.rhs));
  2906. } else {
  2907. newStr = UNCONST(pattern.rhs);
  2908. free(UNCONST(pattern.lhs));
  2909. }
  2910. if (v->flags & VAR_JUNK) {
  2911. v->flags |= VAR_KEEP;
  2912. }
  2913. break;
  2914. }
  2915. #ifndef NO_REGEX
  2916. case 'C':
  2917. {
  2918. VarREPattern pattern;
  2919. char *re;
  2920. int error;
  2921. Var_Parse_State tmpparsestate;
  2922. pattern.flags = 0;
  2923. tmpparsestate = parsestate;
  2924. delim = tstr[1];
  2925. tstr += 2;
  2926. cp = tstr;
  2927. if ((re = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim,
  2928. NULL, NULL, NULL)) == NULL)
  2929. goto cleanup;
  2930. if ((pattern.replace = VarGetPattern(ctxt, &parsestate,
  2931. errnum, &cp, delim, NULL,
  2932. NULL, NULL)) == NULL){
  2933. free(re);
  2934. goto cleanup;
  2935. }
  2936. for (;; cp++) {
  2937. switch (*cp) {
  2938. case 'g':
  2939. pattern.flags |= VAR_SUB_GLOBAL;
  2940. continue;
  2941. case '1':
  2942. pattern.flags |= VAR_SUB_ONE;
  2943. continue;
  2944. case 'W':
  2945. tmpparsestate.oneBigWord = TRUE;
  2946. continue;
  2947. }
  2948. break;
  2949. }
  2950. termc = *cp;
  2951. error = regcomp(&pattern.re, re, REG_EXTENDED);
  2952. free(re);
  2953. if (error) {
  2954. *lengthPtr = cp - start + 1;
  2955. VarREError(error, &pattern.re, "RE substitution error");
  2956. free(pattern.replace);
  2957. goto cleanup;
  2958. }
  2959. pattern.nsub = pattern.re.re_nsub + 1;
  2960. if (pattern.nsub < 1)
  2961. pattern.nsub = 1;
  2962. if (pattern.nsub > 10)
  2963. pattern.nsub = 10;
  2964. pattern.matches = bmake_malloc(pattern.nsub *
  2965. sizeof(regmatch_t));
  2966. newStr = VarModify(ctxt, &tmpparsestate, nstr,
  2967. VarRESubstitute,
  2968. &pattern);
  2969. regfree(&pattern.re);
  2970. free(pattern.replace);
  2971. free(pattern.matches);
  2972. delim = '\0';
  2973. break;
  2974. }
  2975. #endif
  2976. case 'Q':
  2977. if (tstr[1] == endc || tstr[1] == ':') {
  2978. newStr = VarQuote(nstr);
  2979. cp = tstr + 1;
  2980. termc = *cp;
  2981. break;
  2982. }
  2983. goto default_case;
  2984. case 'T':
  2985. if (tstr[1] == endc || tstr[1] == ':') {
  2986. newStr = VarModify(ctxt, &parsestate, nstr, VarTail,
  2987. NULL);
  2988. cp = tstr + 1;
  2989. termc = *cp;
  2990. break;
  2991. }
  2992. goto default_case;
  2993. case 'H':
  2994. if (tstr[1] == endc || tstr[1] == ':') {
  2995. newStr = VarModify(ctxt, &parsestate, nstr, VarHead,
  2996. NULL);
  2997. cp = tstr + 1;
  2998. termc = *cp;
  2999. break;
  3000. }
  3001. goto default_case;
  3002. case 'E':
  3003. if (tstr[1] == endc || tstr[1] == ':') {
  3004. newStr = VarModify(ctxt, &parsestate, nstr, VarSuffix,
  3005. NULL);
  3006. cp = tstr + 1;
  3007. termc = *cp;
  3008. break;
  3009. }
  3010. goto default_case;
  3011. case 'R':
  3012. if (tstr[1] == endc || tstr[1] == ':') {
  3013. newStr = VarModify(ctxt, &parsestate, nstr, VarRoot,
  3014. NULL);
  3015. cp = tstr + 1;
  3016. termc = *cp;
  3017. break;
  3018. }
  3019. goto default_case;
  3020. case 'O':
  3021. {
  3022. char otype;
  3023. cp = tstr + 1; /* skip to the rest in any case */
  3024. if (tstr[1] == endc || tstr[1] == ':') {
  3025. otype = 's';
  3026. termc = *cp;
  3027. } else if ( (tstr[1] == 'x') &&
  3028. (tstr[2] == endc || tstr[2] == ':') ) {
  3029. otype = tstr[1];
  3030. cp = tstr + 2;
  3031. termc = *cp;
  3032. } else {
  3033. goto bad_modifier;
  3034. }
  3035. newStr = VarOrder(nstr, otype);
  3036. break;
  3037. }
  3038. case 'u':
  3039. if (tstr[1] == endc || tstr[1] == ':') {
  3040. newStr = VarUniq(nstr);
  3041. cp = tstr + 1;
  3042. termc = *cp;
  3043. break;
  3044. }
  3045. goto default_case;
  3046. #ifdef SUNSHCMD
  3047. case 's':
  3048. if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
  3049. const char *emsg;
  3050. newStr = Cmd_Exec(nstr, &emsg);
  3051. if (emsg)
  3052. Error(emsg, nstr);
  3053. cp = tstr + 2;
  3054. termc = *cp;
  3055. break;
  3056. }
  3057. goto default_case;
  3058. #endif
  3059. default:
  3060. default_case:
  3061. {
  3062. #ifdef SYSVVARSUB
  3063. /*
  3064. * This can either be a bogus modifier or a System-V
  3065. * substitution command.
  3066. */
  3067. VarPattern pattern;
  3068. Boolean eqFound;
  3069. pattern.flags = 0;
  3070. eqFound = FALSE;
  3071. /*
  3072. * First we make a pass through the string trying
  3073. * to verify it is a SYSV-make-style translation:
  3074. * it must be: <string1>=<string2>)
  3075. */
  3076. cp = tstr;
  3077. cnt = 1;
  3078. while (*cp != '\0' && cnt) {
  3079. if (*cp == '=') {
  3080. eqFound = TRUE;
  3081. /* continue looking for endc */
  3082. }
  3083. else if (*cp == endc)
  3084. cnt--;
  3085. else if (*cp == startc)
  3086. cnt++;
  3087. if (cnt)
  3088. cp++;
  3089. }
  3090. if (*cp == endc && eqFound) {
  3091. /*
  3092. * Now we break this sucker into the lhs and
  3093. * rhs. We must null terminate them of course.
  3094. */
  3095. delim='=';
  3096. cp = tstr;
  3097. if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
  3098. errnum, &cp, delim, &pattern.flags,
  3099. &pattern.leftLen, NULL)) == NULL)
  3100. goto cleanup;
  3101. delim = endc;
  3102. if ((pattern.rhs = VarGetPattern(ctxt, &parsestate,
  3103. errnum, &cp, delim, NULL, &pattern.rightLen,
  3104. &pattern)) == NULL)
  3105. goto cleanup;
  3106. /*
  3107. * SYSV modifications happen through the whole
  3108. * string. Note the pattern is anchored at the end.
  3109. */
  3110. termc = *--cp;
  3111. delim = '\0';
  3112. newStr = VarModify(ctxt, &parsestate, nstr,
  3113. VarSYSVMatch,
  3114. &pattern);
  3115. free(UNCONST(pattern.lhs));
  3116. free(UNCONST(pattern.rhs));
  3117. } else
  3118. #endif
  3119. {
  3120. Error("Unknown modifier '%c'", *tstr);
  3121. for (cp = tstr+1;
  3122. *cp != ':' && *cp != endc && *cp != '\0';
  3123. cp++)
  3124. continue;
  3125. termc = *cp;
  3126. newStr = var_Error;
  3127. }
  3128. }
  3129. }
  3130. if (DEBUG(VAR)) {
  3131. fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr);
  3132. }
  3133. if (newStr != nstr) {
  3134. if (*freePtr) {
  3135. free(nstr);
  3136. *freePtr = NULL;
  3137. }
  3138. nstr = newStr;
  3139. if (nstr != var_Error && nstr != varNoError) {
  3140. *freePtr = nstr;
  3141. }
  3142. }
  3143. if (termc == '\0' && endc != '\0') {
  3144. Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc, v->name, nstr, modifier);
  3145. } else if (termc == ':') {
  3146. cp++;
  3147. }
  3148. tstr = cp;
  3149. }
  3150. out:
  3151. *lengthPtr = tstr - start;
  3152. return (nstr);
  3153. bad_modifier:
  3154. /* "{(" */
  3155. Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr,
  3156. v->name);
  3157. cleanup:
  3158. *lengthPtr = cp - start;
  3159. if (delim != '\0')
  3160. Error("Unclosed substitution for %s (%c missing)",
  3161. v->name, delim);
  3162. if (*freePtr) {
  3163. free(*freePtr);
  3164. *freePtr = NULL;
  3165. }
  3166. return (var_Error);
  3167. }
  3168. /*-
  3169. *-----------------------------------------------------------------------
  3170. * Var_Parse --
  3171. * Given the start of a variable invocation, extract the variable
  3172. * name and find its value, then modify it according to the
  3173. * specification.
  3174. *
  3175. * Input:
  3176. * str The string to parse
  3177. * ctxt The context for the variable
  3178. * errnum TRUE if undefined variables are an error
  3179. * lengthPtr OUT: The length of the specification
  3180. * freePtr OUT: Non-NULL if caller should free *freePtr
  3181. *
  3182. * Results:
  3183. * The (possibly-modified) value of the variable or var_Error if the
  3184. * specification is invalid. The length of the specification is
  3185. * placed in *lengthPtr (for invalid specifications, this is just
  3186. * 2...?).
  3187. * If *freePtr is non-NULL then it's a pointer that the caller
  3188. * should pass to free() to free memory used by the result.
  3189. *
  3190. * Side Effects:
  3191. * None.
  3192. *
  3193. *-----------------------------------------------------------------------
  3194. */
  3195. /* coverity[+alloc : arg-*4] */
  3196. char *
  3197. Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
  3198. void **freePtr)
  3199. {
  3200. const char *tstr; /* Pointer into str */
  3201. Var *v; /* Variable in invocation */
  3202. Boolean haveModifier;/* TRUE if have modifiers for the variable */
  3203. char endc; /* Ending character when variable in parens
  3204. * or braces */
  3205. char startc; /* Starting character when variable in parens
  3206. * or braces */
  3207. int vlen; /* Length of variable name */
  3208. const char *start; /* Points to original start of str */
  3209. char *nstr; /* New string, used during expansion */
  3210. Boolean dynamic; /* TRUE if the variable is local and we're
  3211. * expanding it in a non-local context. This
  3212. * is done to support dynamic sources. The
  3213. * result is just the invocation, unaltered */
  3214. Var_Parse_State parsestate; /* Flags passed to helper functions */
  3215. char name[2];
  3216. *freePtr = NULL;
  3217. dynamic = FALSE;
  3218. start = str;
  3219. parsestate.oneBigWord = FALSE;
  3220. parsestate.varSpace = ' '; /* word separator */
  3221. startc = str[1];
  3222. if (startc != PROPEN && startc != BROPEN) {
  3223. /*
  3224. * If it's not bounded by braces of some sort, life is much simpler.
  3225. * We just need to check for the first character and return the
  3226. * value if it exists.
  3227. */
  3228. /* Error out some really stupid names */
  3229. if (startc == '\0' || strchr(")}:$", startc)) {
  3230. *lengthPtr = 1;
  3231. return var_Error;
  3232. }
  3233. name[0] = startc;
  3234. name[1] = '\0';
  3235. v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
  3236. if (v == NULL) {
  3237. *lengthPtr = 2;
  3238. if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
  3239. /*
  3240. * If substituting a local variable in a non-local context,
  3241. * assume it's for dynamic source stuff. We have to handle
  3242. * this specially and return the longhand for the variable
  3243. * with the dollar sign escaped so it makes it back to the
  3244. * caller. Only four of the local variables are treated
  3245. * specially as they are the only four that will be set
  3246. * when dynamic sources are expanded.
  3247. */
  3248. switch (str[1]) {
  3249. case '@':
  3250. return UNCONST("$(.TARGET)");
  3251. case '%':
  3252. return UNCONST("$(.ARCHIVE)");
  3253. case '*':
  3254. return UNCONST("$(.PREFIX)");
  3255. case '!':
  3256. return UNCONST("$(.MEMBER)");
  3257. }
  3258. }
  3259. /*
  3260. * Error
  3261. */
  3262. return (errnum ? var_Error : varNoError);
  3263. } else {
  3264. haveModifier = FALSE;
  3265. tstr = &str[1];
  3266. endc = str[1];
  3267. }
  3268. } else {
  3269. Buffer buf; /* Holds the variable name */
  3270. endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
  3271. Buf_Init(&buf, 0);
  3272. /*
  3273. * Skip to the end character or a colon, whichever comes first.
  3274. */
  3275. for (tstr = str + 2;
  3276. *tstr != '\0' && *tstr != endc && *tstr != ':';
  3277. tstr++)
  3278. {
  3279. /*
  3280. * A variable inside a variable, expand
  3281. */
  3282. if (*tstr == '$') {
  3283. int rlen;
  3284. void *freeIt;
  3285. char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt);
  3286. if (rval != NULL) {
  3287. Buf_AddBytes(&buf, strlen(rval), rval);
  3288. }
  3289. if (freeIt)
  3290. free(freeIt);
  3291. tstr += rlen - 1;
  3292. }
  3293. else
  3294. Buf_AddByte(&buf, *tstr);
  3295. }
  3296. if (*tstr == ':') {
  3297. haveModifier = TRUE;
  3298. } else if (*tstr != '\0') {
  3299. haveModifier = FALSE;
  3300. } else {
  3301. /*
  3302. * If we never did find the end character, return NULL
  3303. * right now, setting the length to be the distance to
  3304. * the end of the string, since that's what make does.
  3305. */
  3306. *lengthPtr = tstr - str;
  3307. Buf_Destroy(&buf, TRUE);
  3308. return (var_Error);
  3309. }
  3310. str = Buf_GetAll(&buf, &vlen);
  3311. /*
  3312. * At this point, str points into newly allocated memory from
  3313. * buf, containing only the name of the variable.
  3314. *
  3315. * start and tstr point into the const string that was pointed
  3316. * to by the original value of the str parameter. start points
  3317. * to the '$' at the beginning of the string, while tstr points
  3318. * to the char just after the end of the variable name -- this
  3319. * will be '\0', ':', PRCLOSE, or BRCLOSE.
  3320. */
  3321. v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
  3322. /*
  3323. * Check also for bogus D and F forms of local variables since we're
  3324. * in a local context and the name is the right length.
  3325. */
  3326. if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
  3327. (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
  3328. strchr("@%*!<>", str[0]) != NULL) {
  3329. /*
  3330. * Well, it's local -- go look for it.
  3331. */
  3332. name[0] = *str;
  3333. name[1] = '\0';
  3334. v = VarFind(name, ctxt, 0);
  3335. if (v != NULL) {
  3336. /*
  3337. * No need for nested expansion or anything, as we're
  3338. * the only one who sets these things and we sure don't
  3339. * but nested invocations in them...
  3340. */
  3341. nstr = Buf_GetAll(&v->val, NULL);
  3342. if (str[1] == 'D') {
  3343. nstr = VarModify(ctxt, &parsestate, nstr, VarHead,
  3344. NULL);
  3345. } else {
  3346. nstr = VarModify(ctxt, &parsestate, nstr, VarTail,
  3347. NULL);
  3348. }
  3349. /*
  3350. * Resulting string is dynamically allocated, so
  3351. * tell caller to free it.
  3352. */
  3353. *freePtr = nstr;
  3354. *lengthPtr = tstr-start+1;
  3355. Buf_Destroy(&buf, TRUE);
  3356. VarFreeEnv(v, TRUE);
  3357. return nstr;
  3358. }
  3359. }
  3360. if (v == NULL) {
  3361. if (((vlen == 1) ||
  3362. (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
  3363. ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
  3364. {
  3365. /*
  3366. * If substituting a local variable in a non-local context,
  3367. * assume it's for dynamic source stuff. We have to handle
  3368. * this specially and return the longhand for the variable
  3369. * with the dollar sign escaped so it makes it back to the
  3370. * caller. Only four of the local variables are treated
  3371. * specially as they are the only four that will be set
  3372. * when dynamic sources are expanded.
  3373. */
  3374. switch (*str) {
  3375. case '@':
  3376. case '%':
  3377. case '*':
  3378. case '!':
  3379. dynamic = TRUE;
  3380. break;
  3381. }
  3382. } else if ((vlen > 2) && (*str == '.') &&
  3383. isupper((unsigned char) str[1]) &&
  3384. ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
  3385. {
  3386. int len;
  3387. len = vlen - 1;
  3388. if ((strncmp(str, ".TARGET", len) == 0) ||
  3389. (strncmp(str, ".ARCHIVE", len) == 0) ||
  3390. (strncmp(str, ".PREFIX", len) == 0) ||
  3391. (strncmp(str, ".MEMBER", len) == 0))
  3392. {
  3393. dynamic = TRUE;
  3394. }
  3395. }
  3396. if (!haveModifier) {
  3397. /*
  3398. * No modifiers -- have specification length so we can return
  3399. * now.
  3400. */
  3401. *lengthPtr = tstr - start + 1;
  3402. if (dynamic) {
  3403. char *pstr = bmake_strndup(start, *lengthPtr);
  3404. *freePtr = pstr;
  3405. Buf_Destroy(&buf, TRUE);
  3406. return(pstr);
  3407. } else {
  3408. Buf_Destroy(&buf, TRUE);
  3409. return (errnum ? var_Error : varNoError);
  3410. }
  3411. } else {
  3412. /*
  3413. * Still need to get to the end of the variable specification,
  3414. * so kludge up a Var structure for the modifications
  3415. */
  3416. v = bmake_malloc(sizeof(Var));
  3417. v->name = UNCONST(str);
  3418. Buf_Init(&v->val, 1);
  3419. v->flags = VAR_JUNK;
  3420. Buf_Destroy(&buf, FALSE);
  3421. }
  3422. } else
  3423. Buf_Destroy(&buf, TRUE);
  3424. }
  3425. if (v->flags & VAR_IN_USE) {
  3426. Fatal("Variable %s is recursive.", v->name);
  3427. /*NOTREACHED*/
  3428. } else {
  3429. v->flags |= VAR_IN_USE;
  3430. }
  3431. /*
  3432. * Before doing any modification, we have to make sure the value
  3433. * has been fully expanded. If it looks like recursion might be
  3434. * necessary (there's a dollar sign somewhere in the variable's value)
  3435. * we just call Var_Subst to do any other substitutions that are
  3436. * necessary. Note that the value returned by Var_Subst will have
  3437. * been dynamically-allocated, so it will need freeing when we
  3438. * return.
  3439. */
  3440. nstr = Buf_GetAll(&v->val, NULL);
  3441. if (strchr(nstr, '$') != NULL) {
  3442. nstr = Var_Subst(NULL, nstr, ctxt, errnum);
  3443. *freePtr = nstr;
  3444. }
  3445. v->flags &= ~VAR_IN_USE;
  3446. if ((nstr != NULL) && haveModifier) {
  3447. int used;
  3448. /*
  3449. * Skip initial colon.
  3450. */
  3451. tstr++;
  3452. nstr = ApplyModifiers(nstr, tstr, startc, endc,
  3453. v, ctxt, errnum, &used, freePtr);
  3454. tstr += used;
  3455. }
  3456. if (*tstr) {
  3457. *lengthPtr = tstr - start + 1;
  3458. } else {
  3459. *lengthPtr = tstr - start;
  3460. }
  3461. if (v->flags & VAR_FROM_ENV) {
  3462. Boolean destroy = FALSE;
  3463. if (nstr != Buf_GetAll(&v->val, NULL)) {
  3464. destroy = TRUE;
  3465. } else {
  3466. /*
  3467. * Returning the value unmodified, so tell the caller to free
  3468. * the thing.
  3469. */
  3470. *freePtr = nstr;
  3471. }
  3472. VarFreeEnv(v, destroy);
  3473. } else if (v->flags & VAR_JUNK) {
  3474. /*
  3475. * Perform any free'ing needed and set *freePtr to NULL so the caller
  3476. * doesn't try to free a static pointer.
  3477. * If VAR_KEEP is also set then we want to keep str as is.
  3478. */
  3479. if (!(v->flags & VAR_KEEP)) {
  3480. if (*freePtr) {
  3481. free(nstr);
  3482. *freePtr = NULL;
  3483. }
  3484. if (dynamic) {
  3485. nstr = bmake_strndup(start, *lengthPtr);
  3486. *freePtr = nstr;
  3487. } else {
  3488. nstr = var_Error;
  3489. }
  3490. }
  3491. if (nstr != Buf_GetAll(&v->val, NULL))
  3492. Buf_Destroy(&v->val, TRUE);
  3493. free(v->name);
  3494. free(v);
  3495. }
  3496. return (nstr);
  3497. }
  3498. /*-
  3499. *-----------------------------------------------------------------------
  3500. * Var_Subst --
  3501. * Substitute for all variables in the given string in the given context
  3502. * If undefErr is TRUE, Parse_Error will be called when an undefined
  3503. * variable is encountered.
  3504. *
  3505. * Input:
  3506. * var Named variable || NULL for all
  3507. * str the string which to substitute
  3508. * ctxt the context wherein to find variables
  3509. * undefErr TRUE if undefineds are an error
  3510. *
  3511. * Results:
  3512. * The resulting string.
  3513. *
  3514. * Side Effects:
  3515. * None. The old string must be freed by the caller
  3516. *-----------------------------------------------------------------------
  3517. */
  3518. char *
  3519. Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
  3520. {
  3521. Buffer buf; /* Buffer for forming things */
  3522. char *val; /* Value to substitute for a variable */
  3523. int length; /* Length of the variable invocation */
  3524. Boolean trailingBslash; /* variable ends in \ */
  3525. void *freeIt = NULL; /* Set if it should be freed */
  3526. static Boolean errorReported; /* Set true if an error has already
  3527. * been reported to prevent a plethora
  3528. * of messages when recursing */
  3529. Buf_Init(&buf, 0);
  3530. errorReported = FALSE;
  3531. trailingBslash = FALSE;
  3532. while (*str) {
  3533. if (*str == '\n' && trailingBslash)
  3534. Buf_AddByte(&buf, ' ');
  3535. if (var == NULL && (*str == '$') && (str[1] == '$')) {
  3536. /*
  3537. * A dollar sign may be escaped either with another dollar sign.
  3538. * In such a case, we skip over the escape character and store the
  3539. * dollar sign into the buffer directly.
  3540. */
  3541. str++;
  3542. Buf_AddByte(&buf, *str);
  3543. str++;
  3544. } else if (*str != '$') {
  3545. /*
  3546. * Skip as many characters as possible -- either to the end of
  3547. * the string or to the next dollar sign (variable invocation).
  3548. */
  3549. const char *cp;
  3550. for (cp = str++; *str != '$' && *str != '\0'; str++)
  3551. continue;
  3552. Buf_AddBytes(&buf, str - cp, cp);
  3553. } else {
  3554. if (var != NULL) {
  3555. int expand;
  3556. for (;;) {
  3557. if (str[1] == '\0') {
  3558. /* A trailing $ is kind of a special case */
  3559. Buf_AddByte(&buf, str[0]);
  3560. str++;
  3561. expand = FALSE;
  3562. } else if (str[1] != PROPEN && str[1] != BROPEN) {
  3563. if (str[1] != *var || strlen(var) > 1) {
  3564. Buf_AddBytes(&buf, 2, str);
  3565. str += 2;
  3566. expand = FALSE;
  3567. }
  3568. else
  3569. expand = TRUE;
  3570. break;
  3571. }
  3572. else {
  3573. const char *p;
  3574. /*
  3575. * Scan up to the end of the variable name.
  3576. */
  3577. for (p = &str[2]; *p &&
  3578. *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
  3579. if (*p == '$')
  3580. break;
  3581. /*
  3582. * A variable inside the variable. We cannot expand
  3583. * the external variable yet, so we try again with
  3584. * the nested one
  3585. */
  3586. if (*p == '$') {
  3587. Buf_AddBytes(&buf, p - str, str);
  3588. str = p;
  3589. continue;
  3590. }
  3591. if (strncmp(var, str + 2, p - str - 2) != 0 ||
  3592. var[p - str - 2] != '\0') {
  3593. /*
  3594. * Not the variable we want to expand, scan
  3595. * until the next variable
  3596. */
  3597. for (;*p != '$' && *p != '\0'; p++)
  3598. continue;
  3599. Buf_AddBytes(&buf, p - str, str);
  3600. str = p;
  3601. expand = FALSE;
  3602. }
  3603. else
  3604. expand = TRUE;
  3605. break;
  3606. }
  3607. }
  3608. if (!expand)
  3609. continue;
  3610. }
  3611. val = Var_Parse(str, ctxt, undefErr, &length, &freeIt);
  3612. /*
  3613. * When we come down here, val should either point to the
  3614. * value of this variable, suitably modified, or be NULL.
  3615. * Length should be the total length of the potential
  3616. * variable invocation (from $ to end character...)
  3617. */
  3618. if (val == var_Error || val == varNoError) {
  3619. /*
  3620. * If performing old-time variable substitution, skip over
  3621. * the variable and continue with the substitution. Otherwise,
  3622. * store the dollar sign and advance str so we continue with
  3623. * the string...
  3624. */
  3625. if (oldVars) {
  3626. str += length;
  3627. } else if (undefErr) {
  3628. /*
  3629. * If variable is undefined, complain and skip the
  3630. * variable. The complaint will stop us from doing anything
  3631. * when the file is parsed.
  3632. */
  3633. if (!errorReported) {
  3634. Parse_Error(PARSE_FATAL,
  3635. "Undefined variable \"%.*s\"",length,str);
  3636. }
  3637. str += length;
  3638. errorReported = TRUE;
  3639. } else {
  3640. Buf_AddByte(&buf, *str);
  3641. str += 1;
  3642. }
  3643. } else {
  3644. /*
  3645. * We've now got a variable structure to store in. But first,
  3646. * advance the string pointer.
  3647. */
  3648. str += length;
  3649. /*
  3650. * Copy all the characters from the variable value straight
  3651. * into the new string.
  3652. */
  3653. length = strlen(val);
  3654. Buf_AddBytes(&buf, length, val);
  3655. trailingBslash = length > 0 && val[length - 1] == '\\';
  3656. }
  3657. if (freeIt) {
  3658. free(freeIt);
  3659. freeIt = NULL;
  3660. }
  3661. }
  3662. }
  3663. return Buf_Destroy(&buf, FALSE);
  3664. }
  3665. /*-
  3666. *-----------------------------------------------------------------------
  3667. * Var_GetTail --
  3668. * Return the tail from each of a list of words. Used to set the
  3669. * System V local variables.
  3670. *
  3671. * Input:
  3672. * file Filename to modify
  3673. *
  3674. * Results:
  3675. * The resulting string.
  3676. *
  3677. * Side Effects:
  3678. * None.
  3679. *
  3680. *-----------------------------------------------------------------------
  3681. */
  3682. #if 0
  3683. char *
  3684. Var_GetTail(char *file)
  3685. {
  3686. return(VarModify(file, VarTail, NULL));
  3687. }
  3688. /*-
  3689. *-----------------------------------------------------------------------
  3690. * Var_GetHead --
  3691. * Find the leading components of a (list of) filename(s).
  3692. * XXX: VarHead does not replace foo by ., as (sun) System V make
  3693. * does.
  3694. *
  3695. * Input:
  3696. * file Filename to manipulate
  3697. *
  3698. * Results:
  3699. * The leading components.
  3700. *
  3701. * Side Effects:
  3702. * None.
  3703. *
  3704. *-----------------------------------------------------------------------
  3705. */
  3706. char *
  3707. Var_GetHead(char *file)
  3708. {
  3709. return(VarModify(file, VarHead, NULL));
  3710. }
  3711. #endif
  3712. /*-
  3713. *-----------------------------------------------------------------------
  3714. * Var_Init --
  3715. * Initialize the module
  3716. *
  3717. * Results:
  3718. * None
  3719. *
  3720. * Side Effects:
  3721. * The VAR_CMD and VAR_GLOBAL contexts are created
  3722. *-----------------------------------------------------------------------
  3723. */
  3724. void
  3725. Var_Init(void)
  3726. {
  3727. VAR_GLOBAL = Targ_NewGN("Global");
  3728. VAR_CMD = Targ_NewGN("Command");
  3729. }
  3730. void
  3731. Var_End(void)
  3732. {
  3733. }
  3734. /****************** PRINT DEBUGGING INFO *****************/
  3735. static void
  3736. VarPrintVar(void *vp)
  3737. {
  3738. Var *v = (Var *)vp;
  3739. fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
  3740. }
  3741. /*-
  3742. *-----------------------------------------------------------------------
  3743. * Var_Dump --
  3744. * print all variables in a context
  3745. *-----------------------------------------------------------------------
  3746. */
  3747. void
  3748. Var_Dump(GNode *ctxt)
  3749. {
  3750. Hash_Search search;
  3751. Hash_Entry *h;
  3752. for (h = Hash_EnumFirst(&ctxt->context, &search);
  3753. h != NULL;
  3754. h = Hash_EnumNext(&search)) {
  3755. VarPrintVar(Hash_GetValue(h));
  3756. }
  3757. }