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