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