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