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