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