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