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