1 /* $OpenPackages$ */ 2 /* $OpenBSD: var.c,v 1.58 2003/10/07 18:33:08 fgsch 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 if (result != NULL) 845 *result = false; 846 return length; 847 } 848 849 /* As of now, Var_ParseBuffer is just a wrapper around Var_Parse. For 850 * speed, it may be better to revisit the implementation to do things 851 * directly. */ 852 bool 853 Var_ParseBuffer(buf, str, ctxt, err, lengthPtr) 854 Buffer buf; 855 const char *str; 856 SymTable *ctxt; 857 bool err; 858 size_t *lengthPtr; 859 { 860 char *result; 861 bool freeIt; 862 863 result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt); 864 if (result == var_Error) 865 return false; 866 867 Buf_AddString(buf, result); 868 if (freeIt) 869 free(result); 870 return true; 871 } 872 873 char * 874 Var_Parse(str, ctxt, err, lengthPtr, freePtr) 875 const char *str; /* The string to parse */ 876 SymTable *ctxt; /* The context for the variable */ 877 bool err; /* true if undefined variables are an error */ 878 size_t *lengthPtr; /* OUT: The length of the specification */ 879 bool *freePtr; /* OUT: true if caller should free result */ 880 { 881 const char *tstr; /* Pointer into str */ 882 Var *v; /* Variable in invocation */ 883 char endc; /* Ending character when variable in parens 884 * or braces */ 885 struct Name name; 886 const char *start; 887 char *val; /* Variable value */ 888 u_int32_t k; 889 int idx; 890 891 *freePtr = false; 892 start = str++; 893 894 val = NULL; 895 v = NULL; 896 idx = -1; 897 898 if (*str != '(' && *str != '{') { 899 name.s = str; 900 name.e = str+1; 901 name.tofree = false; 902 tstr = str + 1; 903 *lengthPtr = 2; 904 endc = '\0'; 905 } else { 906 endc = *str == '(' ? ')' : '}'; 907 str++; 908 909 /* Find eventual modifiers in the variable */ 910 tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc)); 911 *lengthPtr = tstr - start; 912 if (*tstr != '\0') 913 (*lengthPtr)++; 914 } 915 916 idx = quick_lookup(name.s, &name.e, &k); 917 v = varfind(name.s, name.e, ctxt, FIND_ENV | FIND_MINE, idx, k); 918 if (v != NULL && (v->flags & VAR_DUMMY) == 0) { 919 if (v->flags & VAR_IN_USE) 920 Fatal("Variable %s is recursive.", v->name); 921 /*NOTREACHED*/ 922 else 923 v->flags |= VAR_IN_USE; 924 925 /* Before doing any modification, we have to make sure the value 926 * has been fully expanded. If it looks like recursion might be 927 * necessary (there's a dollar sign somewhere in the variable's value) 928 * we just call Var_Subst to do any other substitutions that are 929 * necessary. Note that the value returned by Var_Subst will have 930 * been dynamically-allocated, so it will need freeing when we 931 * return. */ 932 val = VarValue(v); 933 if (idx == -1) { 934 if (strchr(val, '$') != NULL) { 935 val = Var_Subst(val, ctxt, err); 936 *freePtr = true; 937 } 938 } else if (idx >= LOCAL_SIZE) { 939 if (IS_EXTENDED_F(idx)) 940 val = Var_GetTail(val); 941 else 942 val = Var_GetHead(val); 943 *freePtr = true; 944 } 945 v->flags &= ~VAR_IN_USE; 946 } 947 if (*tstr == ':' && endc != '\0') 948 val = VarModifiers_Apply(val, &name, ctxt, err, freePtr, tstr, endc, 949 lengthPtr); 950 if (val == NULL) { 951 val = err ? var_Error : varNoError; 952 /* Dynamic source */ 953 if (idx != -1) { 954 /* can't be expanded for now: copy the var spec instead. */ 955 if (ctxt == NULL || ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD) { 956 *freePtr = true; 957 val = Str_dupi(start, start+ *lengthPtr); 958 } else { 959 /* somehow, this should have been expanded already. */ 960 GNode *n; 961 962 n = (GNode *)(((char *)ctxt) - offsetof(GNode, context)); 963 if (idx >= LOCAL_SIZE) 964 idx = EXTENDED2SIMPLE(idx); 965 switch(idx) { 966 case IMPSRC_INDEX: 967 Fatal("Using $< in a non-suffix rule context is a GNUmake idiom (line %lu of %s)", 968 n->lineno, n->fname); 969 default: 970 Error("Using undefined dynamic variable $%s (line %lu of %s)", 971 varnames[idx], n->lineno, n->fname); 972 break; 973 } 974 } 975 } 976 } 977 VarName_Free(&name); 978 return val; 979 } 980 981 char * 982 Var_Subst(str, ctxt, undefErr) 983 const char *str; /* the string in which to substitute */ 984 SymTable *ctxt; /* the context wherein to find variables */ 985 bool undefErr; /* true if undefineds are an error */ 986 { 987 BUFFER buf; /* Buffer for forming things */ 988 static bool errorReported; /* Set true if an error has already 989 * been reported to prevent a plethora 990 * of messages when recursing */ 991 992 Buf_Init(&buf, MAKE_BSIZE); 993 errorReported = false; 994 995 for (;;) { 996 char *val; /* Value to substitute for a variable */ 997 size_t length; /* Length of the variable invocation */ 998 bool doFree; /* Set true if val should be freed */ 999 const char *cp; 1000 1001 /* copy uninteresting stuff */ 1002 for (cp = str; *str != '\0' && *str != '$'; str++) 1003 ; 1004 Buf_Addi(&buf, cp, str); 1005 if (*str == '\0') 1006 break; 1007 if (str[1] == '$') { 1008 /* A dollar sign may be escaped with another dollar sign. */ 1009 Buf_AddChar(&buf, '$'); 1010 str += 2; 1011 continue; 1012 } 1013 val = Var_Parse(str, ctxt, undefErr, &length, &doFree); 1014 /* When we come down here, val should either point to the 1015 * value of this variable, suitably modified, or be NULL. 1016 * Length should be the total length of the potential 1017 * variable invocation (from $ to end character...) */ 1018 if (val == var_Error || val == varNoError) { 1019 /* If performing old-time variable substitution, skip over 1020 * the variable and continue with the substitution. Otherwise, 1021 * store the dollar sign and advance str so we continue with 1022 * the string... */ 1023 if (oldVars) 1024 str += length; 1025 else if (undefErr) { 1026 /* If variable is undefined, complain and skip the 1027 * variable. The complaint will stop us from doing anything 1028 * when the file is parsed. */ 1029 if (!errorReported) 1030 Parse_Error(PARSE_FATAL, 1031 "Undefined variable \"%.*s\"",length,str); 1032 str += length; 1033 errorReported = true; 1034 } else { 1035 Buf_AddChar(&buf, *str); 1036 str++; 1037 } 1038 } else { 1039 /* We've now got a variable structure to store in. But first, 1040 * advance the string pointer. */ 1041 str += length; 1042 1043 /* Copy all the characters from the variable value straight 1044 * into the new string. */ 1045 Buf_AddString(&buf, val); 1046 if (doFree) 1047 free(val); 1048 } 1049 } 1050 return Buf_Retrieve(&buf); 1051 } 1052 1053 void 1054 Var_SubstVar(buf, str, var, val) 1055 Buffer buf; 1056 const char *str; /* The string in which to substitute */ 1057 const char *var; /* Named variable */ 1058 const char *val; /* Its value */ 1059 { 1060 1061 assert(*var != '\0'); 1062 1063 for (;;) { 1064 const char *start; 1065 /* Copy uninteresting stuff */ 1066 for (start = str; *str != '\0' && *str != '$'; str++) 1067 ; 1068 Buf_Addi(buf, start, str); 1069 1070 start = str; 1071 if (*str++ == '\0') 1072 break; 1073 str++; 1074 /* and escaped dollars */ 1075 if (start[1] == '$') { 1076 Buf_Addi(buf, start, start+2); 1077 continue; 1078 } 1079 /* Simple variable, if it's not us, copy. */ 1080 if (start[1] != '(' && start[1] != '{') { 1081 if (start[1] != *var || var[1] != '\0') { 1082 Buf_AddChars(buf, 2, start); 1083 continue; 1084 } 1085 } else { 1086 const char *p; 1087 char endc; 1088 1089 if (start[1] == '(') 1090 endc = ')'; 1091 else 1092 endc = '}'; 1093 1094 /* Find the end of the variable specification. */ 1095 p = str; 1096 while (*p != '\0' && *p != ':' && *p != endc && *p != '$') 1097 p++; 1098 /* A variable inside the variable. We don't know how to 1099 * expand the external variable at this point, so we try 1100 * again with the nested variable. */ 1101 if (*p == '$') { 1102 Buf_Addi(buf, start, p); 1103 str = p; 1104 continue; 1105 } 1106 1107 if (strncmp(var, str, p - str) != 0 || 1108 var[p - str] != '\0') { 1109 /* Not the variable we want to expand. */ 1110 Buf_Addi(buf, start, p); 1111 str = p; 1112 continue; 1113 } 1114 if (*p == ':') { 1115 size_t length; /* Length of the variable invocation */ 1116 bool doFree; /* Set true if val should be freed */ 1117 char *newval; /* Value substituted for a variable */ 1118 struct Name name; 1119 1120 length = p - str + 1; 1121 doFree = false; 1122 name.s = var; 1123 name.e = var + (p-str); 1124 1125 /* val won't be freed since doFree == false, but 1126 * VarModifiers_Apply doesn't know that, hence the cast. */ 1127 newval = VarModifiers_Apply((char *)val, &name, NULL, false, 1128 &doFree, p, endc, &length); 1129 Buf_AddString(buf, newval); 1130 if (doFree) 1131 free(newval); 1132 str += length; 1133 continue; 1134 } else 1135 str = p+1; 1136 } 1137 Buf_AddString(buf, val); 1138 } 1139 } 1140 1141 /*- 1142 *----------------------------------------------------------------------- 1143 * Var_Init -- 1144 * Initialize the module 1145 * 1146 * Side Effects: 1147 * The CTXT_CMD and CTXT_GLOBAL contexts are initialized 1148 *----------------------------------------------------------------------- 1149 */ 1150 void 1151 Var_Init() 1152 { 1153 static GSymT global_vars, cmd_vars; 1154 1155 VAR_GLOBAL = &global_vars; 1156 VAR_CMD = &cmd_vars; 1157 ohash_init(VAR_GLOBAL, 10, &var_info); 1158 ohash_init(VAR_CMD, 5, &var_info); 1159 CTXT_GLOBAL = (SymTable *)VAR_GLOBAL; 1160 CTXT_CMD = (SymTable *)VAR_CMD; 1161 1162 VarModifiers_Init(); 1163 } 1164 1165 1166 #ifdef CLEANUP 1167 void 1168 Var_End() 1169 { 1170 Var *v; 1171 unsigned int i; 1172 1173 for (v = ohash_first(VAR_GLOBAL, &i); v != NULL; 1174 v = ohash_next(VAR_GLOBAL, &i)) 1175 VarDelete(v); 1176 for (v = ohash_first(VAR_CMD, &i); v != NULL; 1177 v = ohash_next(VAR_CMD, &i)) 1178 VarDelete(v); 1179 } 1180 #endif 1181 1182 static const char *interpret(int); 1183 1184 static const char * 1185 interpret(f) 1186 int f; 1187 { 1188 if (f & VAR_DUMMY) 1189 return "(D)"; 1190 return ""; 1191 } 1192 1193 1194 /****************** PRINT DEBUGGING INFO *****************/ 1195 static void 1196 VarPrintVar(v) 1197 Var *v; 1198 { 1199 printf("%-16s%s = %s\n", v->name, interpret(v->flags), 1200 (v->flags & VAR_DUMMY) == 0 ? VarValue(v) : "(none)"); 1201 } 1202 1203 void 1204 Var_Dump() 1205 { 1206 Var *v; 1207 unsigned int i; 1208 1209 printf("#*** Global Variables:\n"); 1210 1211 for (v = ohash_first(VAR_GLOBAL, &i); v != NULL; 1212 v = ohash_next(VAR_GLOBAL, &i)) 1213 VarPrintVar(v); 1214 1215 printf("#*** Command-line Variables:\n"); 1216 1217 for (v = ohash_first(VAR_CMD, &i); v != NULL; v = ohash_next(VAR_CMD, &i)) 1218 VarPrintVar(v); 1219 } 1220 1221 static const char *quotable = " \t\n\\'\""; 1222 1223 /* In POSIX mode, variable assignments passed on the command line are 1224 * propagated to sub makes through MAKEFLAGS. 1225 */ 1226 void 1227 Var_AddCmdline(name) 1228 const char *name; 1229 { 1230 Var *v; 1231 unsigned int i; 1232 BUFFER buf; 1233 char *s; 1234 1235 Buf_Init(&buf, MAKE_BSIZE); 1236 1237 for (v = ohash_first(VAR_CMD, &i); v != NULL; 1238 v = ohash_next(VAR_CMD, &i)) { 1239 /* We assume variable names don't need quoting */ 1240 Buf_AddString(&buf, v->name); 1241 Buf_AddChar(&buf, '='); 1242 for (s = VarValue(v); *s != '\0'; s++) { 1243 if (strchr(quotable, *s)) 1244 Buf_AddChar(&buf, '\\'); 1245 Buf_AddChar(&buf, *s); 1246 } 1247 Buf_AddSpace(&buf); 1248 } 1249 Var_Append(name, Buf_Retrieve(&buf), VAR_GLOBAL); 1250 Buf_Destroy(&buf); 1251 } 1252