| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.312 2020/07/26 13:39:30 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.313 2020/07/26 15:09:10 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -59,34 +59,34 @@ | | | @@ -59,34 +59,34 @@ |
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
68 | * SUCH DAMAGE. | | 68 | * SUCH DAMAGE. |
69 | */ | | 69 | */ |
70 | | | 70 | |
71 | #ifndef MAKE_NATIVE | | 71 | #ifndef MAKE_NATIVE |
72 | static char rcsid[] = "$NetBSD: var.c,v 1.312 2020/07/26 13:39:30 rillig Exp $"; | | 72 | static char rcsid[] = "$NetBSD: var.c,v 1.313 2020/07/26 15:09:10 rillig Exp $"; |
73 | #else | | 73 | #else |
74 | #include <sys/cdefs.h> | | 74 | #include <sys/cdefs.h> |
75 | #ifndef lint | | 75 | #ifndef lint |
76 | #if 0 | | 76 | #if 0 |
77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; | | 77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; |
78 | #else | | 78 | #else |
79 | __RCSID("$NetBSD: var.c,v 1.312 2020/07/26 13:39:30 rillig Exp $"); | | 79 | __RCSID("$NetBSD: var.c,v 1.313 2020/07/26 15:09:10 rillig Exp $"); |
80 | #endif | | 80 | #endif |
81 | #endif /* not lint */ | | 81 | #endif /* not lint */ |
82 | #endif | | 82 | #endif |
83 | | | 83 | |
84 | /*- | | 84 | /*- |
85 | * var.c -- | | 85 | * var.c -- |
86 | * Variable-handling functions | | 86 | * Variable-handling functions |
87 | * | | 87 | * |
88 | * Interface: | | 88 | * Interface: |
89 | * Var_Set Set the value of a variable in the given | | 89 | * Var_Set Set the value of a variable in the given |
90 | * context. The variable is created if it doesn't | | 90 | * context. The variable is created if it doesn't |
91 | * yet exist. | | 91 | * yet exist. |
92 | * | | 92 | * |
| @@ -269,29 +269,26 @@ typedef enum { | | | @@ -269,29 +269,26 @@ typedef enum { |
269 | * FIND_ENV look in the environment as well | | 269 | * FIND_ENV look in the environment as well |
270 | * | | 270 | * |
271 | * Results: | | 271 | * Results: |
272 | * A pointer to the structure describing the desired variable or | | 272 | * A pointer to the structure describing the desired variable or |
273 | * NULL if the variable does not exist. | | 273 | * NULL if the variable does not exist. |
274 | * | | 274 | * |
275 | * Side Effects: | | 275 | * Side Effects: |
276 | * None | | 276 | * None |
277 | *----------------------------------------------------------------------- | | 277 | *----------------------------------------------------------------------- |
278 | */ | | 278 | */ |
279 | static Var * | | 279 | static Var * |
280 | VarFind(const char *name, GNode *ctxt, VarFindFlags flags) | | 280 | VarFind(const char *name, GNode *ctxt, VarFindFlags flags) |
281 | { | | 281 | { |
282 | Hash_Entry *var; | | | |
283 | Var *v; | | | |
284 | | | | |
285 | /* | | 282 | /* |
286 | * If the variable name begins with a '.', it could very well be one of | | 283 | * If the variable name begins with a '.', it could very well be one of |
287 | * the local ones. We check the name against all the local variables | | 284 | * the local ones. We check the name against all the local variables |
288 | * and substitute the short version in for 'name' if it matches one of | | 285 | * and substitute the short version in for 'name' if it matches one of |
289 | * them. | | 286 | * them. |
290 | */ | | 287 | */ |
291 | if (*name == '.' && isupper((unsigned char) name[1])) { | | 288 | if (*name == '.' && isupper((unsigned char) name[1])) { |
292 | switch (name[1]) { | | 289 | switch (name[1]) { |
293 | case 'A': | | 290 | case 'A': |
294 | if (strcmp(name, ".ALLSRC") == 0) | | 291 | if (strcmp(name, ".ALLSRC") == 0) |
295 | name = ALLSRC; | | 292 | name = ALLSRC; |
296 | if (strcmp(name, ".ARCHIVE") == 0) | | 293 | if (strcmp(name, ".ARCHIVE") == 0) |
297 | name = ARCHIVE; | | 294 | name = ARCHIVE; |
| @@ -320,51 +317,48 @@ VarFind(const char *name, GNode *ctxt, V | | | @@ -320,51 +317,48 @@ VarFind(const char *name, GNode *ctxt, V |
320 | } | | 317 | } |
321 | | | 318 | |
322 | #ifdef notyet | | 319 | #ifdef notyet |
323 | /* for compatibility with gmake */ | | 320 | /* for compatibility with gmake */ |
324 | if (name[0] == '^' && name[1] == '\0') | | 321 | if (name[0] == '^' && name[1] == '\0') |
325 | name = ALLSRC; | | 322 | name = ALLSRC; |
326 | #endif | | 323 | #endif |
327 | | | 324 | |
328 | /* | | 325 | /* |
329 | * First look for the variable in the given context. If it's not there, | | 326 | * First look for the variable in the given context. If it's not there, |
330 | * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, | | 327 | * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, |
331 | * depending on the FIND_* flags in 'flags' | | 328 | * depending on the FIND_* flags in 'flags' |
332 | */ | | 329 | */ |
333 | var = Hash_FindEntry(&ctxt->context, name); | | 330 | Hash_Entry *var = Hash_FindEntry(&ctxt->context, name); |
334 | | | 331 | |
335 | if (var == NULL && (flags & FIND_CMD) && ctxt != VAR_CMD) { | | 332 | if (var == NULL && (flags & FIND_CMD) && ctxt != VAR_CMD) { |
336 | var = Hash_FindEntry(&VAR_CMD->context, name); | | 333 | var = Hash_FindEntry(&VAR_CMD->context, name); |
337 | } | | 334 | } |
338 | if (!checkEnvFirst && var == NULL && (flags & FIND_GLOBAL) && | | 335 | if (!checkEnvFirst && var == NULL && (flags & FIND_GLOBAL) && |
339 | ctxt != VAR_GLOBAL) | | 336 | ctxt != VAR_GLOBAL) |
340 | { | | 337 | { |
341 | var = Hash_FindEntry(&VAR_GLOBAL->context, name); | | 338 | var = Hash_FindEntry(&VAR_GLOBAL->context, name); |
342 | if (var == NULL && ctxt != VAR_INTERNAL) { | | 339 | if (var == NULL && ctxt != VAR_INTERNAL) { |
343 | /* VAR_INTERNAL is subordinate to VAR_GLOBAL */ | | 340 | /* VAR_INTERNAL is subordinate to VAR_GLOBAL */ |
344 | var = Hash_FindEntry(&VAR_INTERNAL->context, name); | | 341 | var = Hash_FindEntry(&VAR_INTERNAL->context, name); |
345 | } | | 342 | } |
346 | } | | 343 | } |
347 | if (var == NULL && (flags & FIND_ENV)) { | | 344 | if (var == NULL && (flags & FIND_ENV)) { |
348 | char *env; | | 345 | char *env; |
349 | | | 346 | |
350 | if ((env = getenv(name)) != NULL) { | | 347 | if ((env = getenv(name)) != NULL) { |
351 | int len; | | 348 | Var *v = bmake_malloc(sizeof(Var)); |
352 | | | | |
353 | v = bmake_malloc(sizeof(Var)); | | | |
354 | v->name = bmake_strdup(name); | | 349 | v->name = bmake_strdup(name); |
355 | | | 350 | |
356 | len = strlen(env); | | 351 | int len = (int)strlen(env); |
357 | | | | |
358 | Buf_Init(&v->val, len + 1); | | 352 | Buf_Init(&v->val, len + 1); |
359 | Buf_AddBytes(&v->val, len, env); | | 353 | Buf_AddBytes(&v->val, len, env); |
360 | | | 354 | |
361 | v->flags = VAR_FROM_ENV; | | 355 | v->flags = VAR_FROM_ENV; |
362 | return v; | | 356 | return v; |
363 | } else if (checkEnvFirst && (flags & FIND_GLOBAL) && | | 357 | } else if (checkEnvFirst && (flags & FIND_GLOBAL) && |
364 | ctxt != VAR_GLOBAL) | | 358 | ctxt != VAR_GLOBAL) |
365 | { | | 359 | { |
366 | var = Hash_FindEntry(&VAR_GLOBAL->context, name); | | 360 | var = Hash_FindEntry(&VAR_GLOBAL->context, name); |
367 | if (var == NULL && ctxt != VAR_INTERNAL) { | | 361 | if (var == NULL && ctxt != VAR_INTERNAL) { |
368 | var = Hash_FindEntry(&VAR_INTERNAL->context, name); | | 362 | var = Hash_FindEntry(&VAR_INTERNAL->context, name); |
369 | } | | 363 | } |
370 | if (var == NULL) { | | 364 | if (var == NULL) { |
| @@ -418,39 +412,35 @@ VarFreeEnv(Var *v, Boolean destroy) | | | @@ -418,39 +412,35 @@ VarFreeEnv(Var *v, Boolean destroy) |
418 | * name name of variable to add | | 412 | * name name of variable to add |
419 | * val value to set it to | | 413 | * val value to set it to |
420 | * ctxt context in which to set it | | 414 | * ctxt context in which to set it |
421 | * | | 415 | * |
422 | * Side Effects: | | 416 | * Side Effects: |
423 | * The new variable is placed at the front of the given context | | 417 | * The new variable is placed at the front of the given context |
424 | * The name and val arguments are duplicated so they may | | 418 | * The name and val arguments are duplicated so they may |
425 | * safely be freed. | | 419 | * safely be freed. |
426 | *----------------------------------------------------------------------- | | 420 | *----------------------------------------------------------------------- |
427 | */ | | 421 | */ |
428 | static void | | 422 | static void |
429 | VarAdd(const char *name, const char *val, GNode *ctxt) | | 423 | VarAdd(const char *name, const char *val, GNode *ctxt) |
430 | { | | 424 | { |
431 | Var *v; | | 425 | Var *v = bmake_malloc(sizeof(Var)); |
432 | int len; | | | |
433 | Hash_Entry *h; | | | |
434 | | | | |
435 | v = bmake_malloc(sizeof(Var)); | | | |
436 | | | 426 | |
437 | len = val != NULL ? strlen(val) : 0; | | 427 | int len = val != NULL ? (int)strlen(val) : 0; |
438 | Buf_Init(&v->val, len + 1); | | 428 | Buf_Init(&v->val, len + 1); |
439 | Buf_AddBytes(&v->val, len, val); | | 429 | Buf_AddBytes(&v->val, len, val); |
440 | | | 430 | |
441 | v->flags = 0; | | 431 | v->flags = 0; |
442 | | | 432 | |
443 | h = Hash_CreateEntry(&ctxt->context, name, NULL); | | 433 | Hash_Entry *h = Hash_CreateEntry(&ctxt->context, name, NULL); |
444 | Hash_SetValue(h, v); | | 434 | Hash_SetValue(h, v); |
445 | v->name = h->name; | | 435 | v->name = h->name; |
446 | if (DEBUG(VAR) && !(ctxt->flags & INTERNAL)) { | | 436 | if (DEBUG(VAR) && !(ctxt->flags & INTERNAL)) { |
447 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); | | 437 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); |
448 | } | | 438 | } |
449 | } | | 439 | } |
450 | | | 440 | |
451 | /*- | | 441 | /*- |
452 | *----------------------------------------------------------------------- | | 442 | *----------------------------------------------------------------------- |
453 | * Var_Delete -- | | 443 | * Var_Delete -- |
454 | * Remove a variable from a context. | | 444 | * Remove a variable from a context. |
455 | * | | 445 | * |
456 | * Side Effects: | | 446 | * Side Effects: |
| @@ -828,27 +818,27 @@ Var_Set_with_flags(const char *name, con | | | @@ -828,27 +818,27 @@ Var_Set_with_flags(const char *name, con |
828 | if (v == NULL) { | | 818 | if (v == NULL) { |
829 | if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { | | 819 | if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { |
830 | /* | | 820 | /* |
831 | * This var would normally prevent the same name being added | | 821 | * This var would normally prevent the same name being added |
832 | * to VAR_GLOBAL, so delete it from there if needed. | | 822 | * to VAR_GLOBAL, so delete it from there if needed. |
833 | * Otherwise -V name may show the wrong value. | | 823 | * Otherwise -V name may show the wrong value. |
834 | */ | | 824 | */ |
835 | Var_Delete(name, VAR_GLOBAL); | | 825 | Var_Delete(name, VAR_GLOBAL); |
836 | } | | 826 | } |
837 | VarAdd(name, val, ctxt); | | 827 | VarAdd(name, val, ctxt); |
838 | } else { | | 828 | } else { |
839 | Buf_Empty(&v->val); | | 829 | Buf_Empty(&v->val); |
840 | if (val) | | 830 | if (val) |
841 | Buf_AddBytes(&v->val, strlen(val), val); | | 831 | Buf_AddStr(&v->val, val); |
842 | | | 832 | |
843 | if (DEBUG(VAR)) { | | 833 | if (DEBUG(VAR)) { |
844 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); | | 834 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); |
845 | } | | 835 | } |
846 | if ((v->flags & VAR_EXPORTED)) { | | 836 | if ((v->flags & VAR_EXPORTED)) { |
847 | Var_Export1(name, VAR_EXPORT_PARENT); | | 837 | Var_Export1(name, VAR_EXPORT_PARENT); |
848 | } | | 838 | } |
849 | } | | 839 | } |
850 | /* | | 840 | /* |
851 | * Any variables given on the command line are automatically exported | | 841 | * Any variables given on the command line are automatically exported |
852 | * to the environment (as per POSIX standard) | | 842 | * to the environment (as per POSIX standard) |
853 | */ | | 843 | */ |
854 | if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { | | 844 | if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { |
| @@ -950,27 +940,27 @@ Var_Append(const char *name, const char | | | @@ -950,27 +940,27 @@ Var_Append(const char *name, const char |
950 | } | | 940 | } |
951 | free(expanded_name); | | 941 | free(expanded_name); |
952 | return; | | 942 | return; |
953 | } | | 943 | } |
954 | name = expanded_name; | | 944 | name = expanded_name; |
955 | } | | 945 | } |
956 | | | 946 | |
957 | v = VarFind(name, ctxt, ctxt == VAR_GLOBAL ? (FIND_CMD | FIND_ENV) : 0); | | 947 | v = VarFind(name, ctxt, ctxt == VAR_GLOBAL ? (FIND_CMD | FIND_ENV) : 0); |
958 | | | 948 | |
959 | if (v == NULL) { | | 949 | if (v == NULL) { |
960 | Var_Set(name, val, ctxt); | | 950 | Var_Set(name, val, ctxt); |
961 | } else if (ctxt == VAR_CMD || !(v->flags & VAR_FROM_CMD)) { | | 951 | } else if (ctxt == VAR_CMD || !(v->flags & VAR_FROM_CMD)) { |
962 | Buf_AddByte(&v->val, ' '); | | 952 | Buf_AddByte(&v->val, ' '); |
963 | Buf_AddBytes(&v->val, strlen(val), val); | | 953 | Buf_AddStr(&v->val, val); |
964 | | | 954 | |
965 | if (DEBUG(VAR)) { | | 955 | if (DEBUG(VAR)) { |
966 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, | | 956 | fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, |
967 | Buf_GetAll(&v->val, NULL)); | | 957 | Buf_GetAll(&v->val, NULL)); |
968 | } | | 958 | } |
969 | | | 959 | |
970 | if (v->flags & VAR_FROM_ENV) { | | 960 | if (v->flags & VAR_FROM_ENV) { |
971 | /* | | 961 | /* |
972 | * If the original variable came from the environment, we | | 962 | * If the original variable came from the environment, we |
973 | * have to install it in the global context (we could place | | 963 | * have to install it in the global context (we could place |
974 | * it in the environment, but then we should provide a way to | | 964 | * it in the environment, but then we should provide a way to |
975 | * export other variables...) | | 965 | * export other variables...) |
976 | */ | | 966 | */ |
| @@ -1690,27 +1680,27 @@ VarOrder(const char *str, const char oty | | | @@ -1690,27 +1680,27 @@ VarOrder(const char *str, const char oty |
1690 | * 0 with probability 1). | | 1680 | * 0 with probability 1). |
1691 | */ | | 1681 | */ |
1692 | for (i = ac - 1; i > 0; i--) { | | 1682 | for (i = ac - 1; i > 0; i--) { |
1693 | int rndidx = random() % (i + 1); | | 1683 | int rndidx = random() % (i + 1); |
1694 | char *t = av[i]; | | 1684 | char *t = av[i]; |
1695 | av[i] = av[rndidx]; | | 1685 | av[i] = av[rndidx]; |
1696 | av[rndidx] = t; | | 1686 | av[rndidx] = t; |
1697 | } | | 1687 | } |
1698 | } | | 1688 | } |
1699 | } | | 1689 | } |
1700 | } | | 1690 | } |
1701 | | | 1691 | |
1702 | for (i = 0; i < ac; i++) { | | 1692 | for (i = 0; i < ac; i++) { |
1703 | Buf_AddBytes(&buf, strlen(av[i]), av[i]); | | 1693 | Buf_AddStr(&buf, av[i]); |
1704 | if (i != ac - 1) | | 1694 | if (i != ac - 1) |
1705 | Buf_AddByte(&buf, ' '); | | 1695 | Buf_AddByte(&buf, ' '); |
1706 | } | | 1696 | } |
1707 | | | 1697 | |
1708 | free(as); | | 1698 | free(as); |
1709 | free(av); | | 1699 | free(av); |
1710 | | | 1700 | |
1711 | return Buf_Destroy(&buf, FALSE); | | 1701 | return Buf_Destroy(&buf, FALSE); |
1712 | } | | 1702 | } |
1713 | | | 1703 | |
1714 | | | 1704 | |
1715 | /*- | | 1705 | /*- |
1716 | *----------------------------------------------------------------------- | | 1706 | *----------------------------------------------------------------------- |
| @@ -1737,27 +1727,27 @@ VarUniq(const char *str) | | | @@ -1737,27 +1727,27 @@ VarUniq(const char *str) |
1737 | int ac, i, j; | | 1727 | int ac, i, j; |
1738 | | | 1728 | |
1739 | Buf_Init(&buf, 0); | | 1729 | Buf_Init(&buf, 0); |
1740 | av = brk_string(str, &ac, FALSE, &as); | | 1730 | av = brk_string(str, &ac, FALSE, &as); |
1741 | | | 1731 | |
1742 | if (ac > 1) { | | 1732 | if (ac > 1) { |
1743 | for (j = 0, i = 1; i < ac; i++) | | 1733 | for (j = 0, i = 1; i < ac; i++) |
1744 | if (strcmp(av[i], av[j]) != 0 && (++j != i)) | | 1734 | if (strcmp(av[i], av[j]) != 0 && (++j != i)) |
1745 | av[j] = av[i]; | | 1735 | av[j] = av[i]; |
1746 | ac = j + 1; | | 1736 | ac = j + 1; |
1747 | } | | 1737 | } |
1748 | | | 1738 | |
1749 | for (i = 0; i < ac; i++) { | | 1739 | for (i = 0; i < ac; i++) { |
1750 | Buf_AddBytes(&buf, strlen(av[i]), av[i]); | | 1740 | Buf_AddStr(&buf, av[i]); |
1751 | if (i != ac - 1) | | 1741 | if (i != ac - 1) |
1752 | Buf_AddByte(&buf, ' '); | | 1742 | Buf_AddByte(&buf, ' '); |
1753 | } | | 1743 | } |
1754 | | | 1744 | |
1755 | free(as); | | 1745 | free(as); |
1756 | free(av); | | 1746 | free(av); |
1757 | | | 1747 | |
1758 | return Buf_Destroy(&buf, FALSE); | | 1748 | return Buf_Destroy(&buf, FALSE); |
1759 | } | | 1749 | } |
1760 | | | 1750 | |
1761 | /*- | | 1751 | /*- |
1762 | *----------------------------------------------------------------------- | | 1752 | *----------------------------------------------------------------------- |
1763 | * VarRange -- | | 1753 | * VarRange -- |
| @@ -1852,51 +1842,51 @@ ParseModifierPart(GNode *ctxt, const cha | | | @@ -1852,51 +1842,51 @@ ParseModifierPart(GNode *ctxt, const cha |
1852 | } else { | | 1842 | } else { |
1853 | if (!(eflags & VARE_NOSUBST)) { | | 1843 | if (!(eflags & VARE_NOSUBST)) { |
1854 | char *cp2; | | 1844 | char *cp2; |
1855 | int len; | | 1845 | int len; |
1856 | void *freeIt; | | 1846 | void *freeIt; |
1857 | | | 1847 | |
1858 | /* | | 1848 | /* |
1859 | * If unescaped dollar sign not before the | | 1849 | * If unescaped dollar sign not before the |
1860 | * delimiter, assume it's a variable | | 1850 | * delimiter, assume it's a variable |
1861 | * substitution and recurse. | | 1851 | * substitution and recurse. |
1862 | */ | | 1852 | */ |
1863 | cp2 = Var_Parse(cp, ctxt, errnum | (eflags & VARE_WANTRES), | | 1853 | cp2 = Var_Parse(cp, ctxt, errnum | (eflags & VARE_WANTRES), |
1864 | &len, &freeIt); | | 1854 | &len, &freeIt); |
1865 | Buf_AddBytes(&buf, strlen(cp2), cp2); | | 1855 | Buf_AddStr(&buf, cp2); |
1866 | free(freeIt); | | 1856 | free(freeIt); |
1867 | cp += len - 1; | | 1857 | cp += len - 1; |
1868 | } else { | | 1858 | } else { |
1869 | const char *cp2 = &cp[1]; | | 1859 | const char *cp2 = &cp[1]; |
1870 | | | 1860 | |
1871 | if (*cp2 == PROPEN || *cp2 == BROPEN) { | | 1861 | if (*cp2 == PROPEN || *cp2 == BROPEN) { |
1872 | /* | | 1862 | /* |
1873 | * Find the end of this variable reference | | 1863 | * Find the end of this variable reference |
1874 | * and suck it in without further ado. | | 1864 | * and suck it in without further ado. |
1875 | * It will be interpreted later. | | 1865 | * It will be interpreted later. |
1876 | */ | | 1866 | */ |
1877 | int have = *cp2; | | 1867 | int have = *cp2; |
1878 | int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE; | | 1868 | int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE; |
1879 | int depth = 1; | | 1869 | int depth = 1; |
1880 | | | 1870 | |
1881 | for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) { | | 1871 | for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) { |
1882 | if (cp2[-1] != '\\') { | | 1872 | if (cp2[-1] != '\\') { |
1883 | if (*cp2 == have) | | 1873 | if (*cp2 == have) |
1884 | ++depth; | | 1874 | ++depth; |
1885 | if (*cp2 == want) | | 1875 | if (*cp2 == want) |
1886 | --depth; | | 1876 | --depth; |
1887 | } | | 1877 | } |
1888 | } | | 1878 | } |
1889 | Buf_AddBytes(&buf, cp2 - cp, cp); | | 1879 | Buf_AddBytesBetween(&buf, cp, cp2); |
1890 | cp = --cp2; | | 1880 | cp = --cp2; |
1891 | } else | | 1881 | } else |
1892 | Buf_AddByte(&buf, *cp); | | 1882 | Buf_AddByte(&buf, *cp); |
1893 | } | | 1883 | } |
1894 | } | | 1884 | } |
1895 | } else if (subst != NULL && *cp == '&') | | 1885 | } else if (subst != NULL && *cp == '&') |
1896 | Buf_AddBytes(&buf, subst->lhsLen, subst->lhs); | | 1886 | Buf_AddBytes(&buf, subst->lhsLen, subst->lhs); |
1897 | else | | 1887 | else |
1898 | Buf_AddByte(&buf, *cp); | | 1888 | Buf_AddByte(&buf, *cp); |
1899 | } | | 1889 | } |
1900 | | | 1890 | |
1901 | if (*cp != delim) { | | 1891 | if (*cp != delim) { |
1902 | *tstr = cp; | | 1892 | *tstr = cp; |
| @@ -1927,34 +1917,34 @@ ParseModifierPart(GNode *ctxt, const cha | | | @@ -1927,34 +1917,34 @@ ParseModifierPart(GNode *ctxt, const cha |
1927 | *----------------------------------------------------------------------- | | 1917 | *----------------------------------------------------------------------- |
1928 | */ | | 1918 | */ |
1929 | static char * | | 1919 | static char * |
1930 | VarQuote(char *str, Boolean quoteDollar) | | 1920 | VarQuote(char *str, Boolean quoteDollar) |
1931 | { | | 1921 | { |
1932 | Buffer buf; | | 1922 | Buffer buf; |
1933 | Buf_Init(&buf, 0); | | 1923 | Buf_Init(&buf, 0); |
1934 | | | 1924 | |
1935 | for (; *str != '\0'; str++) { | | 1925 | for (; *str != '\0'; str++) { |
1936 | if (*str == '\n') { | | 1926 | if (*str == '\n') { |
1937 | const char *newline = Shell_GetNewline(); | | 1927 | const char *newline = Shell_GetNewline(); |
1938 | if (newline == NULL) | | 1928 | if (newline == NULL) |
1939 | newline = "\\\n"; | | 1929 | newline = "\\\n"; |
1940 | Buf_AddBytes(&buf, strlen(newline), newline); | | 1930 | Buf_AddStr(&buf, newline); |
1941 | continue; | | 1931 | continue; |
1942 | } | | 1932 | } |
1943 | if (isspace((unsigned char)*str) || ismeta((unsigned char)*str)) | | 1933 | if (isspace((unsigned char)*str) || ismeta((unsigned char)*str)) |
1944 | Buf_AddByte(&buf, '\\'); | | 1934 | Buf_AddByte(&buf, '\\'); |
1945 | Buf_AddByte(&buf, *str); | | 1935 | Buf_AddByte(&buf, *str); |
1946 | if (quoteDollar && *str == '$') | | 1936 | if (quoteDollar && *str == '$') |
1947 | Buf_AddBytes(&buf, 2, "\\$"); | | 1937 | Buf_AddStr(&buf, "\\$"); |
1948 | } | | 1938 | } |
1949 | | | 1939 | |
1950 | str = Buf_Destroy(&buf, FALSE); | | 1940 | str = Buf_Destroy(&buf, FALSE); |
1951 | if (DEBUG(VAR)) | | 1941 | if (DEBUG(VAR)) |
1952 | fprintf(debug_file, "QuoteMeta: [%s]\n", str); | | 1942 | fprintf(debug_file, "QuoteMeta: [%s]\n", str); |
1953 | return str; | | 1943 | return str; |
1954 | } | | 1944 | } |
1955 | | | 1945 | |
1956 | /*- | | 1946 | /*- |
1957 | *----------------------------------------------------------------------- | | 1947 | *----------------------------------------------------------------------- |
1958 | * VarHash -- | | 1948 | * VarHash -- |
1959 | * Hash the string using the MurmurHash3 algorithm. | | 1949 | * Hash the string using the MurmurHash3 algorithm. |
1960 | * Output is computed using 32bit Little Endian arithmetic. | | 1950 | * Output is computed using 32bit Little Endian arithmetic. |
| @@ -2155,27 +2145,27 @@ ApplyModifier_Defined(const char *mod, A | | | @@ -2155,27 +2145,27 @@ ApplyModifier_Defined(const char *mod, A |
2155 | st->cp[1] == '\\')) { | | 2145 | st->cp[1] == '\\')) { |
2156 | Buf_AddByte(&buf, st->cp[1]); | | 2146 | Buf_AddByte(&buf, st->cp[1]); |
2157 | st->cp++; | | 2147 | st->cp++; |
2158 | } else if (*st->cp == '$') { | | 2148 | } else if (*st->cp == '$') { |
2159 | /* | | 2149 | /* |
2160 | * If unescaped dollar sign, assume it's a | | 2150 | * If unescaped dollar sign, assume it's a |
2161 | * variable substitution and recurse. | | 2151 | * variable substitution and recurse. |
2162 | */ | | 2152 | */ |
2163 | char *cp2; | | 2153 | char *cp2; |
2164 | int len; | | 2154 | int len; |
2165 | void *freeIt; | | 2155 | void *freeIt; |
2166 | | | 2156 | |
2167 | cp2 = Var_Parse(st->cp, st->ctxt, neflags, &len, &freeIt); | | 2157 | cp2 = Var_Parse(st->cp, st->ctxt, neflags, &len, &freeIt); |
2168 | Buf_AddBytes(&buf, strlen(cp2), cp2); | | 2158 | Buf_AddStr(&buf, cp2); |
2169 | free(freeIt); | | 2159 | free(freeIt); |
2170 | st->cp += len - 1; | | 2160 | st->cp += len - 1; |
2171 | } else { | | 2161 | } else { |
2172 | Buf_AddByte(&buf, *st->cp); | | 2162 | Buf_AddByte(&buf, *st->cp); |
2173 | } | | 2163 | } |
2174 | } | | 2164 | } |
2175 | | | 2165 | |
2176 | st->termc = *st->cp; | | 2166 | st->termc = *st->cp; |
2177 | | | 2167 | |
2178 | if (st->v->flags & VAR_JUNK) | | 2168 | if (st->v->flags & VAR_JUNK) |
2179 | st->v->flags |= VAR_KEEP; | | 2169 | st->v->flags |= VAR_KEEP; |
2180 | if (neflags & VARE_WANTRES) { | | 2170 | if (neflags & VARE_WANTRES) { |
2181 | st->newStr = Buf_Destroy(&buf, FALSE); | | 2171 | st->newStr = Buf_Destroy(&buf, FALSE); |
| @@ -3487,27 +3477,27 @@ Var_Parse(const char *str, GNode *ctxt, | | | @@ -3487,27 +3477,27 @@ Var_Parse(const char *str, GNode *ctxt, |
3487 | depth++; | | 3477 | depth++; |
3488 | if (*tstr == endc) { | | 3478 | if (*tstr == endc) { |
3489 | if (--depth == 0) | | 3479 | if (--depth == 0) |
3490 | break; | | 3480 | break; |
3491 | } | | 3481 | } |
3492 | if (depth == 1 && *tstr == ':') | | 3482 | if (depth == 1 && *tstr == ':') |
3493 | break; | | 3483 | break; |
3494 | /* A variable inside a variable, expand. */ | | 3484 | /* A variable inside a variable, expand. */ |
3495 | if (*tstr == '$') { | | 3485 | if (*tstr == '$') { |
3496 | int rlen; | | 3486 | int rlen; |
3497 | void *freeIt; | | 3487 | void *freeIt; |
3498 | char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt); | | 3488 | char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt); |
3499 | if (rval != NULL) | | 3489 | if (rval != NULL) |
3500 | Buf_AddBytes(&buf, strlen(rval), rval); | | 3490 | Buf_AddStr(&buf, rval); |
3501 | free(freeIt); | | 3491 | free(freeIt); |
3502 | tstr += rlen - 1; | | 3492 | tstr += rlen - 1; |
3503 | } else | | 3493 | } else |
3504 | Buf_AddByte(&buf, *tstr); | | 3494 | Buf_AddByte(&buf, *tstr); |
3505 | } | | 3495 | } |
3506 | if (*tstr == ':') { | | 3496 | if (*tstr == ':') { |
3507 | haveModifier = TRUE; | | 3497 | haveModifier = TRUE; |
3508 | } else if (*tstr == endc) { | | 3498 | } else if (*tstr == endc) { |
3509 | haveModifier = FALSE; | | 3499 | haveModifier = FALSE; |
3510 | } else { | | 3500 | } else { |
3511 | /* | | 3501 | /* |
3512 | * If we never did find the end character, return NULL | | 3502 | * If we never did find the end character, return NULL |
3513 | * right now, setting the length to be the distance to | | 3503 | * right now, setting the length to be the distance to |
| @@ -3757,27 +3747,27 @@ Var_Subst(const char *var, const char *s | | | @@ -3757,27 +3747,27 @@ Var_Subst(const char *var, const char *s |
3757 | Buf_AddByte(&buf, *str); | | 3747 | Buf_AddByte(&buf, *str); |
3758 | str++; | | 3748 | str++; |
3759 | Buf_AddByte(&buf, *str); | | 3749 | Buf_AddByte(&buf, *str); |
3760 | str++; | | 3750 | str++; |
3761 | } else if (*str != '$') { | | 3751 | } else if (*str != '$') { |
3762 | /* | | 3752 | /* |
3763 | * Skip as many characters as possible -- either to the end of | | 3753 | * Skip as many characters as possible -- either to the end of |
3764 | * the string or to the next dollar sign (variable invocation). | | 3754 | * the string or to the next dollar sign (variable invocation). |
3765 | */ | | 3755 | */ |
3766 | const char *cp; | | 3756 | const char *cp; |
3767 | | | 3757 | |
3768 | for (cp = str++; *str != '$' && *str != '\0'; str++) | | 3758 | for (cp = str++; *str != '$' && *str != '\0'; str++) |
3769 | continue; | | 3759 | continue; |
3770 | Buf_AddBytes(&buf, str - cp, cp); | | 3760 | Buf_AddBytesBetween(&buf, cp, str); |
3771 | } else { | | 3761 | } else { |
3772 | if (var != NULL) { | | 3762 | if (var != NULL) { |
3773 | int expand; | | 3763 | int expand; |
3774 | for (;;) { | | 3764 | for (;;) { |
3775 | if (str[1] == '\0') { | | 3765 | if (str[1] == '\0') { |
3776 | /* A trailing $ is kind of a special case */ | | 3766 | /* A trailing $ is kind of a special case */ |
3777 | Buf_AddByte(&buf, str[0]); | | 3767 | Buf_AddByte(&buf, str[0]); |
3778 | str++; | | 3768 | str++; |
3779 | expand = FALSE; | | 3769 | expand = FALSE; |
3780 | } else if (str[1] != PROPEN && str[1] != BROPEN) { | | 3770 | } else if (str[1] != PROPEN && str[1] != BROPEN) { |
3781 | if (str[1] != *var || strlen(var) > 1) { | | 3771 | if (str[1] != *var || strlen(var) > 1) { |
3782 | Buf_AddBytes(&buf, 2, str); | | 3772 | Buf_AddBytes(&buf, 2, str); |
3783 | str += 2; | | 3773 | str += 2; |
| @@ -3789,40 +3779,40 @@ Var_Subst(const char *var, const char *s | | | @@ -3789,40 +3779,40 @@ Var_Subst(const char *var, const char *s |
3789 | const char *p; | | 3779 | const char *p; |
3790 | | | 3780 | |
3791 | /* Scan up to the end of the variable name. */ | | 3781 | /* Scan up to the end of the variable name. */ |
3792 | for (p = &str[2]; *p && | | 3782 | for (p = &str[2]; *p && |
3793 | *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++) | | 3783 | *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++) |
3794 | if (*p == '$') | | 3784 | if (*p == '$') |
3795 | break; | | 3785 | break; |
3796 | /* | | 3786 | /* |
3797 | * A variable inside the variable. We cannot expand | | 3787 | * A variable inside the variable. We cannot expand |
3798 | * the external variable yet, so we try again with | | 3788 | * the external variable yet, so we try again with |
3799 | * the nested one | | 3789 | * the nested one |
3800 | */ | | 3790 | */ |
3801 | if (*p == '$') { | | 3791 | if (*p == '$') { |
3802 | Buf_AddBytes(&buf, p - str, str); | | 3792 | Buf_AddBytesBetween(&buf, str, p); |
3803 | str = p; | | 3793 | str = p; |
3804 | continue; | | 3794 | continue; |
3805 | } | | 3795 | } |
3806 | | | 3796 | |
3807 | if (strncmp(var, str + 2, p - str - 2) != 0 || | | 3797 | if (strncmp(var, str + 2, p - str - 2) != 0 || |
3808 | var[p - str - 2] != '\0') { | | 3798 | var[p - str - 2] != '\0') { |
3809 | /* | | 3799 | /* |
3810 | * Not the variable we want to expand, scan | | 3800 | * Not the variable we want to expand, scan |
3811 | * until the next variable | | 3801 | * until the next variable |
3812 | */ | | 3802 | */ |
3813 | for (; *p != '$' && *p != '\0'; p++) | | 3803 | for (; *p != '$' && *p != '\0'; p++) |
3814 | continue; | | 3804 | continue; |
3815 | Buf_AddBytes(&buf, p - str, str); | | 3805 | Buf_AddBytesBetween(&buf, str, p); |
3816 | str = p; | | 3806 | str = p; |
3817 | expand = FALSE; | | 3807 | expand = FALSE; |
3818 | } else | | 3808 | } else |
3819 | expand = TRUE; | | 3809 | expand = TRUE; |
3820 | break; | | 3810 | break; |
3821 | } | | 3811 | } |
3822 | } | | 3812 | } |
3823 | if (!expand) | | 3813 | if (!expand) |
3824 | continue; | | 3814 | continue; |
3825 | } | | 3815 | } |
3826 | | | 3816 | |
3827 | val = Var_Parse(str, ctxt, flags, &length, &freeIt); | | 3817 | val = Var_Parse(str, ctxt, flags, &length, &freeIt); |
3828 | | | 3818 | |