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