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