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