| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.329 2020/07/26 19:44:04 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.330 2020/07/26 19:55:24 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.329 2020/07/26 19:44:04 rillig Exp $"; | | 72 | static char rcsid[] = "$NetBSD: var.c,v 1.330 2020/07/26 19:55:24 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.329 2020/07/26 19:44:04 rillig Exp $"); | | 79 | __RCSID("$NetBSD: var.c,v 1.330 2020/07/26 19:55:24 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 | * |
| @@ -1828,37 +1828,37 @@ ParseModifierPart(const char **tstr, int | | | @@ -1828,37 +1828,37 @@ ParseModifierPart(const char **tstr, int |
1828 | cp[1] == delim || cp[1] == '\\' || cp[1] == '$' || | | 1828 | cp[1] == delim || cp[1] == '\\' || cp[1] == '$' || |
1829 | (cp[1] == '&' && subst != NULL)); | | 1829 | (cp[1] == '&' && subst != NULL)); |
1830 | if (is_escaped) { | | 1830 | if (is_escaped) { |
1831 | Buf_AddByte(&buf, cp[1]); | | 1831 | Buf_AddByte(&buf, cp[1]); |
1832 | cp++; | | 1832 | cp++; |
1833 | } else if (*cp == '$') { | | 1833 | } else if (*cp == '$') { |
1834 | if (cp[1] == delim) { /* Unescaped $ at end of pattern */ | | 1834 | if (cp[1] == delim) { /* Unescaped $ at end of pattern */ |
1835 | if (out_pflags != NULL) | | 1835 | if (out_pflags != NULL) |
1836 | *out_pflags |= VARP_ANCHOR_END; | | 1836 | *out_pflags |= VARP_ANCHOR_END; |
1837 | else | | 1837 | else |
1838 | Buf_AddByte(&buf, *cp); | | 1838 | Buf_AddByte(&buf, *cp); |
1839 | } else { | | 1839 | } else { |
1840 | if (eflags & VARE_WANTRES) { | | 1840 | if (eflags & VARE_WANTRES) { |
| | | 1841 | char *cp2; |
1841 | int len; | | 1842 | int len; |
1842 | void *freeIt; | | 1843 | void *freeIt; |
1843 | | | 1844 | |
1844 | /* | | 1845 | /* |
1845 | * If unescaped dollar sign not before the | | 1846 | * If unescaped dollar sign not before the |
1846 | * delimiter, assume it's a variable | | 1847 | * delimiter, assume it's a variable |
1847 | * substitution and recurse. | | 1848 | * substitution and recurse. |
1848 | */ | | 1849 | */ |
1849 | VarEvalFlags sub_eflags = errnum | (eflags & VARE_WANTRES); | | 1850 | cp2 = Var_Parse(cp, ctxt, errnum | (eflags & VARE_WANTRES), |
1850 | const char *cp2 = Var_Parse(cp, ctxt, sub_eflags, | | 1851 | &len, &freeIt); |
1851 | &len, &freeIt); | | | |
1852 | Buf_AddStr(&buf, cp2); | | 1852 | Buf_AddStr(&buf, cp2); |
1853 | free(freeIt); | | 1853 | free(freeIt); |
1854 | cp += len - 1; | | 1854 | cp += len - 1; |
1855 | } else { | | 1855 | } else { |
1856 | const char *cp2 = &cp[1]; | | 1856 | const char *cp2 = &cp[1]; |
1857 | | | 1857 | |
1858 | if (*cp2 == PROPEN || *cp2 == BROPEN) { | | 1858 | if (*cp2 == PROPEN || *cp2 == BROPEN) { |
1859 | /* | | 1859 | /* |
1860 | * Find the end of this variable reference | | 1860 | * Find the end of this variable reference |
1861 | * and suck it in without further ado. | | 1861 | * and suck it in without further ado. |
1862 | * It will be interpreted later. | | 1862 | * It will be interpreted later. |
1863 | */ | | 1863 | */ |
1864 | int have = *cp2; | | 1864 | int have = *cp2; |
| @@ -2135,31 +2135,31 @@ ApplyModifier_Defined(const char *mod, A | | | @@ -2135,31 +2135,31 @@ ApplyModifier_Defined(const char *mod, A |
2135 | for (st->cp = mod + 1; | | 2135 | for (st->cp = mod + 1; |
2136 | *st->cp != st->endc && *st->cp != ':' && *st->cp != '\0'; | | 2136 | *st->cp != st->endc && *st->cp != ':' && *st->cp != '\0'; |
2137 | st->cp++) { | | 2137 | st->cp++) { |
2138 | if (*st->cp == '\\' && | | 2138 | if (*st->cp == '\\' && |
2139 | (st->cp[1] == ':' || st->cp[1] == '$' || st->cp[1] == st->endc || | | 2139 | (st->cp[1] == ':' || st->cp[1] == '$' || st->cp[1] == st->endc || |
2140 | st->cp[1] == '\\')) { | | 2140 | st->cp[1] == '\\')) { |
2141 | Buf_AddByte(&buf, st->cp[1]); | | 2141 | Buf_AddByte(&buf, st->cp[1]); |
2142 | st->cp++; | | 2142 | st->cp++; |
2143 | } else if (*st->cp == '$') { | | 2143 | } else if (*st->cp == '$') { |
2144 | /* | | 2144 | /* |
2145 | * If unescaped dollar sign, assume it's a | | 2145 | * If unescaped dollar sign, assume it's a |
2146 | * variable substitution and recurse. | | 2146 | * variable substitution and recurse. |
2147 | */ | | 2147 | */ |
| | | 2148 | char *cp2; |
2148 | int len; | | 2149 | int len; |
2149 | void *freeIt; | | 2150 | void *freeIt; |
2150 | | | 2151 | |
2151 | const char *cp2 = Var_Parse(st->cp, st->ctxt, neflags, | | 2152 | cp2 = Var_Parse(st->cp, st->ctxt, neflags, &len, &freeIt); |
2152 | &len, &freeIt); | | | |
2153 | Buf_AddStr(&buf, cp2); | | 2153 | Buf_AddStr(&buf, cp2); |
2154 | free(freeIt); | | 2154 | free(freeIt); |
2155 | st->cp += len - 1; | | 2155 | st->cp += len - 1; |
2156 | } else { | | 2156 | } else { |
2157 | Buf_AddByte(&buf, *st->cp); | | 2157 | Buf_AddByte(&buf, *st->cp); |
2158 | } | | 2158 | } |
2159 | } | | 2159 | } |
2160 | | | 2160 | |
2161 | st->termc = *st->cp; | | 2161 | st->termc = *st->cp; |
2162 | | | 2162 | |
2163 | if (st->v->flags & VAR_JUNK) | | 2163 | if (st->v->flags & VAR_JUNK) |
2164 | st->v->flags |= VAR_KEEP; | | 2164 | st->v->flags |= VAR_KEEP; |
2165 | if (neflags & VARE_WANTRES) { | | 2165 | if (neflags & VARE_WANTRES) { |
| @@ -3067,31 +3067,31 @@ ApplyModifiers(char *nstr, const char *t | | | @@ -3067,31 +3067,31 @@ ApplyModifiers(char *nstr, const char *t |
3067 | startc, endc, v, ctxt, eflags, lengthPtr, freePtr, | | 3067 | startc, endc, v, ctxt, eflags, lengthPtr, freePtr, |
3068 | nstr, tstr, tstr, | | 3068 | nstr, tstr, tstr, |
3069 | '\0', '\0', 0, ' ', FALSE, NULL | | 3069 | '\0', '\0', 0, ' ', FALSE, NULL |
3070 | }; | | 3070 | }; |
3071 | | | 3071 | |
3072 | const char *p = tstr; | | 3072 | const char *p = tstr; |
3073 | while (*p != '\0' && *p != endc) { | | 3073 | while (*p != '\0' && *p != endc) { |
3074 | | | 3074 | |
3075 | if (*p == '$') { | | 3075 | if (*p == '$') { |
3076 | /* | | 3076 | /* |
3077 | * We may have some complex modifiers in a variable. | | 3077 | * We may have some complex modifiers in a variable. |
3078 | */ | | 3078 | */ |
3079 | void *freeIt; | | 3079 | void *freeIt; |
| | | 3080 | char *rval; |
3080 | int rlen; | | 3081 | int rlen; |
3081 | int c; | | 3082 | int c; |
3082 | | | 3083 | |
3083 | const char *rval = Var_Parse(p, st.ctxt, st.eflags, | | 3084 | rval = Var_Parse(p, st.ctxt, st.eflags, &rlen, &freeIt); |
3084 | &rlen, &freeIt); | | | |
3085 | | | 3085 | |
3086 | /* | | 3086 | /* |
3087 | * If we have not parsed up to st.endc or ':', | | 3087 | * If we have not parsed up to st.endc or ':', |
3088 | * we are not interested. | | 3088 | * we are not interested. |
3089 | */ | | 3089 | */ |
3090 | if (rval != NULL && *rval && | | 3090 | if (rval != NULL && *rval && |
3091 | (c = p[rlen]) != '\0' && | | 3091 | (c = p[rlen]) != '\0' && |
3092 | c != ':' && | | 3092 | c != ':' && |
3093 | c != st.endc) { | | 3093 | c != st.endc) { |
3094 | free(freeIt); | | 3094 | free(freeIt); |
3095 | goto apply_mods; | | 3095 | goto apply_mods; |
3096 | } | | 3096 | } |
3097 | | | 3097 | |
| @@ -3373,27 +3373,27 @@ cleanup: | | | @@ -3373,27 +3373,27 @@ cleanup: |
3373 | * The (possibly-modified) value of the variable or var_Error if the | | 3373 | * The (possibly-modified) value of the variable or var_Error if the |
3374 | * specification is invalid. The length of the specification is | | 3374 | * specification is invalid. The length of the specification is |
3375 | * placed in *lengthPtr (for invalid specifications, this is just | | 3375 | * placed in *lengthPtr (for invalid specifications, this is just |
3376 | * 2...?). | | 3376 | * 2...?). |
3377 | * If *freePtr is non-NULL then it's a pointer that the caller | | 3377 | * If *freePtr is non-NULL then it's a pointer that the caller |
3378 | * should pass to free() to free memory used by the result. | | 3378 | * should pass to free() to free memory used by the result. |
3379 | * | | 3379 | * |
3380 | * Side Effects: | | 3380 | * Side Effects: |
3381 | * None. | | 3381 | * None. |
3382 | * | | 3382 | * |
3383 | *----------------------------------------------------------------------- | | 3383 | *----------------------------------------------------------------------- |
3384 | */ | | 3384 | */ |
3385 | /* coverity[+alloc : arg-*4] */ | | 3385 | /* coverity[+alloc : arg-*4] */ |
3386 | const char * | | 3386 | char * |
3387 | Var_Parse(const char * const str, GNode *ctxt, VarEvalFlags flags, | | 3387 | Var_Parse(const char * const str, GNode *ctxt, VarEvalFlags flags, |
3388 | int *lengthPtr, void **freePtr) | | 3388 | int *lengthPtr, void **freePtr) |
3389 | { | | 3389 | { |
3390 | const char *tstr; /* Pointer into str */ | | 3390 | const char *tstr; /* Pointer into str */ |
3391 | Var *v; /* Variable in invocation */ | | 3391 | Var *v; /* Variable in invocation */ |
3392 | Boolean haveModifier; /* TRUE if have modifiers for the variable */ | | 3392 | Boolean haveModifier; /* TRUE if have modifiers for the variable */ |
3393 | char endc; /* Ending character when variable in parens | | 3393 | char endc; /* Ending character when variable in parens |
3394 | * or braces */ | | 3394 | * or braces */ |
3395 | char startc; /* Starting character when variable in parens | | 3395 | char startc; /* Starting character when variable in parens |
3396 | * or braces */ | | 3396 | * or braces */ |
3397 | char *nstr; /* New string, used during expansion */ | | 3397 | char *nstr; /* New string, used during expansion */ |
3398 | Boolean dynamic; /* TRUE if the variable is local and we're | | 3398 | Boolean dynamic; /* TRUE if the variable is local and we're |
3399 | * expanding it in a non-local context. This | | 3399 | * expanding it in a non-local context. This |
| @@ -3426,33 +3426,33 @@ Var_Parse(const char * const str, GNode | | | @@ -3426,33 +3426,33 @@ Var_Parse(const char * const str, GNode |
3426 | | | 3426 | |
3427 | if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { | | 3427 | if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { |
3428 | /* | | 3428 | /* |
3429 | * If substituting a local variable in a non-local context, | | 3429 | * If substituting a local variable in a non-local context, |
3430 | * assume it's for dynamic source stuff. We have to handle | | 3430 | * assume it's for dynamic source stuff. We have to handle |
3431 | * this specially and return the longhand for the variable | | 3431 | * this specially and return the longhand for the variable |
3432 | * with the dollar sign escaped so it makes it back to the | | 3432 | * with the dollar sign escaped so it makes it back to the |
3433 | * caller. Only four of the local variables are treated | | 3433 | * caller. Only four of the local variables are treated |
3434 | * specially as they are the only four that will be set | | 3434 | * specially as they are the only four that will be set |
3435 | * when dynamic sources are expanded. | | 3435 | * when dynamic sources are expanded. |
3436 | */ | | 3436 | */ |
3437 | switch (str[1]) { | | 3437 | switch (str[1]) { |
3438 | case '@': | | 3438 | case '@': |
3439 | return "$(.TARGET)"; | | 3439 | return UNCONST("$(.TARGET)"); |
3440 | case '%': | | 3440 | case '%': |
3441 | return "$(.MEMBER)"; | | 3441 | return UNCONST("$(.MEMBER)"); |
3442 | case '*': | | 3442 | case '*': |
3443 | return "$(.PREFIX)"; | | 3443 | return UNCONST("$(.PREFIX)"); |
3444 | case '!': | | 3444 | case '!': |
3445 | return "$(.ARCHIVE)"; | | 3445 | return UNCONST("$(.ARCHIVE)"); |
3446 | } | | 3446 | } |
3447 | } | | 3447 | } |
3448 | return (flags & VARE_UNDEFERR) ? var_Error : varNoError; | | 3448 | return (flags & VARE_UNDEFERR) ? var_Error : varNoError; |
3449 | } else { | | 3449 | } else { |
3450 | haveModifier = FALSE; | | 3450 | haveModifier = FALSE; |
3451 | tstr = str + 1; | | 3451 | tstr = str + 1; |
3452 | endc = str[1]; | | 3452 | endc = str[1]; |
3453 | } | | 3453 | } |
3454 | } else { | | 3454 | } else { |
3455 | Buffer buf; /* Holds the variable name */ | | 3455 | Buffer buf; /* Holds the variable name */ |
3456 | int depth = 1; | | 3456 | int depth = 1; |
3457 | | | 3457 | |
3458 | endc = startc == PROPEN ? PRCLOSE : BRCLOSE; | | 3458 | endc = startc == PROPEN ? PRCLOSE : BRCLOSE; |
| @@ -3465,28 +3465,27 @@ Var_Parse(const char * const str, GNode | | | @@ -3465,28 +3465,27 @@ Var_Parse(const char * const str, GNode |
3465 | /* Track depth so we can spot parse errors. */ | | 3465 | /* Track depth so we can spot parse errors. */ |
3466 | if (*tstr == startc) | | 3466 | if (*tstr == startc) |
3467 | depth++; | | 3467 | depth++; |
3468 | if (*tstr == endc) { | | 3468 | if (*tstr == endc) { |
3469 | if (--depth == 0) | | 3469 | if (--depth == 0) |
3470 | break; | | 3470 | break; |
3471 | } | | 3471 | } |
3472 | if (depth == 1 && *tstr == ':') | | 3472 | if (depth == 1 && *tstr == ':') |
3473 | break; | | 3473 | break; |
3474 | /* A variable inside a variable, expand. */ | | 3474 | /* A variable inside a variable, expand. */ |
3475 | if (*tstr == '$') { | | 3475 | if (*tstr == '$') { |
3476 | int rlen; | | 3476 | int rlen; |
3477 | void *freeIt; | | 3477 | void *freeIt; |
3478 | const char *rval = Var_Parse(tstr, ctxt, flags, | | 3478 | char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt); |
3479 | &rlen, &freeIt); | | | |
3480 | if (rval != NULL) | | 3479 | if (rval != NULL) |
3481 | Buf_AddStr(&buf, rval); | | 3480 | Buf_AddStr(&buf, rval); |
3482 | free(freeIt); | | 3481 | free(freeIt); |
3483 | tstr += rlen - 1; | | 3482 | tstr += rlen - 1; |
3484 | } else | | 3483 | } else |
3485 | Buf_AddByte(&buf, *tstr); | | 3484 | Buf_AddByte(&buf, *tstr); |
3486 | } | | 3485 | } |
3487 | if (*tstr == ':') { | | 3486 | if (*tstr == ':') { |
3488 | haveModifier = TRUE; | | 3487 | haveModifier = TRUE; |
3489 | } else if (*tstr == endc) { | | 3488 | } else if (*tstr == endc) { |
3490 | haveModifier = FALSE; | | 3489 | haveModifier = FALSE; |
3491 | } else { | | 3490 | } else { |
3492 | /* | | 3491 | /* |
| @@ -3704,27 +3703,27 @@ Var_Parse(const char * const str, GNode | | | @@ -3704,27 +3703,27 @@ Var_Parse(const char * const str, GNode |
3704 | * VARE_ASSIGN if we are in a := assignment | | 3703 | * VARE_ASSIGN if we are in a := assignment |
3705 | * | | 3704 | * |
3706 | * Results: | | 3705 | * Results: |
3707 | * The resulting string. | | 3706 | * The resulting string. |
3708 | * | | 3707 | * |
3709 | * Side Effects: | | 3708 | * Side Effects: |
3710 | * None. | | 3709 | * None. |
3711 | *----------------------------------------------------------------------- | | 3710 | *----------------------------------------------------------------------- |
3712 | */ | | 3711 | */ |
3713 | char * | | 3712 | char * |
3714 | Var_Subst(const char *var, const char *str, GNode *ctxt, VarEvalFlags flags) | | 3713 | Var_Subst(const char *var, const char *str, GNode *ctxt, VarEvalFlags flags) |
3715 | { | | 3714 | { |
3716 | Buffer buf; /* Buffer for forming things */ | | 3715 | Buffer buf; /* Buffer for forming things */ |
3717 | const char *val; /* Value to substitute for a variable */ | | 3716 | char *val; /* Value to substitute for a variable */ |
3718 | int length; /* Length of the variable invocation */ | | 3717 | int length; /* Length of the variable invocation */ |
3719 | Boolean trailingBslash; /* variable ends in \ */ | | 3718 | Boolean trailingBslash; /* variable ends in \ */ |
3720 | void *freeIt = NULL; /* Set if it should be freed */ | | 3719 | void *freeIt = NULL; /* Set if it should be freed */ |
3721 | static Boolean errorReported; /* Set true if an error has already | | 3720 | static Boolean errorReported; /* Set true if an error has already |
3722 | * been reported to prevent a plethora | | 3721 | * been reported to prevent a plethora |
3723 | * of messages when recursing */ | | 3722 | * of messages when recursing */ |
3724 | | | 3723 | |
3725 | Buf_Init(&buf, 0); | | 3724 | Buf_Init(&buf, 0); |
3726 | errorReported = FALSE; | | 3725 | errorReported = FALSE; |
3727 | trailingBslash = FALSE; | | 3726 | trailingBslash = FALSE; |
3728 | | | 3727 | |
3729 | while (*str) { | | 3728 | while (*str) { |
3730 | if (*str == '\n' && trailingBslash) | | 3729 | if (*str == '\n' && trailingBslash) |