1 /* $NetBSD: var.c,v 1.1094 2024/01/07 11:39:04 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.1094 2024/01/07 11:39:04 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_FindLast(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_FindLast(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 DEBUG2(VAR, "ModifyWord_Loop: expand \"%s\" to \"%s\"\n", 1600 args->body, s); 1601 1602 if (s[0] == '\n' || Buf_EndsWith(&buf->buf, '\n')) 1603 buf->needSep = false; 1604 SepBuf_AddStr(buf, s); 1605 free(s); 1606 } 1607 1608 1609 /* 1610 * The :[first..last] modifier selects words from the expression. 1611 * It can also reverse the words. 1612 */ 1613 static char * 1614 VarSelectWords(const char *str, int first, int last, 1615 char sep, bool oneBigWord) 1616 { 1617 SubstringWords words; 1618 int len, start, end, step; 1619 int i; 1620 1621 SepBuf buf; 1622 SepBuf_Init(&buf, sep); 1623 1624 if (oneBigWord) { 1625 /* fake what Substring_Words() would do */ 1626 words.len = 1; 1627 words.words = bmake_malloc(sizeof(words.words[0])); 1628 words.freeIt = NULL; 1629 words.words[0] = Substring_InitStr(str); /* no need to copy */ 1630 } else { 1631 words = Substring_Words(str, false); 1632 } 1633 1634 /* Convert -1 to len, -2 to (len - 1), etc. */ 1635 len = (int)words.len; 1636 if (first < 0) 1637 first += len + 1; 1638 if (last < 0) 1639 last += len + 1; 1640 1641 if (first > last) { 1642 start = (first > len ? len : first) - 1; 1643 end = last < 1 ? 0 : last - 1; 1644 step = -1; 1645 } else { 1646 start = first < 1 ? 0 : first - 1; 1647 end = last > len ? len : last; 1648 step = 1; 1649 } 1650 1651 for (i = start; (step < 0) == (i >= end); i += step) { 1652 SepBuf_AddSubstring(&buf, words.words[i]); 1653 SepBuf_Sep(&buf); 1654 } 1655 1656 SubstringWords_Free(words); 1657 1658 return SepBuf_DoneData(&buf); 1659 } 1660 1661 1662 /*ARGSUSED*/ 1663 static void 1664 ModifyWord_Realpath(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 1665 { 1666 struct stat st; 1667 char rbuf[MAXPATHLEN]; 1668 const char *rp; 1669 1670 assert(word.end[0] == '\0'); /* assume null-terminated word */ 1671 rp = cached_realpath(word.start, rbuf); 1672 if (rp != NULL && *rp == '/' && stat(rp, &st) == 0) 1673 SepBuf_AddStr(buf, rp); 1674 else 1675 SepBuf_AddSubstring(buf, word); 1676 } 1677 1678 1679 static char * 1680 SubstringWords_JoinFree(SubstringWords words) 1681 { 1682 Buffer buf; 1683 size_t i; 1684 1685 Buf_Init(&buf); 1686 1687 for (i = 0; i < words.len; i++) { 1688 if (i != 0) { 1689 /* 1690 * XXX: Use ch->sep instead of ' ', for consistency. 1691 */ 1692 Buf_AddByte(&buf, ' '); 1693 } 1694 Buf_AddRange(&buf, words.words[i].start, words.words[i].end); 1695 } 1696 1697 SubstringWords_Free(words); 1698 1699 return Buf_DoneData(&buf); 1700 } 1701 1702 1703 /* 1704 * Quote shell meta-characters and space characters in the string. 1705 * If quoteDollar is set, also quote and double any '$' characters. 1706 */ 1707 static void 1708 QuoteShell(const char *str, bool quoteDollar, LazyBuf *buf) 1709 { 1710 const char *p; 1711 1712 LazyBuf_Init(buf, str); 1713 for (p = str; *p != '\0'; p++) { 1714 if (*p == '\n') { 1715 const char *newline = Shell_GetNewline(); 1716 if (newline == NULL) 1717 newline = "\\\n"; 1718 LazyBuf_AddStr(buf, newline); 1719 continue; 1720 } 1721 if (ch_isspace(*p) || ch_is_shell_meta(*p)) 1722 LazyBuf_Add(buf, '\\'); 1723 LazyBuf_Add(buf, *p); 1724 if (quoteDollar && *p == '$') 1725 LazyBuf_AddStr(buf, "\\$"); 1726 } 1727 } 1728 1729 /* 1730 * Compute the 32-bit hash of the given string, using the MurmurHash3 1731 * algorithm. Output is encoded as 8 hex digits, in Little Endian order. 1732 */ 1733 static char * 1734 Hash(const char *str) 1735 { 1736 static const char hexdigits[16] = "0123456789abcdef"; 1737 const unsigned char *ustr = (const unsigned char *)str; 1738 1739 uint32_t h = 0x971e137bU; 1740 uint32_t c1 = 0x95543787U; 1741 uint32_t c2 = 0x2ad7eb25U; 1742 size_t len2 = strlen(str); 1743 1744 char *buf; 1745 size_t i; 1746 1747 size_t len; 1748 for (len = len2; len != 0;) { 1749 uint32_t k = 0; 1750 switch (len) { 1751 default: 1752 k = ((uint32_t)ustr[3] << 24) | 1753 ((uint32_t)ustr[2] << 16) | 1754 ((uint32_t)ustr[1] << 8) | 1755 (uint32_t)ustr[0]; 1756 len -= 4; 1757 ustr += 4; 1758 break; 1759 case 3: 1760 k |= (uint32_t)ustr[2] << 16; 1761 /* FALLTHROUGH */ 1762 case 2: 1763 k |= (uint32_t)ustr[1] << 8; 1764 /* FALLTHROUGH */ 1765 case 1: 1766 k |= (uint32_t)ustr[0]; 1767 len = 0; 1768 } 1769 c1 = c1 * 5 + 0x7b7d159cU; 1770 c2 = c2 * 5 + 0x6bce6396U; 1771 k *= c1; 1772 k = (k << 11) ^ (k >> 21); 1773 k *= c2; 1774 h = (h << 13) ^ (h >> 19); 1775 h = h * 5 + 0x52dce729U; 1776 h ^= k; 1777 } 1778 h ^= (uint32_t)len2; 1779 h *= 0x85ebca6b; 1780 h ^= h >> 13; 1781 h *= 0xc2b2ae35; 1782 h ^= h >> 16; 1783 1784 buf = bmake_malloc(9); 1785 for (i = 0; i < 8; i++) { 1786 buf[i] = hexdigits[h & 0x0f]; 1787 h >>= 4; 1788 } 1789 buf[8] = '\0'; 1790 return buf; 1791 } 1792 1793 static char * 1794 FormatTime(const char *fmt, time_t t, bool gmt) 1795 { 1796 char buf[BUFSIZ]; 1797 1798 if (t == 0) 1799 time(&t); 1800 if (*fmt == '\0') 1801 fmt = "%c"; 1802 if (gmt && strchr(fmt, 's') != NULL) { 1803 /* strftime "%s" only works with localtime, not with gmtime. */ 1804 const char *prev_tz_env = getenv("TZ"); 1805 char *prev_tz = prev_tz_env != NULL 1806 ? bmake_strdup(prev_tz_env) : NULL; 1807 setenv("TZ", "UTC", 1); 1808 strftime(buf, sizeof buf, fmt, localtime(&t)); 1809 if (prev_tz != NULL) { 1810 setenv("TZ", prev_tz, 1); 1811 free(prev_tz); 1812 } else 1813 unsetenv("TZ"); 1814 } else 1815 strftime(buf, sizeof buf, fmt, (gmt ? gmtime : localtime)(&t)); 1816 1817 buf[sizeof buf - 1] = '\0'; 1818 return bmake_strdup(buf); 1819 } 1820 1821 /* 1822 * The ApplyModifier functions take an expression that is being evaluated. 1823 * Their task is to apply a single modifier to the expression. This involves 1824 * parsing the modifier, evaluating it and finally updating the value of the 1825 * expression. 1826 * 1827 * Parsing the modifier 1828 * 1829 * If parsing succeeds, the parsing position *pp is updated to point to the 1830 * first character following the modifier, which typically is either ':' or 1831 * ch->endc. The modifier doesn't have to check for this delimiter character, 1832 * this is done by ApplyModifiers. 1833 * 1834 * XXX: As of 2020-11-15, some modifiers such as :S, :C, :P, :L do not 1835 * need to be followed by a ':' or endc; this was an unintended mistake. 1836 * 1837 * If parsing fails because of a missing delimiter after a modifier part (as 1838 * in the :S, :C or :@ modifiers), return AMR_CLEANUP. 1839 * 1840 * If parsing fails because the modifier is unknown, return AMR_UNKNOWN to 1841 * try the SysV modifier ':from=to' as fallback. This should only be 1842 * done as long as there have been no side effects from evaluating nested 1843 * variables, to avoid evaluating them more than once. In this case, the 1844 * parsing position may or may not be updated. (XXX: Why not? The original 1845 * parsing position is well-known in ApplyModifiers.) 1846 * 1847 * If parsing fails and the SysV modifier ${VAR:from=to} should not be used 1848 * as a fallback, issue an error message using Parse_Error (preferred over 1849 * Error) and then return AMR_CLEANUP, which stops processing the expression. 1850 * (XXX: As of 2020-08-23, evaluation of the string continues nevertheless 1851 * after skipping a few bytes, which results in garbage.) 1852 * 1853 * Evaluating the modifier 1854 * 1855 * After parsing, the modifier is evaluated. The side effects from evaluating 1856 * nested expressions in the modifier text often already happen 1857 * during parsing though. For most modifiers this doesn't matter since their 1858 * only noticeable effect is that they update the value of the expression. 1859 * Some modifiers such as ':sh' or '::=' have noticeable side effects though. 1860 * 1861 * Evaluating the modifier usually takes the current value of the 1862 * expression from ch->expr->value, or the variable name from ch->var->name, 1863 * and stores the result back in ch->expr->value via Expr_SetValueOwn or 1864 * Expr_SetValueRefer. 1865 * 1866 * If evaluating fails, the fallback error message "Bad modifier" is printed 1867 * using Error. This function has no side effects, it really just prints the 1868 * error message, continuing as if nothing had happened. TODO: This should be 1869 * fixed by adding proper error handling to Var_Subst, Var_Parse, 1870 * ApplyModifiers and ModifyWords. 1871 * 1872 * Some modifiers such as :D and :U turn undefined expressions into defined 1873 * expressions using Expr_Define. 1874 */ 1875 1876 typedef enum ExprDefined { 1877 /* The expression is based on a regular, defined variable. */ 1878 DEF_REGULAR, 1879 /* The expression is based on an undefined variable. */ 1880 DEF_UNDEF, 1881 /* 1882 * The expression started as an undefined expression, but one 1883 * of the modifiers (such as ':D' or ':U') has turned the expression 1884 * from undefined to defined. 1885 */ 1886 DEF_DEFINED 1887 } ExprDefined; 1888 1889 static const char ExprDefined_Name[][10] = { 1890 "regular", 1891 "undefined", 1892 "defined" 1893 }; 1894 1895 #if __STDC_VERSION__ >= 199901L 1896 #define const_member const 1897 #else 1898 #define const_member /* no const possible */ 1899 #endif 1900 1901 /* An expression based on a variable, such as $@ or ${VAR:Mpattern:Q}. */ 1902 typedef struct Expr { 1903 const char *name; 1904 FStr value; 1905 VarEvalMode const_member emode; 1906 GNode *const_member scope; 1907 ExprDefined defined; 1908 } Expr; 1909 1910 /* 1911 * The status of applying a chain of modifiers to an expression. 1912 * 1913 * The modifiers of an expression are broken into chains of modifiers, 1914 * starting a new nested chain whenever an indirect modifier starts. There 1915 * are at most 2 nesting levels: the outer one for the direct modifiers, and 1916 * the inner one for the indirect modifiers. 1917 * 1918 * For example, the expression ${VAR:M*:${IND1}:${IND2}:O:u} has 3 chains of 1919 * modifiers: 1920 * 1921 * Chain 1 starts with the single modifier ':M*'. 1922 * Chain 2 starts with all modifiers from ${IND1}. 1923 * Chain 2 ends at the ':' between ${IND1} and ${IND2}. 1924 * Chain 3 starts with all modifiers from ${IND2}. 1925 * Chain 3 ends at the ':' after ${IND2}. 1926 * Chain 1 continues with the 2 modifiers ':O' and ':u'. 1927 * Chain 1 ends at the final '}' of the expression. 1928 * 1929 * After such a chain ends, its properties no longer have any effect. 1930 * 1931 * See varmod-indirect.mk. 1932 */ 1933 typedef struct ModChain { 1934 Expr *expr; 1935 /* '\0' or '{' or '(' */ 1936 char const_member startc; 1937 /* '\0' or '}' or ')' */ 1938 char const_member endc; 1939 /* Separator when joining words (see the :ts modifier). */ 1940 char sep; 1941 /* 1942 * Whether some modifiers that otherwise split the variable value 1943 * into words, like :S and :C, treat the variable value as a single 1944 * big word, possibly containing spaces. 1945 */ 1946 bool oneBigWord; 1947 } ModChain; 1948 1949 static void 1950 Expr_Define(Expr *expr) 1951 { 1952 if (expr->defined == DEF_UNDEF) 1953 expr->defined = DEF_DEFINED; 1954 } 1955 1956 static const char * 1957 Expr_Str(const Expr *expr) 1958 { 1959 return expr->value.str; 1960 } 1961 1962 static SubstringWords 1963 Expr_Words(const Expr *expr) 1964 { 1965 return Substring_Words(Expr_Str(expr), false); 1966 } 1967 1968 static void 1969 Expr_SetValue(Expr *expr, FStr value) 1970 { 1971 FStr_Done(&expr->value); 1972 expr->value = value; 1973 } 1974 1975 static void 1976 Expr_SetValueOwn(Expr *expr, char *value) 1977 { 1978 Expr_SetValue(expr, FStr_InitOwn(value)); 1979 } 1980 1981 static void 1982 Expr_SetValueRefer(Expr *expr, const char *value) 1983 { 1984 Expr_SetValue(expr, FStr_InitRefer(value)); 1985 } 1986 1987 static bool 1988 Expr_ShouldEval(const Expr *expr) 1989 { 1990 return VarEvalMode_ShouldEval(expr->emode); 1991 } 1992 1993 static bool 1994 ModChain_ShouldEval(const ModChain *ch) 1995 { 1996 return Expr_ShouldEval(ch->expr); 1997 } 1998 1999 2000 typedef enum ApplyModifierResult { 2001 /* Continue parsing */ 2002 AMR_OK, 2003 /* Not a match, try the ':from=to' modifier as well. */ 2004 AMR_UNKNOWN, 2005 /* Error out with "Bad modifier" message. */ 2006 AMR_BAD, 2007 /* Error out without the standard error message. */ 2008 AMR_CLEANUP 2009 } ApplyModifierResult; 2010 2011 /* 2012 * Allow backslashes to escape the delimiter, $, and \, but don't touch other 2013 * backslashes. 2014 */ 2015 static bool 2016 IsEscapedModifierPart(const char *p, char delim, 2017 struct ModifyWord_SubstArgs *subst) 2018 { 2019 if (p[0] != '\\') 2020 return false; 2021 if (p[1] == delim || p[1] == '\\' || p[1] == '$') 2022 return true; 2023 return p[1] == '&' && subst != NULL; 2024 } 2025 2026 /* 2027 * In a part of a modifier, parse a subexpression and evaluate it. 2028 */ 2029 static void 2030 ParseModifierPartExpr(const char **pp, LazyBuf *part, const ModChain *ch, 2031 VarEvalMode emode) 2032 { 2033 const char *p = *pp; 2034 FStr nested_val = Var_Parse(&p, ch->expr->scope, 2035 VarEvalMode_WithoutKeepDollar(emode)); 2036 /* TODO: handle errors */ 2037 if (VarEvalMode_ShouldEval(emode)) 2038 LazyBuf_AddStr(part, nested_val.str); 2039 else 2040 LazyBuf_AddSubstring(part, Substring_Init(*pp, p)); 2041 FStr_Done(&nested_val); 2042 *pp = p; 2043 } 2044 2045 /* 2046 * In a part of a modifier, parse some text that looks like a subexpression. 2047 * If the text starts with '$(', any '(' and ')' must be balanced. 2048 * If the text starts with '${', any '{' and '}' must be balanced. 2049 * If the text starts with '$', that '$' is copied verbatim, it is not parsed 2050 * as a short-name expression. 2051 */ 2052 static void 2053 ParseModifierPartBalanced(const char **pp, LazyBuf *part) 2054 { 2055 const char *p = *pp; 2056 2057 if (p[1] == '(' || p[1] == '{') { 2058 char startc = p[1]; 2059 int endc = startc == '(' ? ')' : '}'; 2060 int depth = 1; 2061 2062 for (p += 2; *p != '\0' && depth > 0; p++) { 2063 if (p[-1] != '\\') { 2064 if (*p == startc) 2065 depth++; 2066 if (*p == endc) 2067 depth--; 2068 } 2069 } 2070 LazyBuf_AddSubstring(part, Substring_Init(*pp, p)); 2071 *pp = p; 2072 } else { 2073 LazyBuf_Add(part, *p); 2074 *pp = p + 1; 2075 } 2076 } 2077 2078 /* See ParseModifierPart for the documentation. */ 2079 static bool 2080 ParseModifierPartSubst( 2081 const char **pp, 2082 /* If true, parse up to but excluding the next ':' or ch->endc. */ 2083 bool whole, 2084 char delim, 2085 VarEvalMode emode, 2086 ModChain *ch, 2087 LazyBuf *part, 2088 /* 2089 * For the first part of the ':S' modifier, set anchorEnd if the last 2090 * character of the pattern is a $. 2091 */ 2092 PatternFlags *out_pflags, 2093 /* 2094 * For the second part of the ':S' modifier, allow ampersands to be 2095 * escaped and replace unescaped ampersands with subst->lhs. 2096 */ 2097 struct ModifyWord_SubstArgs *subst 2098 ) 2099 { 2100 const char *p; 2101 char end1, end2; 2102 2103 p = *pp; 2104 LazyBuf_Init(part, p); 2105 2106 end1 = whole ? ':' : delim; 2107 end2 = whole ? ch->endc : delim; 2108 while (*p != '\0' && *p != end1 && *p != end2) { 2109 if (IsEscapedModifierPart(p, delim, subst)) { 2110 LazyBuf_Add(part, p[1]); 2111 p += 2; 2112 } else if (*p != '$') { /* Unescaped, simple text */ 2113 if (subst != NULL && *p == '&') 2114 LazyBuf_AddSubstring(part, subst->lhs); 2115 else 2116 LazyBuf_Add(part, *p); 2117 p++; 2118 } else if (p[1] == delim) { /* Unescaped '$' at end */ 2119 if (out_pflags != NULL) 2120 out_pflags->anchorEnd = true; 2121 else 2122 LazyBuf_Add(part, *p); 2123 p++; 2124 } else if (emode == VARE_PARSE_BALANCED) 2125 ParseModifierPartBalanced(&p, part); 2126 else 2127 ParseModifierPartExpr(&p, part, ch, emode); 2128 } 2129 2130 *pp = p; 2131 if (*p != end1 && *p != end2) { 2132 Error("Unfinished modifier for \"%s\" ('%c' missing)", 2133 ch->expr->name, end2); 2134 LazyBuf_Done(part); 2135 return false; 2136 } 2137 if (!whole) 2138 (*pp)++; 2139 2140 { 2141 Substring sub = LazyBuf_Get(part); 2142 DEBUG2(VAR, "Modifier part: \"%.*s\"\n", 2143 (int)Substring_Length(sub), sub.start); 2144 } 2145 2146 return true; 2147 } 2148 2149 /* 2150 * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or 2151 * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and 2152 * including the next unescaped delimiter. The delimiter, as well as the 2153 * backslash or the dollar, can be escaped with a backslash. 2154 * 2155 * Return true if parsing succeeded, together with the parsed (and possibly 2156 * expanded) part. In that case, pp points right after the delimiter. The 2157 * delimiter is not included in the part though. 2158 */ 2159 static bool 2160 ParseModifierPart( 2161 /* The parsing position, updated upon return */ 2162 const char **pp, 2163 /* Parsing stops at this delimiter */ 2164 char delim, 2165 /* Mode for evaluating nested expressions. */ 2166 VarEvalMode emode, 2167 ModChain *ch, 2168 LazyBuf *part 2169 ) 2170 { 2171 return ParseModifierPartSubst(pp, false, delim, emode, ch, part, 2172 NULL, NULL); 2173 } 2174 2175 MAKE_INLINE bool 2176 IsDelimiter(char c, const ModChain *ch) 2177 { 2178 return c == ':' || c == ch->endc || c == '\0'; 2179 } 2180 2181 /* Test whether mod starts with modname, followed by a delimiter. */ 2182 MAKE_INLINE bool 2183 ModMatch(const char *mod, const char *modname, const ModChain *ch) 2184 { 2185 size_t n = strlen(modname); 2186 return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], ch); 2187 } 2188 2189 /* Test whether mod starts with modname, followed by a delimiter or '='. */ 2190 MAKE_INLINE bool 2191 ModMatchEq(const char *mod, const char *modname, const ModChain *ch) 2192 { 2193 size_t n = strlen(modname); 2194 return strncmp(mod, modname, n) == 0 && 2195 (IsDelimiter(mod[n], ch) || mod[n] == '='); 2196 } 2197 2198 static bool 2199 TryParseIntBase0(const char **pp, int *out_num) 2200 { 2201 char *end; 2202 long n; 2203 2204 errno = 0; 2205 n = strtol(*pp, &end, 0); 2206 2207 if (end == *pp) 2208 return false; 2209 if ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE) 2210 return false; 2211 if (n < INT_MIN || n > INT_MAX) 2212 return false; 2213 2214 *pp = end; 2215 *out_num = (int)n; 2216 return true; 2217 } 2218 2219 static bool 2220 TryParseSize(const char **pp, size_t *out_num) 2221 { 2222 char *end; 2223 unsigned long n; 2224 2225 if (!ch_isdigit(**pp)) 2226 return false; 2227 2228 errno = 0; 2229 n = strtoul(*pp, &end, 10); 2230 if (n == ULONG_MAX && errno == ERANGE) 2231 return false; 2232 if (n > SIZE_MAX) 2233 return false; 2234 2235 *pp = end; 2236 *out_num = (size_t)n; 2237 return true; 2238 } 2239 2240 static bool 2241 TryParseChar(const char **pp, int base, char *out_ch) 2242 { 2243 char *end; 2244 unsigned long n; 2245 2246 if (!ch_isalnum(**pp)) 2247 return false; 2248 2249 errno = 0; 2250 n = strtoul(*pp, &end, base); 2251 if (n == ULONG_MAX && errno == ERANGE) 2252 return false; 2253 if (n > UCHAR_MAX) 2254 return false; 2255 2256 *pp = end; 2257 *out_ch = (char)n; 2258 return true; 2259 } 2260 2261 /* 2262 * Modify each word of the expression using the given function and place the 2263 * result back in the expression. 2264 */ 2265 static void 2266 ModifyWords(ModChain *ch, 2267 ModifyWordProc modifyWord, void *modifyWord_args, 2268 bool oneBigWord) 2269 { 2270 Expr *expr = ch->expr; 2271 const char *val = Expr_Str(expr); 2272 SepBuf result; 2273 SubstringWords words; 2274 size_t i; 2275 Substring word; 2276 2277 if (oneBigWord) { 2278 SepBuf_Init(&result, ch->sep); 2279 /* XXX: performance: Substring_InitStr calls strlen */ 2280 word = Substring_InitStr(val); 2281 modifyWord(word, &result, modifyWord_args); 2282 goto done; 2283 } 2284 2285 words = Substring_Words(val, false); 2286 2287 DEBUG3(VAR, "ModifyWords: split \"%s\" into %u %s\n", 2288 val, (unsigned)words.len, words.len != 1 ? "words" : "word"); 2289 2290 SepBuf_Init(&result, ch->sep); 2291 for (i = 0; i < words.len; i++) { 2292 modifyWord(words.words[i], &result, modifyWord_args); 2293 if (result.buf.len > 0) 2294 SepBuf_Sep(&result); 2295 } 2296 2297 SubstringWords_Free(words); 2298 2299 done: 2300 Expr_SetValueOwn(expr, SepBuf_DoneData(&result)); 2301 } 2302 2303 /* :@var@...${var}...@ */ 2304 static ApplyModifierResult 2305 ApplyModifier_Loop(const char **pp, ModChain *ch) 2306 { 2307 Expr *expr = ch->expr; 2308 struct ModifyWord_LoopArgs args; 2309 char prev_sep; 2310 LazyBuf tvarBuf, strBuf; 2311 FStr tvar, str; 2312 2313 args.scope = expr->scope; 2314 2315 (*pp)++; /* Skip the first '@' */ 2316 if (!ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &tvarBuf)) 2317 return AMR_CLEANUP; 2318 tvar = LazyBuf_DoneGet(&tvarBuf); 2319 args.var = tvar.str; 2320 if (strchr(args.var, '$') != NULL) { 2321 Parse_Error(PARSE_FATAL, 2322 "In the :@ modifier of \"%s\", the variable name \"%s\" " 2323 "must not contain a dollar", 2324 expr->name, args.var); 2325 return AMR_CLEANUP; 2326 } 2327 2328 if (!ParseModifierPart(pp, '@', VARE_PARSE_BALANCED, ch, &strBuf)) 2329 return AMR_CLEANUP; 2330 str = LazyBuf_DoneGet(&strBuf); 2331 args.body = str.str; 2332 2333 if (!Expr_ShouldEval(expr)) 2334 goto done; 2335 2336 args.emode = VarEvalMode_WithoutKeepDollar(expr->emode); 2337 prev_sep = ch->sep; 2338 ch->sep = ' '; /* XXX: should be ch->sep for consistency */ 2339 ModifyWords(ch, ModifyWord_Loop, &args, ch->oneBigWord); 2340 ch->sep = prev_sep; 2341 /* XXX: Consider restoring the previous value instead of deleting. */ 2342 Var_Delete(expr->scope, args.var); 2343 2344 done: 2345 FStr_Done(&tvar); 2346 FStr_Done(&str); 2347 return AMR_OK; 2348 } 2349 2350 static void 2351 ParseModifier_Defined(const char **pp, ModChain *ch, bool shouldEval, 2352 LazyBuf *buf) 2353 { 2354 const char *p; 2355 2356 p = *pp + 1; 2357 LazyBuf_Init(buf, p); 2358 while (!IsDelimiter(*p, ch)) { 2359 2360 /* 2361 * XXX: This code is similar to the one in Var_Parse. See if 2362 * the code can be merged. See also ParseModifier_Match and 2363 * ParseModifierPart. 2364 */ 2365 2366 /* See Buf_AddEscaped in for.c for the counterpart. */ 2367 if (*p == '\\') { 2368 char c = p[1]; 2369 if ((IsDelimiter(c, ch) && c != '\0') || 2370 c == '$' || c == '\\') { 2371 if (shouldEval) 2372 LazyBuf_Add(buf, c); 2373 p += 2; 2374 continue; 2375 } 2376 } 2377 2378 if (*p == '$') { 2379 FStr val = Var_Parse(&p, ch->expr->scope, 2380 shouldEval ? ch->expr->emode : VARE_PARSE_ONLY); 2381 /* TODO: handle errors */ 2382 if (shouldEval) 2383 LazyBuf_AddStr(buf, val.str); 2384 FStr_Done(&val); 2385 continue; 2386 } 2387 2388 if (shouldEval) 2389 LazyBuf_Add(buf, *p); 2390 p++; 2391 } 2392 *pp = p; 2393 } 2394 2395 /* :Ddefined or :Uundefined */ 2396 static ApplyModifierResult 2397 ApplyModifier_Defined(const char **pp, ModChain *ch) 2398 { 2399 Expr *expr = ch->expr; 2400 LazyBuf buf; 2401 bool shouldEval = 2402 Expr_ShouldEval(expr) && 2403 (**pp == 'D') == (expr->defined == DEF_REGULAR); 2404 2405 ParseModifier_Defined(pp, ch, shouldEval, &buf); 2406 2407 Expr_Define(expr); 2408 if (shouldEval) 2409 Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf))); 2410 2411 return AMR_OK; 2412 } 2413 2414 /* :L */ 2415 static ApplyModifierResult 2416 ApplyModifier_Literal(const char **pp, ModChain *ch) 2417 { 2418 Expr *expr = ch->expr; 2419 2420 (*pp)++; 2421 2422 if (Expr_ShouldEval(expr)) { 2423 Expr_Define(expr); 2424 Expr_SetValueOwn(expr, bmake_strdup(expr->name)); 2425 } 2426 2427 return AMR_OK; 2428 } 2429 2430 static bool 2431 TryParseTime(const char **pp, time_t *out_time) 2432 { 2433 char *end; 2434 unsigned long n; 2435 2436 if (!ch_isdigit(**pp)) 2437 return false; 2438 2439 errno = 0; 2440 n = strtoul(*pp, &end, 10); 2441 if (n == ULONG_MAX && errno == ERANGE) 2442 return false; 2443 2444 *pp = end; 2445 *out_time = (time_t)n; /* ignore possible truncation for now */ 2446 return true; 2447 } 2448 2449 /* :gmtime and :localtime */ 2450 static ApplyModifierResult 2451 ApplyModifier_Time(const char **pp, ModChain *ch) 2452 { 2453 Expr *expr; 2454 time_t t; 2455 const char *args; 2456 const char *mod = *pp; 2457 bool gmt = mod[0] == 'g'; 2458 2459 if (!ModMatchEq(mod, gmt ? "gmtime" : "localtime", ch)) 2460 return AMR_UNKNOWN; 2461 args = mod + (gmt ? 6 : 9); 2462 2463 if (args[0] == '=') { 2464 const char *p = args + 1; 2465 LazyBuf buf; 2466 if (!ParseModifierPartSubst(&p, true, '\0', ch->expr->emode, 2467 ch, &buf, NULL, NULL)) 2468 return AMR_CLEANUP; 2469 if (ModChain_ShouldEval(ch)) { 2470 Substring arg = LazyBuf_Get(&buf); 2471 const char *arg_p = arg.start; 2472 if (!TryParseTime(&arg_p, &t) || arg_p != arg.end) { 2473 Parse_Error(PARSE_FATAL, 2474 "Invalid time value \"%.*s\"", 2475 (int)Substring_Length(arg), arg.start); 2476 LazyBuf_Done(&buf); 2477 return AMR_CLEANUP; 2478 } 2479 } else 2480 t = 0; 2481 LazyBuf_Done(&buf); 2482 *pp = p; 2483 } else { 2484 t = 0; 2485 *pp = args; 2486 } 2487 2488 expr = ch->expr; 2489 if (Expr_ShouldEval(expr)) 2490 Expr_SetValueOwn(expr, FormatTime(Expr_Str(expr), t, gmt)); 2491 2492 return AMR_OK; 2493 } 2494 2495 /* :hash */ 2496 static ApplyModifierResult 2497 ApplyModifier_Hash(const char **pp, ModChain *ch) 2498 { 2499 if (!ModMatch(*pp, "hash", ch)) 2500 return AMR_UNKNOWN; 2501 *pp += 4; 2502 2503 if (ModChain_ShouldEval(ch)) 2504 Expr_SetValueOwn(ch->expr, Hash(Expr_Str(ch->expr))); 2505 2506 return AMR_OK; 2507 } 2508 2509 /* :P */ 2510 static ApplyModifierResult 2511 ApplyModifier_Path(const char **pp, ModChain *ch) 2512 { 2513 Expr *expr = ch->expr; 2514 GNode *gn; 2515 char *path; 2516 2517 (*pp)++; 2518 2519 if (!Expr_ShouldEval(expr)) 2520 return AMR_OK; 2521 2522 Expr_Define(expr); 2523 2524 gn = Targ_FindNode(expr->name); 2525 if (gn == NULL || gn->type & OP_NOPATH) 2526 path = NULL; 2527 else if (gn->path != NULL) 2528 path = bmake_strdup(gn->path); 2529 else { 2530 SearchPath *searchPath = Suff_FindPath(gn); 2531 path = Dir_FindFile(expr->name, searchPath); 2532 } 2533 if (path == NULL) 2534 path = bmake_strdup(expr->name); 2535 Expr_SetValueOwn(expr, path); 2536 2537 return AMR_OK; 2538 } 2539 2540 /* :!cmd! */ 2541 static ApplyModifierResult 2542 ApplyModifier_ShellCommand(const char **pp, ModChain *ch) 2543 { 2544 Expr *expr = ch->expr; 2545 LazyBuf cmdBuf; 2546 FStr cmd; 2547 2548 (*pp)++; 2549 if (!ParseModifierPart(pp, '!', expr->emode, ch, &cmdBuf)) 2550 return AMR_CLEANUP; 2551 cmd = LazyBuf_DoneGet(&cmdBuf); 2552 2553 if (Expr_ShouldEval(expr)) { 2554 char *output, *error; 2555 output = Cmd_Exec(cmd.str, &error); 2556 Expr_SetValueOwn(expr, output); 2557 if (error != NULL) { 2558 /* XXX: why still return AMR_OK? */ 2559 Error("%s", error); 2560 free(error); 2561 } 2562 } else 2563 Expr_SetValueRefer(expr, ""); 2564 2565 FStr_Done(&cmd); 2566 Expr_Define(expr); 2567 2568 return AMR_OK; 2569 } 2570 2571 /* 2572 * The :range modifier generates an integer sequence as long as the words. 2573 * The :range=7 modifier generates an integer sequence from 1 to 7. 2574 */ 2575 static ApplyModifierResult 2576 ApplyModifier_Range(const char **pp, ModChain *ch) 2577 { 2578 size_t n; 2579 Buffer buf; 2580 size_t i; 2581 2582 const char *mod = *pp; 2583 if (!ModMatchEq(mod, "range", ch)) 2584 return AMR_UNKNOWN; 2585 2586 if (mod[5] == '=') { 2587 const char *p = mod + 6; 2588 if (!TryParseSize(&p, &n)) { 2589 Parse_Error(PARSE_FATAL, 2590 "Invalid number \"%s\" for ':range' modifier", 2591 mod + 6); 2592 return AMR_CLEANUP; 2593 } 2594 *pp = p; 2595 } else { 2596 n = 0; 2597 *pp = mod + 5; 2598 } 2599 2600 if (!ModChain_ShouldEval(ch)) 2601 return AMR_OK; 2602 2603 if (n == 0) { 2604 SubstringWords words = Expr_Words(ch->expr); 2605 n = words.len; 2606 SubstringWords_Free(words); 2607 } 2608 2609 Buf_Init(&buf); 2610 2611 for (i = 0; i < n; i++) { 2612 if (i != 0) { 2613 /* 2614 * XXX: Use ch->sep instead of ' ', for consistency. 2615 */ 2616 Buf_AddByte(&buf, ' '); 2617 } 2618 Buf_AddInt(&buf, 1 + (int)i); 2619 } 2620 2621 Expr_SetValueOwn(ch->expr, Buf_DoneData(&buf)); 2622 return AMR_OK; 2623 } 2624 2625 /* Parse a ':M' or ':N' modifier. */ 2626 static char * 2627 ParseModifier_Match(const char **pp, const ModChain *ch) 2628 { 2629 const char *mod = *pp; 2630 Expr *expr = ch->expr; 2631 bool copy = false; /* pattern should be, or has been, copied */ 2632 bool needSubst = false; 2633 const char *endpat; 2634 char *pattern; 2635 2636 /* 2637 * In the loop below, ignore ':' unless we are at (or back to) the 2638 * original brace level. 2639 * XXX: This will likely not work right if $() and ${} are intermixed. 2640 */ 2641 /* 2642 * XXX: This code is similar to the one in Var_Parse. 2643 * See if the code can be merged. 2644 * See also ApplyModifier_Defined. 2645 */ 2646 int depth = 0; 2647 const char *p; 2648 for (p = mod + 1; *p != '\0' && !(*p == ':' && depth == 0); p++) { 2649 if (*p == '\\' && p[1] != '\0' && 2650 (IsDelimiter(p[1], ch) || p[1] == ch->startc)) { 2651 if (!needSubst) 2652 copy = true; 2653 p++; 2654 continue; 2655 } 2656 if (*p == '$') 2657 needSubst = true; 2658 if (*p == '(' || *p == '{') 2659 depth++; 2660 if (*p == ')' || *p == '}') { 2661 depth--; 2662 if (depth < 0) 2663 break; 2664 } 2665 } 2666 *pp = p; 2667 endpat = p; 2668 2669 if (copy) { 2670 char *dst; 2671 const char *src; 2672 2673 /* Compress the \:'s out of the pattern. */ 2674 pattern = bmake_malloc((size_t)(endpat - (mod + 1)) + 1); 2675 dst = pattern; 2676 src = mod + 1; 2677 for (; src < endpat; src++, dst++) { 2678 if (src[0] == '\\' && src + 1 < endpat && 2679 /* XXX: ch->startc is missing here; see above */ 2680 IsDelimiter(src[1], ch)) 2681 src++; 2682 *dst = *src; 2683 } 2684 *dst = '\0'; 2685 } else { 2686 pattern = bmake_strsedup(mod + 1, endpat); 2687 } 2688 2689 if (needSubst) { 2690 char *old_pattern = pattern; 2691 /* 2692 * XXX: Contrary to ParseModifierPart, a dollar in a ':M' or 2693 * ':N' modifier must be escaped as '$$', not as '\$'. 2694 */ 2695 pattern = Var_Subst(pattern, expr->scope, expr->emode); 2696 /* TODO: handle errors */ 2697 free(old_pattern); 2698 } 2699 2700 DEBUG2(VAR, "Pattern for ':%c' is \"%s\"\n", mod[0], pattern); 2701 2702 return pattern; 2703 } 2704 2705 struct ModifyWord_MatchArgs { 2706 const char *pattern; 2707 bool neg; 2708 bool error_reported; 2709 }; 2710 2711 static void 2712 ModifyWord_Match(Substring word, SepBuf *buf, void *data) 2713 { 2714 struct ModifyWord_MatchArgs *args = data; 2715 StrMatchResult res; 2716 assert(word.end[0] == '\0'); /* assume null-terminated word */ 2717 res = Str_Match(word.start, args->pattern); 2718 if (res.error != NULL && !args->error_reported) { 2719 args->error_reported = true; 2720 Parse_Error(PARSE_WARNING, 2721 "%s in pattern '%s' of modifier '%s'", 2722 res.error, args->pattern, args->neg ? ":N" : ":M"); 2723 } 2724 if (res.matched != args->neg) 2725 SepBuf_AddSubstring(buf, word); 2726 } 2727 2728 /* :Mpattern or :Npattern */ 2729 static ApplyModifierResult 2730 ApplyModifier_Match(const char **pp, ModChain *ch) 2731 { 2732 char mod = **pp; 2733 char *pattern; 2734 2735 pattern = ParseModifier_Match(pp, ch); 2736 2737 if (ModChain_ShouldEval(ch)) { 2738 struct ModifyWord_MatchArgs args; 2739 args.pattern = pattern; 2740 args.neg = mod == 'N'; 2741 args.error_reported = false; 2742 ModifyWords(ch, ModifyWord_Match, &args, ch->oneBigWord); 2743 } 2744 2745 free(pattern); 2746 return AMR_OK; 2747 } 2748 2749 struct ModifyWord_MtimeArgs { 2750 bool error; 2751 bool use_fallback; 2752 ApplyModifierResult rc; 2753 time_t fallback; 2754 }; 2755 2756 static void 2757 ModifyWord_Mtime(Substring word, SepBuf *buf, void *data) 2758 { 2759 struct ModifyWord_MtimeArgs *args = data; 2760 struct stat st; 2761 char tbuf[21]; 2762 2763 if (Substring_IsEmpty(word)) 2764 return; 2765 assert(word.end[0] == '\0'); /* assume null-terminated word */ 2766 if (stat(word.start, &st) < 0) { 2767 if (args->error) { 2768 Parse_Error(PARSE_FATAL, 2769 "Cannot determine mtime for '%s': %s", 2770 word.start, strerror(errno)); 2771 args->rc = AMR_CLEANUP; 2772 return; 2773 } 2774 if (args->use_fallback) 2775 st.st_mtime = args->fallback; 2776 else 2777 time(&st.st_mtime); 2778 } 2779 snprintf(tbuf, sizeof(tbuf), "%u", (unsigned)st.st_mtime); 2780 SepBuf_AddStr(buf, tbuf); 2781 } 2782 2783 /* :mtime */ 2784 static ApplyModifierResult 2785 ApplyModifier_Mtime(const char **pp, ModChain *ch) 2786 { 2787 const char *p, *mod = *pp; 2788 struct ModifyWord_MtimeArgs args; 2789 2790 if (!ModMatchEq(mod, "mtime", ch)) 2791 return AMR_UNKNOWN; 2792 *pp += 5; 2793 p = *pp; 2794 args.error = false; 2795 args.use_fallback = p[0] == '='; 2796 args.rc = AMR_OK; 2797 if (args.use_fallback) { 2798 p++; 2799 if (TryParseTime(&p, &args.fallback)) { 2800 } else if (strncmp(p, "error", 5) == 0) { 2801 p += 5; 2802 args.error = true; 2803 } else 2804 goto invalid_argument; 2805 if (!IsDelimiter(*p, ch)) 2806 goto invalid_argument; 2807 *pp = p; 2808 } 2809 if (ModChain_ShouldEval(ch)) 2810 ModifyWords(ch, ModifyWord_Mtime, &args, ch->oneBigWord); 2811 return args.rc; 2812 2813 invalid_argument: 2814 Parse_Error(PARSE_FATAL, 2815 "Invalid argument '%.*s' for modifier ':mtime'", 2816 (int)strcspn(*pp + 1, ":{}()"), *pp + 1); 2817 return AMR_CLEANUP; 2818 } 2819 2820 static void 2821 ParsePatternFlags(const char **pp, PatternFlags *pflags, bool *oneBigWord) 2822 { 2823 for (;; (*pp)++) { 2824 if (**pp == 'g') 2825 pflags->subGlobal = true; 2826 else if (**pp == '1') 2827 pflags->subOnce = true; 2828 else if (**pp == 'W') 2829 *oneBigWord = true; 2830 else 2831 break; 2832 } 2833 } 2834 2835 MAKE_INLINE PatternFlags 2836 PatternFlags_None(void) 2837 { 2838 PatternFlags pflags = { false, false, false, false }; 2839 return pflags; 2840 } 2841 2842 /* :S,from,to, */ 2843 static ApplyModifierResult 2844 ApplyModifier_Subst(const char **pp, ModChain *ch) 2845 { 2846 struct ModifyWord_SubstArgs args; 2847 bool oneBigWord; 2848 LazyBuf lhsBuf, rhsBuf; 2849 2850 char delim = (*pp)[1]; 2851 if (delim == '\0') { 2852 Error("Missing delimiter for modifier ':S'"); 2853 (*pp)++; 2854 return AMR_CLEANUP; 2855 } 2856 2857 *pp += 2; 2858 2859 args.pflags = PatternFlags_None(); 2860 args.matched = false; 2861 2862 if (**pp == '^') { 2863 args.pflags.anchorStart = true; 2864 (*pp)++; 2865 } 2866 2867 if (!ParseModifierPartSubst(pp, 2868 false, delim, ch->expr->emode, ch, &lhsBuf, &args.pflags, NULL)) 2869 return AMR_CLEANUP; 2870 args.lhs = LazyBuf_Get(&lhsBuf); 2871 2872 if (!ParseModifierPartSubst(pp, 2873 false, delim, ch->expr->emode, ch, &rhsBuf, NULL, &args)) { 2874 LazyBuf_Done(&lhsBuf); 2875 return AMR_CLEANUP; 2876 } 2877 args.rhs = LazyBuf_Get(&rhsBuf); 2878 2879 oneBigWord = ch->oneBigWord; 2880 ParsePatternFlags(pp, &args.pflags, &oneBigWord); 2881 2882 ModifyWords(ch, ModifyWord_Subst, &args, oneBigWord); 2883 2884 LazyBuf_Done(&lhsBuf); 2885 LazyBuf_Done(&rhsBuf); 2886 return AMR_OK; 2887 } 2888 2889 #ifndef NO_REGEX 2890 2891 /* :C,from,to, */ 2892 static ApplyModifierResult 2893 ApplyModifier_Regex(const char **pp, ModChain *ch) 2894 { 2895 struct ModifyWord_SubstRegexArgs args; 2896 bool oneBigWord; 2897 int error; 2898 LazyBuf reBuf, replaceBuf; 2899 FStr re; 2900 2901 char delim = (*pp)[1]; 2902 if (delim == '\0') { 2903 Error("Missing delimiter for :C modifier"); 2904 (*pp)++; 2905 return AMR_CLEANUP; 2906 } 2907 2908 *pp += 2; 2909 2910 if (!ParseModifierPart(pp, delim, ch->expr->emode, ch, &reBuf)) 2911 return AMR_CLEANUP; 2912 re = LazyBuf_DoneGet(&reBuf); 2913 2914 if (!ParseModifierPart(pp, delim, ch->expr->emode, ch, &replaceBuf)) { 2915 FStr_Done(&re); 2916 return AMR_CLEANUP; 2917 } 2918 args.replace = LazyBuf_Get(&replaceBuf); 2919 2920 args.pflags = PatternFlags_None(); 2921 args.matched = false; 2922 oneBigWord = ch->oneBigWord; 2923 ParsePatternFlags(pp, &args.pflags, &oneBigWord); 2924 2925 if (!ModChain_ShouldEval(ch)) 2926 goto done; 2927 2928 error = regcomp(&args.re, re.str, REG_EXTENDED); 2929 if (error != 0) { 2930 RegexError(error, &args.re, "Regex compilation error"); 2931 LazyBuf_Done(&replaceBuf); 2932 FStr_Done(&re); 2933 return AMR_CLEANUP; 2934 } 2935 2936 args.nsub = args.re.re_nsub + 1; 2937 if (args.nsub > 10) 2938 args.nsub = 10; 2939 2940 ModifyWords(ch, ModifyWord_SubstRegex, &args, oneBigWord); 2941 2942 regfree(&args.re); 2943 done: 2944 LazyBuf_Done(&replaceBuf); 2945 FStr_Done(&re); 2946 return AMR_OK; 2947 } 2948 2949 #endif 2950 2951 /* :Q, :q */ 2952 static ApplyModifierResult 2953 ApplyModifier_Quote(const char **pp, ModChain *ch) 2954 { 2955 LazyBuf buf; 2956 bool quoteDollar; 2957 2958 quoteDollar = **pp == 'q'; 2959 if (!IsDelimiter((*pp)[1], ch)) 2960 return AMR_UNKNOWN; 2961 (*pp)++; 2962 2963 if (!ModChain_ShouldEval(ch)) 2964 return AMR_OK; 2965 2966 QuoteShell(Expr_Str(ch->expr), quoteDollar, &buf); 2967 if (buf.data != NULL) 2968 Expr_SetValue(ch->expr, LazyBuf_DoneGet(&buf)); 2969 else 2970 LazyBuf_Done(&buf); 2971 2972 return AMR_OK; 2973 } 2974 2975 /*ARGSUSED*/ 2976 static void 2977 ModifyWord_Copy(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 2978 { 2979 SepBuf_AddSubstring(buf, word); 2980 } 2981 2982 /* :ts<separator> */ 2983 static ApplyModifierResult 2984 ApplyModifier_ToSep(const char **pp, ModChain *ch) 2985 { 2986 const char *sep = *pp + 2; 2987 2988 /* 2989 * Even in parse-only mode, apply the side effects, since the side 2990 * effects are neither observable nor is there a performance penalty. 2991 * Checking for wantRes for every single piece of code in here 2992 * would make the code in this function too hard to read. 2993 */ 2994 2995 /* ":ts<any><endc>" or ":ts<any>:" */ 2996 if (sep[0] != ch->endc && IsDelimiter(sep[1], ch)) { 2997 *pp = sep + 1; 2998 ch->sep = sep[0]; 2999 goto ok; 3000 } 3001 3002 /* ":ts<endc>" or ":ts:" */ 3003 if (IsDelimiter(sep[0], ch)) { 3004 *pp = sep; 3005 ch->sep = '\0'; /* no separator */ 3006 goto ok; 3007 } 3008 3009 /* ":ts<unrecognized><unrecognized>". */ 3010 if (sep[0] != '\\') { 3011 (*pp)++; /* just for backwards compatibility */ 3012 return AMR_BAD; 3013 } 3014 3015 /* ":ts\n" */ 3016 if (sep[1] == 'n') { 3017 *pp = sep + 2; 3018 ch->sep = '\n'; 3019 goto ok; 3020 } 3021 3022 /* ":ts\t" */ 3023 if (sep[1] == 't') { 3024 *pp = sep + 2; 3025 ch->sep = '\t'; 3026 goto ok; 3027 } 3028 3029 /* ":ts\x40" or ":ts\100" */ 3030 { 3031 const char *p = sep + 1; 3032 int base = 8; /* assume octal */ 3033 3034 if (sep[1] == 'x') { 3035 base = 16; 3036 p++; 3037 } else if (!ch_isdigit(sep[1])) { 3038 (*pp)++; /* just for backwards compatibility */ 3039 return AMR_BAD; /* ":ts<backslash><unrecognized>". */ 3040 } 3041 3042 if (!TryParseChar(&p, base, &ch->sep)) { 3043 Parse_Error(PARSE_FATAL, 3044 "Invalid character number at \"%s\"", p); 3045 return AMR_CLEANUP; 3046 } 3047 if (!IsDelimiter(*p, ch)) { 3048 (*pp)++; /* just for backwards compatibility */ 3049 return AMR_BAD; 3050 } 3051 3052 *pp = p; 3053 } 3054 3055 ok: 3056 ModifyWords(ch, ModifyWord_Copy, NULL, ch->oneBigWord); 3057 return AMR_OK; 3058 } 3059 3060 static char * 3061 str_toupper(const char *str) 3062 { 3063 char *res; 3064 size_t i, len; 3065 3066 len = strlen(str); 3067 res = bmake_malloc(len + 1); 3068 for (i = 0; i < len + 1; i++) 3069 res[i] = ch_toupper(str[i]); 3070 3071 return res; 3072 } 3073 3074 static char * 3075 str_tolower(const char *str) 3076 { 3077 char *res; 3078 size_t i, len; 3079 3080 len = strlen(str); 3081 res = bmake_malloc(len + 1); 3082 for (i = 0; i < len + 1; i++) 3083 res[i] = ch_tolower(str[i]); 3084 3085 return res; 3086 } 3087 3088 /* :tA, :tu, :tl, :ts<separator>, etc. */ 3089 static ApplyModifierResult 3090 ApplyModifier_To(const char **pp, ModChain *ch) 3091 { 3092 Expr *expr = ch->expr; 3093 const char *mod = *pp; 3094 assert(mod[0] == 't'); 3095 3096 if (IsDelimiter(mod[1], ch)) { 3097 *pp = mod + 1; 3098 return AMR_BAD; /* Found ":t<endc>" or ":t:". */ 3099 } 3100 3101 if (mod[1] == 's') 3102 return ApplyModifier_ToSep(pp, ch); 3103 3104 if (!IsDelimiter(mod[2], ch)) { /* :t<any><any> */ 3105 *pp = mod + 1; 3106 return AMR_BAD; 3107 } 3108 3109 if (mod[1] == 'A') { /* :tA */ 3110 *pp = mod + 2; 3111 ModifyWords(ch, ModifyWord_Realpath, NULL, ch->oneBigWord); 3112 return AMR_OK; 3113 } 3114 3115 if (mod[1] == 'u') { /* :tu */ 3116 *pp = mod + 2; 3117 if (Expr_ShouldEval(expr)) 3118 Expr_SetValueOwn(expr, str_toupper(Expr_Str(expr))); 3119 return AMR_OK; 3120 } 3121 3122 if (mod[1] == 'l') { /* :tl */ 3123 *pp = mod + 2; 3124 if (Expr_ShouldEval(expr)) 3125 Expr_SetValueOwn(expr, str_tolower(Expr_Str(expr))); 3126 return AMR_OK; 3127 } 3128 3129 if (mod[1] == 'W' || mod[1] == 'w') { /* :tW, :tw */ 3130 *pp = mod + 2; 3131 ch->oneBigWord = mod[1] == 'W'; 3132 return AMR_OK; 3133 } 3134 3135 /* Found ":t<unrecognized>:" or ":t<unrecognized><endc>". */ 3136 *pp = mod + 1; /* XXX: unnecessary but observable */ 3137 return AMR_BAD; 3138 } 3139 3140 /* :[#], :[1], :[-1..1], etc. */ 3141 static ApplyModifierResult 3142 ApplyModifier_Words(const char **pp, ModChain *ch) 3143 { 3144 Expr *expr = ch->expr; 3145 int first, last; 3146 const char *p; 3147 LazyBuf argBuf; 3148 FStr arg; 3149 3150 (*pp)++; /* skip the '[' */ 3151 if (!ParseModifierPart(pp, ']', expr->emode, ch, &argBuf)) 3152 return AMR_CLEANUP; 3153 arg = LazyBuf_DoneGet(&argBuf); 3154 p = arg.str; 3155 3156 if (!IsDelimiter(**pp, ch)) 3157 goto bad_modifier; /* Found junk after ']' */ 3158 3159 if (!ModChain_ShouldEval(ch)) 3160 goto ok; 3161 3162 if (p[0] == '\0') 3163 goto bad_modifier; /* Found ":[]". */ 3164 3165 if (strcmp(p, "#") == 0) { /* Found ":[#]" */ 3166 if (ch->oneBigWord) 3167 Expr_SetValueRefer(expr, "1"); 3168 else { 3169 Buffer buf; 3170 3171 SubstringWords words = Expr_Words(expr); 3172 size_t ac = words.len; 3173 SubstringWords_Free(words); 3174 3175 Buf_Init(&buf); 3176 Buf_AddInt(&buf, (int)ac); 3177 Expr_SetValueOwn(expr, Buf_DoneData(&buf)); 3178 } 3179 goto ok; 3180 } 3181 3182 if (strcmp(p, "*") == 0) { /* ":[*]" */ 3183 ch->oneBigWord = true; 3184 goto ok; 3185 } 3186 3187 if (strcmp(p, "@") == 0) { /* ":[@]" */ 3188 ch->oneBigWord = false; 3189 goto ok; 3190 } 3191 3192 /* Expect ":[N]" or ":[start..end]" */ 3193 if (!TryParseIntBase0(&p, &first)) 3194 goto bad_modifier; 3195 3196 if (p[0] == '\0') /* ":[N]" */ 3197 last = first; 3198 else if (strncmp(p, "..", 2) == 0) { 3199 p += 2; 3200 if (!TryParseIntBase0(&p, &last) || *p != '\0') 3201 goto bad_modifier; 3202 } else 3203 goto bad_modifier; 3204 3205 if (first == 0 && last == 0) { /* ":[0]" or ":[0..0]" */ 3206 ch->oneBigWord = true; 3207 goto ok; 3208 } 3209 3210 if (first == 0 || last == 0) /* ":[0..N]" or ":[N..0]" */ 3211 goto bad_modifier; 3212 3213 Expr_SetValueOwn(expr, 3214 VarSelectWords(Expr_Str(expr), first, last, 3215 ch->sep, ch->oneBigWord)); 3216 3217 ok: 3218 FStr_Done(&arg); 3219 return AMR_OK; 3220 3221 bad_modifier: 3222 FStr_Done(&arg); 3223 return AMR_BAD; 3224 } 3225 3226 #if __STDC_VERSION__ >= 199901L 3227 # define NUM_TYPE long long 3228 # define PARSE_NUM_TYPE strtoll 3229 #else 3230 # define NUM_TYPE long 3231 # define PARSE_NUM_TYPE strtol 3232 #endif 3233 3234 static NUM_TYPE 3235 num_val(Substring s) 3236 { 3237 NUM_TYPE val; 3238 char *ep; 3239 3240 val = PARSE_NUM_TYPE(s.start, &ep, 0); 3241 if (ep != s.start) { 3242 switch (*ep) { 3243 case 'K': 3244 case 'k': 3245 val <<= 10; 3246 break; 3247 case 'M': 3248 case 'm': 3249 val <<= 20; 3250 break; 3251 case 'G': 3252 case 'g': 3253 val <<= 30; 3254 break; 3255 } 3256 } 3257 return val; 3258 } 3259 3260 static int 3261 SubNumAsc(const void *sa, const void *sb) 3262 { 3263 NUM_TYPE a, b; 3264 3265 a = num_val(*((const Substring *)sa)); 3266 b = num_val(*((const Substring *)sb)); 3267 return a > b ? 1 : b > a ? -1 : 0; 3268 } 3269 3270 static int 3271 SubNumDesc(const void *sa, const void *sb) 3272 { 3273 return SubNumAsc(sb, sa); 3274 } 3275 3276 static int 3277 Substring_Cmp(Substring a, Substring b) 3278 { 3279 for (; a.start < a.end && b.start < b.end; a.start++, b.start++) 3280 if (a.start[0] != b.start[0]) 3281 return (unsigned char)a.start[0] 3282 - (unsigned char)b.start[0]; 3283 return (int)((a.end - a.start) - (b.end - b.start)); 3284 } 3285 3286 static int 3287 SubStrAsc(const void *sa, const void *sb) 3288 { 3289 return Substring_Cmp(*(const Substring *)sa, *(const Substring *)sb); 3290 } 3291 3292 static int 3293 SubStrDesc(const void *sa, const void *sb) 3294 { 3295 return SubStrAsc(sb, sa); 3296 } 3297 3298 static void 3299 ShuffleSubstrings(Substring *strs, size_t n) 3300 { 3301 size_t i; 3302 3303 for (i = n - 1; i > 0; i--) { 3304 size_t rndidx = (size_t)random() % (i + 1); 3305 Substring t = strs[i]; 3306 strs[i] = strs[rndidx]; 3307 strs[rndidx] = t; 3308 } 3309 } 3310 3311 /* 3312 * :O order ascending 3313 * :Or order descending 3314 * :Ox shuffle 3315 * :On numeric ascending 3316 * :Onr, :Orn numeric descending 3317 */ 3318 static ApplyModifierResult 3319 ApplyModifier_Order(const char **pp, ModChain *ch) 3320 { 3321 const char *mod = *pp; 3322 SubstringWords words; 3323 int (*cmp)(const void *, const void *); 3324 3325 if (IsDelimiter(mod[1], ch)) { 3326 cmp = SubStrAsc; 3327 (*pp)++; 3328 } else if (IsDelimiter(mod[2], ch)) { 3329 if (mod[1] == 'n') 3330 cmp = SubNumAsc; 3331 else if (mod[1] == 'r') 3332 cmp = SubStrDesc; 3333 else if (mod[1] == 'x') 3334 cmp = NULL; 3335 else 3336 goto bad; 3337 *pp += 2; 3338 } else if (IsDelimiter(mod[3], ch)) { 3339 if ((mod[1] == 'n' && mod[2] == 'r') || 3340 (mod[1] == 'r' && mod[2] == 'n')) 3341 cmp = SubNumDesc; 3342 else 3343 goto bad; 3344 *pp += 3; 3345 } else 3346 goto bad; 3347 3348 if (!ModChain_ShouldEval(ch)) 3349 return AMR_OK; 3350 3351 words = Expr_Words(ch->expr); 3352 if (cmp == NULL) 3353 ShuffleSubstrings(words.words, words.len); 3354 else { 3355 assert(words.words[0].end[0] == '\0'); 3356 qsort(words.words, words.len, sizeof(words.words[0]), cmp); 3357 } 3358 Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words)); 3359 3360 return AMR_OK; 3361 3362 bad: 3363 (*pp)++; 3364 return AMR_BAD; 3365 } 3366 3367 /* :? then : else */ 3368 static ApplyModifierResult 3369 ApplyModifier_IfElse(const char **pp, ModChain *ch) 3370 { 3371 Expr *expr = ch->expr; 3372 LazyBuf thenBuf; 3373 LazyBuf elseBuf; 3374 3375 VarEvalMode then_emode = VARE_PARSE_ONLY; 3376 VarEvalMode else_emode = VARE_PARSE_ONLY; 3377 3378 CondResult cond_rc = CR_TRUE; /* just not CR_ERROR */ 3379 if (Expr_ShouldEval(expr)) { 3380 cond_rc = Cond_EvalCondition(expr->name); 3381 if (cond_rc == CR_TRUE) 3382 then_emode = expr->emode; 3383 if (cond_rc == CR_FALSE) 3384 else_emode = expr->emode; 3385 } 3386 3387 (*pp)++; /* skip past the '?' */ 3388 if (!ParseModifierPart(pp, ':', then_emode, ch, &thenBuf)) 3389 return AMR_CLEANUP; 3390 3391 if (!ParseModifierPart(pp, ch->endc, else_emode, ch, &elseBuf)) { 3392 LazyBuf_Done(&thenBuf); 3393 return AMR_CLEANUP; 3394 } 3395 3396 (*pp)--; /* Go back to the ch->endc. */ 3397 3398 if (cond_rc == CR_ERROR) { 3399 Substring thenExpr = LazyBuf_Get(&thenBuf); 3400 Substring elseExpr = LazyBuf_Get(&elseBuf); 3401 Error("Bad conditional expression '%s' before '?%.*s:%.*s'", 3402 expr->name, 3403 (int)Substring_Length(thenExpr), thenExpr.start, 3404 (int)Substring_Length(elseExpr), elseExpr.start); 3405 LazyBuf_Done(&thenBuf); 3406 LazyBuf_Done(&elseBuf); 3407 return AMR_CLEANUP; 3408 } 3409 3410 if (!Expr_ShouldEval(expr)) { 3411 LazyBuf_Done(&thenBuf); 3412 LazyBuf_Done(&elseBuf); 3413 } else if (cond_rc == CR_TRUE) { 3414 Expr_SetValue(expr, LazyBuf_DoneGet(&thenBuf)); 3415 LazyBuf_Done(&elseBuf); 3416 } else { 3417 LazyBuf_Done(&thenBuf); 3418 Expr_SetValue(expr, LazyBuf_DoneGet(&elseBuf)); 3419 } 3420 Expr_Define(expr); 3421 return AMR_OK; 3422 } 3423 3424 /* 3425 * The ::= modifiers are special in that they do not read the variable value 3426 * but instead assign to that variable. They always expand to an empty 3427 * string. 3428 * 3429 * Their main purpose is in supporting .for loops that generate shell commands 3430 * since an ordinary variable assignment at that point would terminate the 3431 * dependency group for these targets. For example: 3432 * 3433 * list-targets: .USE 3434 * .for i in ${.TARGET} ${.TARGET:R}.gz 3435 * @${t::=$i} 3436 * @echo 'The target is ${t:T}.' 3437 * .endfor 3438 * 3439 * ::=<str> Assigns <str> as the new value of variable. 3440 * ::?=<str> Assigns <str> as value of variable if 3441 * it was not already set. 3442 * ::+=<str> Appends <str> to variable. 3443 * ::!=<cmd> Assigns output of <cmd> as the new value of 3444 * variable. 3445 */ 3446 static ApplyModifierResult 3447 ApplyModifier_Assign(const char **pp, ModChain *ch) 3448 { 3449 Expr *expr = ch->expr; 3450 GNode *scope; 3451 FStr val; 3452 LazyBuf buf; 3453 3454 const char *mod = *pp; 3455 const char *op = mod + 1; 3456 3457 if (op[0] == '=') 3458 goto found_op; 3459 if ((op[0] == '+' || op[0] == '?' || op[0] == '!') && op[1] == '=') 3460 goto found_op; 3461 return AMR_UNKNOWN; /* "::<unrecognized>" */ 3462 3463 found_op: 3464 if (expr->name[0] == '\0') { 3465 *pp = mod + 1; 3466 return AMR_BAD; 3467 } 3468 3469 *pp = mod + (op[0] != '=' ? 3 : 2); 3470 3471 if (!ParseModifierPart(pp, ch->endc, expr->emode, ch, &buf)) 3472 return AMR_CLEANUP; 3473 val = LazyBuf_DoneGet(&buf); 3474 3475 (*pp)--; /* Go back to the ch->endc. */ 3476 3477 if (!Expr_ShouldEval(expr)) 3478 goto done; 3479 3480 scope = expr->scope; /* scope where v belongs */ 3481 if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL 3482 && VarFind(expr->name, expr->scope, false) == NULL) 3483 scope = SCOPE_GLOBAL; 3484 3485 if (op[0] == '+') 3486 Var_Append(scope, expr->name, val.str); 3487 else if (op[0] == '!') { 3488 char *output, *error; 3489 output = Cmd_Exec(val.str, &error); 3490 if (error != NULL) { 3491 Error("%s", error); 3492 free(error); 3493 } else 3494 Var_Set(scope, expr->name, output); 3495 free(output); 3496 } else if (op[0] == '?' && expr->defined == DEF_REGULAR) { 3497 /* Do nothing. */ 3498 } else 3499 Var_Set(scope, expr->name, val.str); 3500 3501 Expr_SetValueRefer(expr, ""); 3502 3503 done: 3504 FStr_Done(&val); 3505 return AMR_OK; 3506 } 3507 3508 /* 3509 * :_=... 3510 * remember current value 3511 */ 3512 static ApplyModifierResult 3513 ApplyModifier_Remember(const char **pp, ModChain *ch) 3514 { 3515 Expr *expr = ch->expr; 3516 const char *mod = *pp; 3517 FStr name; 3518 3519 if (!ModMatchEq(mod, "_", ch)) 3520 return AMR_UNKNOWN; 3521 3522 name = FStr_InitRefer("_"); 3523 if (mod[1] == '=') { 3524 /* 3525 * XXX: This ad-hoc call to strcspn deviates from the usual 3526 * behavior defined in ParseModifierPart. This creates an 3527 * unnecessary and undocumented inconsistency in make. 3528 */ 3529 const char *arg = mod + 2; 3530 size_t argLen = strcspn(arg, ":)}"); 3531 *pp = arg + argLen; 3532 name = FStr_InitOwn(bmake_strldup(arg, argLen)); 3533 } else 3534 *pp = mod + 1; 3535 3536 if (Expr_ShouldEval(expr)) 3537 Var_Set(SCOPE_GLOBAL, name.str, Expr_Str(expr)); 3538 FStr_Done(&name); 3539 3540 return AMR_OK; 3541 } 3542 3543 /* 3544 * Apply the given function to each word of the variable value, 3545 * for a single-letter modifier such as :H, :T. 3546 */ 3547 static ApplyModifierResult 3548 ApplyModifier_WordFunc(const char **pp, ModChain *ch, 3549 ModifyWordProc modifyWord) 3550 { 3551 if (!IsDelimiter((*pp)[1], ch)) 3552 return AMR_UNKNOWN; 3553 (*pp)++; 3554 3555 if (ModChain_ShouldEval(ch)) 3556 ModifyWords(ch, modifyWord, NULL, ch->oneBigWord); 3557 3558 return AMR_OK; 3559 } 3560 3561 /* Remove adjacent duplicate words. */ 3562 static ApplyModifierResult 3563 ApplyModifier_Unique(const char **pp, ModChain *ch) 3564 { 3565 SubstringWords words; 3566 3567 if (!IsDelimiter((*pp)[1], ch)) 3568 return AMR_UNKNOWN; 3569 (*pp)++; 3570 3571 if (!ModChain_ShouldEval(ch)) 3572 return AMR_OK; 3573 3574 words = Expr_Words(ch->expr); 3575 3576 if (words.len > 1) { 3577 size_t di, si; 3578 3579 di = 0; 3580 for (si = 1; si < words.len; si++) { 3581 if (!Substring_Eq(words.words[si], words.words[di])) { 3582 di++; 3583 if (di != si) 3584 words.words[di] = words.words[si]; 3585 } 3586 } 3587 words.len = di + 1; 3588 } 3589 3590 Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words)); 3591 3592 return AMR_OK; 3593 } 3594 3595 #ifdef SYSVVARSUB 3596 /* Test whether the modifier has the form '<lhs>=<rhs>'. */ 3597 static bool 3598 IsSysVModifier(const char *p, char startc, char endc) 3599 { 3600 bool eqFound = false; 3601 3602 int depth = 1; 3603 while (*p != '\0' && depth > 0) { 3604 if (*p == '=') /* XXX: should also test depth == 1 */ 3605 eqFound = true; 3606 else if (*p == endc) 3607 depth--; 3608 else if (*p == startc) 3609 depth++; 3610 if (depth > 0) 3611 p++; 3612 } 3613 return *p == endc && eqFound; 3614 } 3615 3616 /* :from=to */ 3617 static ApplyModifierResult 3618 ApplyModifier_SysV(const char **pp, ModChain *ch) 3619 { 3620 Expr *expr = ch->expr; 3621 LazyBuf lhsBuf, rhsBuf; 3622 FStr rhs; 3623 struct ModifyWord_SysVSubstArgs args; 3624 Substring lhs; 3625 const char *lhsSuffix; 3626 3627 const char *mod = *pp; 3628 3629 if (!IsSysVModifier(mod, ch->startc, ch->endc)) 3630 return AMR_UNKNOWN; 3631 3632 if (!ParseModifierPart(pp, '=', expr->emode, ch, &lhsBuf)) 3633 return AMR_CLEANUP; 3634 3635 /* 3636 * The SysV modifier lasts until the end of the expression. 3637 */ 3638 if (!ParseModifierPart(pp, ch->endc, expr->emode, ch, &rhsBuf)) { 3639 LazyBuf_Done(&lhsBuf); 3640 return AMR_CLEANUP; 3641 } 3642 rhs = LazyBuf_DoneGet(&rhsBuf); 3643 3644 (*pp)--; /* Go back to the ch->endc. */ 3645 3646 /* Do not turn an empty expression into non-empty. */ 3647 if (lhsBuf.len == 0 && Expr_Str(expr)[0] == '\0') 3648 goto done; 3649 3650 lhs = LazyBuf_Get(&lhsBuf); 3651 lhsSuffix = Substring_SkipFirst(lhs, '%'); 3652 3653 args.scope = expr->scope; 3654 args.lhsPrefix = Substring_Init(lhs.start, 3655 lhsSuffix != lhs.start ? lhsSuffix - 1 : lhs.start); 3656 args.lhsPercent = lhsSuffix != lhs.start; 3657 args.lhsSuffix = Substring_Init(lhsSuffix, lhs.end); 3658 args.rhs = rhs.str; 3659 3660 ModifyWords(ch, ModifyWord_SysVSubst, &args, ch->oneBigWord); 3661 3662 done: 3663 LazyBuf_Done(&lhsBuf); 3664 FStr_Done(&rhs); 3665 return AMR_OK; 3666 } 3667 #endif 3668 3669 #ifdef SUNSHCMD 3670 /* :sh */ 3671 static ApplyModifierResult 3672 ApplyModifier_SunShell(const char **pp, ModChain *ch) 3673 { 3674 Expr *expr = ch->expr; 3675 const char *p = *pp; 3676 if (!(p[1] == 'h' && IsDelimiter(p[2], ch))) 3677 return AMR_UNKNOWN; 3678 *pp = p + 2; 3679 3680 if (Expr_ShouldEval(expr)) { 3681 char *output, *error; 3682 output = Cmd_Exec(Expr_Str(expr), &error); 3683 if (error != NULL) { 3684 Error("%s", error); 3685 free(error); 3686 } 3687 Expr_SetValueOwn(expr, output); 3688 } 3689 3690 return AMR_OK; 3691 } 3692 #endif 3693 3694 /* 3695 * In cases where the evaluation mode and the definedness are the "standard" 3696 * ones, don't log them, to keep the logs readable. 3697 */ 3698 static bool 3699 ShouldLogInSimpleFormat(const Expr *expr) 3700 { 3701 return (expr->emode == VARE_WANTRES || 3702 expr->emode == VARE_UNDEFERR) && 3703 expr->defined == DEF_REGULAR; 3704 } 3705 3706 static void 3707 LogBeforeApply(const ModChain *ch, const char *mod) 3708 { 3709 const Expr *expr = ch->expr; 3710 bool is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], ch); 3711 3712 /* 3713 * At this point, only the first character of the modifier can 3714 * be used since the end of the modifier is not yet known. 3715 */ 3716 3717 if (!Expr_ShouldEval(expr)) { 3718 debug_printf("Parsing modifier ${%s:%c%s}\n", 3719 expr->name, mod[0], is_single_char ? "" : "..."); 3720 return; 3721 } 3722 3723 if (ShouldLogInSimpleFormat(expr)) { 3724 debug_printf( 3725 "Evaluating modifier ${%s:%c%s} on value \"%s\"\n", 3726 expr->name, mod[0], is_single_char ? "" : "...", 3727 Expr_Str(expr)); 3728 return; 3729 } 3730 3731 debug_printf( 3732 "Evaluating modifier ${%s:%c%s} on value \"%s\" (%s, %s)\n", 3733 expr->name, mod[0], is_single_char ? "" : "...", Expr_Str(expr), 3734 VarEvalMode_Name[expr->emode], ExprDefined_Name[expr->defined]); 3735 } 3736 3737 static void 3738 LogAfterApply(const ModChain *ch, const char *p, const char *mod) 3739 { 3740 const Expr *expr = ch->expr; 3741 const char *value = Expr_Str(expr); 3742 const char *quot = value == var_Error ? "" : "\""; 3743 3744 if (ShouldLogInSimpleFormat(expr)) { 3745 debug_printf("Result of ${%s:%.*s} is %s%s%s\n", 3746 expr->name, (int)(p - mod), mod, 3747 quot, value == var_Error ? "error" : value, quot); 3748 return; 3749 } 3750 3751 debug_printf("Result of ${%s:%.*s} is %s%s%s (%s, %s)\n", 3752 expr->name, (int)(p - mod), mod, 3753 quot, value == var_Error ? "error" : value, quot, 3754 VarEvalMode_Name[expr->emode], 3755 ExprDefined_Name[expr->defined]); 3756 } 3757 3758 static ApplyModifierResult 3759 ApplyModifier(const char **pp, ModChain *ch) 3760 { 3761 switch (**pp) { 3762 case '!': 3763 return ApplyModifier_ShellCommand(pp, ch); 3764 case ':': 3765 return ApplyModifier_Assign(pp, ch); 3766 case '?': 3767 return ApplyModifier_IfElse(pp, ch); 3768 case '@': 3769 return ApplyModifier_Loop(pp, ch); 3770 case '[': 3771 return ApplyModifier_Words(pp, ch); 3772 case '_': 3773 return ApplyModifier_Remember(pp, ch); 3774 #ifndef NO_REGEX 3775 case 'C': 3776 return ApplyModifier_Regex(pp, ch); 3777 #endif 3778 case 'D': 3779 case 'U': 3780 return ApplyModifier_Defined(pp, ch); 3781 case 'E': 3782 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Suffix); 3783 case 'g': 3784 case 'l': 3785 return ApplyModifier_Time(pp, ch); 3786 case 'H': 3787 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Head); 3788 case 'h': 3789 return ApplyModifier_Hash(pp, ch); 3790 case 'L': 3791 return ApplyModifier_Literal(pp, ch); 3792 case 'M': 3793 case 'N': 3794 return ApplyModifier_Match(pp, ch); 3795 case 'm': 3796 return ApplyModifier_Mtime(pp, ch); 3797 case 'O': 3798 return ApplyModifier_Order(pp, ch); 3799 case 'P': 3800 return ApplyModifier_Path(pp, ch); 3801 case 'Q': 3802 case 'q': 3803 return ApplyModifier_Quote(pp, ch); 3804 case 'R': 3805 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Root); 3806 case 'r': 3807 return ApplyModifier_Range(pp, ch); 3808 case 'S': 3809 return ApplyModifier_Subst(pp, ch); 3810 #ifdef SUNSHCMD 3811 case 's': 3812 return ApplyModifier_SunShell(pp, ch); 3813 #endif 3814 case 'T': 3815 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Tail); 3816 case 't': 3817 return ApplyModifier_To(pp, ch); 3818 case 'u': 3819 return ApplyModifier_Unique(pp, ch); 3820 default: 3821 return AMR_UNKNOWN; 3822 } 3823 } 3824 3825 static void ApplyModifiers(Expr *, const char **, char, char); 3826 3827 typedef enum ApplyModifiersIndirectResult { 3828 /* The indirect modifiers have been applied successfully. */ 3829 AMIR_CONTINUE, 3830 /* Fall back to the SysV modifier. */ 3831 AMIR_SYSV, 3832 /* Error out. */ 3833 AMIR_OUT 3834 } ApplyModifiersIndirectResult; 3835 3836 /* 3837 * While expanding an expression, expand and apply indirect modifiers, 3838 * such as in ${VAR:${M_indirect}}. 3839 * 3840 * All indirect modifiers of a group must come from a single 3841 * expression. ${VAR:${M1}} is valid but ${VAR:${M1}${M2}} is not. 3842 * 3843 * Multiple groups of indirect modifiers can be chained by separating them 3844 * with colons. ${VAR:${M1}:${M2}} contains 2 indirect modifiers. 3845 * 3846 * If the expression is not followed by ch->endc or ':', fall 3847 * back to trying the SysV modifier, such as in ${VAR:${FROM}=${TO}}. 3848 */ 3849 static ApplyModifiersIndirectResult 3850 ApplyModifiersIndirect(ModChain *ch, const char **pp) 3851 { 3852 Expr *expr = ch->expr; 3853 const char *p = *pp; 3854 FStr mods = Var_Parse(&p, expr->scope, expr->emode); 3855 /* TODO: handle errors */ 3856 3857 if (mods.str[0] != '\0' && !IsDelimiter(*p, ch)) { 3858 FStr_Done(&mods); 3859 return AMIR_SYSV; 3860 } 3861 3862 DEBUG3(VAR, "Indirect modifier \"%s\" from \"%.*s\"\n", 3863 mods.str, (int)(p - *pp), *pp); 3864 3865 if (mods.str[0] != '\0') { 3866 const char *modsp = mods.str; 3867 ApplyModifiers(expr, &modsp, '\0', '\0'); 3868 if (Expr_Str(expr) == var_Error || *modsp != '\0') { 3869 FStr_Done(&mods); 3870 *pp = p; 3871 return AMIR_OUT; /* error already reported */ 3872 } 3873 } 3874 FStr_Done(&mods); 3875 3876 if (*p == ':') 3877 p++; 3878 else if (*p == '\0' && ch->endc != '\0') { 3879 Error("Unclosed expression after indirect modifier, " 3880 "expecting '%c' for variable \"%s\"", 3881 ch->endc, expr->name); 3882 *pp = p; 3883 return AMIR_OUT; 3884 } 3885 3886 *pp = p; 3887 return AMIR_CONTINUE; 3888 } 3889 3890 static ApplyModifierResult 3891 ApplySingleModifier(const char **pp, ModChain *ch) 3892 { 3893 ApplyModifierResult res; 3894 const char *mod = *pp; 3895 const char *p = *pp; 3896 3897 if (DEBUG(VAR)) 3898 LogBeforeApply(ch, mod); 3899 3900 res = ApplyModifier(&p, ch); 3901 3902 #ifdef SYSVVARSUB 3903 if (res == AMR_UNKNOWN) { 3904 assert(p == mod); 3905 res = ApplyModifier_SysV(&p, ch); 3906 } 3907 #endif 3908 3909 if (res == AMR_UNKNOWN) { 3910 /* 3911 * Guess the end of the current modifier. 3912 * XXX: Skipping the rest of the modifier hides 3913 * errors and leads to wrong results. 3914 * Parsing should rather stop here. 3915 */ 3916 for (p++; !IsDelimiter(*p, ch); p++) 3917 continue; 3918 Parse_Error(PARSE_FATAL, "Unknown modifier \"%.*s\"", 3919 (int)(p - mod), mod); 3920 Expr_SetValueRefer(ch->expr, var_Error); 3921 } 3922 if (res == AMR_CLEANUP || res == AMR_BAD) { 3923 *pp = p; 3924 return res; 3925 } 3926 3927 if (DEBUG(VAR)) 3928 LogAfterApply(ch, p, mod); 3929 3930 if (*p == '\0' && ch->endc != '\0') { 3931 Error( 3932 "Unclosed expression, expecting '%c' for " 3933 "modifier \"%.*s\" of variable \"%s\" with value \"%s\"", 3934 ch->endc, 3935 (int)(p - mod), mod, 3936 ch->expr->name, Expr_Str(ch->expr)); 3937 } else if (*p == ':') { 3938 p++; 3939 } else if (opts.strict && *p != '\0' && *p != ch->endc) { 3940 Parse_Error(PARSE_FATAL, 3941 "Missing delimiter ':' after modifier \"%.*s\"", 3942 (int)(p - mod), mod); 3943 /* 3944 * TODO: propagate parse error to the enclosing 3945 * expression 3946 */ 3947 } 3948 *pp = p; 3949 return AMR_OK; 3950 } 3951 3952 #if __STDC_VERSION__ >= 199901L 3953 #define ModChain_Init(expr, startc, endc, sep, oneBigWord) \ 3954 (ModChain) { expr, startc, endc, sep, oneBigWord } 3955 #else 3956 MAKE_INLINE ModChain 3957 ModChain_Init(Expr *expr, char startc, char endc, char sep, bool oneBigWord) 3958 { 3959 ModChain ch; 3960 ch.expr = expr; 3961 ch.startc = startc; 3962 ch.endc = endc; 3963 ch.sep = sep; 3964 ch.oneBigWord = oneBigWord; 3965 return ch; 3966 } 3967 #endif 3968 3969 /* Apply any modifiers (such as :Mpattern or :@var@loop@ or :Q or ::=value). */ 3970 static void 3971 ApplyModifiers( 3972 Expr *expr, 3973 const char **pp, /* the parsing position, updated upon return */ 3974 char startc, /* '(' or '{'; or '\0' for indirect modifiers */ 3975 char endc /* ')' or '}'; or '\0' for indirect modifiers */ 3976 ) 3977 { 3978 ModChain ch = ModChain_Init(expr, startc, endc, ' ', false); 3979 const char *p; 3980 const char *mod; 3981 3982 assert(startc == '(' || startc == '{' || startc == '\0'); 3983 assert(endc == ')' || endc == '}' || endc == '\0'); 3984 assert(Expr_Str(expr) != NULL); 3985 3986 p = *pp; 3987 3988 if (*p == '\0' && endc != '\0') { 3989 Error( 3990 "Unclosed expression, expecting '%c' for \"%s\"", 3991 ch.endc, expr->name); 3992 goto cleanup; 3993 } 3994 3995 while (*p != '\0' && *p != endc) { 3996 ApplyModifierResult res; 3997 3998 if (*p == '$') { 3999 /* 4000 * TODO: Only evaluate the expression once, no matter 4001 * whether it's an indirect modifier or the initial 4002 * part of a SysV modifier. 4003 */ 4004 ApplyModifiersIndirectResult amir = 4005 ApplyModifiersIndirect(&ch, &p); 4006 if (amir == AMIR_CONTINUE) 4007 continue; 4008 if (amir == AMIR_OUT) 4009 break; 4010 } 4011 4012 mod = p; 4013 4014 res = ApplySingleModifier(&p, &ch); 4015 if (res == AMR_CLEANUP) 4016 goto cleanup; 4017 if (res == AMR_BAD) 4018 goto bad_modifier; 4019 } 4020 4021 *pp = p; 4022 assert(Expr_Str(expr) != NULL); /* Use var_Error or varUndefined. */ 4023 return; 4024 4025 bad_modifier: 4026 /* Take a guess at where the modifier ends. */ 4027 Error("Bad modifier \":%.*s\" for variable \"%s\"", 4028 (int)strcspn(mod, ":)}"), mod, expr->name); 4029 4030 cleanup: 4031 /* 4032 * TODO: Use p + strlen(p) instead, to stop parsing immediately. 4033 * 4034 * In the unit tests, this generates a few shell commands with 4035 * unbalanced quotes. Instead of producing these incomplete strings, 4036 * commands with evaluation errors should not be run at all. 4037 * 4038 * To make that happen, Var_Subst must report the actual errors 4039 * instead of returning the resulting string unconditionally. 4040 */ 4041 *pp = p; 4042 Expr_SetValueRefer(expr, var_Error); 4043 } 4044 4045 /* 4046 * Only 4 of the 7 built-in local variables are treated specially as they are 4047 * the only ones that will be set when dynamic sources are expanded. 4048 */ 4049 static bool 4050 VarnameIsDynamic(Substring varname) 4051 { 4052 const char *name; 4053 size_t len; 4054 4055 name = varname.start; 4056 len = Substring_Length(varname); 4057 if (len == 1 || (len == 2 && (name[1] == 'F' || name[1] == 'D'))) { 4058 switch (name[0]) { 4059 case '@': 4060 case '%': 4061 case '*': 4062 case '!': 4063 return true; 4064 } 4065 return false; 4066 } 4067 4068 if ((len == 7 || len == 8) && name[0] == '.' && ch_isupper(name[1])) { 4069 return Substring_Equals(varname, ".TARGET") || 4070 Substring_Equals(varname, ".ARCHIVE") || 4071 Substring_Equals(varname, ".PREFIX") || 4072 Substring_Equals(varname, ".MEMBER"); 4073 } 4074 4075 return false; 4076 } 4077 4078 static const char * 4079 UndefinedShortVarValue(char varname, const GNode *scope) 4080 { 4081 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) { 4082 /* 4083 * If substituting a local variable in a non-local scope, 4084 * assume it's for dynamic source stuff. We have to handle 4085 * this specially and return the longhand for the variable 4086 * with the dollar sign escaped so it makes it back to the 4087 * caller. Only four of the local variables are treated 4088 * specially as they are the only four that will be set 4089 * when dynamic sources are expanded. 4090 */ 4091 switch (varname) { 4092 case '@': 4093 return "$(.TARGET)"; 4094 case '%': 4095 return "$(.MEMBER)"; 4096 case '*': 4097 return "$(.PREFIX)"; 4098 case '!': 4099 return "$(.ARCHIVE)"; 4100 } 4101 } 4102 return NULL; 4103 } 4104 4105 /* 4106 * Parse a variable name, until the end character or a colon, whichever 4107 * comes first. 4108 */ 4109 static void 4110 ParseVarname(const char **pp, char startc, char endc, 4111 GNode *scope, VarEvalMode emode, 4112 LazyBuf *buf) 4113 { 4114 const char *p = *pp; 4115 int depth = 0; 4116 4117 LazyBuf_Init(buf, p); 4118 4119 while (*p != '\0') { 4120 if ((*p == endc || *p == ':') && depth == 0) 4121 break; 4122 if (*p == startc) 4123 depth++; 4124 if (*p == endc) 4125 depth--; 4126 4127 if (*p == '$') { 4128 FStr nested_val = Var_Parse(&p, scope, emode); 4129 /* TODO: handle errors */ 4130 LazyBuf_AddStr(buf, nested_val.str); 4131 FStr_Done(&nested_val); 4132 } else { 4133 LazyBuf_Add(buf, *p); 4134 p++; 4135 } 4136 } 4137 *pp = p; 4138 } 4139 4140 static bool 4141 IsShortVarnameValid(char varname, const char *start) 4142 { 4143 if (varname != '$' && varname != ':' && varname != '}' && 4144 varname != ')' && varname != '\0') 4145 return true; 4146 4147 if (!opts.strict) 4148 return false; /* XXX: Missing error message */ 4149 4150 if (varname == '$') 4151 Parse_Error(PARSE_FATAL, 4152 "To escape a dollar, use \\$, not $$, at \"%s\"", start); 4153 else if (varname == '\0') 4154 Parse_Error(PARSE_FATAL, "Dollar followed by nothing"); 4155 else 4156 Parse_Error(PARSE_FATAL, 4157 "Invalid variable name '%c', at \"%s\"", varname, start); 4158 4159 return false; 4160 } 4161 4162 /* 4163 * Parse a single-character variable name such as in $V or $@. 4164 * Return whether to continue parsing. 4165 */ 4166 static bool 4167 ParseVarnameShort(char varname, const char **pp, GNode *scope, 4168 VarEvalMode emode, 4169 const char **out_false_val, 4170 Var **out_true_var) 4171 { 4172 char name[2]; 4173 Var *v; 4174 const char *val; 4175 4176 if (!IsShortVarnameValid(varname, *pp)) { 4177 (*pp)++; /* only skip the '$' */ 4178 *out_false_val = var_Error; 4179 return false; 4180 } 4181 4182 name[0] = varname; 4183 name[1] = '\0'; 4184 v = VarFind(name, scope, true); 4185 if (v != NULL) { 4186 /* No need to advance *pp, the calling code handles this. */ 4187 *out_true_var = v; 4188 return true; 4189 } 4190 4191 *pp += 2; 4192 4193 val = UndefinedShortVarValue(varname, scope); 4194 if (val == NULL) 4195 val = emode == VARE_UNDEFERR ? var_Error : varUndefined; 4196 4197 if (opts.strict && val == var_Error) { 4198 Parse_Error(PARSE_FATAL, 4199 "Variable \"%s\" is undefined", name); 4200 } 4201 4202 *out_false_val = val; 4203 return false; 4204 } 4205 4206 /* Find variables like @F or <D. */ 4207 static Var * 4208 FindLocalLegacyVar(Substring varname, GNode *scope, 4209 const char **out_extraModifiers) 4210 { 4211 Var *v; 4212 4213 /* Only resolve these variables if scope is a "real" target. */ 4214 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) 4215 return NULL; 4216 4217 if (Substring_Length(varname) != 2) 4218 return NULL; 4219 if (varname.start[1] != 'F' && varname.start[1] != 'D') 4220 return NULL; 4221 if (strchr("@%?*!<>", varname.start[0]) == NULL) 4222 return NULL; 4223 4224 v = VarFindSubstring(Substring_Init(varname.start, varname.start + 1), 4225 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 *out_value = emode == VARE_PARSE_ONLY 4402 ? FStr_InitRefer("") 4403 : FStr_InitOwn(bmake_strsedup(*pp + 4, p)); 4404 *pp = p + 1; 4405 return true; 4406 } 4407 4408 /* 4409 * Given the start of an expression (such as $v, $(VAR), ${VAR:Mpattern}), 4410 * extract the variable name and the modifiers, if any. While parsing, apply 4411 * the modifiers to the value of the expression. 4412 * 4413 * Input: 4414 * *pp The string to parse. 4415 * When called from CondParser_FuncCallEmpty, it can 4416 * also point to the "y" of "empty(VARNAME:Modifiers)". 4417 * scope The scope for finding variables. 4418 * emode Controls the exact details of parsing and evaluation. 4419 * 4420 * Output: 4421 * *pp The position where to continue parsing. 4422 * TODO: After a parse error, the value of *pp is 4423 * unspecified. It may not have been updated at all, 4424 * point to some random character in the string, to the 4425 * location of the parse error, or at the end of the 4426 * string. 4427 * return The value of the expression, never NULL. 4428 * return var_Error if there was a parse error. 4429 * return var_Error if the base variable of the expression was 4430 * undefined, emode is VARE_UNDEFERR, and none of 4431 * the modifiers turned the undefined expression into a 4432 * defined expression. 4433 * XXX: It is not guaranteed that an error message has 4434 * been printed. 4435 * return varUndefined if the base variable of the expression 4436 * was undefined, emode was not VARE_UNDEFERR, 4437 * and none of the modifiers turned the undefined 4438 * expression into a defined expression. 4439 * XXX: It is not guaranteed that an error message has 4440 * been printed. 4441 */ 4442 FStr 4443 Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) 4444 { 4445 const char *p = *pp; 4446 const char *const start = p; 4447 bool haveModifier; /* true for ${VAR:...}, false for ${VAR} */ 4448 char startc; /* the actual '{' or '(' or '\0' */ 4449 char endc; /* the expected '}' or ')' or '\0' */ 4450 /* 4451 * true if the expression is based on one of the 7 predefined 4452 * variables that are local to a target, and the expression is 4453 * expanded in a non-local scope. The result is the text of the 4454 * expression, unaltered. This is needed to support dynamic sources. 4455 */ 4456 bool dynamic; 4457 const char *extramodifiers; 4458 Var *v; 4459 Expr expr = Expr_Init(NULL, FStr_InitRefer(NULL), emode, 4460 scope, DEF_REGULAR); 4461 FStr val; 4462 4463 if (Var_Parse_FastLane(pp, emode, &val)) 4464 return val; 4465 4466 DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]); 4467 4468 val = FStr_InitRefer(NULL); 4469 extramodifiers = NULL; /* extra modifiers to apply first */ 4470 dynamic = false; 4471 4472 endc = '\0'; /* Appease GCC. */ 4473 4474 startc = p[1]; 4475 if (startc != '(' && startc != '{') { 4476 if (!ParseVarnameShort(startc, pp, scope, emode, &val.str, &v)) 4477 return val; 4478 haveModifier = false; 4479 p++; 4480 } else { 4481 if (!ParseVarnameLong(&p, startc, scope, emode, 4482 pp, &val, 4483 &endc, &v, &haveModifier, &extramodifiers, 4484 &dynamic, &expr.defined)) 4485 return val; 4486 } 4487 4488 expr.name = v->name.str; 4489 if (v->inUse && VarEvalMode_ShouldEval(emode)) { 4490 if (scope->fname != NULL) { 4491 fprintf(stderr, "In a command near "); 4492 PrintLocation(stderr, false, scope); 4493 } 4494 Fatal("Variable %s is recursive.", v->name.str); 4495 } 4496 4497 /* 4498 * FIXME: This assignment creates an alias to the current value of the 4499 * variable. This means that as long as the value of the expression 4500 * stays the same, the value of the variable must not change, and the 4501 * variable must not be deleted. Using the ':@' modifier, it is 4502 * possible (since var.c 1.212 from 2017-02-01) to delete the variable 4503 * while its value is still being used: 4504 * 4505 * VAR= value 4506 * _:= ${VAR:${:U@VAR@loop@}:S,^,prefix,} 4507 * 4508 * The same effect might be achievable using the '::=' or the ':_' 4509 * modifiers. 4510 * 4511 * At the bottom of this function, the resulting value is compared to 4512 * the then-current value of the variable. This might also invoke 4513 * undefined behavior. 4514 */ 4515 expr.value = FStr_InitRefer(v->val.data); 4516 4517 /* 4518 * Before applying any modifiers, expand any nested expressions from 4519 * the variable value. 4520 */ 4521 if (VarEvalMode_ShouldEval(emode) && 4522 strchr(Expr_Str(&expr), '$') != NULL) { 4523 char *expanded; 4524 VarEvalMode nested_emode = emode; 4525 if (opts.strict) 4526 nested_emode = VarEvalMode_UndefOk(nested_emode); 4527 v->inUse = true; 4528 expanded = Var_Subst(Expr_Str(&expr), scope, nested_emode); 4529 v->inUse = false; 4530 /* TODO: handle errors */ 4531 Expr_SetValueOwn(&expr, expanded); 4532 } 4533 4534 if (extramodifiers != NULL) { 4535 const char *em = extramodifiers; 4536 ApplyModifiers(&expr, &em, '\0', '\0'); 4537 } 4538 4539 if (haveModifier) { 4540 p++; /* Skip initial colon. */ 4541 ApplyModifiers(&expr, &p, startc, endc); 4542 } 4543 4544 if (*p != '\0') /* Skip past endc if possible. */ 4545 p++; 4546 4547 *pp = p; 4548 4549 if (expr.defined == DEF_UNDEF) { 4550 if (dynamic) 4551 Expr_SetValueOwn(&expr, bmake_strsedup(start, p)); 4552 else { 4553 /* 4554 * The expression is still undefined, therefore 4555 * discard the actual value and return an error marker 4556 * instead. 4557 */ 4558 Expr_SetValueRefer(&expr, 4559 emode == VARE_UNDEFERR 4560 ? var_Error : varUndefined); 4561 } 4562 } 4563 4564 if (v->shortLived) { 4565 if (expr.value.str == v->val.data) { 4566 /* move ownership */ 4567 expr.value.freeIt = v->val.data; 4568 v->val.data = NULL; 4569 } 4570 VarFreeShortLived(v); 4571 } 4572 4573 return expr.value; 4574 } 4575 4576 static void 4577 VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalMode emode) 4578 { 4579 /* A dollar sign may be escaped with another dollar sign. */ 4580 if (save_dollars && VarEvalMode_ShouldKeepDollar(emode)) 4581 Buf_AddByte(res, '$'); 4582 Buf_AddByte(res, '$'); 4583 *pp += 2; 4584 } 4585 4586 static void 4587 VarSubstExpr(const char **pp, Buffer *buf, GNode *scope, 4588 VarEvalMode emode, bool *inout_errorReported) 4589 { 4590 const char *p = *pp; 4591 const char *nested_p = p; 4592 FStr val = Var_Parse(&nested_p, scope, emode); 4593 /* TODO: handle errors */ 4594 4595 if (val.str == var_Error || val.str == varUndefined) { 4596 if (!VarEvalMode_ShouldKeepUndef(emode)) { 4597 p = nested_p; 4598 } else if (val.str == var_Error) { 4599 4600 /* 4601 * FIXME: The condition 'val.str == var_Error' doesn't 4602 * mean there was an undefined variable. It could 4603 * equally well be a parse error; see 4604 * unit-tests/varmod-order.mk. 4605 */ 4606 4607 /* 4608 * If variable is undefined, complain and skip the 4609 * variable. The complaint will stop us from doing 4610 * anything when the file is parsed. 4611 */ 4612 if (!*inout_errorReported) { 4613 Parse_Error(PARSE_FATAL, 4614 "Undefined variable \"%.*s\"", 4615 (int)(nested_p - p), p); 4616 *inout_errorReported = true; 4617 } 4618 p = nested_p; 4619 } else { 4620 /* 4621 * Copy the initial '$' of the undefined expression, 4622 * thereby deferring expansion of the expression, but 4623 * expand nested expressions if already possible. See 4624 * unit-tests/varparse-undef-partial.mk. 4625 */ 4626 Buf_AddByte(buf, *p); 4627 p++; 4628 } 4629 } else { 4630 p = nested_p; 4631 Buf_AddStr(buf, val.str); 4632 } 4633 4634 FStr_Done(&val); 4635 4636 *pp = p; 4637 } 4638 4639 /* 4640 * Skip as many characters as possible -- either to the end of the string, 4641 * or to the next dollar sign, which may start an expression. 4642 */ 4643 static void 4644 VarSubstPlain(const char **pp, Buffer *res) 4645 { 4646 const char *p = *pp; 4647 const char *start = p; 4648 4649 for (p++; *p != '$' && *p != '\0'; p++) 4650 continue; 4651 Buf_AddRange(res, start, p); 4652 *pp = p; 4653 } 4654 4655 /* 4656 * Expand all expressions like $V, ${VAR}, $(VAR:Modifiers) in the 4657 * given string. 4658 * 4659 * Input: 4660 * str The string in which the expressions are 4661 * expanded. 4662 * scope The scope in which to start searching for 4663 * variables. The other scopes are searched as well. 4664 * emode The mode for parsing or evaluating subexpressions. 4665 */ 4666 char * 4667 Var_Subst(const char *str, GNode *scope, VarEvalMode emode) 4668 { 4669 const char *p = str; 4670 Buffer res; 4671 4672 /* 4673 * Set true if an error has already been reported, to prevent a 4674 * plethora of messages when recursing 4675 */ 4676 static bool errorReported; 4677 4678 Buf_Init(&res); 4679 errorReported = false; 4680 4681 while (*p != '\0') { 4682 if (p[0] == '$' && p[1] == '$') 4683 VarSubstDollarDollar(&p, &res, emode); 4684 else if (p[0] == '$') 4685 VarSubstExpr(&p, &res, scope, emode, &errorReported); 4686 else 4687 VarSubstPlain(&p, &res); 4688 } 4689 4690 return Buf_DoneDataCompact(&res); 4691 } 4692 4693 void 4694 Var_Expand(FStr *str, GNode *scope, VarEvalMode emode) 4695 { 4696 char *expanded; 4697 4698 if (strchr(str->str, '$') == NULL) 4699 return; 4700 expanded = Var_Subst(str->str, scope, emode); 4701 /* TODO: handle errors */ 4702 FStr_Done(str); 4703 *str = FStr_InitOwn(expanded); 4704 } 4705 4706 /* Initialize the variables module. */ 4707 void 4708 Var_Init(void) 4709 { 4710 SCOPE_INTERNAL = GNode_New("Internal"); 4711 SCOPE_GLOBAL = GNode_New("Global"); 4712 SCOPE_CMDLINE = GNode_New("Command"); 4713 } 4714 4715 /* Clean up the variables module. */ 4716 void 4717 Var_End(void) 4718 { 4719 Var_Stats(); 4720 } 4721 4722 void 4723 Var_Stats(void) 4724 { 4725 HashTable_DebugStats(&SCOPE_GLOBAL->vars, "Global variables"); 4726 } 4727 4728 static int 4729 StrAsc(const void *sa, const void *sb) 4730 { 4731 return strcmp( 4732 *((const char *const *)sa), *((const char *const *)sb)); 4733 } 4734 4735 4736 /* Print all variables in a scope, sorted by name. */ 4737 void 4738 Var_Dump(GNode *scope) 4739 { 4740 Vector /* of const char * */ vec; 4741 HashIter hi; 4742 size_t i; 4743 const char **varnames; 4744 4745 Vector_Init(&vec, sizeof(const char *)); 4746 4747 HashIter_Init(&hi, &scope->vars); 4748 while (HashIter_Next(&hi) != NULL) 4749 *(const char **)Vector_Push(&vec) = hi.entry->key; 4750 varnames = vec.items; 4751 4752 qsort(varnames, vec.len, sizeof varnames[0], StrAsc); 4753 4754 for (i = 0; i < vec.len; i++) { 4755 const char *varname = varnames[i]; 4756 const Var *var = HashTable_FindValue(&scope->vars, varname); 4757 debug_printf("%-16s = %s%s\n", varname, 4758 var->val.data, ValueDescription(var->val.data)); 4759 } 4760 4761 Vector_Done(&vec); 4762 } 4763