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