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