1 /* $NetBSD: var.c,v 1.930 2021/04/19 22:22:27 rillig 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 /* 72 * Handling of variables and the expressions formed from them. 73 * 74 * Variables are set using lines of the form VAR=value. Both the variable 75 * name and the value can contain references to other variables, by using 76 * expressions like ${VAR}, ${VAR:Modifiers}, ${${VARNAME}} or ${VAR:${MODS}}. 77 * 78 * Interface: 79 * Var_Init Initialize this module. 80 * 81 * Var_End Clean up the module. 82 * 83 * Var_Set 84 * Var_SetExpand 85 * Set the value of the variable, creating it if 86 * necessary. 87 * 88 * Var_Append 89 * Var_AppendExpand 90 * Append more characters to the variable, creating it if 91 * necessary. A space is placed between the old value and 92 * the new one. 93 * 94 * Var_Exists 95 * Var_ExistsExpand 96 * See if a variable exists. 97 * 98 * Var_Value Return the unexpanded value of a variable, or NULL if 99 * the variable is undefined. 100 * 101 * Var_Subst Substitute all variable expressions in a string. 102 * 103 * Var_Parse Parse a variable expression such as ${VAR:Mpattern}. 104 * 105 * Var_Delete 106 * Var_DeleteExpand 107 * Delete a variable. 108 * 109 * Var_ReexportVars 110 * Export some or even all variables to the environment 111 * of this process and its child processes. 112 * 113 * Var_Export Export the variable to the environment of this process 114 * and its child processes. 115 * 116 * Var_UnExport Don't export the variable anymore. 117 * 118 * Debugging: 119 * Var_Stats Print out hashing statistics if in -dh mode. 120 * 121 * Var_Dump Print out all variables defined in the given scope. 122 * 123 * XXX: There's a lot of almost duplicate code in these functions that only 124 * differs in subtle details that are not mentioned in the manual page. 125 */ 126 127 #include <sys/stat.h> 128 #ifndef NO_REGEX 129 #include <sys/types.h> 130 #include <regex.h> 131 #endif 132 #include <errno.h> 133 #include <inttypes.h> 134 #include <limits.h> 135 #include <time.h> 136 137 #include "make.h" 138 #include "dir.h" 139 #include "job.h" 140 #include "metachar.h" 141 142 /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 143 MAKE_RCSID("$NetBSD: var.c,v 1.930 2021/04/19 22:22:27 rillig Exp $"); 144 145 /* 146 * Variables are defined using one of the VAR=value assignments. Their 147 * value can be queried by expressions such as $V, ${VAR}, or with modifiers 148 * such as ${VAR:S,from,to,g:Q}. 149 * 150 * There are 3 kinds of variables: scope variables, environment variables, 151 * undefined variables. 152 * 153 * Scope variables are stored in a GNode.scope. The only way to undefine 154 * a scope variable is using the .undef directive. In particular, it must 155 * not be possible to undefine a variable during the evaluation of an 156 * expression, or Var.name might point nowhere. 157 * 158 * Environment variables are temporary. They are returned by VarFind, and 159 * after using them, they must be freed using VarFreeEnv. 160 * 161 * Undefined variables occur during evaluation of variable expressions such 162 * as ${UNDEF:Ufallback} in Var_Parse and ApplyModifiers. 163 */ 164 typedef struct Var { 165 /* 166 * The name of the variable, once set, doesn't change anymore. 167 * For scope variables, it aliases the corresponding HashEntry name. 168 * For environment and undefined variables, it is allocated. 169 */ 170 FStr name; 171 172 /* The unexpanded value of the variable. */ 173 Buffer val; 174 175 /* The variable came from the command line. */ 176 bool fromCmd: 1; 177 178 /* 179 * The variable comes from the environment. 180 * These variables are not registered in any GNode, therefore they 181 * must be freed as soon as they are not used anymore. 182 */ 183 bool fromEnv: 1; 184 185 /* 186 * The variable value cannot be changed anymore, and the variable 187 * cannot be deleted. Any attempts to do so are silently ignored, 188 * they are logged with -dv though. 189 * 190 * See VAR_SET_READONLY. 191 */ 192 bool readOnly: 1; 193 194 /* 195 * The variable's value is currently being used by Var_Parse or 196 * Var_Subst. This marker is used to avoid endless recursion. 197 */ 198 bool inUse: 1; 199 200 /* 201 * The variable is exported to the environment, to be used by child 202 * processes. 203 */ 204 bool exported: 1; 205 206 /* 207 * At the point where this variable was exported, it contained an 208 * unresolved reference to another variable. Before any child 209 * process is started, it needs to be exported again, in the hope 210 * that the referenced variable can then be resolved. 211 */ 212 bool reexport: 1; 213 } Var; 214 215 /* 216 * Exporting variables is expensive and may leak memory, so skip it if we 217 * can. 218 * 219 * To avoid this, it might be worth encapsulating the environment variables 220 * in a separate data structure called EnvVars. 221 */ 222 typedef enum VarExportedMode { 223 VAR_EXPORTED_NONE, 224 VAR_EXPORTED_SOME, 225 VAR_EXPORTED_ALL 226 } VarExportedMode; 227 228 typedef enum UnexportWhat { 229 /* Unexport the variables given by name. */ 230 UNEXPORT_NAMED, 231 /* 232 * Unexport all globals previously exported, but keep the environment 233 * inherited from the parent. 234 */ 235 UNEXPORT_ALL, 236 /* 237 * Unexport all globals previously exported and clear the environment 238 * inherited from the parent. 239 */ 240 UNEXPORT_ENV 241 } UnexportWhat; 242 243 /* Flags for pattern matching in the :S and :C modifiers */ 244 typedef struct PatternFlags { 245 bool subGlobal: 1; /* 'g': replace as often as possible */ 246 bool subOnce: 1; /* '1': replace only once */ 247 bool anchorStart: 1; /* '^': match only at start of word */ 248 bool anchorEnd: 1; /* '$': match only at end of word */ 249 } PatternFlags; 250 251 /* SepBuf builds a string from words interleaved with separators. */ 252 typedef struct SepBuf { 253 Buffer buf; 254 bool needSep; 255 /* Usually ' ', but see the ':ts' modifier. */ 256 char sep; 257 } SepBuf; 258 259 260 /* 261 * This lets us tell if we have replaced the original environ 262 * (which we cannot free). 263 */ 264 char **savedEnv = NULL; 265 266 /* 267 * Special return value for Var_Parse, indicating a parse error. It may be 268 * caused by an undefined variable, a syntax error in a modifier or 269 * something entirely different. 270 */ 271 char var_Error[] = ""; 272 273 /* 274 * Special return value for Var_Parse, indicating an undefined variable in 275 * a case where VARE_UNDEFERR is not set. This undefined variable is 276 * typically a dynamic variable such as ${.TARGET}, whose expansion needs to 277 * be deferred until it is defined in an actual target. 278 * 279 * See VARE_EVAL_KEEP_UNDEF. 280 */ 281 static char varUndefined[] = ""; 282 283 /* 284 * Traditionally this make consumed $$ during := like any other expansion. 285 * Other make's do not, and this make follows straight since 2016-01-09. 286 * 287 * This knob allows controlling the behavior: 288 * false to consume $$ during := assignment. 289 * true to preserve $$ during := assignment. 290 */ 291 #define MAKE_SAVE_DOLLARS ".MAKE.SAVE_DOLLARS" 292 static bool save_dollars = true; 293 294 /* 295 * A scope collects variable names and their values. 296 * 297 * The main scope is SCOPE_GLOBAL, which contains the variables that are set 298 * in the makefiles. SCOPE_INTERNAL acts as a fallback for SCOPE_GLOBAL and 299 * contains some internal make variables. These internal variables can thus 300 * be overridden, they can also be restored by undefining the overriding 301 * variable. 302 * 303 * SCOPE_CMDLINE contains variables from the command line arguments. These 304 * override variables from SCOPE_GLOBAL. 305 * 306 * There is no scope for environment variables, these are generated on-the-fly 307 * whenever they are referenced. If there were such a scope, each change to 308 * environment variables would have to be reflected in that scope, which may 309 * be simpler or more complex than the current implementation. 310 * 311 * Each target has its own scope, containing the 7 target-local variables 312 * .TARGET, .ALLSRC, etc. No other variables are in these scopes. 313 */ 314 315 GNode *SCOPE_CMDLINE; 316 GNode *SCOPE_GLOBAL; 317 GNode *SCOPE_INTERNAL; 318 319 static VarExportedMode var_exportedVars = VAR_EXPORTED_NONE; 320 321 static const char *VarEvalMode_Name[] = { 322 "parse-only", 323 "eval", 324 "eval-defined", 325 "eval-keep-dollar", 326 "eval-keep-undefined", 327 "eval-keep-dollar-and-undefined", 328 }; 329 330 331 static Var * 332 VarNew(FStr name, const char *value, bool fromEnv, bool readOnly) 333 { 334 size_t value_len = strlen(value); 335 Var *var = bmake_malloc(sizeof *var); 336 var->name = name; 337 Buf_InitSize(&var->val, value_len + 1); 338 Buf_AddBytes(&var->val, value, value_len); 339 var->fromCmd = false; 340 var->fromEnv = fromEnv; 341 var->readOnly = readOnly; 342 var->inUse = false; 343 var->exported = false; 344 var->reexport = false; 345 return var; 346 } 347 348 static Substring 349 CanonicalVarname(Substring name) 350 { 351 352 if (!(Substring_Length(name) > 0 && name.start[0] == '.')) 353 return name; 354 355 if (Substring_Equals(name, ".ALLSRC")) 356 return Substring_InitStr(ALLSRC); 357 if (Substring_Equals(name, ".ARCHIVE")) 358 return Substring_InitStr(ARCHIVE); 359 if (Substring_Equals(name, ".IMPSRC")) 360 return Substring_InitStr(IMPSRC); 361 if (Substring_Equals(name, ".MEMBER")) 362 return Substring_InitStr(MEMBER); 363 if (Substring_Equals(name, ".OODATE")) 364 return Substring_InitStr(OODATE); 365 if (Substring_Equals(name, ".PREFIX")) 366 return Substring_InitStr(PREFIX); 367 if (Substring_Equals(name, ".TARGET")) 368 return Substring_InitStr(TARGET); 369 370 if (Substring_Equals(name, ".SHELL") && shellPath == NULL) 371 Shell_Init(); 372 373 /* GNU make has an additional alias $^ == ${.ALLSRC}. */ 374 375 return name; 376 } 377 378 static Var * 379 GNode_FindVar(GNode *scope, Substring varname, unsigned int hash) 380 { 381 return HashTable_FindValueBySubstringHash(&scope->vars, varname, hash); 382 } 383 384 /* 385 * Find the variable in the scope, and maybe in other scopes as well. 386 * 387 * Input: 388 * name name to find, is not expanded any further 389 * scope scope in which to look first 390 * elsewhere true to look in other scopes as well 391 * 392 * Results: 393 * The found variable, or NULL if the variable does not exist. 394 * If the variable is an environment variable, it must be freed using 395 * VarFreeEnv after use. 396 */ 397 static Var * 398 VarFindSubstring(Substring name, GNode *scope, bool elsewhere) 399 { 400 Var *var; 401 unsigned int nameHash; 402 403 /* Replace '.TARGET' with '@', likewise for other local variables. */ 404 name = CanonicalVarname(name); 405 nameHash = Hash_Substring(name); 406 407 var = GNode_FindVar(scope, name, nameHash); 408 if (!elsewhere) 409 return var; 410 411 if (var == NULL && scope != SCOPE_CMDLINE) 412 var = GNode_FindVar(SCOPE_CMDLINE, name, nameHash); 413 414 if (!opts.checkEnvFirst && var == NULL && scope != SCOPE_GLOBAL) { 415 var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash); 416 if (var == NULL && scope != SCOPE_INTERNAL) { 417 /* SCOPE_INTERNAL is subordinate to SCOPE_GLOBAL */ 418 var = GNode_FindVar(SCOPE_INTERNAL, name, nameHash); 419 } 420 } 421 422 if (var == NULL) { 423 FStr envName; 424 const char *envValue; 425 426 /* 427 * TODO: try setting an environment variable with the empty 428 * name, which should be technically possible, just to see 429 * how make reacts. All .for loops should be broken then. 430 */ 431 envName = Substring_Str(name); 432 envValue = getenv(envName.str); 433 if (envValue != NULL) 434 return VarNew(envName, envValue, true, false); 435 FStr_Done(&envName); 436 437 if (opts.checkEnvFirst && scope != SCOPE_GLOBAL) { 438 var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash); 439 if (var == NULL && scope != SCOPE_INTERNAL) 440 var = GNode_FindVar(SCOPE_INTERNAL, name, 441 nameHash); 442 return var; 443 } 444 445 return NULL; 446 } 447 448 return var; 449 } 450 451 /* TODO: Replace these calls with VarFindSubstring, as far as possible. */ 452 static Var * 453 VarFind(const char *name, GNode *scope, bool elsewhere) 454 { 455 return VarFindSubstring(Substring_InitStr(name), scope, elsewhere); 456 } 457 458 /* If the variable is an environment variable, free it, including its value. */ 459 static void 460 VarFreeEnv(Var *v) 461 { 462 if (!v->fromEnv) 463 return; 464 465 FStr_Done(&v->name); 466 Buf_Done(&v->val); 467 free(v); 468 } 469 470 /* Add a new variable of the given name and value to the given scope. */ 471 static Var * 472 VarAdd(const char *name, const char *value, GNode *scope, VarSetFlags flags) 473 { 474 HashEntry *he = HashTable_CreateEntry(&scope->vars, name, NULL); 475 Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), value, 476 false, (flags & VAR_SET_READONLY) != 0); 477 HashEntry_Set(he, v); 478 DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, value); 479 return v; 480 } 481 482 /* 483 * Remove a variable from a scope, freeing all related memory as well. 484 * The variable name is kept as-is, it is not expanded. 485 */ 486 void 487 Var_Delete(GNode *scope, const char *varname) 488 { 489 HashEntry *he = HashTable_FindEntry(&scope->vars, varname); 490 Var *v; 491 492 if (he == NULL) { 493 DEBUG2(VAR, "%s:delete %s (not found)\n", scope->name, varname); 494 return; 495 } 496 497 DEBUG2(VAR, "%s:delete %s\n", scope->name, varname); 498 v = he->value; 499 if (v->exported) 500 unsetenv(v->name.str); 501 if (strcmp(v->name.str, MAKE_EXPORTED) == 0) 502 var_exportedVars = VAR_EXPORTED_NONE; 503 assert(v->name.freeIt == NULL); 504 HashTable_DeleteEntry(&scope->vars, he); 505 Buf_Done(&v->val); 506 free(v); 507 } 508 509 /* 510 * Remove a variable from a scope, freeing all related memory as well. 511 * The variable name is expanded once. 512 */ 513 void 514 Var_DeleteExpand(GNode *scope, const char *name) 515 { 516 FStr varname = FStr_InitRefer(name); 517 518 if (strchr(varname.str, '$') != NULL) { 519 char *expanded; 520 (void)Var_Subst(varname.str, SCOPE_GLOBAL, VARE_WANTRES, 521 &expanded); 522 /* TODO: handle errors */ 523 varname = FStr_InitOwn(expanded); 524 } 525 526 Var_Delete(scope, varname.str); 527 FStr_Done(&varname); 528 } 529 530 /* 531 * Undefine one or more variables from the global scope. 532 * The argument is expanded exactly once and then split into words. 533 */ 534 void 535 Var_Undef(const char *arg) 536 { 537 VarParseResult vpr; 538 char *expanded; 539 Words varnames; 540 size_t i; 541 542 if (arg[0] == '\0') { 543 Parse_Error(PARSE_FATAL, 544 "The .undef directive requires an argument"); 545 return; 546 } 547 548 vpr = Var_Subst(arg, SCOPE_GLOBAL, VARE_WANTRES, &expanded); 549 if (vpr != VPR_OK) { 550 Parse_Error(PARSE_FATAL, 551 "Error in variable names to be undefined"); 552 return; 553 } 554 555 varnames = Str_Words(expanded, false); 556 if (varnames.len == 1 && varnames.words[0][0] == '\0') 557 varnames.len = 0; 558 559 for (i = 0; i < varnames.len; i++) { 560 const char *varname = varnames.words[i]; 561 Global_Delete(varname); 562 } 563 564 Words_Free(varnames); 565 free(expanded); 566 } 567 568 static bool 569 MayExport(const char *name) 570 { 571 if (name[0] == '.') 572 return false; /* skip internals */ 573 if (name[0] == '-') 574 return false; /* skip misnamed variables */ 575 if (name[1] == '\0') { 576 /* 577 * A single char. 578 * If it is one of the variables that should only appear in 579 * local scope, skip it, else we can get Var_Subst 580 * into a loop. 581 */ 582 switch (name[0]) { 583 case '@': 584 case '%': 585 case '*': 586 case '!': 587 return false; 588 } 589 } 590 return true; 591 } 592 593 static bool 594 ExportVarEnv(Var *v) 595 { 596 const char *name = v->name.str; 597 char *val = v->val.data; 598 char *expr; 599 600 if (v->exported && !v->reexport) 601 return false; /* nothing to do */ 602 603 if (strchr(val, '$') == NULL) { 604 if (!v->exported) 605 setenv(name, val, 1); 606 return true; 607 } 608 609 if (v->inUse) { 610 /* 611 * We recursed while exporting in a child. 612 * This isn't going to end well, just skip it. 613 */ 614 return false; 615 } 616 617 /* XXX: name is injected without escaping it */ 618 expr = str_concat3("${", name, "}"); 619 (void)Var_Subst(expr, SCOPE_GLOBAL, VARE_WANTRES, &val); 620 /* TODO: handle errors */ 621 setenv(name, val, 1); 622 free(val); 623 free(expr); 624 return true; 625 } 626 627 static bool 628 ExportVarPlain(Var *v) 629 { 630 if (strchr(v->val.data, '$') == NULL) { 631 setenv(v->name.str, v->val.data, 1); 632 v->exported = true; 633 v->reexport = false; 634 return true; 635 } 636 637 /* 638 * Flag the variable as something we need to re-export. 639 * No point actually exporting it now though, 640 * the child process can do it at the last minute. 641 * Avoid calling setenv more often than necessary since it can leak. 642 */ 643 v->exported = true; 644 v->reexport = true; 645 return true; 646 } 647 648 static bool 649 ExportVarLiteral(Var *v) 650 { 651 if (v->exported && !v->reexport) 652 return false; 653 654 if (!v->exported) 655 setenv(v->name.str, v->val.data, 1); 656 657 return true; 658 } 659 660 /* 661 * Mark a single variable to be exported later for subprocesses. 662 * 663 * Internal variables (those starting with '.') are not exported. 664 */ 665 static bool 666 ExportVar(const char *name, VarExportMode mode) 667 { 668 Var *v; 669 670 if (!MayExport(name)) 671 return false; 672 673 v = VarFind(name, SCOPE_GLOBAL, false); 674 if (v == NULL) 675 return false; 676 677 if (mode == VEM_ENV) 678 return ExportVarEnv(v); 679 else if (mode == VEM_PLAIN) 680 return ExportVarPlain(v); 681 else 682 return ExportVarLiteral(v); 683 } 684 685 /* 686 * Actually export the variables that have been marked as needing to be 687 * re-exported. 688 */ 689 void 690 Var_ReexportVars(void) 691 { 692 char *xvarnames; 693 694 /* 695 * Several make implementations support this sort of mechanism for 696 * tracking recursion - but each uses a different name. 697 * We allow the makefiles to update MAKELEVEL and ensure 698 * children see a correctly incremented value. 699 */ 700 char tmp[21]; 701 snprintf(tmp, sizeof tmp, "%d", makelevel + 1); 702 setenv(MAKE_LEVEL_ENV, tmp, 1); 703 704 if (var_exportedVars == VAR_EXPORTED_NONE) 705 return; 706 707 if (var_exportedVars == VAR_EXPORTED_ALL) { 708 HashIter hi; 709 710 /* Ouch! Exporting all variables at once is crazy. */ 711 HashIter_Init(&hi, &SCOPE_GLOBAL->vars); 712 while (HashIter_Next(&hi) != NULL) { 713 Var *var = hi.entry->value; 714 ExportVar(var->name.str, VEM_ENV); 715 } 716 return; 717 } 718 719 (void)Var_Subst("${" MAKE_EXPORTED ":O:u}", SCOPE_GLOBAL, VARE_WANTRES, 720 &xvarnames); 721 /* TODO: handle errors */ 722 if (xvarnames[0] != '\0') { 723 Words varnames = Str_Words(xvarnames, false); 724 size_t i; 725 726 for (i = 0; i < varnames.len; i++) 727 ExportVar(varnames.words[i], VEM_ENV); 728 Words_Free(varnames); 729 } 730 free(xvarnames); 731 } 732 733 static void 734 ExportVars(const char *varnames, bool isExport, VarExportMode mode) 735 /* TODO: try to combine the parameters 'isExport' and 'mode'. */ 736 { 737 Words words = Str_Words(varnames, false); 738 size_t i; 739 740 if (words.len == 1 && words.words[0][0] == '\0') 741 words.len = 0; 742 743 for (i = 0; i < words.len; i++) { 744 const char *varname = words.words[i]; 745 if (!ExportVar(varname, mode)) 746 continue; 747 748 if (var_exportedVars == VAR_EXPORTED_NONE) 749 var_exportedVars = VAR_EXPORTED_SOME; 750 751 if (isExport && mode == VEM_PLAIN) 752 Global_Append(MAKE_EXPORTED, varname); 753 } 754 Words_Free(words); 755 } 756 757 static void 758 ExportVarsExpand(const char *uvarnames, bool isExport, VarExportMode mode) 759 { 760 char *xvarnames; 761 762 (void)Var_Subst(uvarnames, SCOPE_GLOBAL, VARE_WANTRES, &xvarnames); 763 /* TODO: handle errors */ 764 ExportVars(xvarnames, isExport, mode); 765 free(xvarnames); 766 } 767 768 /* Export the named variables, or all variables. */ 769 void 770 Var_Export(VarExportMode mode, const char *varnames) 771 { 772 if (mode == VEM_PLAIN && varnames[0] == '\0') { 773 var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */ 774 return; 775 } 776 777 ExportVarsExpand(varnames, true, mode); 778 } 779 780 void 781 Var_ExportVars(const char *varnames) 782 { 783 ExportVarsExpand(varnames, false, VEM_PLAIN); 784 } 785 786 787 extern char **environ; 788 789 static void 790 ClearEnv(void) 791 { 792 const char *cp; 793 char **newenv; 794 795 cp = getenv(MAKE_LEVEL_ENV); /* we should preserve this */ 796 if (environ == savedEnv) { 797 /* we have been here before! */ 798 newenv = bmake_realloc(environ, 2 * sizeof(char *)); 799 } else { 800 if (savedEnv != NULL) { 801 free(savedEnv); 802 savedEnv = NULL; 803 } 804 newenv = bmake_malloc(2 * sizeof(char *)); 805 } 806 807 /* Note: we cannot safely free() the original environ. */ 808 environ = savedEnv = newenv; 809 newenv[0] = NULL; 810 newenv[1] = NULL; 811 if (cp != NULL && *cp != '\0') 812 setenv(MAKE_LEVEL_ENV, cp, 1); 813 } 814 815 static void 816 GetVarnamesToUnexport(bool isEnv, const char *arg, 817 FStr *out_varnames, UnexportWhat *out_what) 818 { 819 UnexportWhat what; 820 FStr varnames = FStr_InitRefer(""); 821 822 if (isEnv) { 823 if (arg[0] != '\0') { 824 Parse_Error(PARSE_FATAL, 825 "The directive .unexport-env does not take " 826 "arguments"); 827 /* continue anyway */ 828 } 829 what = UNEXPORT_ENV; 830 831 } else { 832 what = arg[0] != '\0' ? UNEXPORT_NAMED : UNEXPORT_ALL; 833 if (what == UNEXPORT_NAMED) 834 varnames = FStr_InitRefer(arg); 835 } 836 837 if (what != UNEXPORT_NAMED) { 838 char *expanded; 839 /* Using .MAKE.EXPORTED */ 840 (void)Var_Subst("${" MAKE_EXPORTED ":O:u}", SCOPE_GLOBAL, 841 VARE_WANTRES, &expanded); 842 /* TODO: handle errors */ 843 varnames = FStr_InitOwn(expanded); 844 } 845 846 *out_varnames = varnames; 847 *out_what = what; 848 } 849 850 static void 851 UnexportVar(const char *varname, UnexportWhat what) 852 { 853 Var *v = VarFind(varname, SCOPE_GLOBAL, false); 854 if (v == NULL) { 855 DEBUG1(VAR, "Not unexporting \"%s\" (not found)\n", varname); 856 return; 857 } 858 859 DEBUG1(VAR, "Unexporting \"%s\"\n", varname); 860 if (what != UNEXPORT_ENV && v->exported && !v->reexport) 861 unsetenv(v->name.str); 862 v->exported = false; 863 v->reexport = false; 864 865 if (what == UNEXPORT_NAMED) { 866 /* Remove the variable names from .MAKE.EXPORTED. */ 867 /* XXX: v->name is injected without escaping it */ 868 char *expr = str_concat3("${" MAKE_EXPORTED ":N", 869 v->name.str, "}"); 870 char *cp; 871 (void)Var_Subst(expr, SCOPE_GLOBAL, VARE_WANTRES, &cp); 872 /* TODO: handle errors */ 873 Global_Set(MAKE_EXPORTED, cp); 874 free(cp); 875 free(expr); 876 } 877 } 878 879 static void 880 UnexportVars(FStr *varnames, UnexportWhat what) 881 { 882 size_t i; 883 Words words; 884 885 if (what == UNEXPORT_ENV) 886 ClearEnv(); 887 888 words = Str_Words(varnames->str, false); 889 for (i = 0; i < words.len; i++) { 890 const char *varname = words.words[i]; 891 UnexportVar(varname, what); 892 } 893 Words_Free(words); 894 895 if (what != UNEXPORT_NAMED) 896 Global_Delete(MAKE_EXPORTED); 897 } 898 899 /* 900 * This is called when .unexport[-env] is seen. 901 * 902 * str must have the form "unexport[-env] varname...". 903 */ 904 void 905 Var_UnExport(bool isEnv, const char *arg) 906 { 907 UnexportWhat what; 908 FStr varnames; 909 910 GetVarnamesToUnexport(isEnv, arg, &varnames, &what); 911 UnexportVars(&varnames, what); 912 FStr_Done(&varnames); 913 } 914 915 /* 916 * When there is a variable of the same name in the command line scope, the 917 * global variable would not be visible anywhere. Therefore there is no 918 * point in setting it at all. 919 * 920 * See 'scope == SCOPE_CMDLINE' in Var_SetWithFlags. 921 */ 922 static bool 923 ExistsInCmdline(const char *name, const char *val) 924 { 925 Var *v; 926 927 v = VarFind(name, SCOPE_CMDLINE, false); 928 if (v == NULL) 929 return false; 930 931 if (v->fromCmd) { 932 DEBUG3(VAR, "%s: %s = %s ignored!\n", 933 SCOPE_GLOBAL->name, name, val); 934 return true; 935 } 936 937 VarFreeEnv(v); 938 return false; 939 } 940 941 /* Set the variable to the value; the name is not expanded. */ 942 void 943 Var_SetWithFlags(GNode *scope, const char *name, const char *val, 944 VarSetFlags flags) 945 { 946 Var *v; 947 948 assert(val != NULL); 949 if (name[0] == '\0') { 950 DEBUG0(VAR, "SetVar: variable name is empty - ignored\n"); 951 return; 952 } 953 954 if (scope == SCOPE_GLOBAL && ExistsInCmdline(name, val)) 955 return; 956 957 /* 958 * Only look for a variable in the given scope since anything set 959 * here will override anything in a lower scope, so there's not much 960 * point in searching them all. 961 */ 962 v = VarFind(name, scope, false); 963 if (v == NULL) { 964 if (scope == SCOPE_CMDLINE && !(flags & VAR_SET_NO_EXPORT)) { 965 /* 966 * This var would normally prevent the same name being 967 * added to SCOPE_GLOBAL, so delete it from there if 968 * needed. Otherwise -V name may show the wrong value. 969 * 970 * See ExistsInCmdline. 971 */ 972 Var_Delete(SCOPE_GLOBAL, name); 973 } 974 v = VarAdd(name, val, scope, flags); 975 } else { 976 if (v->readOnly && !(flags & VAR_SET_READONLY)) { 977 DEBUG3(VAR, "%s: %s = %s ignored (read-only)\n", 978 scope->name, name, val); 979 return; 980 } 981 Buf_Empty(&v->val); 982 Buf_AddStr(&v->val, val); 983 984 DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, val); 985 if (v->exported) 986 ExportVar(name, VEM_PLAIN); 987 } 988 989 /* 990 * Any variables given on the command line are automatically exported 991 * to the environment (as per POSIX standard), except for internals. 992 */ 993 if (scope == SCOPE_CMDLINE && !(flags & VAR_SET_NO_EXPORT) && 994 name[0] != '.') { 995 v->fromCmd = true; 996 997 /* 998 * If requested, don't export these in the environment 999 * individually. We still put them in MAKEOVERRIDES so 1000 * that the command-line settings continue to override 1001 * Makefile settings. 1002 */ 1003 if (!opts.varNoExportEnv) 1004 setenv(name, val, 1); 1005 /* XXX: What about .MAKE.EXPORTED? */ 1006 /* XXX: Why not just mark the variable for needing export, 1007 * as in ExportVarPlain? */ 1008 1009 Global_Append(MAKEOVERRIDES, name); 1010 } 1011 1012 if (name[0] == '.' && strcmp(name, MAKE_SAVE_DOLLARS) == 0) 1013 save_dollars = ParseBoolean(val, save_dollars); 1014 1015 if (v != NULL) 1016 VarFreeEnv(v); 1017 } 1018 1019 /* See Var_Set for documentation. */ 1020 void 1021 Var_SetExpandWithFlags(GNode *scope, const char *name, const char *val, 1022 VarSetFlags flags) 1023 { 1024 const char *unexpanded_name = name; 1025 FStr varname = FStr_InitRefer(name); 1026 1027 assert(val != NULL); 1028 1029 if (strchr(varname.str, '$') != NULL) { 1030 char *expanded; 1031 (void)Var_Subst(varname.str, scope, VARE_WANTRES, &expanded); 1032 /* TODO: handle errors */ 1033 varname = FStr_InitOwn(expanded); 1034 } 1035 1036 if (varname.str[0] == '\0') { 1037 DEBUG2(VAR, 1038 "Var_SetExpand: variable name \"%s\" expands " 1039 "to empty string, with value \"%s\" - ignored\n", 1040 unexpanded_name, val); 1041 } else 1042 Var_SetWithFlags(scope, varname.str, val, flags); 1043 1044 FStr_Done(&varname); 1045 } 1046 1047 void 1048 Var_Set(GNode *scope, const char *name, const char *val) 1049 { 1050 Var_SetWithFlags(scope, name, val, VAR_SET_NONE); 1051 } 1052 1053 /* 1054 * Set the variable name to the value val in the given scope. 1055 * 1056 * If the variable doesn't yet exist, it is created. 1057 * Otherwise the new value overwrites and replaces the old value. 1058 * 1059 * Input: 1060 * name name of the variable to set, is expanded once 1061 * val value to give to the variable 1062 * scope scope in which to set it 1063 */ 1064 void 1065 Var_SetExpand(GNode *scope, const char *name, const char *val) 1066 { 1067 Var_SetExpandWithFlags(scope, name, val, VAR_SET_NONE); 1068 } 1069 1070 void 1071 Global_Set(const char *name, const char *value) 1072 { 1073 Var_Set(SCOPE_GLOBAL, name, value); 1074 } 1075 1076 void 1077 Global_SetExpand(const char *name, const char *value) 1078 { 1079 Var_SetExpand(SCOPE_GLOBAL, name, value); 1080 } 1081 1082 void 1083 Global_Delete(const char *name) 1084 { 1085 Var_Delete(SCOPE_GLOBAL, name); 1086 } 1087 1088 /* 1089 * Append the value to the named variable. 1090 * 1091 * If the variable doesn't exist, it is created. Otherwise a single space 1092 * and the given value are appended. 1093 */ 1094 void 1095 Var_Append(GNode *scope, const char *name, const char *val) 1096 { 1097 Var *v; 1098 1099 v = VarFind(name, scope, scope == SCOPE_GLOBAL); 1100 1101 if (v == NULL) { 1102 Var_SetWithFlags(scope, name, val, VAR_SET_NONE); 1103 } else if (v->readOnly) { 1104 DEBUG1(VAR, "Ignoring append to %s since it is read-only\n", 1105 name); 1106 } else if (scope == SCOPE_CMDLINE || !v->fromCmd) { 1107 Buf_AddByte(&v->val, ' '); 1108 Buf_AddStr(&v->val, val); 1109 1110 DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, v->val.data); 1111 1112 if (v->fromEnv) { 1113 /* 1114 * If the original variable came from the environment, 1115 * we have to install it in the global scope (we 1116 * could place it in the environment, but then we 1117 * should provide a way to export other variables...) 1118 */ 1119 v->fromEnv = false; 1120 /* 1121 * This is the only place where a variable is 1122 * created whose v->name is not the same as 1123 * scope->vars->key. 1124 */ 1125 HashTable_Set(&scope->vars, name, v); 1126 } 1127 } 1128 } 1129 1130 /* 1131 * The variable of the given name has the given value appended to it in the 1132 * given scope. 1133 * 1134 * If the variable doesn't exist, it is created. Otherwise the strings are 1135 * concatenated, with a space in between. 1136 * 1137 * Input: 1138 * name name of the variable to modify, is expanded once 1139 * val string to append to it 1140 * scope scope in which this should occur 1141 * 1142 * Notes: 1143 * Only if the variable is being sought in the global scope is the 1144 * environment searched. 1145 * XXX: Knows its calling circumstances in that if called with scope 1146 * an actual target, it will only search that scope since only 1147 * a local variable could be being appended to. This is actually 1148 * a big win and must be tolerated. 1149 */ 1150 void 1151 Var_AppendExpand(GNode *scope, const char *name, const char *val) 1152 { 1153 FStr xname = FStr_InitRefer(name); 1154 1155 assert(val != NULL); 1156 1157 if (strchr(name, '$') != NULL) { 1158 char *expanded; 1159 (void)Var_Subst(name, scope, VARE_WANTRES, &expanded); 1160 /* TODO: handle errors */ 1161 xname = FStr_InitOwn(expanded); 1162 if (expanded[0] == '\0') { 1163 DEBUG2(VAR, 1164 "Var_AppendExpand: variable name \"%s\" expands " 1165 "to empty string, with value \"%s\" - ignored\n", 1166 name, val); 1167 FStr_Done(&xname); 1168 return; 1169 } 1170 } 1171 1172 Var_Append(scope, xname.str, val); 1173 1174 FStr_Done(&xname); 1175 } 1176 1177 void 1178 Global_Append(const char *name, const char *value) 1179 { 1180 Var_Append(SCOPE_GLOBAL, name, value); 1181 } 1182 1183 bool 1184 Var_Exists(GNode *scope, const char *name) 1185 { 1186 Var *v = VarFind(name, scope, true); 1187 if (v == NULL) 1188 return false; 1189 1190 VarFreeEnv(v); 1191 return true; 1192 } 1193 1194 /* 1195 * See if the given variable exists, in the given scope or in other 1196 * fallback scopes. 1197 * 1198 * Input: 1199 * name Variable to find, is expanded once 1200 * scope Scope in which to start search 1201 */ 1202 bool 1203 Var_ExistsExpand(GNode *scope, const char *name) 1204 { 1205 FStr varname = FStr_InitRefer(name); 1206 bool exists; 1207 1208 if (strchr(varname.str, '$') != NULL) { 1209 char *expanded; 1210 (void)Var_Subst(varname.str, scope, VARE_WANTRES, &expanded); 1211 /* TODO: handle errors */ 1212 varname = FStr_InitOwn(expanded); 1213 } 1214 1215 exists = Var_Exists(scope, varname.str); 1216 FStr_Done(&varname); 1217 return exists; 1218 } 1219 1220 /* 1221 * Return the unexpanded value of the given variable in the given scope, 1222 * or the usual scopes. 1223 * 1224 * Input: 1225 * name name to find, is not expanded any further 1226 * scope scope in which to search for it 1227 * 1228 * Results: 1229 * The value if the variable exists, NULL if it doesn't. 1230 * The value is valid until the next modification to any variable. 1231 */ 1232 FStr 1233 Var_Value(GNode *scope, const char *name) 1234 { 1235 Var *v = VarFind(name, scope, true); 1236 char *value; 1237 1238 if (v == NULL) 1239 return FStr_InitRefer(NULL); 1240 1241 if (!v->fromEnv) 1242 return FStr_InitRefer(v->val.data); 1243 1244 /* Since environment variables are short-lived, free it now. */ 1245 FStr_Done(&v->name); 1246 value = Buf_DoneData(&v->val); 1247 free(v); 1248 return FStr_InitOwn(value); 1249 } 1250 1251 /* 1252 * Return the unexpanded variable value from this node, without trying to look 1253 * up the variable in any other scope. 1254 */ 1255 const char * 1256 GNode_ValueDirect(GNode *gn, const char *name) 1257 { 1258 Var *v = VarFind(name, gn, false); 1259 return v != NULL ? v->val.data : NULL; 1260 } 1261 1262 static VarEvalMode 1263 VarEvalMode_WithoutKeepDollar(VarEvalMode emode) 1264 { 1265 if (emode == VARE_KEEP_DOLLAR_UNDEF) 1266 return VARE_EVAL_KEEP_UNDEF; 1267 if (emode == VARE_EVAL_KEEP_DOLLAR) 1268 return VARE_WANTRES; 1269 return emode; 1270 } 1271 1272 static VarEvalMode 1273 VarEvalMode_UndefOk(VarEvalMode emode) 1274 { 1275 return emode == VARE_UNDEFERR ? VARE_WANTRES : emode; 1276 } 1277 1278 static bool 1279 VarEvalMode_ShouldEval(VarEvalMode emode) 1280 { 1281 return emode != VARE_PARSE_ONLY; 1282 } 1283 1284 static bool 1285 VarEvalMode_ShouldKeepUndef(VarEvalMode emode) 1286 { 1287 return emode == VARE_EVAL_KEEP_UNDEF || 1288 emode == VARE_KEEP_DOLLAR_UNDEF; 1289 } 1290 1291 static bool 1292 VarEvalMode_ShouldKeepDollar(VarEvalMode emode) 1293 { 1294 return emode == VARE_EVAL_KEEP_DOLLAR || 1295 emode == VARE_KEEP_DOLLAR_UNDEF; 1296 } 1297 1298 1299 static void 1300 SepBuf_Init(SepBuf *buf, char sep) 1301 { 1302 Buf_InitSize(&buf->buf, 32); 1303 buf->needSep = false; 1304 buf->sep = sep; 1305 } 1306 1307 static void 1308 SepBuf_Sep(SepBuf *buf) 1309 { 1310 buf->needSep = true; 1311 } 1312 1313 static void 1314 SepBuf_AddBytes(SepBuf *buf, const char *mem, size_t mem_size) 1315 { 1316 if (mem_size == 0) 1317 return; 1318 if (buf->needSep && buf->sep != '\0') { 1319 Buf_AddByte(&buf->buf, buf->sep); 1320 buf->needSep = false; 1321 } 1322 Buf_AddBytes(&buf->buf, mem, mem_size); 1323 } 1324 1325 static void 1326 SepBuf_AddBytesBetween(SepBuf *buf, const char *start, const char *end) 1327 { 1328 SepBuf_AddBytes(buf, start, (size_t)(end - start)); 1329 } 1330 1331 static void 1332 SepBuf_AddStr(SepBuf *buf, const char *str) 1333 { 1334 SepBuf_AddBytes(buf, str, strlen(str)); 1335 } 1336 1337 static void 1338 SepBuf_AddSubstring(SepBuf *buf, Substring sub) 1339 { 1340 SepBuf_AddBytesBetween(buf, sub.start, sub.end); 1341 } 1342 1343 static char * 1344 SepBuf_DoneData(SepBuf *buf) 1345 { 1346 return Buf_DoneData(&buf->buf); 1347 } 1348 1349 1350 /* 1351 * This callback for ModifyWords gets a single word from a variable expression 1352 * and typically adds a modification of this word to the buffer. It may also 1353 * do nothing or add several words. 1354 * 1355 * For example, when evaluating the modifier ':M*b' in ${:Ua b c:M*b}, the 1356 * callback is called 3 times, once for "a", "b" and "c". 1357 * 1358 * Some ModifyWord functions assume that they are always passed a 1359 * null-terminated substring, which is currently guaranteed but may change in 1360 * the future. 1361 */ 1362 typedef void (*ModifyWordProc)(Substring word, SepBuf *buf, void *data); 1363 1364 1365 /* 1366 * Callback for ModifyWords to implement the :H modifier. 1367 * Add the dirname of the given word to the buffer. 1368 */ 1369 /*ARGSUSED*/ 1370 static void 1371 ModifyWord_Head(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED) 1372 { 1373 SepBuf_AddSubstring(buf, Substring_Dirname(word)); 1374 } 1375 1376 /* 1377 * Callback for ModifyWords to implement the :T modifier. 1378 * Add the basename of the given word to the buffer. 1379 */ 1380 /*ARGSUSED*/ 1381 static void 1382 ModifyWord_Tail(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED) 1383 { 1384 SepBuf_AddSubstring(buf, Substring_Basename(word)); 1385 } 1386 1387 /* 1388 * Callback for ModifyWords to implement the :E modifier. 1389 * Add the filename suffix of the given word to the buffer, if it exists. 1390 */ 1391 /*ARGSUSED*/ 1392 static void 1393 ModifyWord_Suffix(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED) 1394 { 1395 const char *lastDot = Substring_LastIndex(word, '.'); 1396 if (lastDot != NULL) 1397 SepBuf_AddBytesBetween(buf, lastDot + 1, word.end); 1398 } 1399 1400 /* 1401 * Callback for ModifyWords to implement the :R modifier. 1402 * Add the filename without extension of the given word to the buffer. 1403 */ 1404 /*ARGSUSED*/ 1405 static void 1406 ModifyWord_Root(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED) 1407 { 1408 const char *lastDot, *end; 1409 1410 lastDot = Substring_LastIndex(word, '.'); 1411 end = lastDot != NULL ? lastDot : word.end; 1412 SepBuf_AddBytesBetween(buf, word.start, end); 1413 } 1414 1415 /* 1416 * Callback for ModifyWords to implement the :M modifier. 1417 * Place the word in the buffer if it matches the given pattern. 1418 */ 1419 static void 1420 ModifyWord_Match(Substring word, SepBuf *buf, void *data) 1421 { 1422 const char *pattern = data; 1423 1424 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1425 if (Str_Match(word.start, pattern)) 1426 SepBuf_AddSubstring(buf, word); 1427 } 1428 1429 /* 1430 * Callback for ModifyWords to implement the :N modifier. 1431 * Place the word in the buffer if it doesn't match the given pattern. 1432 */ 1433 static void 1434 ModifyWord_NoMatch(Substring word, SepBuf *buf, void *data) 1435 { 1436 const char *pattern = data; 1437 1438 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1439 if (!Str_Match(word.start, pattern)) 1440 SepBuf_AddSubstring(buf, word); 1441 } 1442 1443 #ifdef SYSVVARSUB 1444 struct ModifyWord_SysVSubstArgs { 1445 GNode *scope; 1446 Substring lhsPrefix; 1447 bool lhsPercent; 1448 Substring lhsSuffix; 1449 const char *rhs; 1450 }; 1451 1452 /* Callback for ModifyWords to implement the :%.from=%.to modifier. */ 1453 static void 1454 ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data) 1455 { 1456 const struct ModifyWord_SysVSubstArgs *args = data; 1457 FStr rhs; 1458 char *rhsExp; 1459 const char *percent; 1460 1461 if (Substring_IsEmpty(word)) 1462 return; 1463 1464 if (!Substring_HasPrefix(word, args->lhsPrefix)) 1465 goto no_match; 1466 if (!Substring_HasSuffix(word, args->lhsSuffix)) 1467 goto no_match; 1468 1469 rhs = FStr_InitRefer(args->rhs); 1470 if (strchr(rhs.str, '$') != NULL) { 1471 (void)Var_Subst(args->rhs, args->scope, VARE_WANTRES, &rhsExp); 1472 /* TODO: handle errors */ 1473 rhs = FStr_InitOwn(rhsExp); 1474 } 1475 1476 percent = args->lhsPercent ? strchr(rhs.str, '%') : NULL; 1477 1478 if (percent != NULL) 1479 SepBuf_AddBytesBetween(buf, rhs.str, percent); 1480 if (percent != NULL || !args->lhsPercent) 1481 SepBuf_AddBytesBetween(buf, 1482 word.start + Substring_Length(args->lhsPrefix), 1483 word.end - Substring_Length(args->lhsSuffix)); 1484 SepBuf_AddStr(buf, percent != NULL ? percent + 1 : rhs.str); 1485 1486 FStr_Done(&rhs); 1487 return; 1488 1489 no_match: 1490 SepBuf_AddSubstring(buf, word); 1491 } 1492 #endif 1493 1494 1495 struct ModifyWord_SubstArgs { 1496 Substring lhs; 1497 Substring rhs; 1498 PatternFlags pflags; 1499 bool matched; 1500 }; 1501 1502 static const char * 1503 Substring_Find(Substring haystack, Substring needle) 1504 { 1505 size_t len, needleLen, i; 1506 1507 len = Substring_Length(haystack); 1508 needleLen = Substring_Length(needle); 1509 for (i = 0; i + needleLen <= len; i++) 1510 if (memcmp(haystack.start + i, needle.start, needleLen) == 0) 1511 return haystack.start + i; 1512 return NULL; 1513 } 1514 1515 /* 1516 * Callback for ModifyWords to implement the :S,from,to, modifier. 1517 * Perform a string substitution on the given word. 1518 */ 1519 static void 1520 ModifyWord_Subst(Substring word, SepBuf *buf, void *data) 1521 { 1522 struct ModifyWord_SubstArgs *args = data; 1523 size_t wordLen, lhsLen; 1524 const char *wordEnd, *match; 1525 1526 wordLen = Substring_Length(word); 1527 wordEnd = word.end; 1528 if (args->pflags.subOnce && args->matched) 1529 goto nosub; 1530 1531 lhsLen = Substring_Length(args->lhs); 1532 if (args->pflags.anchorStart) { 1533 if (wordLen < lhsLen || 1534 memcmp(word.start, args->lhs.start, lhsLen) != 0) 1535 goto nosub; 1536 1537 if (args->pflags.anchorEnd && wordLen != lhsLen) 1538 goto nosub; 1539 1540 /* :S,^prefix,replacement, or :S,^whole$,replacement, */ 1541 SepBuf_AddSubstring(buf, args->rhs); 1542 SepBuf_AddBytesBetween(buf, word.start + lhsLen, wordEnd); 1543 args->matched = true; 1544 return; 1545 } 1546 1547 if (args->pflags.anchorEnd) { 1548 if (wordLen < lhsLen) 1549 goto nosub; 1550 if (memcmp(wordEnd - lhsLen, args->lhs.start, lhsLen) != 0) 1551 goto nosub; 1552 1553 /* :S,suffix$,replacement, */ 1554 SepBuf_AddBytesBetween(buf, word.start, wordEnd - lhsLen); 1555 SepBuf_AddSubstring(buf, args->rhs); 1556 args->matched = true; 1557 return; 1558 } 1559 1560 if (Substring_IsEmpty(args->lhs)) 1561 goto nosub; 1562 1563 /* unanchored case, may match more than once */ 1564 while ((match = Substring_Find(word, args->lhs)) != NULL) { 1565 SepBuf_AddBytesBetween(buf, word.start, match); 1566 SepBuf_AddSubstring(buf, args->rhs); 1567 args->matched = true; 1568 word.start = match + lhsLen; 1569 if (Substring_IsEmpty(word) || !args->pflags.subGlobal) 1570 break; 1571 } 1572 nosub: 1573 SepBuf_AddSubstring(buf, word); 1574 } 1575 1576 #ifndef NO_REGEX 1577 /* Print the error caused by a regcomp or regexec call. */ 1578 static void 1579 VarREError(int reerr, const regex_t *pat, const char *str) 1580 { 1581 size_t errlen = regerror(reerr, pat, NULL, 0); 1582 char *errbuf = bmake_malloc(errlen); 1583 regerror(reerr, pat, errbuf, errlen); 1584 Error("%s: %s", str, errbuf); 1585 free(errbuf); 1586 } 1587 1588 struct ModifyWord_SubstRegexArgs { 1589 regex_t re; 1590 size_t nsub; 1591 const char *replace; 1592 PatternFlags pflags; 1593 bool matched; 1594 }; 1595 1596 /* 1597 * Callback for ModifyWords to implement the :C/from/to/ modifier. 1598 * Perform a regex substitution on the given word. 1599 */ 1600 static void 1601 ModifyWord_SubstRegex(Substring word, SepBuf *buf, void *data) 1602 { 1603 struct ModifyWord_SubstRegexArgs *args = data; 1604 int xrv; 1605 const char *wp; 1606 const char *rp; 1607 int flags = 0; 1608 regmatch_t m[10]; 1609 1610 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1611 wp = word.start; 1612 if (args->pflags.subOnce && args->matched) 1613 goto nosub; 1614 1615 tryagain: 1616 xrv = regexec(&args->re, wp, args->nsub, m, flags); 1617 1618 switch (xrv) { 1619 case 0: 1620 args->matched = true; 1621 SepBuf_AddBytes(buf, wp, (size_t)m[0].rm_so); 1622 1623 /* 1624 * Replacement of regular expressions is not specified by 1625 * POSIX, therefore implement it here. 1626 */ 1627 1628 for (rp = args->replace; *rp != '\0'; rp++) { 1629 if (*rp == '\\' && (rp[1] == '&' || rp[1] == '\\')) { 1630 SepBuf_AddBytes(buf, rp + 1, 1); 1631 rp++; 1632 continue; 1633 } 1634 1635 if (*rp == '&') { 1636 SepBuf_AddBytesBetween(buf, 1637 wp + m[0].rm_so, wp + m[0].rm_eo); 1638 continue; 1639 } 1640 1641 if (*rp != '\\' || !ch_isdigit(rp[1])) { 1642 SepBuf_AddBytes(buf, rp, 1); 1643 continue; 1644 } 1645 1646 { /* \0 to \9 backreference */ 1647 size_t n = (size_t)(rp[1] - '0'); 1648 rp++; 1649 1650 if (n >= args->nsub) { 1651 Error("No subexpression \\%u", 1652 (unsigned)n); 1653 } else if (m[n].rm_so == -1) { 1654 Error( 1655 "No match for subexpression \\%u", 1656 (unsigned)n); 1657 } else { 1658 SepBuf_AddBytesBetween(buf, 1659 wp + m[n].rm_so, wp + m[n].rm_eo); 1660 } 1661 } 1662 } 1663 1664 wp += m[0].rm_eo; 1665 if (args->pflags.subGlobal) { 1666 flags |= REG_NOTBOL; 1667 if (m[0].rm_so == 0 && m[0].rm_eo == 0) { 1668 SepBuf_AddBytes(buf, wp, 1); 1669 wp++; 1670 } 1671 if (*wp != '\0') 1672 goto tryagain; 1673 } 1674 if (*wp != '\0') 1675 SepBuf_AddStr(buf, wp); 1676 break; 1677 default: 1678 VarREError(xrv, &args->re, "Unexpected regex error"); 1679 /* FALLTHROUGH */ 1680 case REG_NOMATCH: 1681 nosub: 1682 SepBuf_AddStr(buf, wp); 1683 break; 1684 } 1685 } 1686 #endif 1687 1688 1689 struct ModifyWord_LoopArgs { 1690 GNode *scope; 1691 const char *var; /* name of the temporary variable */ 1692 const char *body; /* string to expand */ 1693 VarEvalMode emode; 1694 }; 1695 1696 /* Callback for ModifyWords to implement the :@var@...@ modifier of ODE make. */ 1697 static void 1698 ModifyWord_Loop(Substring word, SepBuf *buf, void *data) 1699 { 1700 const struct ModifyWord_LoopArgs *args; 1701 char *s; 1702 1703 if (Substring_IsEmpty(word)) 1704 return; 1705 1706 args = data; 1707 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1708 Var_SetWithFlags(args->scope, args->var, word.start, 1709 VAR_SET_NO_EXPORT); 1710 (void)Var_Subst(args->body, args->scope, args->emode, &s); 1711 /* TODO: handle errors */ 1712 1713 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1714 DEBUG4(VAR, "ModifyWord_Loop: " 1715 "in \"%s\", replace \"%s\" with \"%s\" to \"%s\"\n", 1716 word.start, args->var, args->body, s); 1717 1718 if (s[0] == '\n' || Buf_EndsWith(&buf->buf, '\n')) 1719 buf->needSep = false; 1720 SepBuf_AddStr(buf, s); 1721 free(s); 1722 } 1723 1724 1725 /* 1726 * The :[first..last] modifier selects words from the expression. 1727 * It can also reverse the words. 1728 */ 1729 static char * 1730 VarSelectWords(const char *str, int first, int last, 1731 char sep, bool oneBigWord) 1732 { 1733 Words words; 1734 int len, start, end, step; 1735 int i; 1736 1737 SepBuf buf; 1738 SepBuf_Init(&buf, sep); 1739 1740 if (oneBigWord) { 1741 /* fake what Str_Words() would do if there were only one word */ 1742 words.len = 1; 1743 words.words = bmake_malloc( 1744 (words.len + 1) * sizeof(words.words[0])); 1745 words.freeIt = bmake_strdup(str); 1746 words.words[0] = words.freeIt; 1747 words.words[1] = NULL; 1748 } else { 1749 words = Str_Words(str, false); 1750 } 1751 1752 /* 1753 * Now sanitize the given range. If first or last are negative, 1754 * convert them to the positive equivalents (-1 gets converted to len, 1755 * -2 gets converted to (len - 1), etc.). 1756 */ 1757 len = (int)words.len; 1758 if (first < 0) 1759 first += len + 1; 1760 if (last < 0) 1761 last += len + 1; 1762 1763 /* We avoid scanning more of the list than we need to. */ 1764 if (first > last) { 1765 start = (first > len ? len : first) - 1; 1766 end = last < 1 ? 0 : last - 1; 1767 step = -1; 1768 } else { 1769 start = first < 1 ? 0 : first - 1; 1770 end = last > len ? len : last; 1771 step = 1; 1772 } 1773 1774 for (i = start; (step < 0) == (i >= end); i += step) { 1775 SepBuf_AddStr(&buf, words.words[i]); 1776 SepBuf_Sep(&buf); 1777 } 1778 1779 Words_Free(words); 1780 1781 return SepBuf_DoneData(&buf); 1782 } 1783 1784 1785 /* 1786 * Callback for ModifyWords to implement the :tA modifier. 1787 * Replace each word with the result of realpath() if successful. 1788 */ 1789 /*ARGSUSED*/ 1790 static void 1791 ModifyWord_Realpath(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 1792 { 1793 struct stat st; 1794 char rbuf[MAXPATHLEN]; 1795 const char *rp; 1796 1797 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1798 rp = cached_realpath(word.start, rbuf); 1799 if (rp != NULL && *rp == '/' && stat(rp, &st) == 0) 1800 SepBuf_AddStr(buf, rp); 1801 else 1802 SepBuf_AddSubstring(buf, word); 1803 } 1804 1805 1806 static char * 1807 Words_JoinFree(Words words) 1808 { 1809 Buffer buf; 1810 size_t i; 1811 1812 Buf_Init(&buf); 1813 1814 for (i = 0; i < words.len; i++) { 1815 if (i != 0) { 1816 /* XXX: Use ch->sep instead of ' ', for consistency. */ 1817 Buf_AddByte(&buf, ' '); 1818 } 1819 Buf_AddStr(&buf, words.words[i]); 1820 } 1821 1822 Words_Free(words); 1823 1824 return Buf_DoneData(&buf); 1825 } 1826 1827 /* Remove adjacent duplicate words. */ 1828 static char * 1829 VarUniq(const char *str) 1830 { 1831 Words words = Str_Words(str, false); 1832 1833 if (words.len > 1) { 1834 size_t i, j; 1835 for (j = 0, i = 1; i < words.len; i++) 1836 if (strcmp(words.words[i], words.words[j]) != 0 && 1837 (++j != i)) 1838 words.words[j] = words.words[i]; 1839 words.len = j + 1; 1840 } 1841 1842 return Words_JoinFree(words); 1843 } 1844 1845 1846 /* 1847 * Quote shell meta-characters and space characters in the string. 1848 * If quoteDollar is set, also quote and double any '$' characters. 1849 */ 1850 static void 1851 VarQuote(const char *str, bool quoteDollar, LazyBuf *buf) 1852 { 1853 const char *p; 1854 1855 LazyBuf_Init(buf, str); 1856 for (p = str; *p != '\0'; p++) { 1857 if (*p == '\n') { 1858 const char *newline = Shell_GetNewline(); 1859 if (newline == NULL) 1860 newline = "\\\n"; 1861 LazyBuf_AddStr(buf, newline); 1862 continue; 1863 } 1864 if (ch_isspace(*p) || is_shell_metachar((unsigned char)*p)) 1865 LazyBuf_Add(buf, '\\'); 1866 LazyBuf_Add(buf, *p); 1867 if (quoteDollar && *p == '$') 1868 LazyBuf_AddStr(buf, "\\$"); 1869 } 1870 } 1871 1872 /* 1873 * Compute the 32-bit hash of the given string, using the MurmurHash3 1874 * algorithm. Output is encoded as 8 hex digits, in Little Endian order. 1875 */ 1876 static char * 1877 VarHash(const char *str) 1878 { 1879 static const char hexdigits[16] = "0123456789abcdef"; 1880 const unsigned char *ustr = (const unsigned char *)str; 1881 1882 uint32_t h = 0x971e137bU; 1883 uint32_t c1 = 0x95543787U; 1884 uint32_t c2 = 0x2ad7eb25U; 1885 size_t len2 = strlen(str); 1886 1887 char *buf; 1888 size_t i; 1889 1890 size_t len; 1891 for (len = len2; len != 0;) { 1892 uint32_t k = 0; 1893 switch (len) { 1894 default: 1895 k = ((uint32_t)ustr[3] << 24) | 1896 ((uint32_t)ustr[2] << 16) | 1897 ((uint32_t)ustr[1] << 8) | 1898 (uint32_t)ustr[0]; 1899 len -= 4; 1900 ustr += 4; 1901 break; 1902 case 3: 1903 k |= (uint32_t)ustr[2] << 16; 1904 /* FALLTHROUGH */ 1905 case 2: 1906 k |= (uint32_t)ustr[1] << 8; 1907 /* FALLTHROUGH */ 1908 case 1: 1909 k |= (uint32_t)ustr[0]; 1910 len = 0; 1911 } 1912 c1 = c1 * 5 + 0x7b7d159cU; 1913 c2 = c2 * 5 + 0x6bce6396U; 1914 k *= c1; 1915 k = (k << 11) ^ (k >> 21); 1916 k *= c2; 1917 h = (h << 13) ^ (h >> 19); 1918 h = h * 5 + 0x52dce729U; 1919 h ^= k; 1920 } 1921 h ^= (uint32_t)len2; 1922 h *= 0x85ebca6b; 1923 h ^= h >> 13; 1924 h *= 0xc2b2ae35; 1925 h ^= h >> 16; 1926 1927 buf = bmake_malloc(9); 1928 for (i = 0; i < 8; i++) { 1929 buf[i] = hexdigits[h & 0x0f]; 1930 h >>= 4; 1931 } 1932 buf[8] = '\0'; 1933 return buf; 1934 } 1935 1936 static char * 1937 VarStrftime(const char *fmt, bool zulu, time_t tim) 1938 { 1939 char buf[BUFSIZ]; 1940 1941 if (tim == 0) 1942 time(&tim); 1943 if (*fmt == '\0') 1944 fmt = "%c"; 1945 strftime(buf, sizeof buf, fmt, zulu ? gmtime(&tim) : localtime(&tim)); 1946 1947 buf[sizeof buf - 1] = '\0'; 1948 return bmake_strdup(buf); 1949 } 1950 1951 /* 1952 * The ApplyModifier functions take an expression that is being evaluated. 1953 * Their task is to apply a single modifier to the expression. This involves 1954 * parsing the modifier, evaluating it and finally updating the value of the 1955 * expression. 1956 * 1957 * Parsing the modifier 1958 * 1959 * If parsing succeeds, the parsing position *pp is updated to point to the 1960 * first character following the modifier, which typically is either ':' or 1961 * ch->endc. The modifier doesn't have to check for this delimiter character, 1962 * this is done by ApplyModifiers. 1963 * 1964 * XXX: As of 2020-11-15, some modifiers such as :S, :C, :P, :L do not 1965 * need to be followed by a ':' or endc; this was an unintended mistake. 1966 * 1967 * If parsing fails because of a missing delimiter (as in the :S, :C or :@ 1968 * modifiers), return AMR_CLEANUP. 1969 * 1970 * If parsing fails because the modifier is unknown, return AMR_UNKNOWN to 1971 * try the SysV modifier ${VAR:from=to} as fallback. This should only be 1972 * done as long as there have been no side effects from evaluating nested 1973 * variables, to avoid evaluating them more than once. In this case, the 1974 * parsing position may or may not be updated. (XXX: Why not? The original 1975 * parsing position is well-known in ApplyModifiers.) 1976 * 1977 * If parsing fails and the SysV modifier ${VAR:from=to} should not be used 1978 * as a fallback, either issue an error message using Error or Parse_Error 1979 * and then return AMR_CLEANUP, or return AMR_BAD for the default error 1980 * message. Both of these return values will stop processing the variable 1981 * expression. (XXX: As of 2020-08-23, evaluation of the whole string 1982 * continues nevertheless after skipping a few bytes, which essentially is 1983 * undefined behavior. Not in the sense of C, but still the resulting string 1984 * is garbage.) 1985 * 1986 * Evaluating the modifier 1987 * 1988 * After parsing, the modifier is evaluated. The side effects from evaluating 1989 * nested variable expressions in the modifier text often already happen 1990 * during parsing though. For most modifiers this doesn't matter since their 1991 * only noticeable effect is that the update the value of the expression. 1992 * Some modifiers such as ':sh' or '::=' have noticeable side effects though. 1993 * 1994 * Evaluating the modifier usually takes the current value of the variable 1995 * expression from ch->expr->value, or the variable name from ch->var->name 1996 * and stores the result back in expr->value via Expr_SetValueOwn or 1997 * Expr_SetValueRefer. 1998 * 1999 * If evaluating fails (as of 2020-08-23), an error message is printed using 2000 * Error. This function has no side-effects, it really just prints the error 2001 * message. Processing the expression continues as if everything were ok. 2002 * XXX: This should be fixed by adding proper error handling to Var_Subst, 2003 * Var_Parse, ApplyModifiers and ModifyWords. 2004 * 2005 * Housekeeping 2006 * 2007 * Some modifiers such as :D and :U turn undefined expressions into defined 2008 * expressions (see Expr_Define). 2009 * 2010 * Some modifiers need to free some memory. 2011 */ 2012 2013 typedef enum ExprDefined { 2014 /* The variable expression is based on a regular, defined variable. */ 2015 DEF_REGULAR, 2016 /* The variable expression is based on an undefined variable. */ 2017 DEF_UNDEF, 2018 /* 2019 * The variable expression started as an undefined expression, but one 2020 * of the modifiers (such as ':D' or ':U') has turned the expression 2021 * from undefined to defined. 2022 */ 2023 DEF_DEFINED 2024 } ExprDefined; 2025 2026 static const char *const ExprDefined_Name[] = { 2027 "regular", 2028 "undefined", 2029 "defined" 2030 }; 2031 2032 #if __STDC_VERSION__ >= 199901L 2033 #define const_member const 2034 #else 2035 #define const_member /* no const possible */ 2036 #endif 2037 2038 /* A variable expression such as $@ or ${VAR:Mpattern:Q}. */ 2039 typedef struct Expr { 2040 const char *name; 2041 FStr value; 2042 VarEvalMode const_member emode; 2043 GNode *const_member scope; 2044 ExprDefined defined; 2045 } Expr; 2046 2047 /* 2048 * The status of applying a chain of modifiers to an expression. 2049 * 2050 * The modifiers of an expression are broken into chains of modifiers, 2051 * starting a new nested chain whenever an indirect modifier starts. There 2052 * are at most 2 nesting levels: the outer one for the direct modifiers, and 2053 * the inner one for the indirect modifiers. 2054 * 2055 * For example, the expression ${VAR:M*:${IND1}:${IND2}:O:u} has 3 chains of 2056 * modifiers: 2057 * 2058 * Chain 1 starts with the single modifier ':M*'. 2059 * Chain 2 starts with all modifiers from ${IND1}. 2060 * Chain 2 ends at the ':' between ${IND1} and ${IND2}. 2061 * Chain 3 starts with all modifiers from ${IND2}. 2062 * Chain 3 ends at the ':' after ${IND2}. 2063 * Chain 1 continues with the the 2 modifiers ':O' and ':u'. 2064 * Chain 1 ends at the final '}' of the expression. 2065 * 2066 * After such a chain ends, its properties no longer have any effect. 2067 * 2068 * It may or may not have been intended that 'defined' has scope Expr while 2069 * 'sep' and 'oneBigWord' have smaller scope. 2070 * 2071 * See varmod-indirect.mk. 2072 */ 2073 typedef struct ModChain { 2074 Expr *expr; 2075 /* '\0' or '{' or '(' */ 2076 char const_member startc; 2077 /* '\0' or '}' or ')' */ 2078 char const_member endc; 2079 /* Word separator in expansions (see the :ts modifier). */ 2080 char sep; 2081 /* 2082 * True if some modifiers that otherwise split the variable value 2083 * into words, like :S and :C, treat the variable value as a single 2084 * big word, possibly containing spaces. 2085 */ 2086 bool oneBigWord; 2087 } ModChain; 2088 2089 static void 2090 Expr_Define(Expr *expr) 2091 { 2092 if (expr->defined == DEF_UNDEF) 2093 expr->defined = DEF_DEFINED; 2094 } 2095 2096 static void 2097 Expr_SetValue(Expr *expr, FStr value) 2098 { 2099 FStr_Done(&expr->value); 2100 expr->value = value; 2101 } 2102 2103 static void 2104 Expr_SetValueOwn(Expr *expr, char *value) 2105 { 2106 Expr_SetValue(expr, FStr_InitOwn(value)); 2107 } 2108 2109 static void 2110 Expr_SetValueRefer(Expr *expr, const char *value) 2111 { 2112 Expr_SetValue(expr, FStr_InitRefer(value)); 2113 } 2114 2115 static bool 2116 Expr_ShouldEval(const Expr *expr) 2117 { 2118 return VarEvalMode_ShouldEval(expr->emode); 2119 } 2120 2121 static bool 2122 ModChain_ShouldEval(const ModChain *ch) 2123 { 2124 return Expr_ShouldEval(ch->expr); 2125 } 2126 2127 2128 typedef enum ApplyModifierResult { 2129 /* Continue parsing */ 2130 AMR_OK, 2131 /* Not a match, try other modifiers as well. */ 2132 AMR_UNKNOWN, 2133 /* Error out with "Bad modifier" message. */ 2134 AMR_BAD, 2135 /* Error out without the standard error message. */ 2136 AMR_CLEANUP 2137 } ApplyModifierResult; 2138 2139 /* 2140 * Allow backslashes to escape the delimiter, $, and \, but don't touch other 2141 * backslashes. 2142 */ 2143 static bool 2144 IsEscapedModifierPart(const char *p, char delim, 2145 struct ModifyWord_SubstArgs *subst) 2146 { 2147 if (p[0] != '\\') 2148 return false; 2149 if (p[1] == delim || p[1] == '\\' || p[1] == '$') 2150 return true; 2151 return p[1] == '&' && subst != NULL; 2152 } 2153 2154 /* See ParseModifierPart */ 2155 static VarParseResult 2156 ParseModifierPartSubst( 2157 const char **pp, 2158 char delim, 2159 VarEvalMode emode, 2160 ModChain *ch, 2161 LazyBuf *part, 2162 /* For the first part of the :S modifier, sets the VARP_ANCHOR_END flag 2163 * if the last character of the pattern is a $. */ 2164 PatternFlags *out_pflags, 2165 /* For the second part of the :S modifier, allow ampersands to be 2166 * escaped and replace unescaped ampersands with subst->lhs. */ 2167 struct ModifyWord_SubstArgs *subst 2168 ) 2169 { 2170 const char *p; 2171 2172 p = *pp; 2173 LazyBuf_Init(part, p); 2174 2175 /* 2176 * Skim through until the matching delimiter is found; pick up 2177 * variable expressions on the way. 2178 */ 2179 while (*p != '\0' && *p != delim) { 2180 const char *varstart; 2181 2182 if (IsEscapedModifierPart(p, delim, subst)) { 2183 LazyBuf_Add(part, p[1]); 2184 p += 2; 2185 continue; 2186 } 2187 2188 if (*p != '$') { /* Unescaped, simple text */ 2189 if (subst != NULL && *p == '&') 2190 LazyBuf_AddSubstring(part, subst->lhs); 2191 else 2192 LazyBuf_Add(part, *p); 2193 p++; 2194 continue; 2195 } 2196 2197 if (p[1] == delim) { /* Unescaped $ at end of pattern */ 2198 if (out_pflags != NULL) 2199 out_pflags->anchorEnd = true; 2200 else 2201 LazyBuf_Add(part, *p); 2202 p++; 2203 continue; 2204 } 2205 2206 if (VarEvalMode_ShouldEval(emode)) { 2207 /* Nested variable, evaluated */ 2208 const char *nested_p = p; 2209 FStr nested_val; 2210 2211 (void)Var_Parse(&nested_p, ch->expr->scope, 2212 VarEvalMode_WithoutKeepDollar(emode), &nested_val); 2213 /* TODO: handle errors */ 2214 LazyBuf_AddStr(part, nested_val.str); 2215 FStr_Done(&nested_val); 2216 p += nested_p - p; 2217 continue; 2218 } 2219 2220 /* 2221 * XXX: This whole block is very similar to Var_Parse without 2222 * VARE_WANTRES. There may be subtle edge cases 2223 * though that are not yet covered in the unit tests and that 2224 * are parsed differently, depending on whether they are 2225 * evaluated or not. 2226 * 2227 * This subtle difference is not documented in the manual 2228 * page, neither is the difference between parsing :D and 2229 * :M documented. No code should ever depend on these 2230 * details, but who knows. 2231 */ 2232 2233 varstart = p; /* Nested variable, only parsed */ 2234 if (p[1] == '(' || p[1] == '{') { 2235 /* 2236 * Find the end of this variable reference 2237 * and suck it in without further ado. 2238 * It will be interpreted later. 2239 */ 2240 char startc = p[1]; 2241 int endc = startc == '(' ? ')' : '}'; 2242 int depth = 1; 2243 2244 for (p += 2; *p != '\0' && depth > 0; p++) { 2245 if (p[-1] != '\\') { 2246 if (*p == startc) 2247 depth++; 2248 if (*p == endc) 2249 depth--; 2250 } 2251 } 2252 LazyBuf_AddBytesBetween(part, varstart, p); 2253 } else { 2254 LazyBuf_Add(part, *varstart); 2255 p++; 2256 } 2257 } 2258 2259 if (*p != delim) { 2260 *pp = p; 2261 Error("Unfinished modifier for \"%s\" ('%c' missing)", 2262 ch->expr->name, delim); 2263 LazyBuf_Done(part); 2264 return VPR_ERR; 2265 } 2266 2267 *pp = p + 1; 2268 2269 { 2270 Substring sub = LazyBuf_Get(part); 2271 DEBUG2(VAR, "Modifier part: \"%.*s\"\n", 2272 (int)Substring_Length(sub), sub.start); 2273 } 2274 2275 return VPR_OK; 2276 } 2277 2278 /* 2279 * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or 2280 * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and 2281 * including the next unescaped delimiter. The delimiter, as well as the 2282 * backslash or the dollar, can be escaped with a backslash. 2283 * 2284 * Return the parsed (and possibly expanded) string, or NULL if no delimiter 2285 * was found. On successful return, the parsing position pp points right 2286 * after the delimiter. The delimiter is not included in the returned 2287 * value though. 2288 */ 2289 static VarParseResult 2290 ParseModifierPart( 2291 /* The parsing position, updated upon return */ 2292 const char **pp, 2293 /* Parsing stops at this delimiter */ 2294 char delim, 2295 /* Mode for evaluating nested variables. */ 2296 VarEvalMode emode, 2297 ModChain *ch, 2298 LazyBuf *part 2299 ) 2300 { 2301 return ParseModifierPartSubst(pp, delim, emode, ch, part, NULL, NULL); 2302 } 2303 2304 MAKE_INLINE bool 2305 IsDelimiter(char c, const ModChain *ch) 2306 { 2307 return c == ':' || c == ch->endc; 2308 } 2309 2310 /* Test whether mod starts with modname, followed by a delimiter. */ 2311 MAKE_INLINE bool 2312 ModMatch(const char *mod, const char *modname, const ModChain *ch) 2313 { 2314 size_t n = strlen(modname); 2315 return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], ch); 2316 } 2317 2318 /* Test whether mod starts with modname, followed by a delimiter or '='. */ 2319 MAKE_INLINE bool 2320 ModMatchEq(const char *mod, const char *modname, const ModChain *ch) 2321 { 2322 size_t n = strlen(modname); 2323 return strncmp(mod, modname, n) == 0 && 2324 (IsDelimiter(mod[n], ch) || mod[n] == '='); 2325 } 2326 2327 static bool 2328 TryParseIntBase0(const char **pp, int *out_num) 2329 { 2330 char *end; 2331 long n; 2332 2333 errno = 0; 2334 n = strtol(*pp, &end, 0); 2335 2336 if (end == *pp) 2337 return false; 2338 if ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE) 2339 return false; 2340 if (n < INT_MIN || n > INT_MAX) 2341 return false; 2342 2343 *pp = end; 2344 *out_num = (int)n; 2345 return true; 2346 } 2347 2348 static bool 2349 TryParseSize(const char **pp, size_t *out_num) 2350 { 2351 char *end; 2352 unsigned long n; 2353 2354 if (!ch_isdigit(**pp)) 2355 return false; 2356 2357 errno = 0; 2358 n = strtoul(*pp, &end, 10); 2359 if (n == ULONG_MAX && errno == ERANGE) 2360 return false; 2361 if (n > SIZE_MAX) 2362 return false; 2363 2364 *pp = end; 2365 *out_num = (size_t)n; 2366 return true; 2367 } 2368 2369 static bool 2370 TryParseChar(const char **pp, int base, char *out_ch) 2371 { 2372 char *end; 2373 unsigned long n; 2374 2375 if (!ch_isalnum(**pp)) 2376 return false; 2377 2378 errno = 0; 2379 n = strtoul(*pp, &end, base); 2380 if (n == ULONG_MAX && errno == ERANGE) 2381 return false; 2382 if (n > UCHAR_MAX) 2383 return false; 2384 2385 *pp = end; 2386 *out_ch = (char)n; 2387 return true; 2388 } 2389 2390 /* 2391 * Modify each word of the expression using the given function and place the 2392 * result back in the expression. 2393 */ 2394 static void 2395 ModifyWords(ModChain *ch, 2396 ModifyWordProc modifyWord, void *modifyWord_args, 2397 bool oneBigWord) 2398 { 2399 Expr *expr = ch->expr; 2400 const char *val = expr->value.str; 2401 SepBuf result; 2402 SubstringWords words; 2403 size_t i; 2404 Substring word; 2405 2406 if (oneBigWord) { 2407 SepBuf_Init(&result, ch->sep); 2408 /* XXX: performance: Substring_InitStr calls strlen */ 2409 word = Substring_InitStr(val); 2410 modifyWord(word, &result, modifyWord_args); 2411 goto done; 2412 } 2413 2414 words = Substring_Words(val, false); 2415 2416 DEBUG2(VAR, "ModifyWords: split \"%s\" into %u words\n", 2417 val, (unsigned)words.len); 2418 2419 SepBuf_Init(&result, ch->sep); 2420 for (i = 0; i < words.len; i++) { 2421 modifyWord(words.words[i], &result, modifyWord_args); 2422 if (result.buf.len > 0) 2423 SepBuf_Sep(&result); 2424 } 2425 2426 SubstringWords_Free(words); 2427 2428 done: 2429 Expr_SetValueOwn(expr, SepBuf_DoneData(&result)); 2430 } 2431 2432 /* :@var@...${var}...@ */ 2433 static ApplyModifierResult 2434 ApplyModifier_Loop(const char **pp, ModChain *ch) 2435 { 2436 Expr *expr = ch->expr; 2437 struct ModifyWord_LoopArgs args; 2438 char prev_sep; 2439 VarParseResult res; 2440 LazyBuf tvarBuf, strBuf; 2441 FStr tvar, str; 2442 2443 args.scope = expr->scope; 2444 2445 (*pp)++; /* Skip the first '@' */ 2446 res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &tvarBuf); 2447 if (res != VPR_OK) 2448 return AMR_CLEANUP; 2449 tvar = LazyBuf_DoneGet(&tvarBuf); 2450 args.var = tvar.str; 2451 if (strchr(args.var, '$') != NULL) { 2452 Parse_Error(PARSE_FATAL, 2453 "In the :@ modifier of \"%s\", the variable name \"%s\" " 2454 "must not contain a dollar.", 2455 expr->name, args.var); 2456 return AMR_CLEANUP; 2457 } 2458 2459 res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &strBuf); 2460 if (res != VPR_OK) 2461 return AMR_CLEANUP; 2462 str = LazyBuf_DoneGet(&strBuf); 2463 args.body = str.str; 2464 2465 if (!Expr_ShouldEval(expr)) 2466 goto done; 2467 2468 args.emode = VarEvalMode_WithoutKeepDollar(expr->emode); 2469 prev_sep = ch->sep; 2470 ch->sep = ' '; /* XXX: should be ch->sep for consistency */ 2471 ModifyWords(ch, ModifyWord_Loop, &args, ch->oneBigWord); 2472 ch->sep = prev_sep; 2473 /* XXX: Consider restoring the previous value instead of deleting. */ 2474 Var_Delete(expr->scope, args.var); 2475 2476 done: 2477 FStr_Done(&tvar); 2478 FStr_Done(&str); 2479 return AMR_OK; 2480 } 2481 2482 /* :Ddefined or :Uundefined */ 2483 static ApplyModifierResult 2484 ApplyModifier_Defined(const char **pp, ModChain *ch) 2485 { 2486 Expr *expr = ch->expr; 2487 LazyBuf buf; 2488 const char *p; 2489 2490 VarEvalMode emode = VARE_PARSE_ONLY; 2491 if (Expr_ShouldEval(expr)) 2492 if ((**pp == 'D') == (expr->defined == DEF_REGULAR)) 2493 emode = expr->emode; 2494 2495 p = *pp + 1; 2496 LazyBuf_Init(&buf, p); 2497 while (!IsDelimiter(*p, ch) && *p != '\0') { 2498 2499 /* XXX: This code is similar to the one in Var_Parse. 2500 * See if the code can be merged. 2501 * See also ApplyModifier_Match and ParseModifierPart. */ 2502 2503 /* Escaped delimiter or other special character */ 2504 /* See Buf_AddEscaped in for.c. */ 2505 if (*p == '\\') { 2506 char c = p[1]; 2507 if (IsDelimiter(c, ch) || c == '$' || c == '\\') { 2508 LazyBuf_Add(&buf, c); 2509 p += 2; 2510 continue; 2511 } 2512 } 2513 2514 /* Nested variable expression */ 2515 if (*p == '$') { 2516 FStr nested_val; 2517 2518 (void)Var_Parse(&p, expr->scope, emode, &nested_val); 2519 /* TODO: handle errors */ 2520 if (Expr_ShouldEval(expr)) 2521 LazyBuf_AddStr(&buf, nested_val.str); 2522 FStr_Done(&nested_val); 2523 continue; 2524 } 2525 2526 /* Ordinary text */ 2527 LazyBuf_Add(&buf, *p); 2528 p++; 2529 } 2530 *pp = p; 2531 2532 Expr_Define(expr); 2533 2534 if (VarEvalMode_ShouldEval(emode)) 2535 Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf))); 2536 else 2537 LazyBuf_Done(&buf); 2538 2539 return AMR_OK; 2540 } 2541 2542 /* :L */ 2543 static ApplyModifierResult 2544 ApplyModifier_Literal(const char **pp, ModChain *ch) 2545 { 2546 Expr *expr = ch->expr; 2547 2548 (*pp)++; 2549 2550 if (Expr_ShouldEval(expr)) { 2551 Expr_Define(expr); 2552 Expr_SetValueOwn(expr, bmake_strdup(expr->name)); 2553 } 2554 2555 return AMR_OK; 2556 } 2557 2558 static bool 2559 TryParseTime(const char **pp, time_t *out_time) 2560 { 2561 char *end; 2562 unsigned long n; 2563 2564 if (!ch_isdigit(**pp)) 2565 return false; 2566 2567 errno = 0; 2568 n = strtoul(*pp, &end, 10); 2569 if (n == ULONG_MAX && errno == ERANGE) 2570 return false; 2571 2572 *pp = end; 2573 *out_time = (time_t)n; /* ignore possible truncation for now */ 2574 return true; 2575 } 2576 2577 /* :gmtime */ 2578 static ApplyModifierResult 2579 ApplyModifier_Gmtime(const char **pp, ModChain *ch) 2580 { 2581 time_t utc; 2582 2583 const char *mod = *pp; 2584 if (!ModMatchEq(mod, "gmtime", ch)) 2585 return AMR_UNKNOWN; 2586 2587 if (mod[6] == '=') { 2588 const char *p = mod + 7; 2589 if (!TryParseTime(&p, &utc)) { 2590 Parse_Error(PARSE_FATAL, 2591 "Invalid time value: %s", mod + 7); 2592 return AMR_CLEANUP; 2593 } 2594 *pp = p; 2595 } else { 2596 utc = 0; 2597 *pp = mod + 6; 2598 } 2599 2600 if (ModChain_ShouldEval(ch)) 2601 Expr_SetValueOwn(ch->expr, 2602 VarStrftime(ch->expr->value.str, true, utc)); 2603 2604 return AMR_OK; 2605 } 2606 2607 /* :localtime */ 2608 static ApplyModifierResult 2609 ApplyModifier_Localtime(const char **pp, ModChain *ch) 2610 { 2611 time_t utc; 2612 2613 const char *mod = *pp; 2614 if (!ModMatchEq(mod, "localtime", ch)) 2615 return AMR_UNKNOWN; 2616 2617 if (mod[9] == '=') { 2618 const char *p = mod + 10; 2619 if (!TryParseTime(&p, &utc)) { 2620 Parse_Error(PARSE_FATAL, 2621 "Invalid time value: %s", mod + 10); 2622 return AMR_CLEANUP; 2623 } 2624 *pp = p; 2625 } else { 2626 utc = 0; 2627 *pp = mod + 9; 2628 } 2629 2630 if (ModChain_ShouldEval(ch)) 2631 Expr_SetValueOwn(ch->expr, 2632 VarStrftime(ch->expr->value.str, false, utc)); 2633 2634 return AMR_OK; 2635 } 2636 2637 /* :hash */ 2638 static ApplyModifierResult 2639 ApplyModifier_Hash(const char **pp, ModChain *ch) 2640 { 2641 if (!ModMatch(*pp, "hash", ch)) 2642 return AMR_UNKNOWN; 2643 *pp += 4; 2644 2645 if (ModChain_ShouldEval(ch)) 2646 Expr_SetValueOwn(ch->expr, VarHash(ch->expr->value.str)); 2647 2648 return AMR_OK; 2649 } 2650 2651 /* :P */ 2652 static ApplyModifierResult 2653 ApplyModifier_Path(const char **pp, ModChain *ch) 2654 { 2655 Expr *expr = ch->expr; 2656 GNode *gn; 2657 char *path; 2658 2659 (*pp)++; 2660 2661 if (!ModChain_ShouldEval(ch)) 2662 return AMR_OK; 2663 2664 Expr_Define(expr); 2665 2666 gn = Targ_FindNode(expr->name); 2667 if (gn == NULL || gn->type & OP_NOPATH) { 2668 path = NULL; 2669 } else if (gn->path != NULL) { 2670 path = bmake_strdup(gn->path); 2671 } else { 2672 SearchPath *searchPath = Suff_FindPath(gn); 2673 path = Dir_FindFile(expr->name, searchPath); 2674 } 2675 if (path == NULL) 2676 path = bmake_strdup(expr->name); 2677 Expr_SetValueOwn(expr, path); 2678 2679 return AMR_OK; 2680 } 2681 2682 /* :!cmd! */ 2683 static ApplyModifierResult 2684 ApplyModifier_ShellCommand(const char **pp, ModChain *ch) 2685 { 2686 Expr *expr = ch->expr; 2687 const char *errfmt; 2688 VarParseResult res; 2689 LazyBuf cmdBuf; 2690 FStr cmd; 2691 2692 (*pp)++; 2693 res = ParseModifierPart(pp, '!', expr->emode, ch, &cmdBuf); 2694 if (res != VPR_OK) 2695 return AMR_CLEANUP; 2696 cmd = LazyBuf_DoneGet(&cmdBuf); 2697 2698 2699 errfmt = NULL; 2700 if (Expr_ShouldEval(expr)) 2701 Expr_SetValueOwn(expr, Cmd_Exec(cmd.str, &errfmt)); 2702 else 2703 Expr_SetValueRefer(expr, ""); 2704 if (errfmt != NULL) 2705 Error(errfmt, cmd.str); /* XXX: why still return AMR_OK? */ 2706 FStr_Done(&cmd); 2707 Expr_Define(expr); 2708 2709 return AMR_OK; 2710 } 2711 2712 /* 2713 * The :range modifier generates an integer sequence as long as the words. 2714 * The :range=7 modifier generates an integer sequence from 1 to 7. 2715 */ 2716 static ApplyModifierResult 2717 ApplyModifier_Range(const char **pp, ModChain *ch) 2718 { 2719 size_t n; 2720 Buffer buf; 2721 size_t i; 2722 2723 const char *mod = *pp; 2724 if (!ModMatchEq(mod, "range", ch)) 2725 return AMR_UNKNOWN; 2726 2727 if (mod[5] == '=') { 2728 const char *p = mod + 6; 2729 if (!TryParseSize(&p, &n)) { 2730 Parse_Error(PARSE_FATAL, 2731 "Invalid number \"%s\" for ':range' modifier", 2732 mod + 6); 2733 return AMR_CLEANUP; 2734 } 2735 *pp = p; 2736 } else { 2737 n = 0; 2738 *pp = mod + 5; 2739 } 2740 2741 if (!ModChain_ShouldEval(ch)) 2742 return AMR_OK; 2743 2744 if (n == 0) { 2745 Words words = Str_Words(ch->expr->value.str, false); 2746 n = words.len; 2747 Words_Free(words); 2748 } 2749 2750 Buf_Init(&buf); 2751 2752 for (i = 0; i < n; i++) { 2753 if (i != 0) { 2754 /* XXX: Use ch->sep instead of ' ', for consistency. */ 2755 Buf_AddByte(&buf, ' '); 2756 } 2757 Buf_AddInt(&buf, 1 + (int)i); 2758 } 2759 2760 Expr_SetValueOwn(ch->expr, Buf_DoneData(&buf)); 2761 return AMR_OK; 2762 } 2763 2764 /* Parse a ':M' or ':N' modifier. */ 2765 static void 2766 ParseModifier_Match(const char **pp, const ModChain *ch, 2767 char **out_pattern) 2768 { 2769 const char *mod = *pp; 2770 Expr *expr = ch->expr; 2771 bool copy = false; /* pattern should be, or has been, copied */ 2772 bool needSubst = false; 2773 const char *endpat; 2774 char *pattern; 2775 2776 /* 2777 * In the loop below, ignore ':' unless we are at (or back to) the 2778 * original brace level. 2779 * XXX: This will likely not work right if $() and ${} are intermixed. 2780 */ 2781 /* 2782 * XXX: This code is similar to the one in Var_Parse. 2783 * See if the code can be merged. 2784 * See also ApplyModifier_Defined. 2785 */ 2786 int nest = 0; 2787 const char *p; 2788 for (p = mod + 1; *p != '\0' && !(*p == ':' && nest == 0); p++) { 2789 if (*p == '\\' && 2790 (IsDelimiter(p[1], ch) || p[1] == ch->startc)) { 2791 if (!needSubst) 2792 copy = true; 2793 p++; 2794 continue; 2795 } 2796 if (*p == '$') 2797 needSubst = true; 2798 if (*p == '(' || *p == '{') 2799 nest++; 2800 if (*p == ')' || *p == '}') { 2801 nest--; 2802 if (nest < 0) 2803 break; 2804 } 2805 } 2806 *pp = p; 2807 endpat = p; 2808 2809 if (copy) { 2810 char *dst; 2811 const char *src; 2812 2813 /* Compress the \:'s out of the pattern. */ 2814 pattern = bmake_malloc((size_t)(endpat - (mod + 1)) + 1); 2815 dst = pattern; 2816 src = mod + 1; 2817 for (; src < endpat; src++, dst++) { 2818 if (src[0] == '\\' && src + 1 < endpat && 2819 /* XXX: ch->startc is missing here; see above */ 2820 IsDelimiter(src[1], ch)) 2821 src++; 2822 *dst = *src; 2823 } 2824 *dst = '\0'; 2825 } else { 2826 pattern = bmake_strsedup(mod + 1, endpat); 2827 } 2828 2829 if (needSubst) { 2830 char *old_pattern = pattern; 2831 (void)Var_Subst(pattern, expr->scope, expr->emode, &pattern); 2832 /* TODO: handle errors */ 2833 free(old_pattern); 2834 } 2835 2836 DEBUG2(VAR, "Pattern for ':%c' is \"%s\"\n", mod[0], pattern); 2837 2838 *out_pattern = pattern; 2839 } 2840 2841 /* :Mpattern or :Npattern */ 2842 static ApplyModifierResult 2843 ApplyModifier_Match(const char **pp, ModChain *ch) 2844 { 2845 const char mod = **pp; 2846 char *pattern; 2847 2848 ParseModifier_Match(pp, ch, &pattern); 2849 2850 if (ModChain_ShouldEval(ch)) { 2851 ModifyWordProc modifyWord = 2852 mod == 'M' ? ModifyWord_Match : ModifyWord_NoMatch; 2853 ModifyWords(ch, modifyWord, pattern, ch->oneBigWord); 2854 } 2855 2856 free(pattern); 2857 return AMR_OK; 2858 } 2859 2860 static void 2861 ParsePatternFlags(const char **pp, PatternFlags *pflags, bool *oneBigWord) 2862 { 2863 for (;; (*pp)++) { 2864 if (**pp == 'g') 2865 pflags->subGlobal = true; 2866 else if (**pp == '1') 2867 pflags->subOnce = true; 2868 else if (**pp == 'W') 2869 *oneBigWord = true; 2870 else 2871 break; 2872 } 2873 } 2874 2875 MAKE_INLINE PatternFlags 2876 PatternFlags_None(void) 2877 { 2878 PatternFlags pflags = { false, false, false, false }; 2879 return pflags; 2880 } 2881 2882 /* :S,from,to, */ 2883 static ApplyModifierResult 2884 ApplyModifier_Subst(const char **pp, ModChain *ch) 2885 { 2886 struct ModifyWord_SubstArgs args; 2887 bool oneBigWord; 2888 VarParseResult res; 2889 LazyBuf lhsBuf, rhsBuf; 2890 2891 char delim = (*pp)[1]; 2892 if (delim == '\0') { 2893 Error("Missing delimiter for modifier ':S'"); 2894 (*pp)++; 2895 return AMR_CLEANUP; 2896 } 2897 2898 *pp += 2; 2899 2900 args.pflags = PatternFlags_None(); 2901 args.matched = false; 2902 2903 if (**pp == '^') { 2904 args.pflags.anchorStart = true; 2905 (*pp)++; 2906 } 2907 2908 res = ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &lhsBuf, 2909 &args.pflags, NULL); 2910 if (res != VPR_OK) 2911 return AMR_CLEANUP; 2912 args.lhs = LazyBuf_Get(&lhsBuf); 2913 2914 res = ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &rhsBuf, 2915 NULL, &args); 2916 if (res != VPR_OK) { 2917 LazyBuf_Done(&lhsBuf); 2918 return AMR_CLEANUP; 2919 } 2920 args.rhs = LazyBuf_Get(&rhsBuf); 2921 2922 oneBigWord = ch->oneBigWord; 2923 ParsePatternFlags(pp, &args.pflags, &oneBigWord); 2924 2925 ModifyWords(ch, ModifyWord_Subst, &args, oneBigWord); 2926 2927 LazyBuf_Done(&lhsBuf); 2928 LazyBuf_Done(&rhsBuf); 2929 return AMR_OK; 2930 } 2931 2932 #ifndef NO_REGEX 2933 2934 /* :C,from,to, */ 2935 static ApplyModifierResult 2936 ApplyModifier_Regex(const char **pp, ModChain *ch) 2937 { 2938 struct ModifyWord_SubstRegexArgs args; 2939 bool oneBigWord; 2940 int error; 2941 VarParseResult res; 2942 LazyBuf reBuf, replaceBuf; 2943 FStr re, replace; 2944 2945 char delim = (*pp)[1]; 2946 if (delim == '\0') { 2947 Error("Missing delimiter for :C modifier"); 2948 (*pp)++; 2949 return AMR_CLEANUP; 2950 } 2951 2952 *pp += 2; 2953 2954 res = ParseModifierPart(pp, delim, ch->expr->emode, ch, &reBuf); 2955 if (res != VPR_OK) 2956 return AMR_CLEANUP; 2957 re = LazyBuf_DoneGet(&reBuf); 2958 2959 res = ParseModifierPart(pp, delim, ch->expr->emode, ch, &replaceBuf); 2960 if (res != VPR_OK) { 2961 FStr_Done(&re); 2962 return AMR_CLEANUP; 2963 } 2964 replace = LazyBuf_DoneGet(&replaceBuf); 2965 args.replace = replace.str; 2966 2967 args.pflags = PatternFlags_None(); 2968 args.matched = false; 2969 oneBigWord = ch->oneBigWord; 2970 ParsePatternFlags(pp, &args.pflags, &oneBigWord); 2971 2972 if (!ModChain_ShouldEval(ch)) { 2973 FStr_Done(&replace); 2974 FStr_Done(&re); 2975 return AMR_OK; 2976 } 2977 2978 error = regcomp(&args.re, re.str, REG_EXTENDED); 2979 if (error != 0) { 2980 VarREError(error, &args.re, "Regex compilation error"); 2981 FStr_Done(&replace); 2982 FStr_Done(&re); 2983 return AMR_CLEANUP; 2984 } 2985 2986 args.nsub = args.re.re_nsub + 1; 2987 if (args.nsub > 10) 2988 args.nsub = 10; 2989 2990 ModifyWords(ch, ModifyWord_SubstRegex, &args, oneBigWord); 2991 2992 regfree(&args.re); 2993 FStr_Done(&replace); 2994 FStr_Done(&re); 2995 return AMR_OK; 2996 } 2997 2998 #endif 2999 3000 /* :Q, :q */ 3001 static ApplyModifierResult 3002 ApplyModifier_Quote(const char **pp, ModChain *ch) 3003 { 3004 LazyBuf buf; 3005 bool quoteDollar; 3006 3007 quoteDollar = **pp == 'q'; 3008 if (!IsDelimiter((*pp)[1], ch)) 3009 return AMR_UNKNOWN; 3010 (*pp)++; 3011 3012 if (!ModChain_ShouldEval(ch)) 3013 return AMR_OK; 3014 3015 VarQuote(ch->expr->value.str, quoteDollar, &buf); 3016 if (buf.data != NULL) 3017 Expr_SetValue(ch->expr, LazyBuf_DoneGet(&buf)); 3018 else 3019 LazyBuf_Done(&buf); 3020 3021 return AMR_OK; 3022 } 3023 3024 /*ARGSUSED*/ 3025 static void 3026 ModifyWord_Copy(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 3027 { 3028 SepBuf_AddSubstring(buf, word); 3029 } 3030 3031 /* :ts<separator> */ 3032 static ApplyModifierResult 3033 ApplyModifier_ToSep(const char **pp, ModChain *ch) 3034 { 3035 const char *sep = *pp + 2; 3036 3037 /* 3038 * Even in parse-only mode, proceed as normal since there is 3039 * neither any observable side effect nor a performance penalty. 3040 * Checking for wantRes for every single piece of code in here 3041 * would make the code in this function too hard to read. 3042 */ 3043 3044 /* ":ts<any><endc>" or ":ts<any>:" */ 3045 if (sep[0] != ch->endc && IsDelimiter(sep[1], ch)) { 3046 *pp = sep + 1; 3047 ch->sep = sep[0]; 3048 goto ok; 3049 } 3050 3051 /* ":ts<endc>" or ":ts:" */ 3052 if (IsDelimiter(sep[0], ch)) { 3053 *pp = sep; 3054 ch->sep = '\0'; /* no separator */ 3055 goto ok; 3056 } 3057 3058 /* ":ts<unrecognised><unrecognised>". */ 3059 if (sep[0] != '\\') { 3060 (*pp)++; /* just for backwards compatibility */ 3061 return AMR_BAD; 3062 } 3063 3064 /* ":ts\n" */ 3065 if (sep[1] == 'n') { 3066 *pp = sep + 2; 3067 ch->sep = '\n'; 3068 goto ok; 3069 } 3070 3071 /* ":ts\t" */ 3072 if (sep[1] == 't') { 3073 *pp = sep + 2; 3074 ch->sep = '\t'; 3075 goto ok; 3076 } 3077 3078 /* ":ts\x40" or ":ts\100" */ 3079 { 3080 const char *p = sep + 1; 3081 int base = 8; /* assume octal */ 3082 3083 if (sep[1] == 'x') { 3084 base = 16; 3085 p++; 3086 } else if (!ch_isdigit(sep[1])) { 3087 (*pp)++; /* just for backwards compatibility */ 3088 return AMR_BAD; /* ":ts<backslash><unrecognised>". */ 3089 } 3090 3091 if (!TryParseChar(&p, base, &ch->sep)) { 3092 Parse_Error(PARSE_FATAL, 3093 "Invalid character number: %s", p); 3094 return AMR_CLEANUP; 3095 } 3096 if (!IsDelimiter(*p, ch)) { 3097 (*pp)++; /* just for backwards compatibility */ 3098 return AMR_BAD; 3099 } 3100 3101 *pp = p; 3102 } 3103 3104 ok: 3105 ModifyWords(ch, ModifyWord_Copy, NULL, ch->oneBigWord); 3106 return AMR_OK; 3107 } 3108 3109 static char * 3110 str_toupper(const char *str) 3111 { 3112 char *res; 3113 size_t i, len; 3114 3115 len = strlen(str); 3116 res = bmake_malloc(len + 1); 3117 for (i = 0; i < len + 1; i++) 3118 res[i] = ch_toupper(str[i]); 3119 3120 return res; 3121 } 3122 3123 static char * 3124 str_tolower(const char *str) 3125 { 3126 char *res; 3127 size_t i, len; 3128 3129 len = strlen(str); 3130 res = bmake_malloc(len + 1); 3131 for (i = 0; i < len + 1; i++) 3132 res[i] = ch_tolower(str[i]); 3133 3134 return res; 3135 } 3136 3137 /* :tA, :tu, :tl, :ts<separator>, etc. */ 3138 static ApplyModifierResult 3139 ApplyModifier_To(const char **pp, ModChain *ch) 3140 { 3141 Expr *expr = ch->expr; 3142 const char *mod = *pp; 3143 assert(mod[0] == 't'); 3144 3145 if (IsDelimiter(mod[1], ch) || mod[1] == '\0') { 3146 *pp = mod + 1; 3147 return AMR_BAD; /* Found ":t<endc>" or ":t:". */ 3148 } 3149 3150 if (mod[1] == 's') 3151 return ApplyModifier_ToSep(pp, ch); 3152 3153 if (!IsDelimiter(mod[2], ch)) { /* :t<unrecognized> */ 3154 *pp = mod + 1; 3155 return AMR_BAD; 3156 } 3157 3158 if (mod[1] == 'A') { /* :tA */ 3159 *pp = mod + 2; 3160 ModifyWords(ch, ModifyWord_Realpath, NULL, ch->oneBigWord); 3161 return AMR_OK; 3162 } 3163 3164 if (mod[1] == 'u') { /* :tu */ 3165 *pp = mod + 2; 3166 if (ModChain_ShouldEval(ch)) 3167 Expr_SetValueOwn(expr, str_toupper(expr->value.str)); 3168 return AMR_OK; 3169 } 3170 3171 if (mod[1] == 'l') { /* :tl */ 3172 *pp = mod + 2; 3173 if (ModChain_ShouldEval(ch)) 3174 Expr_SetValueOwn(expr, str_tolower(expr->value.str)); 3175 return AMR_OK; 3176 } 3177 3178 if (mod[1] == 'W' || mod[1] == 'w') { /* :tW, :tw */ 3179 *pp = mod + 2; 3180 ch->oneBigWord = mod[1] == 'W'; 3181 return AMR_OK; 3182 } 3183 3184 /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */ 3185 *pp = mod + 1; /* XXX: unnecessary but observable */ 3186 return AMR_BAD; 3187 } 3188 3189 /* :[#], :[1], :[-1..1], etc. */ 3190 static ApplyModifierResult 3191 ApplyModifier_Words(const char **pp, ModChain *ch) 3192 { 3193 Expr *expr = ch->expr; 3194 const char *estr; 3195 int first, last; 3196 VarParseResult res; 3197 const char *p; 3198 LazyBuf estrBuf; 3199 FStr festr; 3200 3201 (*pp)++; /* skip the '[' */ 3202 res = ParseModifierPart(pp, ']', expr->emode, ch, &estrBuf); 3203 if (res != VPR_OK) 3204 return AMR_CLEANUP; 3205 festr = LazyBuf_DoneGet(&estrBuf); 3206 estr = festr.str; 3207 3208 if (!IsDelimiter(**pp, ch)) 3209 goto bad_modifier; /* Found junk after ']' */ 3210 3211 if (!ModChain_ShouldEval(ch)) 3212 goto ok; 3213 3214 if (estr[0] == '\0') 3215 goto bad_modifier; /* Found ":[]". */ 3216 3217 if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */ 3218 if (ch->oneBigWord) { 3219 Expr_SetValueRefer(expr, "1"); 3220 } else { 3221 Buffer buf; 3222 3223 Words words = Str_Words(expr->value.str, false); 3224 size_t ac = words.len; 3225 Words_Free(words); 3226 3227 /* 3 digits + '\0' is usually enough */ 3228 Buf_InitSize(&buf, 4); 3229 Buf_AddInt(&buf, (int)ac); 3230 Expr_SetValueOwn(expr, Buf_DoneData(&buf)); 3231 } 3232 goto ok; 3233 } 3234 3235 if (estr[0] == '*' && estr[1] == '\0') { /* Found ":[*]" */ 3236 ch->oneBigWord = true; 3237 goto ok; 3238 } 3239 3240 if (estr[0] == '@' && estr[1] == '\0') { /* Found ":[@]" */ 3241 ch->oneBigWord = false; 3242 goto ok; 3243 } 3244 3245 /* 3246 * We expect estr to contain a single integer for :[N], or two 3247 * integers separated by ".." for :[start..end]. 3248 */ 3249 p = estr; 3250 if (!TryParseIntBase0(&p, &first)) 3251 goto bad_modifier; /* Found junk instead of a number */ 3252 3253 if (p[0] == '\0') { /* Found only one integer in :[N] */ 3254 last = first; 3255 } else if (p[0] == '.' && p[1] == '.' && p[2] != '\0') { 3256 /* Expecting another integer after ".." */ 3257 p += 2; 3258 if (!TryParseIntBase0(&p, &last) || *p != '\0') 3259 goto bad_modifier; /* Found junk after ".." */ 3260 } else 3261 goto bad_modifier; /* Found junk instead of ".." */ 3262 3263 /* 3264 * Now first and last are properly filled in, but we still have to 3265 * check for 0 as a special case. 3266 */ 3267 if (first == 0 && last == 0) { 3268 /* ":[0]" or perhaps ":[0..0]" */ 3269 ch->oneBigWord = true; 3270 goto ok; 3271 } 3272 3273 /* ":[0..N]" or ":[N..0]" */ 3274 if (first == 0 || last == 0) 3275 goto bad_modifier; 3276 3277 /* Normal case: select the words described by first and last. */ 3278 Expr_SetValueOwn(expr, 3279 VarSelectWords(expr->value.str, first, last, 3280 ch->sep, ch->oneBigWord)); 3281 3282 ok: 3283 FStr_Done(&festr); 3284 return AMR_OK; 3285 3286 bad_modifier: 3287 FStr_Done(&festr); 3288 return AMR_BAD; 3289 } 3290 3291 static int 3292 str_cmp_asc(const void *a, const void *b) 3293 { 3294 return strcmp(*(const char *const *)a, *(const char *const *)b); 3295 } 3296 3297 static int 3298 str_cmp_desc(const void *a, const void *b) 3299 { 3300 return strcmp(*(const char *const *)b, *(const char *const *)a); 3301 } 3302 3303 static void 3304 ShuffleStrings(char **strs, size_t n) 3305 { 3306 size_t i; 3307 3308 for (i = n - 1; i > 0; i--) { 3309 size_t rndidx = (size_t)random() % (i + 1); 3310 char *t = strs[i]; 3311 strs[i] = strs[rndidx]; 3312 strs[rndidx] = t; 3313 } 3314 } 3315 3316 /* :O (order ascending) or :Or (order descending) or :Ox (shuffle) */ 3317 static ApplyModifierResult 3318 ApplyModifier_Order(const char **pp, ModChain *ch) 3319 { 3320 const char *mod = (*pp)++; /* skip past the 'O' in any case */ 3321 Words words; 3322 enum SortMode { 3323 ASC, DESC, SHUFFLE 3324 } mode; 3325 3326 if (IsDelimiter(mod[1], ch)) { 3327 mode = ASC; 3328 } else if ((mod[1] == 'r' || mod[1] == 'x') && 3329 IsDelimiter(mod[2], ch)) { 3330 (*pp)++; 3331 mode = mod[1] == 'r' ? DESC : SHUFFLE; 3332 } else 3333 return AMR_BAD; 3334 3335 if (!ModChain_ShouldEval(ch)) 3336 return AMR_OK; 3337 3338 words = Str_Words(ch->expr->value.str, false); 3339 if (mode == SHUFFLE) 3340 ShuffleStrings(words.words, words.len); 3341 else 3342 qsort(words.words, words.len, sizeof words.words[0], 3343 mode == ASC ? str_cmp_asc : str_cmp_desc); 3344 Expr_SetValueOwn(ch->expr, Words_JoinFree(words)); 3345 3346 return AMR_OK; 3347 } 3348 3349 /* :? then : else */ 3350 static ApplyModifierResult 3351 ApplyModifier_IfElse(const char **pp, ModChain *ch) 3352 { 3353 Expr *expr = ch->expr; 3354 VarParseResult res; 3355 LazyBuf buf; 3356 FStr then_expr, else_expr; 3357 3358 bool value = false; 3359 VarEvalMode then_emode = VARE_PARSE_ONLY; 3360 VarEvalMode else_emode = VARE_PARSE_ONLY; 3361 3362 int cond_rc = COND_PARSE; /* anything other than COND_INVALID */ 3363 if (Expr_ShouldEval(expr)) { 3364 cond_rc = Cond_EvalCondition(expr->name, &value); 3365 if (cond_rc != COND_INVALID && value) 3366 then_emode = expr->emode; 3367 if (cond_rc != COND_INVALID && !value) 3368 else_emode = expr->emode; 3369 } 3370 3371 (*pp)++; /* skip past the '?' */ 3372 res = ParseModifierPart(pp, ':', then_emode, ch, &buf); 3373 if (res != VPR_OK) 3374 return AMR_CLEANUP; 3375 then_expr = LazyBuf_DoneGet(&buf); 3376 3377 res = ParseModifierPart(pp, ch->endc, else_emode, ch, &buf); 3378 if (res != VPR_OK) { 3379 FStr_Done(&then_expr); 3380 return AMR_CLEANUP; 3381 } 3382 else_expr = LazyBuf_DoneGet(&buf); 3383 3384 (*pp)--; /* Go back to the ch->endc. */ 3385 3386 if (cond_rc == COND_INVALID) { 3387 Error("Bad conditional expression '%s' in '%s?%s:%s'", 3388 expr->name, expr->name, then_expr.str, else_expr.str); 3389 return AMR_CLEANUP; 3390 } 3391 3392 if (!ModChain_ShouldEval(ch)) { 3393 FStr_Done(&then_expr); 3394 FStr_Done(&else_expr); 3395 } else if (value) { 3396 Expr_SetValue(expr, then_expr); 3397 FStr_Done(&else_expr); 3398 } else { 3399 FStr_Done(&then_expr); 3400 Expr_SetValue(expr, else_expr); 3401 } 3402 Expr_Define(expr); 3403 return AMR_OK; 3404 } 3405 3406 /* 3407 * The ::= modifiers are special in that they do not read the variable value 3408 * but instead assign to that variable. They always expand to an empty 3409 * string. 3410 * 3411 * Their main purpose is in supporting .for loops that generate shell commands 3412 * since an ordinary variable assignment at that point would terminate the 3413 * dependency group for these targets. For example: 3414 * 3415 * list-targets: .USE 3416 * .for i in ${.TARGET} ${.TARGET:R}.gz 3417 * @${t::=$i} 3418 * @echo 'The target is ${t:T}.' 3419 * .endfor 3420 * 3421 * ::=<str> Assigns <str> as the new value of variable. 3422 * ::?=<str> Assigns <str> as value of variable if 3423 * it was not already set. 3424 * ::+=<str> Appends <str> to variable. 3425 * ::!=<cmd> Assigns output of <cmd> as the new value of 3426 * variable. 3427 */ 3428 static ApplyModifierResult 3429 ApplyModifier_Assign(const char **pp, ModChain *ch) 3430 { 3431 Expr *expr = ch->expr; 3432 GNode *scope; 3433 FStr val; 3434 VarParseResult res; 3435 LazyBuf buf; 3436 3437 const char *mod = *pp; 3438 const char *op = mod + 1; 3439 3440 if (op[0] == '=') 3441 goto ok; 3442 if ((op[0] == '!' || op[0] == '+' || op[0] == '?') && op[1] == '=') 3443 goto ok; 3444 return AMR_UNKNOWN; /* "::<unrecognised>" */ 3445 3446 ok: 3447 if (expr->name[0] == '\0') { 3448 *pp = mod + 1; 3449 return AMR_BAD; 3450 } 3451 3452 switch (op[0]) { 3453 case '+': 3454 case '?': 3455 case '!': 3456 *pp = mod + 3; 3457 break; 3458 default: 3459 *pp = mod + 2; 3460 break; 3461 } 3462 3463 res = ParseModifierPart(pp, ch->endc, expr->emode, ch, &buf); 3464 if (res != VPR_OK) 3465 return AMR_CLEANUP; 3466 val = LazyBuf_DoneGet(&buf); 3467 3468 (*pp)--; /* Go back to the ch->endc. */ 3469 3470 if (!Expr_ShouldEval(expr)) 3471 goto done; 3472 3473 scope = expr->scope; /* scope where v belongs */ 3474 if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL) { 3475 Var *gv = VarFind(expr->name, expr->scope, false); 3476 if (gv == NULL) 3477 scope = SCOPE_GLOBAL; 3478 else 3479 VarFreeEnv(gv); 3480 } 3481 3482 switch (op[0]) { 3483 case '+': 3484 Var_Append(scope, expr->name, val.str); 3485 break; 3486 case '!': { 3487 const char *errfmt; 3488 char *cmd_output = Cmd_Exec(val.str, &errfmt); 3489 if (errfmt != NULL) 3490 Error(errfmt, val.str); 3491 else 3492 Var_Set(scope, expr->name, cmd_output); 3493 free(cmd_output); 3494 break; 3495 } 3496 case '?': 3497 if (expr->defined == DEF_REGULAR) 3498 break; 3499 /* FALLTHROUGH */ 3500 default: 3501 Var_Set(scope, expr->name, val.str); 3502 break; 3503 } 3504 Expr_SetValueRefer(expr, ""); 3505 3506 done: 3507 FStr_Done(&val); 3508 return AMR_OK; 3509 } 3510 3511 /* 3512 * :_=... 3513 * remember current value 3514 */ 3515 static ApplyModifierResult 3516 ApplyModifier_Remember(const char **pp, ModChain *ch) 3517 { 3518 Expr *expr = ch->expr; 3519 const char *mod = *pp; 3520 FStr name; 3521 3522 if (!ModMatchEq(mod, "_", ch)) 3523 return AMR_UNKNOWN; 3524 3525 name = FStr_InitRefer("_"); 3526 if (mod[1] == '=') { 3527 /* 3528 * XXX: This ad-hoc call to strcspn deviates from the usual 3529 * behavior defined in ParseModifierPart. This creates an 3530 * unnecessary, undocumented inconsistency in make. 3531 */ 3532 const char *arg = mod + 2; 3533 size_t argLen = strcspn(arg, ":)}"); 3534 *pp = arg + argLen; 3535 name = FStr_InitOwn(bmake_strldup(arg, argLen)); 3536 } else 3537 *pp = mod + 1; 3538 3539 if (Expr_ShouldEval(expr)) 3540 Var_Set(expr->scope, name.str, expr->value.str); 3541 FStr_Done(&name); 3542 3543 return AMR_OK; 3544 } 3545 3546 /* 3547 * Apply the given function to each word of the variable value, 3548 * for a single-letter modifier such as :H, :T. 3549 */ 3550 static ApplyModifierResult 3551 ApplyModifier_WordFunc(const char **pp, ModChain *ch, 3552 ModifyWordProc modifyWord) 3553 { 3554 if (!IsDelimiter((*pp)[1], ch)) 3555 return AMR_UNKNOWN; 3556 (*pp)++; 3557 3558 if (ModChain_ShouldEval(ch)) 3559 ModifyWords(ch, modifyWord, NULL, ch->oneBigWord); 3560 3561 return AMR_OK; 3562 } 3563 3564 static ApplyModifierResult 3565 ApplyModifier_Unique(const char **pp, ModChain *ch) 3566 { 3567 if (!IsDelimiter((*pp)[1], ch)) 3568 return AMR_UNKNOWN; 3569 (*pp)++; 3570 3571 if (ModChain_ShouldEval(ch)) 3572 Expr_SetValueOwn(ch->expr, VarUniq(ch->expr->value.str)); 3573 3574 return AMR_OK; 3575 } 3576 3577 #ifdef SYSVVARSUB 3578 /* :from=to */ 3579 static ApplyModifierResult 3580 ApplyModifier_SysV(const char **pp, ModChain *ch) 3581 { 3582 Expr *expr = ch->expr; 3583 VarParseResult res; 3584 LazyBuf lhsBuf, rhsBuf; 3585 FStr rhs; 3586 struct ModifyWord_SysVSubstArgs args; 3587 Substring lhs; 3588 const char *lhsSuffix; 3589 3590 const char *mod = *pp; 3591 bool eqFound = false; 3592 3593 /* 3594 * First we make a pass through the string trying to verify it is a 3595 * SysV-make-style translation. It must be: <lhs>=<rhs> 3596 */ 3597 int depth = 1; 3598 const char *p = mod; 3599 while (*p != '\0' && depth > 0) { 3600 if (*p == '=') { /* XXX: should also test depth == 1 */ 3601 eqFound = true; 3602 /* continue looking for ch->endc */ 3603 } else if (*p == ch->endc) 3604 depth--; 3605 else if (*p == ch->startc) 3606 depth++; 3607 if (depth > 0) 3608 p++; 3609 } 3610 if (*p != ch->endc || !eqFound) 3611 return AMR_UNKNOWN; 3612 3613 res = ParseModifierPart(pp, '=', expr->emode, ch, &lhsBuf); 3614 if (res != VPR_OK) 3615 return AMR_CLEANUP; 3616 3617 /* The SysV modifier lasts until the end of the variable expression. */ 3618 res = ParseModifierPart(pp, ch->endc, expr->emode, ch, &rhsBuf); 3619 if (res != VPR_OK) { 3620 LazyBuf_Done(&lhsBuf); 3621 return AMR_CLEANUP; 3622 } 3623 rhs = LazyBuf_DoneGet(&rhsBuf); 3624 3625 (*pp)--; /* Go back to the ch->endc. */ 3626 3627 /* Do not turn an empty expression into non-empty. */ 3628 if (lhsBuf.len == 0 && expr->value.str[0] == '\0') 3629 goto done; 3630 3631 lhs = LazyBuf_Get(&lhsBuf); 3632 lhsSuffix = Substring_SkipFirst(lhs, '%'); 3633 3634 args.scope = expr->scope; 3635 args.lhsPrefix = Substring_Init(lhs.start, 3636 lhsSuffix != lhs.start ? lhsSuffix - 1 : lhs.start); 3637 args.lhsPercent = lhsSuffix != lhs.start; 3638 args.lhsSuffix = Substring_Init(lhsSuffix, lhs.end); 3639 args.rhs = rhs.str; 3640 3641 ModifyWords(ch, ModifyWord_SysVSubst, &args, ch->oneBigWord); 3642 3643 done: 3644 LazyBuf_Done(&lhsBuf); 3645 return AMR_OK; 3646 } 3647 #endif 3648 3649 #ifdef SUNSHCMD 3650 /* :sh */ 3651 static ApplyModifierResult 3652 ApplyModifier_SunShell(const char **pp, ModChain *ch) 3653 { 3654 Expr *expr = ch->expr; 3655 const char *p = *pp; 3656 if (!(p[1] == 'h' && IsDelimiter(p[2], ch))) 3657 return AMR_UNKNOWN; 3658 *pp = p + 2; 3659 3660 if (Expr_ShouldEval(expr)) { 3661 const char *errfmt; 3662 char *output = Cmd_Exec(expr->value.str, &errfmt); 3663 if (errfmt != NULL) 3664 Error(errfmt, expr->value.str); 3665 Expr_SetValueOwn(expr, output); 3666 } 3667 3668 return AMR_OK; 3669 } 3670 #endif 3671 3672 static void 3673 LogBeforeApply(const ModChain *ch, const char *mod) 3674 { 3675 const Expr *expr = ch->expr; 3676 bool is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], ch); 3677 3678 /* 3679 * At this point, only the first character of the modifier can 3680 * be used since the end of the modifier is not yet known. 3681 */ 3682 3683 if (!Expr_ShouldEval(expr)) { 3684 debug_printf("Parsing modifier ${%s:%c%s}\n", 3685 expr->name, mod[0], is_single_char ? "" : "..."); 3686 return; 3687 } 3688 3689 if ((expr->emode == VARE_WANTRES || expr->emode == VARE_UNDEFERR) && 3690 expr->defined == DEF_REGULAR) { 3691 debug_printf( 3692 "Evaluating modifier ${%s:%c%s} on value \"%s\"\n", 3693 expr->name, mod[0], is_single_char ? "" : "...", 3694 expr->value.str); 3695 return; 3696 } 3697 3698 debug_printf( 3699 "Evaluating modifier ${%s:%c%s} on value \"%s\" (%s, %s)\n", 3700 expr->name, mod[0], is_single_char ? "" : "...", expr->value.str, 3701 VarEvalMode_Name[expr->emode], ExprDefined_Name[expr->defined]); 3702 } 3703 3704 static void 3705 LogAfterApply(const ModChain *ch, const char *p, const char *mod) 3706 { 3707 const Expr *expr = ch->expr; 3708 const char *value = expr->value.str; 3709 const char *quot = value == var_Error ? "" : "\""; 3710 3711 if ((expr->emode == VARE_WANTRES || expr->emode == VARE_UNDEFERR) && 3712 expr->defined == DEF_REGULAR) { 3713 3714 debug_printf("Result of ${%s:%.*s} is %s%s%s\n", 3715 expr->name, (int)(p - mod), mod, 3716 quot, value == var_Error ? "error" : value, quot); 3717 return; 3718 } 3719 3720 debug_printf("Result of ${%s:%.*s} is %s%s%s (%s, %s)\n", 3721 expr->name, (int)(p - mod), mod, 3722 quot, value == var_Error ? "error" : value, quot, 3723 VarEvalMode_Name[expr->emode], 3724 ExprDefined_Name[expr->defined]); 3725 } 3726 3727 static ApplyModifierResult 3728 ApplyModifier(const char **pp, ModChain *ch) 3729 { 3730 switch (**pp) { 3731 case '!': 3732 return ApplyModifier_ShellCommand(pp, ch); 3733 case ':': 3734 return ApplyModifier_Assign(pp, ch); 3735 case '?': 3736 return ApplyModifier_IfElse(pp, ch); 3737 case '@': 3738 return ApplyModifier_Loop(pp, ch); 3739 case '[': 3740 return ApplyModifier_Words(pp, ch); 3741 case '_': 3742 return ApplyModifier_Remember(pp, ch); 3743 #ifndef NO_REGEX 3744 case 'C': 3745 return ApplyModifier_Regex(pp, ch); 3746 #endif 3747 case 'D': 3748 return ApplyModifier_Defined(pp, ch); 3749 case 'E': 3750 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Suffix); 3751 case 'g': 3752 return ApplyModifier_Gmtime(pp, ch); 3753 case 'H': 3754 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Head); 3755 case 'h': 3756 return ApplyModifier_Hash(pp, ch); 3757 case 'L': 3758 return ApplyModifier_Literal(pp, ch); 3759 case 'l': 3760 return ApplyModifier_Localtime(pp, ch); 3761 case 'M': 3762 case 'N': 3763 return ApplyModifier_Match(pp, ch); 3764 case 'O': 3765 return ApplyModifier_Order(pp, ch); 3766 case 'P': 3767 return ApplyModifier_Path(pp, ch); 3768 case 'Q': 3769 case 'q': 3770 return ApplyModifier_Quote(pp, ch); 3771 case 'R': 3772 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Root); 3773 case 'r': 3774 return ApplyModifier_Range(pp, ch); 3775 case 'S': 3776 return ApplyModifier_Subst(pp, ch); 3777 #ifdef SUNSHCMD 3778 case 's': 3779 return ApplyModifier_SunShell(pp, ch); 3780 #endif 3781 case 'T': 3782 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Tail); 3783 case 't': 3784 return ApplyModifier_To(pp, ch); 3785 case 'U': 3786 return ApplyModifier_Defined(pp, ch); 3787 case 'u': 3788 return ApplyModifier_Unique(pp, ch); 3789 default: 3790 return AMR_UNKNOWN; 3791 } 3792 } 3793 3794 static void ApplyModifiers(Expr *, const char **, char, char); 3795 3796 typedef enum ApplyModifiersIndirectResult { 3797 /* The indirect modifiers have been applied successfully. */ 3798 AMIR_CONTINUE, 3799 /* Fall back to the SysV modifier. */ 3800 AMIR_SYSV, 3801 /* Error out. */ 3802 AMIR_OUT 3803 } ApplyModifiersIndirectResult; 3804 3805 /* 3806 * While expanding a variable expression, expand and apply indirect modifiers, 3807 * such as in ${VAR:${M_indirect}}. 3808 * 3809 * All indirect modifiers of a group must come from a single variable 3810 * expression. ${VAR:${M1}} is valid but ${VAR:${M1}${M2}} is not. 3811 * 3812 * Multiple groups of indirect modifiers can be chained by separating them 3813 * with colons. ${VAR:${M1}:${M2}} contains 2 indirect modifiers. 3814 * 3815 * If the variable expression is not followed by ch->endc or ':', fall 3816 * back to trying the SysV modifier, such as in ${VAR:${FROM}=${TO}}. 3817 */ 3818 static ApplyModifiersIndirectResult 3819 ApplyModifiersIndirect(ModChain *ch, const char **pp) 3820 { 3821 Expr *expr = ch->expr; 3822 const char *p = *pp; 3823 FStr mods; 3824 3825 (void)Var_Parse(&p, expr->scope, expr->emode, &mods); 3826 /* TODO: handle errors */ 3827 3828 if (mods.str[0] != '\0' && *p != '\0' && !IsDelimiter(*p, ch)) { 3829 FStr_Done(&mods); 3830 return AMIR_SYSV; 3831 } 3832 3833 DEBUG3(VAR, "Indirect modifier \"%s\" from \"%.*s\"\n", 3834 mods.str, (int)(p - *pp), *pp); 3835 3836 if (mods.str[0] != '\0') { 3837 const char *modsp = mods.str; 3838 ApplyModifiers(expr, &modsp, '\0', '\0'); 3839 if (expr->value.str == var_Error || *modsp != '\0') { 3840 FStr_Done(&mods); 3841 *pp = p; 3842 return AMIR_OUT; /* error already reported */ 3843 } 3844 } 3845 FStr_Done(&mods); 3846 3847 if (*p == ':') 3848 p++; 3849 else if (*p == '\0' && ch->endc != '\0') { 3850 Error("Unclosed variable expression after indirect " 3851 "modifier, expecting '%c' for variable \"%s\"", 3852 ch->endc, expr->name); 3853 *pp = p; 3854 return AMIR_OUT; 3855 } 3856 3857 *pp = p; 3858 return AMIR_CONTINUE; 3859 } 3860 3861 static ApplyModifierResult 3862 ApplySingleModifier(const char **pp, ModChain *ch) 3863 { 3864 ApplyModifierResult res; 3865 const char *mod = *pp; 3866 const char *p = *pp; 3867 3868 if (DEBUG(VAR)) 3869 LogBeforeApply(ch, mod); 3870 3871 res = ApplyModifier(&p, ch); 3872 3873 #ifdef SYSVVARSUB 3874 if (res == AMR_UNKNOWN) { 3875 assert(p == mod); 3876 res = ApplyModifier_SysV(&p, ch); 3877 } 3878 #endif 3879 3880 if (res == AMR_UNKNOWN) { 3881 /* 3882 * Guess the end of the current modifier. 3883 * XXX: Skipping the rest of the modifier hides 3884 * errors and leads to wrong results. 3885 * Parsing should rather stop here. 3886 */ 3887 for (p++; !IsDelimiter(*p, ch) && *p != '\0'; p++) 3888 continue; 3889 Parse_Error(PARSE_FATAL, "Unknown modifier \"%.*s\"", 3890 (int)(p - mod), mod); 3891 Expr_SetValueRefer(ch->expr, var_Error); 3892 } 3893 if (res == AMR_CLEANUP || res == AMR_BAD) { 3894 *pp = p; 3895 return res; 3896 } 3897 3898 if (DEBUG(VAR)) 3899 LogAfterApply(ch, p, mod); 3900 3901 if (*p == '\0' && ch->endc != '\0') { 3902 Error( 3903 "Unclosed variable expression, expecting '%c' for " 3904 "modifier \"%.*s\" of variable \"%s\" with value \"%s\"", 3905 ch->endc, 3906 (int)(p - mod), mod, 3907 ch->expr->name, ch->expr->value.str); 3908 } else if (*p == ':') { 3909 p++; 3910 } else if (opts.strict && *p != '\0' && *p != ch->endc) { 3911 Parse_Error(PARSE_FATAL, 3912 "Missing delimiter ':' after modifier \"%.*s\"", 3913 (int)(p - mod), mod); 3914 /* 3915 * TODO: propagate parse error to the enclosing 3916 * expression 3917 */ 3918 } 3919 *pp = p; 3920 return AMR_OK; 3921 } 3922 3923 #if __STDC_VERSION__ >= 199901L 3924 #define ModChain_Literal(expr, startc, endc, sep, oneBigWord) \ 3925 (ModChain) { expr, startc, endc, sep, oneBigWord } 3926 #else 3927 MAKE_INLINE ModChain 3928 ModChain_Literal(Expr *expr, char startc, char endc, char sep, bool oneBigWord) 3929 { 3930 ModChain ch; 3931 ch.expr = expr; 3932 ch.startc = startc; 3933 ch.endc = endc; 3934 ch.sep = sep; 3935 ch.oneBigWord = oneBigWord; 3936 return ch; 3937 } 3938 #endif 3939 3940 /* Apply any modifiers (such as :Mpattern or :@var@loop@ or :Q or ::=value). */ 3941 static void 3942 ApplyModifiers( 3943 Expr *expr, 3944 const char **pp, /* the parsing position, updated upon return */ 3945 char startc, /* '(' or '{'; or '\0' for indirect modifiers */ 3946 char endc /* ')' or '}'; or '\0' for indirect modifiers */ 3947 ) 3948 { 3949 ModChain ch = ModChain_Literal(expr, startc, endc, ' ', false); 3950 const char *p; 3951 const char *mod; 3952 3953 assert(startc == '(' || startc == '{' || startc == '\0'); 3954 assert(endc == ')' || endc == '}' || endc == '\0'); 3955 assert(expr->value.str != NULL); 3956 3957 p = *pp; 3958 3959 if (*p == '\0' && endc != '\0') { 3960 Error( 3961 "Unclosed variable expression (expecting '%c') for \"%s\"", 3962 ch.endc, expr->name); 3963 goto cleanup; 3964 } 3965 3966 while (*p != '\0' && *p != endc) { 3967 ApplyModifierResult res; 3968 3969 if (*p == '$') { 3970 ApplyModifiersIndirectResult amir = 3971 ApplyModifiersIndirect(&ch, &p); 3972 if (amir == AMIR_CONTINUE) 3973 continue; 3974 if (amir == AMIR_OUT) 3975 break; 3976 /* 3977 * It's neither '${VAR}:' nor '${VAR}}'. Try to parse 3978 * it as a SysV modifier, as that is the only modifier 3979 * that can start with '$'. 3980 */ 3981 } 3982 3983 mod = p; 3984 3985 res = ApplySingleModifier(&p, &ch); 3986 if (res == AMR_CLEANUP) 3987 goto cleanup; 3988 if (res == AMR_BAD) 3989 goto bad_modifier; 3990 } 3991 3992 *pp = p; 3993 assert(expr->value.str != NULL); /* Use var_Error or varUndefined. */ 3994 return; 3995 3996 bad_modifier: 3997 /* XXX: The modifier end is only guessed. */ 3998 Error("Bad modifier \":%.*s\" for variable \"%s\"", 3999 (int)strcspn(mod, ":)}"), mod, expr->name); 4000 4001 cleanup: 4002 /* 4003 * TODO: Use p + strlen(p) instead, to stop parsing immediately. 4004 * 4005 * In the unit tests, this generates a few unterminated strings in the 4006 * shell commands though. Instead of producing these unfinished 4007 * strings, commands with evaluation errors should not be run at all. 4008 * 4009 * To make that happen, Var_Subst must report the actual errors 4010 * instead of returning VPR_OK unconditionally. 4011 */ 4012 *pp = p; 4013 Expr_SetValueRefer(expr, var_Error); 4014 } 4015 4016 /* 4017 * Only 4 of the 7 local variables are treated specially as they are the only 4018 * ones that will be set when dynamic sources are expanded. 4019 */ 4020 static bool 4021 VarnameIsDynamic(Substring varname) 4022 { 4023 const char *name; 4024 size_t len; 4025 4026 name = varname.start; 4027 len = Substring_Length(varname); 4028 if (len == 1 || (len == 2 && (name[1] == 'F' || name[1] == 'D'))) { 4029 switch (name[0]) { 4030 case '@': 4031 case '%': 4032 case '*': 4033 case '!': 4034 return true; 4035 } 4036 return false; 4037 } 4038 4039 if ((len == 7 || len == 8) && name[0] == '.' && ch_isupper(name[1])) { 4040 return Substring_Equals(varname, ".TARGET") || 4041 Substring_Equals(varname, ".ARCHIVE") || 4042 Substring_Equals(varname, ".PREFIX") || 4043 Substring_Equals(varname, ".MEMBER"); 4044 } 4045 4046 return false; 4047 } 4048 4049 static const char * 4050 UndefinedShortVarValue(char varname, const GNode *scope) 4051 { 4052 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) { 4053 /* 4054 * If substituting a local variable in a non-local scope, 4055 * assume it's for dynamic source stuff. We have to handle 4056 * this specially and return the longhand for the variable 4057 * with the dollar sign escaped so it makes it back to the 4058 * caller. Only four of the local variables are treated 4059 * specially as they are the only four that will be set 4060 * when dynamic sources are expanded. 4061 */ 4062 switch (varname) { 4063 case '@': 4064 return "$(.TARGET)"; 4065 case '%': 4066 return "$(.MEMBER)"; 4067 case '*': 4068 return "$(.PREFIX)"; 4069 case '!': 4070 return "$(.ARCHIVE)"; 4071 } 4072 } 4073 return NULL; 4074 } 4075 4076 /* 4077 * Parse a variable name, until the end character or a colon, whichever 4078 * comes first. 4079 */ 4080 static void 4081 ParseVarname(const char **pp, char startc, char endc, 4082 GNode *scope, VarEvalMode emode, 4083 LazyBuf *buf) 4084 { 4085 const char *p = *pp; 4086 int depth = 0; /* Track depth so we can spot parse errors. */ 4087 4088 LazyBuf_Init(buf, p); 4089 4090 while (*p != '\0') { 4091 if ((*p == endc || *p == ':') && depth == 0) 4092 break; 4093 if (*p == startc) 4094 depth++; 4095 if (*p == endc) 4096 depth--; 4097 4098 /* A variable inside a variable, expand. */ 4099 if (*p == '$') { 4100 FStr nested_val; 4101 (void)Var_Parse(&p, scope, emode, &nested_val); 4102 /* TODO: handle errors */ 4103 LazyBuf_AddStr(buf, nested_val.str); 4104 FStr_Done(&nested_val); 4105 } else { 4106 LazyBuf_Add(buf, *p); 4107 p++; 4108 } 4109 } 4110 *pp = p; 4111 } 4112 4113 static VarParseResult 4114 ValidShortVarname(char varname, const char *start) 4115 { 4116 if (varname != '$' && varname != ':' && varname != '}' && 4117 varname != ')' && varname != '\0') 4118 return VPR_OK; 4119 4120 if (!opts.strict) 4121 return VPR_ERR; /* XXX: Missing error message */ 4122 4123 if (varname == '$') 4124 Parse_Error(PARSE_FATAL, 4125 "To escape a dollar, use \\$, not $$, at \"%s\"", start); 4126 else if (varname == '\0') 4127 Parse_Error(PARSE_FATAL, "Dollar followed by nothing"); 4128 else 4129 Parse_Error(PARSE_FATAL, 4130 "Invalid variable name '%c', at \"%s\"", varname, start); 4131 4132 return VPR_ERR; 4133 } 4134 4135 /* 4136 * Parse a single-character variable name such as in $V or $@. 4137 * Return whether to continue parsing. 4138 */ 4139 static bool 4140 ParseVarnameShort(char varname, const char **pp, GNode *scope, 4141 VarEvalMode emode, 4142 VarParseResult *out_false_res, const char **out_false_val, 4143 Var **out_true_var) 4144 { 4145 char name[2]; 4146 Var *v; 4147 VarParseResult vpr; 4148 4149 vpr = ValidShortVarname(varname, *pp); 4150 if (vpr != VPR_OK) { 4151 (*pp)++; 4152 *out_false_res = vpr; 4153 *out_false_val = var_Error; 4154 return false; 4155 } 4156 4157 name[0] = varname; 4158 name[1] = '\0'; 4159 v = VarFind(name, scope, true); 4160 if (v == NULL) { 4161 const char *val; 4162 *pp += 2; 4163 4164 val = UndefinedShortVarValue(varname, scope); 4165 if (val == NULL) 4166 val = emode == VARE_UNDEFERR 4167 ? var_Error : varUndefined; 4168 4169 if (opts.strict && val == var_Error) { 4170 Parse_Error(PARSE_FATAL, 4171 "Variable \"%s\" is undefined", name); 4172 *out_false_res = VPR_ERR; 4173 *out_false_val = val; 4174 return false; 4175 } 4176 4177 /* 4178 * XXX: This looks completely wrong. 4179 * 4180 * If undefined expressions are not allowed, this should 4181 * rather be VPR_ERR instead of VPR_UNDEF, together with an 4182 * error message. 4183 * 4184 * If undefined expressions are allowed, this should rather 4185 * be VPR_UNDEF instead of VPR_OK. 4186 */ 4187 *out_false_res = emode == VARE_UNDEFERR 4188 ? VPR_UNDEF : VPR_OK; 4189 *out_false_val = val; 4190 return false; 4191 } 4192 4193 *out_true_var = v; 4194 return true; 4195 } 4196 4197 /* Find variables like @F or <D. */ 4198 static Var * 4199 FindLocalLegacyVar(Substring varname, GNode *scope, 4200 const char **out_extraModifiers) 4201 { 4202 Var *v; 4203 4204 /* Only resolve these variables if scope is a "real" target. */ 4205 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) 4206 return NULL; 4207 4208 if (Substring_Length(varname) != 2) 4209 return NULL; 4210 if (varname.start[1] != 'F' && varname.start[1] != 'D') 4211 return NULL; 4212 if (strchr("@%?*!<>", varname.start[0]) == NULL) 4213 return NULL; 4214 4215 v = VarFindSubstring(Substring_Sub(varname, 0, 1), scope, false); 4216 if (v == NULL) 4217 return NULL; 4218 4219 *out_extraModifiers = varname.start[1] == 'D' ? "H:" : "T:"; 4220 return v; 4221 } 4222 4223 static VarParseResult 4224 EvalUndefined(bool dynamic, const char *start, const char *p, 4225 Substring varname, VarEvalMode emode, FStr *out_val) 4226 { 4227 if (dynamic) { 4228 *out_val = FStr_InitOwn(bmake_strsedup(start, p)); 4229 return VPR_OK; 4230 } 4231 4232 if (emode == VARE_UNDEFERR && opts.strict) { 4233 Parse_Error(PARSE_FATAL, 4234 "Variable \"%.*s\" is undefined", 4235 (int)Substring_Length(varname), varname.start); 4236 *out_val = FStr_InitRefer(var_Error); 4237 return VPR_ERR; 4238 } 4239 4240 if (emode == VARE_UNDEFERR) { 4241 *out_val = FStr_InitRefer(var_Error); 4242 return VPR_UNDEF; /* XXX: Should be VPR_ERR instead. */ 4243 } 4244 4245 *out_val = FStr_InitRefer(varUndefined); 4246 return VPR_OK; 4247 } 4248 4249 /* 4250 * Parse a long variable name enclosed in braces or parentheses such as $(VAR) 4251 * or ${VAR}, up to the closing brace or parenthesis, or in the case of 4252 * ${VAR:Modifiers}, up to the ':' that starts the modifiers. 4253 * Return whether to continue parsing. 4254 */ 4255 static bool 4256 ParseVarnameLong( 4257 const char **pp, 4258 char startc, 4259 GNode *scope, 4260 VarEvalMode emode, 4261 4262 const char **out_false_pp, 4263 VarParseResult *out_false_res, 4264 FStr *out_false_val, 4265 4266 char *out_true_endc, 4267 Var **out_true_v, 4268 bool *out_true_haveModifier, 4269 const char **out_true_extraModifiers, 4270 bool *out_true_dynamic, 4271 ExprDefined *out_true_exprDefined 4272 ) 4273 { 4274 LazyBuf varname; 4275 Var *v; 4276 bool haveModifier; 4277 bool dynamic = false; 4278 4279 const char *p = *pp; 4280 const char *const start = p; 4281 char endc = startc == '(' ? ')' : '}'; 4282 4283 p += 2; /* skip "${" or "$(" or "y(" */ 4284 ParseVarname(&p, startc, endc, scope, emode, &varname); 4285 4286 if (*p == ':') { 4287 haveModifier = true; 4288 } else if (*p == endc) { 4289 haveModifier = false; 4290 } else { 4291 Substring name = LazyBuf_Get(&varname); 4292 Parse_Error(PARSE_FATAL, "Unclosed variable \"%.*s\"", 4293 (int)Substring_Length(name), name.start); 4294 LazyBuf_Done(&varname); 4295 *out_false_pp = p; 4296 *out_false_val = FStr_InitRefer(var_Error); 4297 *out_false_res = VPR_ERR; 4298 return false; 4299 } 4300 4301 v = VarFindSubstring(LazyBuf_Get(&varname), scope, true); 4302 4303 /* At this point, p points just after the variable name, 4304 * either at ':' or at endc. */ 4305 4306 if (v == NULL) { 4307 v = FindLocalLegacyVar(LazyBuf_Get(&varname), scope, 4308 out_true_extraModifiers); 4309 } 4310 4311 if (v == NULL) { 4312 /* 4313 * Defer expansion of dynamic variables if they appear in 4314 * non-local scope since they are not defined there. 4315 */ 4316 dynamic = VarnameIsDynamic(LazyBuf_Get(&varname)) && 4317 (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL); 4318 4319 if (!haveModifier) { 4320 p++; /* skip endc */ 4321 *out_false_pp = p; 4322 *out_false_res = EvalUndefined(dynamic, start, p, 4323 LazyBuf_Get(&varname), emode, out_false_val); 4324 return false; 4325 } 4326 4327 /* 4328 * The variable expression is based on an undefined variable. 4329 * Nevertheless it needs a Var, for modifiers that access the 4330 * variable name, such as :L or :?. 4331 * 4332 * Most modifiers leave this expression in the "undefined" 4333 * state (VES_UNDEF), only a few modifiers like :D, :U, :L, 4334 * :P turn this undefined expression into a defined 4335 * expression (VES_DEF). 4336 * 4337 * In the end, after applying all modifiers, if the expression 4338 * is still undefined, Var_Parse will return an empty string 4339 * instead of the actually computed value. 4340 */ 4341 v = VarNew(LazyBuf_DoneGet(&varname), "", false, false); 4342 *out_true_exprDefined = DEF_UNDEF; 4343 } else 4344 LazyBuf_Done(&varname); 4345 4346 *pp = p; 4347 *out_true_endc = endc; 4348 *out_true_v = v; 4349 *out_true_haveModifier = haveModifier; 4350 *out_true_dynamic = dynamic; 4351 return true; 4352 } 4353 4354 /* Free the environment variable now since we own it. */ 4355 static void 4356 FreeEnvVar(Var *v, FStr *inout_val) 4357 { 4358 char *varValue = Buf_DoneData(&v->val); 4359 if (inout_val->str == varValue) 4360 inout_val->freeIt = varValue; 4361 else 4362 free(varValue); 4363 4364 FStr_Done(&v->name); 4365 free(v); 4366 } 4367 4368 #if __STDC_VERSION__ >= 199901L 4369 #define Expr_Literal(name, value, emode, scope, defined) \ 4370 { name, value, emode, scope, defined } 4371 #else 4372 MAKE_INLINE Expr 4373 Expr_Literal(const char *name, FStr value, 4374 VarEvalMode emode, GNode *scope, ExprDefined defined) 4375 { 4376 Expr expr; 4377 4378 expr.name = name; 4379 expr.value = value; 4380 expr.emode = emode; 4381 expr.scope = scope; 4382 expr.defined = defined; 4383 return expr; 4384 } 4385 #endif 4386 4387 /* 4388 * Expressions of the form ${:U...} with a trivial value are often generated 4389 * by .for loops and are boring, therefore parse and evaluate them in a fast 4390 * lane without debug logging. 4391 */ 4392 static bool 4393 Var_Parse_FastLane(const char **pp, VarEvalMode emode, FStr *out_value) 4394 { 4395 const char *p; 4396 4397 p = *pp; 4398 if (!(p[0] == '$' && p[1] == '{' && p[2] == ':' && p[3] == 'U')) 4399 return false; 4400 4401 p += 4; 4402 while (*p != '$' && *p != '{' && *p != ':' && *p != '\\' && 4403 *p != '}' && *p != '\0') 4404 p++; 4405 if (*p != '}') 4406 return false; 4407 4408 if (emode == VARE_PARSE_ONLY) 4409 *out_value = FStr_InitRefer(""); 4410 else 4411 *out_value = FStr_InitOwn(bmake_strsedup(*pp + 4, p)); 4412 *pp = p + 1; 4413 return true; 4414 } 4415 4416 /* 4417 * Given the start of a variable expression (such as $v, $(VAR), 4418 * ${VAR:Mpattern}), extract the variable name and value, and the modifiers, 4419 * if any. While doing that, apply the modifiers to the value of the 4420 * expression, forming its final value. A few of the modifiers such as :!cmd! 4421 * or ::= have side effects. 4422 * 4423 * Input: 4424 * *pp The string to parse. 4425 * When parsing a condition in ParseEmptyArg, it may also 4426 * point to the "y" of "empty(VARNAME:Modifiers)", which 4427 * is syntactically the same. 4428 * scope The scope for finding variables 4429 * emode Controls the exact details of parsing and evaluation 4430 * 4431 * Output: 4432 * *pp The position where to continue parsing. 4433 * TODO: After a parse error, the value of *pp is 4434 * unspecified. It may not have been updated at all, 4435 * point to some random character in the string, to the 4436 * location of the parse error, or at the end of the 4437 * string. 4438 * *out_val The value of the variable expression, never NULL. 4439 * *out_val var_Error if there was a parse error. 4440 * *out_val var_Error if the base variable of the expression was 4441 * undefined, emode is VARE_UNDEFERR, and none of 4442 * the modifiers turned the undefined expression into a 4443 * defined expression. 4444 * XXX: It is not guaranteed that an error message has 4445 * been printed. 4446 * *out_val varUndefined if the base variable of the expression 4447 * was undefined, emode was not VARE_UNDEFERR, 4448 * and none of the modifiers turned the undefined 4449 * expression into a defined expression. 4450 * XXX: It is not guaranteed that an error message has 4451 * been printed. 4452 */ 4453 VarParseResult 4454 Var_Parse(const char **pp, GNode *scope, VarEvalMode emode, FStr *out_val) 4455 { 4456 const char *p = *pp; 4457 const char *const start = p; 4458 /* true if have modifiers for the variable. */ 4459 bool haveModifier; 4460 /* Starting character if variable in parens or braces. */ 4461 char startc; 4462 /* Ending character if variable in parens or braces. */ 4463 char endc; 4464 /* 4465 * true if the variable is local and we're expanding it in a 4466 * non-local scope. This is done to support dynamic sources. 4467 * The result is just the expression, unaltered. 4468 */ 4469 bool dynamic; 4470 const char *extramodifiers; 4471 Var *v; 4472 Expr expr = Expr_Literal(NULL, FStr_InitRefer(NULL), emode, 4473 scope, DEF_REGULAR); 4474 4475 if (Var_Parse_FastLane(pp, emode, out_val)) 4476 return VPR_OK; 4477 4478 DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]); 4479 4480 *out_val = FStr_InitRefer(NULL); 4481 extramodifiers = NULL; /* extra modifiers to apply first */ 4482 dynamic = false; 4483 4484 /* 4485 * Appease GCC, which thinks that the variable might not be 4486 * initialized. 4487 */ 4488 endc = '\0'; 4489 4490 startc = p[1]; 4491 if (startc != '(' && startc != '{') { 4492 VarParseResult res; 4493 if (!ParseVarnameShort(startc, pp, scope, emode, &res, 4494 &out_val->str, &v)) 4495 return res; 4496 haveModifier = false; 4497 p++; 4498 } else { 4499 VarParseResult res; 4500 if (!ParseVarnameLong(&p, startc, scope, emode, 4501 pp, &res, out_val, 4502 &endc, &v, &haveModifier, &extramodifiers, 4503 &dynamic, &expr.defined)) 4504 return res; 4505 } 4506 4507 expr.name = v->name.str; 4508 if (v->inUse) 4509 Fatal("Variable %s is recursive.", v->name.str); 4510 4511 /* 4512 * XXX: This assignment creates an alias to the current value of the 4513 * variable. This means that as long as the value of the expression 4514 * stays the same, the value of the variable must not change. 4515 * Using the '::=' modifier, it could be possible to do exactly this. 4516 * At the bottom of this function, the resulting value is compared to 4517 * the then-current value of the variable. This might also invoke 4518 * undefined behavior. 4519 */ 4520 expr.value = FStr_InitRefer(v->val.data); 4521 4522 /* 4523 * Before applying any modifiers, expand any nested expressions from 4524 * the variable value. 4525 */ 4526 if (strchr(expr.value.str, '$') != NULL && 4527 VarEvalMode_ShouldEval(emode)) { 4528 char *expanded; 4529 VarEvalMode nested_emode = emode; 4530 if (opts.strict) 4531 nested_emode = VarEvalMode_UndefOk(nested_emode); 4532 v->inUse = true; 4533 (void)Var_Subst(expr.value.str, scope, nested_emode, 4534 &expanded); 4535 v->inUse = false; 4536 /* TODO: handle errors */ 4537 Expr_SetValueOwn(&expr, expanded); 4538 } 4539 4540 if (extramodifiers != NULL) { 4541 const char *em = extramodifiers; 4542 ApplyModifiers(&expr, &em, '\0', '\0'); 4543 } 4544 4545 if (haveModifier) { 4546 p++; /* Skip initial colon. */ 4547 ApplyModifiers(&expr, &p, startc, endc); 4548 } 4549 4550 if (*p != '\0') /* Skip past endc if possible. */ 4551 p++; 4552 4553 *pp = p; 4554 4555 if (v->fromEnv) { 4556 FreeEnvVar(v, &expr.value); 4557 4558 } else if (expr.defined != DEF_REGULAR) { 4559 if (expr.defined == DEF_UNDEF) { 4560 if (dynamic) { 4561 Expr_SetValueOwn(&expr, 4562 bmake_strsedup(start, p)); 4563 } else { 4564 /* 4565 * The expression is still undefined, 4566 * therefore discard the actual value and 4567 * return an error marker instead. 4568 */ 4569 Expr_SetValueRefer(&expr, 4570 emode == VARE_UNDEFERR 4571 ? var_Error : varUndefined); 4572 } 4573 } 4574 /* XXX: This is not standard memory management. */ 4575 if (expr.value.str != v->val.data) 4576 Buf_Done(&v->val); 4577 FStr_Done(&v->name); 4578 free(v); 4579 } 4580 *out_val = expr.value; 4581 return VPR_OK; /* XXX: Is not correct in all cases */ 4582 } 4583 4584 static void 4585 VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalMode emode) 4586 { 4587 /* A dollar sign may be escaped with another dollar sign. */ 4588 if (save_dollars && VarEvalMode_ShouldKeepDollar(emode)) 4589 Buf_AddByte(res, '$'); 4590 Buf_AddByte(res, '$'); 4591 *pp += 2; 4592 } 4593 4594 static void 4595 VarSubstExpr(const char **pp, Buffer *buf, GNode *scope, 4596 VarEvalMode emode, bool *inout_errorReported) 4597 { 4598 const char *p = *pp; 4599 const char *nested_p = p; 4600 FStr val; 4601 4602 (void)Var_Parse(&nested_p, scope, emode, &val); 4603 /* TODO: handle errors */ 4604 4605 if (val.str == var_Error || val.str == varUndefined) { 4606 if (!VarEvalMode_ShouldKeepUndef(emode)) { 4607 p = nested_p; 4608 } else if (emode == VARE_UNDEFERR || val.str == var_Error) { 4609 4610 /* 4611 * XXX: This condition is wrong. If val == var_Error, 4612 * this doesn't necessarily mean there was an undefined 4613 * variable. It could equally well be a parse error; 4614 * see unit-tests/varmod-order.exp. 4615 */ 4616 4617 /* 4618 * If variable is undefined, complain and skip the 4619 * variable. The complaint will stop us from doing 4620 * anything when the file is parsed. 4621 */ 4622 if (!*inout_errorReported) { 4623 Parse_Error(PARSE_FATAL, 4624 "Undefined variable \"%.*s\"", 4625 (int)(size_t)(nested_p - p), p); 4626 } 4627 p = nested_p; 4628 *inout_errorReported = true; 4629 } else { 4630 /* Copy the initial '$' of the undefined expression, 4631 * thereby deferring expansion of the expression, but 4632 * expand nested expressions if already possible. 4633 * See unit-tests/varparse-undef-partial.mk. */ 4634 Buf_AddByte(buf, *p); 4635 p++; 4636 } 4637 } else { 4638 p = nested_p; 4639 Buf_AddStr(buf, val.str); 4640 } 4641 4642 FStr_Done(&val); 4643 4644 *pp = p; 4645 } 4646 4647 /* 4648 * Skip as many characters as possible -- either to the end of the string 4649 * or to the next dollar sign (variable expression). 4650 */ 4651 static void 4652 VarSubstPlain(const char **pp, Buffer *res) 4653 { 4654 const char *p = *pp; 4655 const char *start = p; 4656 4657 for (p++; *p != '$' && *p != '\0'; p++) 4658 continue; 4659 Buf_AddBytesBetween(res, start, p); 4660 *pp = p; 4661 } 4662 4663 /* 4664 * Expand all variable expressions like $V, ${VAR}, $(VAR:Modifiers) in the 4665 * given string. 4666 * 4667 * Input: 4668 * str The string in which the variable expressions are 4669 * expanded. 4670 * scope The scope in which to start searching for 4671 * variables. The other scopes are searched as well. 4672 * emode The mode for parsing or evaluating subexpressions. 4673 */ 4674 VarParseResult 4675 Var_Subst(const char *str, GNode *scope, VarEvalMode emode, char **out_res) 4676 { 4677 const char *p = str; 4678 Buffer res; 4679 4680 /* Set true if an error has already been reported, 4681 * to prevent a plethora of messages when recursing */ 4682 /* XXX: Why is the 'static' necessary here? */ 4683 static bool errorReported; 4684 4685 Buf_Init(&res); 4686 errorReported = false; 4687 4688 while (*p != '\0') { 4689 if (p[0] == '$' && p[1] == '$') 4690 VarSubstDollarDollar(&p, &res, emode); 4691 else if (p[0] == '$') 4692 VarSubstExpr(&p, &res, scope, emode, &errorReported); 4693 else 4694 VarSubstPlain(&p, &res); 4695 } 4696 4697 *out_res = Buf_DoneDataCompact(&res); 4698 return VPR_OK; 4699 } 4700 4701 /* Initialize the variables module. */ 4702 void 4703 Var_Init(void) 4704 { 4705 SCOPE_INTERNAL = GNode_New("Internal"); 4706 SCOPE_GLOBAL = GNode_New("Global"); 4707 SCOPE_CMDLINE = GNode_New("Command"); 4708 } 4709 4710 /* Clean up the variables module. */ 4711 void 4712 Var_End(void) 4713 { 4714 Var_Stats(); 4715 } 4716 4717 void 4718 Var_Stats(void) 4719 { 4720 HashTable_DebugStats(&SCOPE_GLOBAL->vars, "Global variables"); 4721 } 4722 4723 /* Print all variables in a scope, sorted by name. */ 4724 void 4725 Var_Dump(GNode *scope) 4726 { 4727 Vector /* of const char * */ vec; 4728 HashIter hi; 4729 size_t i; 4730 const char **varnames; 4731 4732 Vector_Init(&vec, sizeof(const char *)); 4733 4734 HashIter_Init(&hi, &scope->vars); 4735 while (HashIter_Next(&hi) != NULL) 4736 *(const char **)Vector_Push(&vec) = hi.entry->key; 4737 varnames = vec.items; 4738 4739 qsort(varnames, vec.len, sizeof varnames[0], str_cmp_asc); 4740 4741 for (i = 0; i < vec.len; i++) { 4742 const char *varname = varnames[i]; 4743 Var *var = HashTable_FindValue(&scope->vars, varname); 4744 debug_printf("%-16s = %s\n", varname, var->val.data); 4745 } 4746 4747 Vector_Done(&vec); 4748 } 4749