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