1 /* $OpenPackages$ */ 2 /* $OpenBSD: var.c,v 1.57 2003/06/03 02:56:12 millert Exp $ */ 3 /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ 4 5 /* 6 * Copyright (c) 1999,2000 Marc Espie. 7 * 8 * Extensive code modifications for the OpenBSD project. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD 23 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * Copyright (c) 1988, 1989, 1990, 1993 33 * The Regents of the University of California. All rights reserved. 34 * Copyright (c) 1989 by Berkeley Softworks 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to Berkeley by 38 * Adam de Boor. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 */ 64 65 #include <sys/types.h> 66 #include <assert.h> 67 #include <stddef.h> 68 #include <stdio.h> 69 #include <stdlib.h> 70 #include <string.h> 71 72 #include "config.h" 73 #include "defines.h" 74 #include "buf.h" 75 #include "stats.h" 76 #include "ohash.h" 77 #include "varmodifiers.h" 78 #include "var.h" 79 #include "varname.h" 80 #include "error.h" 81 #include "str.h" 82 #include "var_int.h" 83 #include "memory.h" 84 #include "symtable.h" 85 #include "gnode.h" 86 87 /* extended indices for System V stuff */ 88 #define FTARGET_INDEX 7 89 #define DTARGET_INDEX 8 90 #define FPREFIX_INDEX 9 91 #define DPREFIX_INDEX 10 92 #define FARCHIVE_INDEX 11 93 #define DARCHIVE_INDEX 12 94 #define FMEMBER_INDEX 13 95 #define DMEMBER_INDEX 14 96 97 #define EXTENDED2SIMPLE(i) (((i)-LOCAL_SIZE)/2) 98 #define IS_EXTENDED_F(i) ((i)%2 == 1) 99 100 /* 101 * This is a harmless return value for Var_Parse that can be used by Var_Subst 102 * to determine if there was an error in parsing -- easier than returning 103 * a flag, as things outside this module don't give a hoot. 104 */ 105 char var_Error[] = ""; 106 107 /* 108 * Similar to var_Error, but returned when the 'err' flag for Var_Parse is 109 * set false. Why not just use a constant? Well, gcc likes to condense 110 * identical string instances... 111 */ 112 static char varNoError[] = ""; 113 114 /* 115 * Variable values are obtained from four different contexts: 116 * 1) the process environment. The process environment itself 117 * may not be changed, but these variables may be modified, 118 * unless make is invoked with -e, in which case those variables 119 * are unmodifiable and supersede the global context. 120 * 2) the global context. Variables set in the Makefile are located in 121 * the global context. It is the penultimate context searched when 122 * substituting. 123 * 3) the command-line context. All variables set on the command line 124 * are placed in this context. They are UNALTERABLE once placed here. 125 * 4) the local context. Each target has associated with it a context 126 * list. On this list are located the structures describing such 127 * local variables as $(@) and $(*) 128 * The four contexts are searched in the reverse order from which they are 129 * listed. 130 */ 131 GSymT *VAR_GLOBAL; /* variables from the makefile */ 132 GSymT *VAR_CMD; /* variables defined on the command-line */ 133 134 static SymTable *CTXT_GLOBAL, *CTXT_CMD; 135 136 137 static char *varnames[] = { 138 TARGET, 139 PREFIX, 140 ARCHIVE, 141 MEMBER, 142 OODATE, 143 ALLSRC, 144 IMPSRC, 145 FTARGET, 146 DTARGET, 147 FPREFIX, 148 DPREFIX, 149 FARCHIVE, 150 DARCHIVE, 151 FMEMBER, 152 DMEMBER 153 }; 154 155 156 #define FIND_MINE 0x1 /* look in CTXT_CMD and CTXT_GLOBAL */ 157 #define FIND_ENV 0x2 /* look in the environment */ 158 159 typedef struct Var_ { 160 BUFFER val; /* its value */ 161 unsigned int flags; /* miscellaneous status flags */ 162 #define VAR_IN_USE 1 /* Variable's value currently being used. 163 * Used to avoid recursion */ 164 #define VAR_READ_ONLY 2 /* Environment variable not modifiable */ 165 #define VAR_FROM_ENV 4 /* Var was read from env */ 166 #define VAR_DUMMY 8 /* Var does not exist, actually */ 167 char name[1]; /* the variable's name */ 168 } Var; 169 170 171 static struct ohash_info var_info = { 172 offsetof(Var, name), 173 NULL, hash_alloc, hash_free, element_alloc }; 174 static int quick_lookup(const char *, const char **, u_int32_t *); 175 #define VarValue(v) Buf_Retrieve(&((v)->val)) 176 static Var *varfind(const char *, const char *, SymTable *, int, int, u_int32_t); 177 static Var *VarFindi(const char *, const char *, SymTable *, int); 178 static Var *VarAdd(const char *, const char *, u_int32_t, const char *, GSymT *); 179 static void VarDelete(void *); 180 static void VarPrintVar(Var *); 181 static const char *context_name(GSymT *); 182 static Var *new_var(const char *, const char *, const char *); 183 static Var *getvar(GSymT *, const char *, const char *, u_int32_t); 184 static Var *create_var(const char *, const char *); 185 static Var *var_from_env(const char *, const char *, u_int32_t); 186 static void var_init_string(Var *, const char *); 187 188 static const char *find_0(const char *); 189 static const char *find_rparen(const char *); 190 static const char *find_ket(const char *); 191 typedef const char * (*find_t)(const char *); 192 static find_t find_pos(int); 193 194 /* retrieve the hashed values for well-known variables. */ 195 #include "varhashconsts.h" 196 197 void 198 SymTable_Init(ctxt) 199 SymTable *ctxt; 200 { 201 static SymTable sym_template; 202 memcpy(ctxt, &sym_template, sizeof(*ctxt)); 203 } 204 205 #ifdef CLEANUP 206 void 207 SymTable_Destroy(ctxt) 208 SymTable *ctxt; 209 { 210 int i; 211 212 for (i = 0; i < LOCAL_SIZE; i++) 213 if (ctxt->locals[i] != NULL) 214 VarDelete(ctxt->locals[i]); 215 } 216 #endif 217 218 static int 219 quick_lookup(name, end, pk) 220 const char *name; 221 const char **end; 222 u_int32_t *pk; 223 { 224 size_t len; 225 226 *pk = ohash_interval(name, end); 227 len = *end - name; 228 /* substitute short version for long local name */ 229 switch (*pk % MAGICSLOTS1) { /* MAGICSLOTS should be the */ 230 case K_LONGALLSRC % MAGICSLOTS1: /* smallest constant yielding */ 231 /* distinct case values */ 232 if (*pk == K_LONGALLSRC && len == strlen(LONGALLSRC) && 233 strncmp(name, LONGALLSRC, len) == 0) 234 return ALLSRC_INDEX; 235 break; 236 case K_LONGARCHIVE % MAGICSLOTS1: 237 if (*pk == K_LONGARCHIVE && len == strlen(LONGARCHIVE) && 238 strncmp(name, LONGARCHIVE, len) == 0) 239 return ARCHIVE_INDEX; 240 break; 241 case K_LONGIMPSRC % MAGICSLOTS1: 242 if (*pk == K_LONGIMPSRC && len == strlen(LONGIMPSRC) && 243 strncmp(name, LONGIMPSRC, len) == 0) 244 return IMPSRC_INDEX; 245 break; 246 case K_LONGMEMBER % MAGICSLOTS1: 247 if (*pk == K_LONGMEMBER && len == strlen(LONGMEMBER) && 248 strncmp(name, LONGMEMBER, len) == 0) 249 return MEMBER_INDEX; 250 break; 251 case K_LONGOODATE % MAGICSLOTS1: 252 if (*pk == K_LONGOODATE && len == strlen(LONGOODATE) && 253 strncmp(name, LONGOODATE, len) == 0) 254 return OODATE_INDEX; 255 break; 256 case K_LONGPREFIX % MAGICSLOTS1: 257 if (*pk == K_LONGPREFIX && len == strlen(LONGPREFIX) && 258 strncmp(name, LONGPREFIX, len) == 0) 259 return PREFIX_INDEX; 260 break; 261 case K_LONGTARGET % MAGICSLOTS1: 262 if (*pk == K_LONGTARGET && len == strlen(LONGTARGET) && 263 strncmp(name, LONGTARGET, len) == 0) 264 return TARGET_INDEX; 265 break; 266 case K_TARGET % MAGICSLOTS1: 267 if (name[0] == TARGET[0] && len == 1) 268 return TARGET_INDEX; 269 break; 270 case K_OODATE % MAGICSLOTS1: 271 if (name[0] == OODATE[0] && len == 1) 272 return OODATE_INDEX; 273 break; 274 case K_ALLSRC % MAGICSLOTS1: 275 if (name[0] == ALLSRC[0] && len == 1) 276 return ALLSRC_INDEX; 277 break; 278 case K_IMPSRC % MAGICSLOTS1: 279 if (name[0] == IMPSRC[0] && len == 1) 280 return IMPSRC_INDEX; 281 break; 282 case K_PREFIX % MAGICSLOTS1: 283 if (name[0] == PREFIX[0] && len == 1) 284 return PREFIX_INDEX; 285 break; 286 case K_ARCHIVE % MAGICSLOTS1: 287 if (name[0] == ARCHIVE[0] && len == 1) 288 return ARCHIVE_INDEX; 289 break; 290 case K_MEMBER % MAGICSLOTS1: 291 if (name[0] == MEMBER[0] && len == 1) 292 return MEMBER_INDEX; 293 break; 294 case K_FTARGET % MAGICSLOTS1: 295 if (name[0] == FTARGET[0] && name[1] == FTARGET[1] && len == 2) 296 return FTARGET_INDEX; 297 break; 298 case K_DTARGET % MAGICSLOTS1: 299 if (name[0] == DTARGET[0] && name[1] == DTARGET[1] && len == 2) 300 return DTARGET_INDEX; 301 break; 302 case K_FPREFIX % MAGICSLOTS1: 303 if (name[0] == FPREFIX[0] && name[1] == FPREFIX[1] && len == 2) 304 return FPREFIX_INDEX; 305 break; 306 case K_DPREFIX % MAGICSLOTS1: 307 if (name[0] == DPREFIX[0] && name[1] == DPREFIX[1] && len == 2) 308 return DPREFIX_INDEX; 309 break; 310 case K_FARCHIVE % MAGICSLOTS1: 311 if (name[0] == FARCHIVE[0] && name[1] == FARCHIVE[1] && len == 2) 312 return FARCHIVE_INDEX; 313 break; 314 case K_DARCHIVE % MAGICSLOTS1: 315 if (name[0] == DARCHIVE[0] && name[1] == DARCHIVE[1] && len == 2) 316 return DARCHIVE_INDEX; 317 break; 318 case K_FMEMBER % MAGICSLOTS1: 319 if (name[0] == FMEMBER[0] && name[1] == FMEMBER[1] && len == 2) 320 return FMEMBER_INDEX; 321 break; 322 case K_DMEMBER % MAGICSLOTS1: 323 if (name[0] == DMEMBER[0] && name[1] == DMEMBER[1] && len == 2) 324 return DMEMBER_INDEX; 325 break; 326 default: 327 break; 328 } 329 return -1; 330 } 331 332 void 333 Varq_Set(idx, val, gn) 334 int idx; 335 const char *val; 336 GNode *gn; 337 { 338 /* We only look for a variable in the given context since anything set 339 * here will override anything in a lower context, so there's not much 340 * point in searching them all just to save a bit of memory... */ 341 Var *v = gn->context.locals[idx]; 342 343 if (v == NULL) { 344 v = new_var(varnames[idx], NULL, val); 345 v->flags = 0; 346 gn->context.locals[idx] = v; 347 } else { 348 Buf_Reset(&(v->val)); 349 Buf_AddString(&(v->val), val); 350 351 } 352 if (DEBUG(VAR)) 353 printf("%s:%s = %s\n", gn->name, varnames[idx], val); 354 } 355 356 void 357 Varq_Append(idx, val, gn) 358 int idx; 359 const char *val; 360 GNode *gn; 361 { 362 Var *v = gn->context.locals[idx]; 363 364 if (v == NULL) { 365 v = new_var(varnames[idx], NULL, val); 366 v->flags = 0; 367 gn->context.locals[idx] = v; 368 } else { 369 Buf_AddSpace(&(v->val)); 370 Buf_AddString(&(v->val), val); 371 } 372 if (DEBUG(VAR)) 373 printf("%s:%s = %s\n", gn->name, varnames[idx], VarValue(v)); 374 } 375 376 char * 377 Varq_Value(idx, gn) 378 int idx; 379 GNode *gn; 380 { 381 Var *v = gn->context.locals[idx]; 382 383 if (v == NULL) 384 return NULL; 385 else 386 return VarValue(v); 387 } 388 389 static const char * 390 context_name(ctxt) 391 GSymT *ctxt; 392 { 393 if (ctxt == VAR_GLOBAL) 394 return "Global"; 395 if (ctxt == VAR_CMD) 396 return "Command"; 397 return "Error"; 398 } 399 400 /* We separate var creation proper from setting of initial value: 401 * VAR_DUMMY corresponds to `lazy' setup, e.g., always create global 402 * variable at first lookup, and then fill it up when value is wanted. 403 * This avoids looking through the environment several times. 404 */ 405 static Var * 406 create_var(name, end) 407 const char *name; 408 const char *end; 409 { 410 return ohash_create_entry(&var_info, name, &end); 411 } 412 413 /* Set the initial value a var should have */ 414 static void 415 var_init_string(v, val) 416 Var *v; 417 const char *val; 418 { 419 size_t len; 420 421 len = strlen(val); 422 Buf_Init(&(v->val), len+1); 423 Buf_AddChars(&(v->val), len, val); 424 } 425 426 static Var * 427 new_var(name, end, val) 428 const char *name; 429 const char *end; 430 const char *val; 431 { 432 Var *v; 433 434 v = create_var(name, end); 435 #ifdef STATS_VAR_LOOKUP 436 STAT_VAR_CREATION++; 437 #endif 438 if (val != NULL) 439 var_init_string(v, val); 440 else 441 Buf_Init(&(v->val), 1); 442 443 return v; 444 } 445 446 static Var * 447 var_from_env(name, end, k) 448 const char *name; 449 const char *end; 450 u_int32_t k; 451 { 452 char *env; 453 Var *v; 454 455 /* getenv requires a null-terminated name, so we create the var 456 * structure first. */ 457 v = create_var(name, end); 458 env = getenv(v->name); 459 if (env == NULL) 460 v->flags = VAR_DUMMY; 461 else { 462 var_init_string(v, env); 463 if (checkEnvFirst) 464 v->flags = VAR_READ_ONLY | VAR_FROM_ENV; 465 else 466 v->flags = VAR_FROM_ENV; 467 } 468 469 #ifdef STATS_VAR_LOOKUP 470 STAT_VAR_FROM_ENV++; 471 #endif 472 473 ohash_insert(VAR_GLOBAL, ohash_lookup_interval(VAR_GLOBAL, name, end, k), v); 474 return v; 475 } 476 477 static Var * 478 getvar(ctxt, name, end, k) 479 GSymT *ctxt; 480 const char *name; 481 const char *end; 482 u_int32_t k; 483 { 484 return ohash_find(ctxt, ohash_lookup_interval(ctxt, name, end, k)); 485 } 486 487 /*- 488 *----------------------------------------------------------------------- 489 * VarFindi -- 490 * Find the given variable in the given context and any other contexts 491 * indicated. if end is NULL, name is a string, otherwise, only 492 * the interval name - end is concerned. 493 * 494 * Results: 495 * A pointer to the structure describing the desired variable or 496 * NULL if the variable does not exist. 497 *----------------------------------------------------------------------- 498 */ 499 static Var * 500 VarFindi(name, end, ctxt, flags) 501 const char *name; /* name to find */ 502 const char *end; /* end of name */ 503 SymTable *ctxt; /* context in which to find it */ 504 int flags; /* FIND_MINE set means to look in the 505 * CTXT_GLOBAL and CTXT_CMD contexts also. 506 * FIND_ENV set means to look in the 507 * environment */ 508 { 509 u_int32_t k; 510 int idx; 511 512 #ifdef STATS_VAR_LOOKUP 513 STAT_VAR_FIND++; 514 #endif 515 516 idx = quick_lookup(name, &end, &k); 517 return varfind(name, end, ctxt, flags, idx, k); 518 } 519 520 static Var * 521 varfind(name, end, ctxt, flags, idx, k) 522 const char *name; 523 const char *end; 524 SymTable *ctxt; 525 int flags; 526 int idx; 527 u_int32_t k; 528 { 529 Var *v; 530 531 /* Handle local variables first */ 532 if (idx != -1) { 533 if (ctxt != NULL && ctxt != CTXT_CMD && ctxt != CTXT_GLOBAL) { 534 if (idx < LOCAL_SIZE) 535 return ctxt->locals[idx]; 536 else 537 return ctxt->locals[EXTENDED2SIMPLE(idx)]; 538 } else 539 return NULL; 540 } 541 /* First look for the variable in the given context. If it's not there, 542 look for it in CTXT_CMD, CTXT_GLOBAL and the environment, 543 depending on the FIND_* flags in 'flags' */ 544 if (ctxt == CTXT_CMD || ctxt == CTXT_GLOBAL) 545 v = getvar((GSymT *)ctxt, name, end, k); 546 else 547 v = NULL; 548 549 if (v == NULL) 550 switch (flags) { 551 case 0: 552 break; 553 case FIND_MINE: 554 if (ctxt != CTXT_CMD) 555 v = getvar(VAR_CMD, name, end, k); 556 if (v == NULL && ctxt != CTXT_GLOBAL) 557 v = getvar(VAR_GLOBAL, name, end, k); 558 break; 559 case FIND_ENV: 560 v = var_from_env(name, end, k); 561 break; 562 case FIND_ENV | FIND_MINE: 563 if (ctxt != CTXT_CMD) 564 v = getvar(VAR_CMD, name, end, k); 565 if (v == NULL) { 566 if (ctxt != CTXT_GLOBAL) 567 v = getvar(VAR_GLOBAL, name, end, k); 568 if (v == NULL) 569 v = var_from_env(name, end, k); 570 else if (checkEnvFirst && (v->flags & VAR_FROM_ENV) == 0) { 571 char *env; 572 573 env = getenv(v->name); 574 if (env != NULL) { 575 Buf_Reset(&(v->val)); 576 Buf_AddString(&(v->val), env); 577 } 578 /* XXX even if no such env variable, fake it, to avoid 579 * further lookup */ 580 v->flags |= VAR_FROM_ENV; 581 } 582 } 583 break; 584 } 585 return v; 586 } 587 588 /*- 589 *----------------------------------------------------------------------- 590 * VarAdd -- 591 * Add a new variable of name name and value val to the given context 592 * 593 * Results: 594 * The added variable. 595 * 596 * Side Effects: 597 * The new variable is placed in the given context. 598 * The name and val arguments are duplicated so they may 599 * safely be freed. 600 *----------------------------------------------------------------------- 601 */ 602 static Var * 603 VarAdd(name, end, k, val, ctxt) 604 const char *name; /* name of variable to add */ 605 const char *end; 606 u_int32_t k; 607 const char *val; /* value to set it to */ 608 GSymT *ctxt; /* context in which to set it */ 609 { 610 Var *v; 611 612 v = new_var(name, end, val); 613 614 v->flags = 0; 615 616 ohash_insert(ctxt, ohash_lookup_interval(ctxt, name, end, k), v); 617 if (DEBUG(VAR)) 618 printf("%s:%s = %s\n", context_name(ctxt), v->name, val); 619 return v; 620 } 621 622 /*- 623 *----------------------------------------------------------------------- 624 * VarDelete -- 625 * Delete a variable and all the space associated with it. 626 *----------------------------------------------------------------------- 627 */ 628 static void 629 VarDelete(vp) 630 void *vp; 631 { 632 Var *v = (Var *)vp; 633 634 if ((v->flags & VAR_DUMMY) == 0) 635 Buf_Destroy(&(v->val)); 636 free(v); 637 } 638 639 640 641 void 642 Var_Delete(name) 643 const char *name; 644 { 645 Var *v; 646 u_int32_t k; 647 unsigned int slot; 648 const char *end = NULL; 649 int idx; 650 651 652 if (DEBUG(VAR)) 653 printf("delete %s\n", name); 654 655 idx = quick_lookup(name, &end, &k); 656 if (idx != -1) 657 Parse_Error(PARSE_FATAL, "Trying to delete dynamic variable"); 658 slot = ohash_lookup_interval(VAR_GLOBAL, name, end, k); 659 v = ohash_find(VAR_GLOBAL, slot); 660 if (v != NULL && (v->flags & VAR_READ_ONLY) == 0) { 661 ohash_remove(VAR_GLOBAL, slot); 662 VarDelete(v); 663 } 664 } 665 666 /* The variable is searched for only in its context before being 667 * created in that context. I.e. if the context is CTXT_GLOBAL, 668 * only CTXT_GLOBAL is searched. Likewise if it is CTXT_CMD, only 669 * CTXT_CMD is searched. 670 */ 671 void 672 Var_Seti(name, end, val, ctxt) 673 const char *name; /* name of variable to set */ 674 const char *end; 675 const char *val; /* value to give to the variable */ 676 GSymT *ctxt; /* context in which to set it */ 677 { 678 Var *v; 679 u_int32_t k; 680 int idx; 681 682 idx = quick_lookup(name, &end, &k); 683 if (idx != -1) 684 Parse_Error(PARSE_FATAL, "Trying to set dynamic variable $%s", 685 varnames[idx]); 686 687 /* We only look for a variable in the given context since anything set 688 * here will override anything in a lower context, so there's not much 689 * point in searching them all just to save a bit of memory... */ 690 v = varfind(name, end, (SymTable *)ctxt, 0, idx, k); 691 if (v == NULL) 692 v = VarAdd(name, end, k, val, ctxt); 693 else { 694 if ((v->flags & VAR_READ_ONLY) == 0) { 695 if ((v->flags & VAR_DUMMY) == 0) { 696 Buf_Reset(&(v->val)); 697 Buf_AddString(&(v->val), val); 698 } else { 699 var_init_string(v, val); 700 v->flags &= ~VAR_DUMMY; 701 } 702 703 } 704 } 705 if (DEBUG(VAR)) 706 printf("%s:%s = %s\n", context_name(ctxt), v->name, val); 707 /* Any variables given on the command line are automatically exported 708 * to the environment (as per POSIX standard). */ 709 if (ctxt == VAR_CMD) 710 esetenv(v->name, val); 711 } 712 713 void 714 Var_Appendi(name, end, val, ctxt) 715 const char *name; /* Name of variable to modify */ 716 const char *end; 717 const char *val; /* String to append to it */ 718 GSymT *ctxt; /* Context in which this should occur */ 719 { 720 Var *v; 721 u_int32_t k; 722 int idx; 723 724 assert(ctxt == VAR_GLOBAL || ctxt == VAR_CMD); 725 726 idx = quick_lookup(name, &end, &k); 727 if (idx != -1) 728 Parse_Error(PARSE_FATAL, "Trying to append to dynamic variable $%s", 729 varnames[idx]); 730 731 v = varfind(name, end, (SymTable *)ctxt, FIND_ENV, idx, k); 732 733 if ((v->flags & VAR_READ_ONLY) == 0) { 734 if ((v->flags & VAR_DUMMY) == 0) { 735 Buf_AddSpace(&(v->val)); 736 Buf_AddString(&(v->val), val); 737 } else { 738 var_init_string(v, val); 739 v->flags &= ~VAR_DUMMY; 740 } 741 742 } 743 if (DEBUG(VAR)) 744 printf("%s:%s = %s\n", context_name(ctxt), v->name, VarValue(v)); 745 } 746 747 char * 748 Var_Valuei(name, end) 749 const char *name; /* name to find */ 750 const char *end; 751 { 752 Var *v; 753 754 v = VarFindi(name, end, NULL, FIND_ENV | FIND_MINE); 755 if (v != NULL && (v->flags & VAR_DUMMY) == 0) 756 return VarValue(v); 757 else 758 return NULL; 759 } 760 761 static const char * 762 find_0(p) 763 const char *p; 764 { 765 while (*p != '$' && *p != '\0' && *p != ':') 766 p++; 767 return p; 768 } 769 770 static const char * 771 find_rparen(p) 772 const char *p; 773 { 774 while (*p != '$' && *p != '\0' && *p != ')' && *p != ':') 775 p++; 776 return p; 777 } 778 779 static const char * 780 find_ket(p) 781 const char *p; 782 { 783 while (*p != '$' && *p != '\0' && *p != '}' && *p != ':') 784 p++; 785 return p; 786 } 787 788 static find_t 789 find_pos(c) 790 int c; 791 { 792 switch(c) { 793 case '\0': 794 return find_0; 795 case ')': 796 return find_rparen; 797 case '}': 798 return find_ket; 799 default: 800 return 0; 801 } 802 } 803 804 size_t 805 Var_ParseSkip(str, ctxt, result) 806 const char *str; 807 SymTable *ctxt; 808 bool *result; 809 { 810 const char *tstr; /* Pointer into str */ 811 Var *v; /* Variable in invocation */ 812 char endc; /* Ending character when variable in parens 813 * or braces */ 814 const char *start; 815 size_t length; 816 struct Name name; 817 818 v = NULL; 819 start = str; 820 str++; 821 822 if (*str != '(' && *str != '{') { 823 name.tofree = false; 824 tstr = str + 1; 825 length = 2; 826 endc = '\0'; 827 } else { 828 endc = *str == '(' ? ')' : '}'; 829 str++; 830 831 /* Find eventual modifiers in the variable */ 832 tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc)); 833 VarName_Free(&name); 834 length = tstr - start; 835 if (*tstr != 0) 836 length++; 837 } 838 839 if (result != NULL) 840 *result = true; 841 if (*tstr == ':' && endc != '\0') 842 if (VarModifiers_Apply(NULL, NULL, ctxt, true, NULL, tstr, endc, 843 &length) == var_Error) 844 *result = false; 845 return length; 846 } 847 848 /* As of now, Var_ParseBuffer is just a wrapper around Var_Parse. For 849 * speed, it may be better to revisit the implementation to do things 850 * directly. */ 851 bool 852 Var_ParseBuffer(buf, str, ctxt, err, lengthPtr) 853 Buffer buf; 854 const char *str; 855 SymTable *ctxt; 856 bool err; 857 size_t *lengthPtr; 858 { 859 char *result; 860 bool freeIt; 861 862 result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt); 863 if (result == var_Error) 864 return false; 865 866 Buf_AddString(buf, result); 867 if (freeIt) 868 free(result); 869 return true; 870 } 871 872 char * 873 Var_Parse(str, ctxt, err, lengthPtr, freePtr) 874 const char *str; /* The string to parse */ 875 SymTable *ctxt; /* The context for the variable */ 876 bool err; /* true if undefined variables are an error */ 877 size_t *lengthPtr; /* OUT: The length of the specification */ 878 bool *freePtr; /* OUT: true if caller should free result */ 879 { 880 const char *tstr; /* Pointer into str */ 881 Var *v; /* Variable in invocation */ 882 char endc; /* Ending character when variable in parens 883 * or braces */ 884 struct Name name; 885 const char *start; 886 char *val; /* Variable value */ 887 u_int32_t k; 888 int idx; 889 890 *freePtr = false; 891 start = str++; 892 893 val = NULL; 894 v = NULL; 895 idx = -1; 896 897 if (*str != '(' && *str != '{') { 898 name.s = str; 899 name.e = str+1; 900 name.tofree = false; 901 tstr = str + 1; 902 *lengthPtr = 2; 903 endc = '\0'; 904 } else { 905 endc = *str == '(' ? ')' : '}'; 906 str++; 907 908 /* Find eventual modifiers in the variable */ 909 tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc)); 910 *lengthPtr = tstr - start; 911 if (*tstr != '\0') 912 (*lengthPtr)++; 913 } 914 915 idx = quick_lookup(name.s, &name.e, &k); 916 v = varfind(name.s, name.e, ctxt, FIND_ENV | FIND_MINE, idx, k); 917 if (v != NULL && (v->flags & VAR_DUMMY) == 0) { 918 if (v->flags & VAR_IN_USE) 919 Fatal("Variable %s is recursive.", v->name); 920 /*NOTREACHED*/ 921 else 922 v->flags |= VAR_IN_USE; 923 924 /* Before doing any modification, we have to make sure the value 925 * has been fully expanded. If it looks like recursion might be 926 * necessary (there's a dollar sign somewhere in the variable's value) 927 * we just call Var_Subst to do any other substitutions that are 928 * necessary. Note that the value returned by Var_Subst will have 929 * been dynamically-allocated, so it will need freeing when we 930 * return. */ 931 val = VarValue(v); 932 if (idx == -1) { 933 if (strchr(val, '$') != NULL) { 934 val = Var_Subst(val, ctxt, err); 935 *freePtr = true; 936 } 937 } else if (idx >= LOCAL_SIZE) { 938 if (IS_EXTENDED_F(idx)) 939 val = Var_GetTail(val); 940 else 941 val = Var_GetHead(val); 942 *freePtr = true; 943 } 944 v->flags &= ~VAR_IN_USE; 945 } 946 if (*tstr == ':' && endc != '\0') 947 val = VarModifiers_Apply(val, &name, ctxt, err, freePtr, tstr, endc, 948 lengthPtr); 949 if (val == NULL) { 950 val = err ? var_Error : varNoError; 951 /* Dynamic source */ 952 if (idx != -1) { 953 /* can't be expanded for now: copy the var spec instead. */ 954 if (ctxt == NULL || ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD) { 955 *freePtr = true; 956 val = Str_dupi(start, start+ *lengthPtr); 957 } else { 958 /* somehow, this should have been expanded already. */ 959 GNode *n; 960 961 n = (GNode *)(((char *)ctxt) - offsetof(GNode, context)); 962 if (idx >= LOCAL_SIZE) 963 idx = EXTENDED2SIMPLE(idx); 964 switch(idx) { 965 case IMPSRC_INDEX: 966 Fatal("Using $< in a non-suffix rule context is a GNUmake idiom (line %lu of %s)", 967 n->lineno, n->fname); 968 default: 969 Error("Using undefined dynamic variable $%s (line %lu of %s)", 970 varnames[idx], n->lineno, n->fname); 971 break; 972 } 973 } 974 } 975 } 976 VarName_Free(&name); 977 return val; 978 } 979 980 char * 981 Var_Subst(str, ctxt, undefErr) 982 const char *str; /* the string in which to substitute */ 983 SymTable *ctxt; /* the context wherein to find variables */ 984 bool undefErr; /* true if undefineds are an error */ 985 { 986 BUFFER buf; /* Buffer for forming things */ 987 static bool errorReported; /* Set true if an error has already 988 * been reported to prevent a plethora 989 * of messages when recursing */ 990 991 Buf_Init(&buf, MAKE_BSIZE); 992 errorReported = false; 993 994 for (;;) { 995 char *val; /* Value to substitute for a variable */ 996 size_t length; /* Length of the variable invocation */ 997 bool doFree; /* Set true if val should be freed */ 998 const char *cp; 999 1000 /* copy uninteresting stuff */ 1001 for (cp = str; *str != '\0' && *str != '$'; str++) 1002 ; 1003 Buf_Addi(&buf, cp, str); 1004 if (*str == '\0') 1005 break; 1006 if (str[1] == '$') { 1007 /* A dollar sign may be escaped with another dollar sign. */ 1008 Buf_AddChar(&buf, '$'); 1009 str += 2; 1010 continue; 1011 } 1012 val = Var_Parse(str, ctxt, undefErr, &length, &doFree); 1013 /* When we come down here, val should either point to the 1014 * value of this variable, suitably modified, or be NULL. 1015 * Length should be the total length of the potential 1016 * variable invocation (from $ to end character...) */ 1017 if (val == var_Error || val == varNoError) { 1018 /* If performing old-time variable substitution, skip over 1019 * the variable and continue with the substitution. Otherwise, 1020 * store the dollar sign and advance str so we continue with 1021 * the string... */ 1022 if (oldVars) 1023 str += length; 1024 else if (undefErr) { 1025 /* If variable is undefined, complain and skip the 1026 * variable. The complaint will stop us from doing anything 1027 * when the file is parsed. */ 1028 if (!errorReported) 1029 Parse_Error(PARSE_FATAL, 1030 "Undefined variable \"%.*s\"",length,str); 1031 str += length; 1032 errorReported = true; 1033 } else { 1034 Buf_AddChar(&buf, *str); 1035 str++; 1036 } 1037 } else { 1038 /* We've now got a variable structure to store in. But first, 1039 * advance the string pointer. */ 1040 str += length; 1041 1042 /* Copy all the characters from the variable value straight 1043 * into the new string. */ 1044 Buf_AddString(&buf, val); 1045 if (doFree) 1046 free(val); 1047 } 1048 } 1049 return Buf_Retrieve(&buf); 1050 } 1051 1052 void 1053 Var_SubstVar(buf, str, var, val) 1054 Buffer buf; 1055 const char *str; /* The string in which to substitute */ 1056 const char *var; /* Named variable */ 1057 const char *val; /* Its value */ 1058 { 1059 1060 assert(*var != '\0'); 1061 1062 for (;;) { 1063 const char *start; 1064 /* Copy uninteresting stuff */ 1065 for (start = str; *str != '\0' && *str != '$'; str++) 1066 ; 1067 Buf_Addi(buf, start, str); 1068 1069 start = str; 1070 if (*str++ == '\0') 1071 break; 1072 str++; 1073 /* and escaped dollars */ 1074 if (start[1] == '$') { 1075 Buf_Addi(buf, start, start+2); 1076 continue; 1077 } 1078 /* Simple variable, if it's not us, copy. */ 1079 if (start[1] != '(' && start[1] != '{') { 1080 if (start[1] != *var || var[1] != '\0') { 1081 Buf_AddChars(buf, 2, start); 1082 continue; 1083 } 1084 } else { 1085 const char *p; 1086 char endc; 1087 1088 if (start[1] == '(') 1089 endc = ')'; 1090 else 1091 endc = '}'; 1092 1093 /* Find the end of the variable specification. */ 1094 p = str; 1095 while (*p != '\0' && *p != ':' && *p != endc && *p != '$') 1096 p++; 1097 /* A variable inside the variable. We don't know how to 1098 * expand the external variable at this point, so we try 1099 * again with the nested variable. */ 1100 if (*p == '$') { 1101 Buf_Addi(buf, start, p); 1102 str = p; 1103 continue; 1104 } 1105 1106 if (strncmp(var, str, p - str) != 0 || 1107 var[p - str] != '\0') { 1108 /* Not the variable we want to expand. */ 1109 Buf_Addi(buf, start, p); 1110 str = p; 1111 continue; 1112 } 1113 if (*p == ':') { 1114 size_t length; /* Length of the variable invocation */ 1115 bool doFree; /* Set true if val should be freed */ 1116 char *newval; /* Value substituted for a variable */ 1117 struct Name name; 1118 1119 length = p - str + 1; 1120 doFree = false; 1121 name.s = var; 1122 name.e = var + (p-str); 1123 1124 /* val won't be freed since doFree == false, but 1125 * VarModifiers_Apply doesn't know that, hence the cast. */ 1126 newval = VarModifiers_Apply((char *)val, &name, NULL, false, 1127 &doFree, p, endc, &length); 1128 Buf_AddString(buf, newval); 1129 if (doFree) 1130 free(newval); 1131 str += length; 1132 continue; 1133 } else 1134 str = p+1; 1135 } 1136 Buf_AddString(buf, val); 1137 } 1138 } 1139 1140 /*- 1141 *----------------------------------------------------------------------- 1142 * Var_Init -- 1143 * Initialize the module 1144 * 1145 * Side Effects: 1146 * The CTXT_CMD and CTXT_GLOBAL contexts are initialized 1147 *----------------------------------------------------------------------- 1148 */ 1149 void 1150 Var_Init() 1151 { 1152 static GSymT global_vars, cmd_vars; 1153 1154 VAR_GLOBAL = &global_vars; 1155 VAR_CMD = &cmd_vars; 1156 ohash_init(VAR_GLOBAL, 10, &var_info); 1157 ohash_init(VAR_CMD, 5, &var_info); 1158 CTXT_GLOBAL = (SymTable *)VAR_GLOBAL; 1159 CTXT_CMD = (SymTable *)VAR_CMD; 1160 1161 VarModifiers_Init(); 1162 } 1163 1164 1165 #ifdef CLEANUP 1166 void 1167 Var_End() 1168 { 1169 Var *v; 1170 unsigned int i; 1171 1172 for (v = ohash_first(VAR_GLOBAL, &i); v != NULL; 1173 v = ohash_next(VAR_GLOBAL, &i)) 1174 VarDelete(v); 1175 for (v = ohash_first(VAR_CMD, &i); v != NULL; 1176 v = ohash_next(VAR_CMD, &i)) 1177 VarDelete(v); 1178 } 1179 #endif 1180 1181 static const char *interpret(int); 1182 1183 static const char * 1184 interpret(f) 1185 int f; 1186 { 1187 if (f & VAR_DUMMY) 1188 return "(D)"; 1189 return ""; 1190 } 1191 1192 1193 /****************** PRINT DEBUGGING INFO *****************/ 1194 static void 1195 VarPrintVar(v) 1196 Var *v; 1197 { 1198 printf("%-16s%s = %s\n", v->name, interpret(v->flags), 1199 (v->flags & VAR_DUMMY) == 0 ? VarValue(v) : "(none)"); 1200 } 1201 1202 void 1203 Var_Dump() 1204 { 1205 Var *v; 1206 unsigned int i; 1207 1208 printf("#*** Global Variables:\n"); 1209 1210 for (v = ohash_first(VAR_GLOBAL, &i); v != NULL; 1211 v = ohash_next(VAR_GLOBAL, &i)) 1212 VarPrintVar(v); 1213 1214 printf("#*** Command-line Variables:\n"); 1215 1216 for (v = ohash_first(VAR_CMD, &i); v != NULL; v = ohash_next(VAR_CMD, &i)) 1217 VarPrintVar(v); 1218 } 1219 1220 static const char *quotable = " \t\n\\'\""; 1221 1222 /* In POSIX mode, variable assignments passed on the command line are 1223 * propagated to sub makes through MAKEFLAGS. 1224 */ 1225 void 1226 Var_AddCmdline(name) 1227 const char *name; 1228 { 1229 Var *v; 1230 unsigned int i; 1231 BUFFER buf; 1232 char *s; 1233 1234 Buf_Init(&buf, MAKE_BSIZE); 1235 1236 for (v = ohash_first(VAR_CMD, &i); v != NULL; 1237 v = ohash_next(VAR_CMD, &i)) { 1238 /* We assume variable names don't need quoting */ 1239 Buf_AddString(&buf, v->name); 1240 Buf_AddChar(&buf, '='); 1241 for (s = VarValue(v); *s != '\0'; s++) { 1242 if (strchr(quotable, *s)) 1243 Buf_AddChar(&buf, '\\'); 1244 Buf_AddChar(&buf, *s); 1245 } 1246 Buf_AddSpace(&buf); 1247 } 1248 Var_Append(name, Buf_Retrieve(&buf), VAR_GLOBAL); 1249 Buf_Destroy(&buf); 1250 } 1251