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