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