Sat Jan 30 20:53:29 2021 UTC ()
make(1): split Buf_Destroy into Buf_Done and Buf_DoneData

In all cases except one, the boolean argument to Buf_Destroy was
constant.  Removing that argument by splitting the function into two
separate functions makes the intention clearer on the call site.  It
also removes the possibility for using the return value of Buf_Done,
which would have made no sense.

The function Buf_Done now pairs with Buf_Init, just as in HashTable and
Lst.

Even though Buf_Done is essentially a no-op, it is kept as a function,
both for symmetry with Buf_Init and for clearing the Buffer members
after use (this will be done only in CLEANUP mode, in a follow-up
commit).


(rillig)
diff -r1.47 -r1.48 src/usr.bin/make/buf.c
diff -r1.38 -r1.39 src/usr.bin/make/buf.h
diff -r1.253 -r1.254 src/usr.bin/make/cond.c
diff -r1.264 -r1.265 src/usr.bin/make/dir.c
diff -r1.138 -r1.139 src/usr.bin/make/for.c
diff -r1.517 -r1.518 src/usr.bin/make/main.c
diff -r1.533 -r1.534 src/usr.bin/make/parse.c
diff -r1.783 -r1.784 src/usr.bin/make/var.c

cvs diff -r1.47 -r1.48 src/usr.bin/make/buf.c (expand / switch to unified diff)

--- src/usr.bin/make/buf.c 2020/12/30 10:03:16 1.47
+++ src/usr.bin/make/buf.c 2021/01/30 20:53:29 1.48
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: buf.c,v 1.47 2020/12/30 10:03:16 rillig Exp $ */ 1/* $NetBSD: buf.c,v 1.48 2021/01/30 20:53:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * 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.
@@ -65,27 +65,27 @@ @@ -65,27 +65,27 @@
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE. 69 * SUCH DAMAGE.
70 */ 70 */
71 71
72/* Automatically-expanding null-terminated character buffers. */ 72/* Automatically-expanding null-terminated character buffers. */
73 73
74#include <limits.h> 74#include <limits.h>
75#include "make.h" 75#include "make.h"
76 76
77/* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */ 77/* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */
78MAKE_RCSID("$NetBSD: buf.c,v 1.47 2020/12/30 10:03:16 rillig Exp $"); 78MAKE_RCSID("$NetBSD: buf.c,v 1.48 2021/01/30 20:53:29 rillig Exp $");
79 79
80/* Make space in the buffer for adding at least 16 more bytes. */ 80/* Make space in the buffer for adding at least 16 more bytes. */
81void 81void
82Buf_Expand(Buffer *buf) 82Buf_Expand(Buffer *buf)
83{ 83{
84 buf->cap += buf->cap > 16 ? buf->cap : 16; 84 buf->cap += buf->cap > 16 ? buf->cap : 16;
85 buf->data = bmake_realloc(buf->data, buf->cap); 85 buf->data = bmake_realloc(buf->data, buf->cap);
86} 86}
87 87
88/* Add the bytes to the buffer. */ 88/* Add the bytes to the buffer. */
89void 89void
90Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len) 90Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len)
91{ 91{
@@ -165,57 +165,66 @@ Buf_InitSize(Buffer *buf, size_t cap) @@ -165,57 +165,66 @@ Buf_InitSize(Buffer *buf, size_t cap)
165 buf->cap = cap; 165 buf->cap = cap;
166 buf->len = 0; 166 buf->len = 0;
167 buf->data = bmake_malloc(cap); 167 buf->data = bmake_malloc(cap);
168 buf->data[0] = '\0'; 168 buf->data[0] = '\0';
169} 169}
170 170
171void 171void
172Buf_Init(Buffer *buf) 172Buf_Init(Buffer *buf)
173{ 173{
174 Buf_InitSize(buf, 256); 174 Buf_InitSize(buf, 256);
175} 175}
176 176
177/* 177/*
178 * Reset the buffer. 178 * Free the data from the buffer.
179 * If freeData is TRUE, the data from the buffer is freed as well. 179 * The buffer is left in an indeterminate state.
180 * Otherwise it is kept and returned. 180 */
 181void
 182Buf_Done(Buffer *buf)
 183{
 184 free(buf->data);
 185
 186 buf->cap = 0;
 187 buf->len = 0;
 188 buf->data = NULL;
 189}
 190
 191/*
 192 * Return the data from the buffer.
 193 * The buffer is left in an indeterminate state.
181 */ 194 */
182char * 195char *
183Buf_Destroy(Buffer *buf, Boolean freeData) 196Buf_DoneData(Buffer *buf)
184{ 197{
185 char *data = buf->data; 198 char *data = buf->data;
186 if (freeData) { 
187 free(data); 
188 data = NULL; 
189 } 
190 199
191 buf->cap = 0; 200 buf->cap = 0;
192 buf->len = 0; 201 buf->len = 0;
193 buf->data = NULL; 202 buf->data = NULL;
194 203
195 return data; 204 return data;
196} 205}
197 206
198#ifndef BUF_COMPACT_LIMIT 207#ifndef BUF_COMPACT_LIMIT
199# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ 208# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
200#endif 209#endif
201 210
202/* 211/*
203 * Reset the buffer and return its data. 212 * Reset the buffer and return its data.
204 * 213 *
205 * If the buffer size is much greater than its content, 214 * If the buffer size is much greater than its content,
206 * a new buffer will be allocated and the old one freed. 215 * a new buffer will be allocated and the old one freed.
207 */ 216 */
208char * 217char *
209Buf_DestroyCompact(Buffer *buf) 218Buf_DoneDataCompact(Buffer *buf)
210{ 219{
211#if BUF_COMPACT_LIMIT > 0 220#if BUF_COMPACT_LIMIT > 0
212 if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) { 221 if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) {
213 /* We trust realloc to be smart */ 222 /* We trust realloc to be smart */
214 char *data = bmake_realloc(buf->data, buf->len + 1); 223 char *data = bmake_realloc(buf->data, buf->len + 1);
215 data[buf->len] = '\0'; /* XXX: unnecessary */ 224 data[buf->len] = '\0'; /* XXX: unnecessary */
216 Buf_Destroy(buf, FALSE); 225 Buf_DoneData(buf);
217 return data; 226 return data;
218 } 227 }
219#endif 228#endif
220 return Buf_Destroy(buf, FALSE); 229 return Buf_DoneData(buf);
221} 230}

cvs diff -r1.38 -r1.39 src/usr.bin/make/buf.h (expand / switch to unified diff)

--- src/usr.bin/make/buf.h 2020/12/28 15:42:53 1.38
+++ src/usr.bin/make/buf.h 2021/01/30 20:53:29 1.39
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: buf.h,v 1.38 2020/12/28 15:42:53 rillig Exp $ */ 1/* $NetBSD: buf.h,v 1.39 2021/01/30 20:53:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * 5 *
6 * This code is derived from software contributed to Berkeley by 6 * This code is derived from software contributed to Berkeley by
7 * Adam de Boor. 7 * Adam de Boor.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -116,17 +116,18 @@ MAKE_INLINE Boolean @@ -116,17 +116,18 @@ MAKE_INLINE Boolean
116Buf_EndsWith(const Buffer *buf, char ch) 116Buf_EndsWith(const Buffer *buf, char ch)
117{ 117{
118 return buf->len > 0 && buf->data[buf->len - 1] == ch; 118 return buf->len > 0 && buf->data[buf->len - 1] == ch;
119} 119}
120 120
121void Buf_AddBytes(Buffer *, const char *, size_t); 121void Buf_AddBytes(Buffer *, const char *, size_t);
122void Buf_AddBytesBetween(Buffer *, const char *, const char *); 122void Buf_AddBytesBetween(Buffer *, const char *, const char *);
123void Buf_AddStr(Buffer *, const char *); 123void Buf_AddStr(Buffer *, const char *);
124void Buf_AddInt(Buffer *, int); 124void Buf_AddInt(Buffer *, int);
125char *Buf_GetAll(Buffer *, size_t *); 125char *Buf_GetAll(Buffer *, size_t *);
126void Buf_Empty(Buffer *); 126void Buf_Empty(Buffer *);
127void Buf_Init(Buffer *); 127void Buf_Init(Buffer *);
128void Buf_InitSize(Buffer *, size_t); 128void Buf_InitSize(Buffer *, size_t);
129char *Buf_Destroy(Buffer *, Boolean); 129void Buf_Done(Buffer *);
130char *Buf_DestroyCompact(Buffer *); 130char *Buf_DoneData(Buffer *);
 131char *Buf_DoneDataCompact(Buffer *);
131 132
132#endif /* MAKE_BUF_H */ 133#endif /* MAKE_BUF_H */

cvs diff -r1.253 -r1.254 src/usr.bin/make/cond.c (expand / switch to unified diff)

--- src/usr.bin/make/cond.c 2021/01/22 00:12:01 1.253
+++ src/usr.bin/make/cond.c 2021/01/30 20:53:29 1.254
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cond.c,v 1.253 2021/01/22 00:12:01 rillig Exp $ */ 1/* $NetBSD: cond.c,v 1.254 2021/01/30 20:53:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * 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.
@@ -85,27 +85,27 @@ @@ -85,27 +85,27 @@
85 * Cond_restore_depth 85 * Cond_restore_depth
86 * Save and restore the nesting of the conditions, at 86 * Save and restore the nesting of the conditions, at
87 * the start and end of including another makefile, to 87 * the start and end of including another makefile, to
88 * ensure that in each makefile the conditional 88 * ensure that in each makefile the conditional
89 * directives are well-balanced. 89 * directives are well-balanced.
90 */ 90 */
91 91
92#include <errno.h> 92#include <errno.h>
93 93
94#include "make.h" 94#include "make.h"
95#include "dir.h" 95#include "dir.h"
96 96
97/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ 97/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
98MAKE_RCSID("$NetBSD: cond.c,v 1.253 2021/01/22 00:12:01 rillig Exp $"); 98MAKE_RCSID("$NetBSD: cond.c,v 1.254 2021/01/30 20:53:29 rillig Exp $");
99 99
100/* 100/*
101 * The parsing of conditional expressions is based on this grammar: 101 * The parsing of conditional expressions is based on this grammar:
102 * Or -> And '||' Or 102 * Or -> And '||' Or
103 * Or -> And 103 * Or -> And
104 * And -> Term '&&' And 104 * And -> Term '&&' And
105 * And -> Term 105 * And -> Term
106 * Term -> Function '(' Argument ')' 106 * Term -> Function '(' Argument ')'
107 * Term -> Leaf Operator Leaf 107 * Term -> Leaf Operator Leaf
108 * Term -> Leaf 108 * Term -> Leaf
109 * Term -> '(' Or ')' 109 * Term -> '(' Or ')'
110 * Term -> '!' Term 110 * Term -> '!' Term
111 * Leaf -> "string" 111 * Leaf -> "string"
@@ -272,28 +272,28 @@ ParseFuncArg(CondParser *par, const char @@ -272,28 +272,28 @@ ParseFuncArg(CondParser *par, const char
272 /* TODO: handle errors */ 272 /* TODO: handle errors */
273 Buf_AddStr(&argBuf, nestedVal.str); 273 Buf_AddStr(&argBuf, nestedVal.str);
274 FStr_Done(&nestedVal); 274 FStr_Done(&nestedVal);
275 continue; 275 continue;
276 } 276 }
277 if (ch == '(') 277 if (ch == '(')
278 paren_depth++; 278 paren_depth++;
279 else if (ch == ')' && --paren_depth < 0) 279 else if (ch == ')' && --paren_depth < 0)
280 break; 280 break;
281 Buf_AddByte(&argBuf, *p); 281 Buf_AddByte(&argBuf, *p);
282 p++; 282 p++;
283 } 283 }
284 284
285 *out_arg = Buf_GetAll(&argBuf, &argLen); 285 argLen = argBuf.len;
286 Buf_Destroy(&argBuf, FALSE); 286 *out_arg = Buf_DoneData(&argBuf);
287 287
288 cpp_skip_hspace(&p); 288 cpp_skip_hspace(&p);
289 289
290 if (func != NULL && *p++ != ')') { 290 if (func != NULL && *p++ != ')') {
291 Parse_Error(PARSE_FATAL, 291 Parse_Error(PARSE_FATAL,
292 "Missing closing parenthesis for %s()", func); 292 "Missing closing parenthesis for %s()", func);
293 par->printedError = TRUE; 293 par->printedError = TRUE;
294 return 0; 294 return 0;
295 } 295 }
296 296
297 *pp = p; 297 *pp = p;
298 return argLen; 298 return argLen;
299} 299}
@@ -529,29 +529,29 @@ CondParser_String(CondParser *par, Boole @@ -529,29 +529,29 @@ CondParser_String(CondParser *par, Boole
529 /* 529 /*
530 * The left-hand side must be quoted, 530 * The left-hand side must be quoted,
531 * a variable reference or a number. 531 * a variable reference or a number.
532 */ 532 */
533 str = FStr_InitRefer(NULL); 533 str = FStr_InitRefer(NULL);
534 goto cleanup; 534 goto cleanup;
535 } 535 }
536 Buf_AddByte(&buf, par->p[0]); 536 Buf_AddByte(&buf, par->p[0]);
537 par->p++; 537 par->p++;
538 continue; 538 continue;
539 } 539 }
540 } 540 }
541got_str: 541got_str:
542 str = FStr_InitOwn(Buf_GetAll(&buf, NULL)); 542 str = FStr_InitOwn(buf.data);
543cleanup: 543cleanup:
544 Buf_Destroy(&buf, FALSE); 544 Buf_DoneData(&buf);
545 *out_str = str; 545 *out_str = str;
546} 546}
547 547
548static Boolean 548static Boolean
549If_Eval(const CondParser *par, const char *arg, size_t arglen) 549If_Eval(const CondParser *par, const char *arg, size_t arglen)
550{ 550{
551 Boolean res = par->evalBare(arglen, arg); 551 Boolean res = par->evalBare(arglen, arg);
552 return par->negateEvalBare ? !res : res; 552 return par->negateEvalBare ? !res : res;
553} 553}
554 554
555/* 555/*
556 * Evaluate a "comparison without operator", such as in ".if ${VAR}" or 556 * Evaluate a "comparison without operator", such as in ".if ${VAR}" or
557 * ".if 0". 557 * ".if 0".

cvs diff -r1.264 -r1.265 src/usr.bin/make/dir.c (expand / switch to unified diff)

--- src/usr.bin/make/dir.c 2021/01/24 20:11:55 1.264
+++ src/usr.bin/make/dir.c 2021/01/30 20:53:29 1.265
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dir.c,v 1.264 2021/01/24 20:11:55 rillig Exp $ */ 1/* $NetBSD: dir.c,v 1.265 2021/01/30 20:53:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * 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.
@@ -128,27 +128,27 @@ @@ -128,27 +128,27 @@
128 */ 128 */
129 129
130#include <sys/types.h> 130#include <sys/types.h>
131#include <sys/stat.h> 131#include <sys/stat.h>
132 132
133#include <dirent.h> 133#include <dirent.h>
134#include <errno.h> 134#include <errno.h>
135 135
136#include "make.h" 136#include "make.h"
137#include "dir.h" 137#include "dir.h"
138#include "job.h" 138#include "job.h"
139 139
140/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */ 140/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
141MAKE_RCSID("$NetBSD: dir.c,v 1.264 2021/01/24 20:11:55 rillig Exp $"); 141MAKE_RCSID("$NetBSD: dir.c,v 1.265 2021/01/30 20:53:29 rillig Exp $");
142 142
143/* 143/*
144 * A search path is a list of CachedDir structures. A CachedDir has in it the 144 * A search path is a list of CachedDir structures. A CachedDir has in it the
145 * name of the directory and the names of all the files in the directory. 145 * name of the directory and the names of all the files in the directory.
146 * This is used to cut down on the number of system calls necessary to find 146 * This is used to cut down on the number of system calls necessary to find
147 * implicit dependents and their like. Since these searches are made before 147 * implicit dependents and their like. Since these searches are made before
148 * any actions are taken, we need not worry about the directory changing due 148 * any actions are taken, we need not worry about the directory changing due
149 * to creation commands. If this hampers the style of some makefiles, they 149 * to creation commands. If this hampers the style of some makefiles, they
150 * must be changed. 150 * must be changed.
151 * 151 *
152 * All previously-read directories are kept in openDirs, which is checked 152 * All previously-read directories are kept in openDirs, which is checked
153 * first before a directory is opened. 153 * first before a directory is opened.
154 * 154 *
@@ -1635,27 +1635,27 @@ SearchPath_ToFlags(SearchPath *path, con @@ -1635,27 +1635,27 @@ SearchPath_ToFlags(SearchPath *path, con
1635 SearchPathNode *ln; 1635 SearchPathNode *ln;
1636 1636
1637 Buf_Init(&buf); 1637 Buf_Init(&buf);
1638 1638
1639 if (path != NULL) { 1639 if (path != NULL) {
1640 for (ln = path->dirs.first; ln != NULL; ln = ln->next) { 1640 for (ln = path->dirs.first; ln != NULL; ln = ln->next) {
1641 CachedDir *dir = ln->datum; 1641 CachedDir *dir = ln->datum;
1642 Buf_AddStr(&buf, " "); 1642 Buf_AddStr(&buf, " ");
1643 Buf_AddStr(&buf, flag); 1643 Buf_AddStr(&buf, flag);
1644 Buf_AddStr(&buf, dir->name); 1644 Buf_AddStr(&buf, dir->name);
1645 } 1645 }
1646 } 1646 }
1647 1647
1648 return Buf_Destroy(&buf, FALSE); 1648 return Buf_DoneData(&buf);
1649} 1649}
1650 1650
1651/* Free the search path and all directories mentioned in it. */ 1651/* Free the search path and all directories mentioned in it. */
1652void 1652void
1653SearchPath_Free(SearchPath *path) 1653SearchPath_Free(SearchPath *path)
1654{ 1654{
1655 SearchPathNode *ln; 1655 SearchPathNode *ln;
1656 1656
1657 for (ln = path->dirs.first; ln != NULL; ln = ln->next) { 1657 for (ln = path->dirs.first; ln != NULL; ln = ln->next) {
1658 CachedDir *dir = ln->datum; 1658 CachedDir *dir = ln->datum;
1659 CachedDir_Unref(dir); 1659 CachedDir_Unref(dir);
1660 } 1660 }
1661 Lst_Done(&path->dirs); 1661 Lst_Done(&path->dirs);

cvs diff -r1.138 -r1.139 src/usr.bin/make/for.c (expand / switch to unified diff)

--- src/usr.bin/make/for.c 2021/01/25 19:39:34 1.138
+++ src/usr.bin/make/for.c 2021/01/30 20:53:29 1.139
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: for.c,v 1.138 2021/01/25 19:39:34 rillig Exp $ */ 1/* $NetBSD: for.c,v 1.139 2021/01/30 20:53:29 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1992, The Regents of the University of California. 4 * Copyright (c) 1992, The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -48,27 +48,27 @@ @@ -48,27 +48,27 @@
48 * body is scanned for variable expressions, and those that match the variable 48 * body is scanned for variable expressions, and those that match the variable
49 * names are replaced with expressions of the form ${:U...} or $(:U...). 49 * names are replaced with expressions of the form ${:U...} or $(:U...).
50 * After that, the body is treated like a file from an .include directive. 50 * After that, the body is treated like a file from an .include directive.
51 * 51 *
52 * Interface: 52 * Interface:
53 * For_Eval Evaluate the loop in the passed line. 53 * For_Eval Evaluate the loop in the passed line.
54 * 54 *
55 * For_Run Run accumulated loop 55 * For_Run Run accumulated loop
56 */ 56 */
57 57
58#include "make.h" 58#include "make.h"
59 59
60/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ 60/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
61MAKE_RCSID("$NetBSD: for.c,v 1.138 2021/01/25 19:39:34 rillig Exp $"); 61MAKE_RCSID("$NetBSD: for.c,v 1.139 2021/01/30 20:53:29 rillig Exp $");
62 62
63 63
64/* One of the variables to the left of the "in" in a .for loop. */ 64/* One of the variables to the left of the "in" in a .for loop. */
65typedef struct ForVar { 65typedef struct ForVar {
66 char *name; 66 char *name;
67 size_t nameLen; 67 size_t nameLen;
68} ForVar; 68} ForVar;
69 69
70typedef struct ForLoop { 70typedef struct ForLoop {
71 Buffer body; /* Unexpanded body of the loop */ 71 Buffer body; /* Unexpanded body of the loop */
72 Vector /* of ForVar */ vars; /* Iteration variables */ 72 Vector /* of ForVar */ vars; /* Iteration variables */
73 Words items; /* Substitution items */ 73 Words items; /* Substitution items */
74 Buffer curBody; /* Expanded body of the current iteration */ 74 Buffer curBody; /* Expanded body of the current iteration */
@@ -93,36 +93,36 @@ ForLoop_New(void) @@ -93,36 +93,36 @@ ForLoop_New(void)
93 Vector_Init(&f->vars, sizeof(ForVar)); 93 Vector_Init(&f->vars, sizeof(ForVar));
94 f->items.words = NULL; 94 f->items.words = NULL;
95 f->items.freeIt = NULL; 95 f->items.freeIt = NULL;
96 Buf_Init(&f->curBody); 96 Buf_Init(&f->curBody);
97 f->short_var = FALSE; 97 f->short_var = FALSE;
98 f->sub_next = 0; 98 f->sub_next = 0;
99 99
100 return f; 100 return f;
101} 101}
102 102
103static void 103static void
104ForLoop_Free(ForLoop *f) 104ForLoop_Free(ForLoop *f)
105{ 105{
106 Buf_Destroy(&f->body, TRUE); 106 Buf_Done(&f->body);
107 107
108 while (f->vars.len > 0) { 108 while (f->vars.len > 0) {
109 ForVar *var = Vector_Pop(&f->vars); 109 ForVar *var = Vector_Pop(&f->vars);
110 free(var->name); 110 free(var->name);
111 } 111 }
112 Vector_Done(&f->vars); 112 Vector_Done(&f->vars);
113 113
114 Words_Free(f->items); 114 Words_Free(f->items);
115 Buf_Destroy(&f->curBody, TRUE); 115 Buf_Done(&f->curBody);
116 116
117 free(f); 117 free(f);
118} 118}
119 119
120static void 120static void
121ForLoop_AddVar(ForLoop *f, const char *name, size_t len) 121ForLoop_AddVar(ForLoop *f, const char *name, size_t len)
122{ 122{
123 ForVar *var = Vector_Push(&f->vars); 123 ForVar *var = Vector_Push(&f->vars);
124 var->name = bmake_strldup(name, len); 124 var->name = bmake_strldup(name, len);
125 var->nameLen = len; 125 var->nameLen = len;
126} 126}
127 127
128static Boolean 128static Boolean

cvs diff -r1.517 -r1.518 src/usr.bin/make/main.c (expand / switch to unified diff)

--- src/usr.bin/make/main.c 2021/01/24 20:11:55 1.517
+++ src/usr.bin/make/main.c 2021/01/30 20:53:29 1.518
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: main.c,v 1.517 2021/01/24 20:11:55 rillig Exp $ */ 1/* $NetBSD: main.c,v 1.518 2021/01/30 20:53:29 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.
@@ -100,27 +100,27 @@ @@ -100,27 +100,27 @@
100 100
101#include <errno.h> 101#include <errno.h>
102#include <signal.h> 102#include <signal.h>
103#include <stdarg.h> 103#include <stdarg.h>
104#include <time.h> 104#include <time.h>
105 105
106#include "make.h" 106#include "make.h"
107#include "dir.h" 107#include "dir.h"
108#include "job.h" 108#include "job.h"
109#include "pathnames.h" 109#include "pathnames.h"
110#include "trace.h" 110#include "trace.h"
111 111
112/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ 112/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
113MAKE_RCSID("$NetBSD: main.c,v 1.517 2021/01/24 20:11:55 rillig Exp $"); 113MAKE_RCSID("$NetBSD: main.c,v 1.518 2021/01/30 20:53:29 rillig Exp $");
114#if defined(MAKE_NATIVE) && !defined(lint) 114#if defined(MAKE_NATIVE) && !defined(lint)
115__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " 115__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
116 "The Regents of the University of California. " 116 "The Regents of the University of California. "
117 "All rights reserved."); 117 "All rights reserved.");
118#endif 118#endif
119 119
120CmdOpts opts; 120CmdOpts opts;
121time_t now; /* Time at start of make */ 121time_t now; /* Time at start of make */
122GNode *defaultNode; /* .DEFAULT node */ 122GNode *defaultNode; /* .DEFAULT node */
123Boolean allPrecious; /* .PRECIOUS given on line by itself */ 123Boolean allPrecious; /* .PRECIOUS given on line by itself */
124Boolean deleteOnError; /* .DELETE_ON_ERROR: set */ 124Boolean deleteOnError; /* .DELETE_ON_ERROR: set */
125 125
126static int maxJobTokens; /* -j argument */ 126static int maxJobTokens; /* -j argument */
@@ -1831,27 +1831,27 @@ Cmd_Exec(const char *cmd, const char **e @@ -1831,27 +1831,27 @@ Cmd_Exec(const char *cmd, const char **e
1831 Buf_AddBytes(&buf, result, (size_t)bytes_read); 1831 Buf_AddBytes(&buf, result, (size_t)bytes_read);
1832 } while (bytes_read > 0 || 1832 } while (bytes_read > 0 ||
1833 (bytes_read == -1 && errno == EINTR)); 1833 (bytes_read == -1 && errno == EINTR));
1834 if (bytes_read == -1) 1834 if (bytes_read == -1)
1835 savederr = errno; 1835 savederr = errno;
1836 1836
1837 (void)close(pipefds[0]); /* Close the input side of the pipe. */ 1837 (void)close(pipefds[0]); /* Close the input side of the pipe. */
1838 1838
1839 /* Wait for the process to exit. */ 1839 /* Wait for the process to exit. */
1840 while ((pid = waitpid(cpid, &status, 0)) != cpid && pid >= 0) 1840 while ((pid = waitpid(cpid, &status, 0)) != cpid && pid >= 0)
1841 JobReapChild(pid, status, FALSE); 1841 JobReapChild(pid, status, FALSE);
1842 1842
1843 res_len = Buf_Len(&buf); 1843 res_len = Buf_Len(&buf);
1844 res = Buf_Destroy(&buf, FALSE); 1844 res = Buf_DoneData(&buf);
1845 1845
1846 if (savederr != 0) 1846 if (savederr != 0)
1847 *errfmt = "Couldn't read shell's output for \"%s\""; 1847 *errfmt = "Couldn't read shell's output for \"%s\"";
1848 1848
1849 if (WIFSIGNALED(status)) 1849 if (WIFSIGNALED(status))
1850 *errfmt = "\"%s\" exited on a signal"; 1850 *errfmt = "\"%s\" exited on a signal";
1851 else if (WEXITSTATUS(status) != 0) 1851 else if (WEXITSTATUS(status) != 0)
1852 *errfmt = "\"%s\" returned non-zero status"; 1852 *errfmt = "\"%s\" returned non-zero status";
1853 1853
1854 /* Convert newlines to spaces. A final newline is just stripped */ 1854 /* Convert newlines to spaces. A final newline is just stripped */
1855 if (res_len > 0 && res[res_len - 1] == '\n') 1855 if (res_len > 0 && res[res_len - 1] == '\n')
1856 res[res_len - 1] = '\0'; 1856 res[res_len - 1] = '\0';
1857 for (cp = res; *cp != '\0'; cp++) 1857 for (cp = res; *cp != '\0'; cp++)
@@ -2017,27 +2017,27 @@ execDie(const char *af, const char *av) @@ -2017,27 +2017,27 @@ execDie(const char *af, const char *av)
2017 2017
2018 Buf_Init(&buf); 2018 Buf_Init(&buf);
2019 Buf_AddStr(&buf, progname); 2019 Buf_AddStr(&buf, progname);
2020 Buf_AddStr(&buf, ": "); 2020 Buf_AddStr(&buf, ": ");
2021 Buf_AddStr(&buf, af); 2021 Buf_AddStr(&buf, af);
2022 Buf_AddStr(&buf, "("); 2022 Buf_AddStr(&buf, "(");
2023 Buf_AddStr(&buf, av); 2023 Buf_AddStr(&buf, av);
2024 Buf_AddStr(&buf, ") failed ("); 2024 Buf_AddStr(&buf, ") failed (");
2025 Buf_AddStr(&buf, strerror(errno)); 2025 Buf_AddStr(&buf, strerror(errno));
2026 Buf_AddStr(&buf, ")\n"); 2026 Buf_AddStr(&buf, ")\n");
2027 2027
2028 write_all(STDERR_FILENO, Buf_GetAll(&buf, NULL), Buf_Len(&buf)); 2028 write_all(STDERR_FILENO, Buf_GetAll(&buf, NULL), Buf_Len(&buf));
2029 2029
2030 Buf_Destroy(&buf, TRUE); 2030 Buf_Done(&buf);
2031 _exit(1); 2031 _exit(1);
2032} 2032}
2033 2033
2034/* purge any relative paths */ 2034/* purge any relative paths */
2035static void 2035static void
2036purge_relative_cached_realpaths(void) 2036purge_relative_cached_realpaths(void)
2037{ 2037{
2038 HashEntry *he, *nhe; 2038 HashEntry *he, *nhe;
2039 HashIter hi; 2039 HashIter hi;
2040 2040
2041 HashIter_Init(&hi, &cached_realpaths); 2041 HashIter_Init(&hi, &cached_realpaths);
2042 he = HashIter_Next(&hi); 2042 he = HashIter_Next(&hi);
2043 while (he != NULL) { 2043 while (he != NULL) {

cvs diff -r1.533 -r1.534 src/usr.bin/make/parse.c (expand / switch to unified diff)

--- src/usr.bin/make/parse.c 2021/01/27 00:02:38 1.533
+++ src/usr.bin/make/parse.c 2021/01/30 20:53:29 1.534
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parse.c,v 1.533 2021/01/27 00:02:38 rillig Exp $ */ 1/* $NetBSD: parse.c,v 1.534 2021/01/30 20:53:29 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.
@@ -99,27 +99,27 @@ @@ -99,27 +99,27 @@
99 99
100#include <sys/types.h> 100#include <sys/types.h>
101#include <sys/stat.h> 101#include <sys/stat.h>
102#include <errno.h> 102#include <errno.h>
103#include <stdarg.h> 103#include <stdarg.h>
104#include <stdint.h> 104#include <stdint.h>
105 105
106#include "make.h" 106#include "make.h"
107#include "dir.h" 107#include "dir.h"
108#include "job.h" 108#include "job.h"
109#include "pathnames.h" 109#include "pathnames.h"
110 110
111/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 111/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
112MAKE_RCSID("$NetBSD: parse.c,v 1.533 2021/01/27 00:02:38 rillig Exp $"); 112MAKE_RCSID("$NetBSD: parse.c,v 1.534 2021/01/30 20:53:29 rillig Exp $");
113 113
114/* types and constants */ 114/* types and constants */
115 115
116/* 116/*
117 * Structure for a file being read ("included file") 117 * Structure for a file being read ("included file")
118 */ 118 */
119typedef struct IFile { 119typedef struct IFile {
120 char *fname; /* name of file (relative? absolute?) */ 120 char *fname; /* name of file (relative? absolute?) */
121 Boolean fromForLoop; /* simulated .include by the .for loop */ 121 Boolean fromForLoop; /* simulated .include by the .for loop */
122 int lineno; /* current line number in file */ 122 int lineno; /* current line number in file */
123 int first_lineno; /* line number of start of text */ 123 int first_lineno; /* line number of start of text */
124 unsigned int cond_depth; /* 'if' nesting when file opened */ 124 unsigned int cond_depth; /* 'if' nesting when file opened */
125 Boolean depending; /* state of doing_depend on EOF */ 125 Boolean depending; /* state of doing_depend on EOF */
@@ -445,27 +445,27 @@ loadfile(const char *path, int fd) @@ -445,27 +445,27 @@ loadfile(const char *path, int fd)
445 buf.len += (size_t)n; 445 buf.len += (size_t)n;
446 } 446 }
447 assert(buf.len <= buf.cap); 447 assert(buf.len <= buf.cap);
448 448
449 if (!Buf_EndsWith(&buf, '\n')) 449 if (!Buf_EndsWith(&buf, '\n'))
450 Buf_AddByte(&buf, '\n'); 450 Buf_AddByte(&buf, '\n');
451 451
452 if (path != NULL) 452 if (path != NULL)
453 close(fd); 453 close(fd);
454 454
455 { 455 {
456 struct loadedfile *lf = loadedfile_create(path, 456 struct loadedfile *lf = loadedfile_create(path,
457 buf.data, buf.len); 457 buf.data, buf.len);
458 Buf_Destroy(&buf, FALSE); 458 Buf_DoneData(&buf);
459 return lf; 459 return lf;
460 } 460 }
461} 461}
462 462
463static void 463static void
464PrintStackTrace(void) 464PrintStackTrace(void)
465{ 465{
466 const IFile *entries; 466 const IFile *entries;
467 size_t i, n; 467 size_t i, n;
468 468
469 if (!(DEBUG(PARSE))) 469 if (!(DEBUG(PARSE)))
470 return; 470 return;
471 471

cvs diff -r1.783 -r1.784 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2021/01/30 15:48:42 1.783
+++ src/usr.bin/make/var.c 2021/01/30 20:53:29 1.784
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.783 2021/01/30 15:48:42 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.784 2021/01/30 20:53:29 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.
@@ -121,27 +121,27 @@ @@ -121,27 +121,27 @@
121#include <regex.h> 121#include <regex.h>
122#endif 122#endif
123#include <errno.h> 123#include <errno.h>
124#include <inttypes.h> 124#include <inttypes.h>
125#include <limits.h> 125#include <limits.h>
126#include <time.h> 126#include <time.h>
127 127
128#include "make.h" 128#include "make.h"
129#include "dir.h" 129#include "dir.h"
130#include "job.h" 130#include "job.h"
131#include "metachar.h" 131#include "metachar.h"
132 132
133/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 133/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
134MAKE_RCSID("$NetBSD: var.c,v 1.783 2021/01/30 15:48:42 rillig Exp $"); 134MAKE_RCSID("$NetBSD: var.c,v 1.784 2021/01/30 20:53:29 rillig Exp $");
135 135
136typedef enum VarFlags { 136typedef enum VarFlags {
137 VAR_NONE = 0, 137 VAR_NONE = 0,
138 138
139 /* 139 /*
140 * The variable's value is currently being used by Var_Parse or 140 * The variable's value is currently being used by Var_Parse or
141 * Var_Subst. This marker is used to avoid endless recursion. 141 * Var_Subst. This marker is used to avoid endless recursion.
142 */ 142 */
143 VAR_IN_USE = 0x01, 143 VAR_IN_USE = 0x01,
144 144
145 /* 145 /*
146 * The variable comes from the environment. 146 * The variable comes from the environment.
147 * These variables are not registered in any GNode, therefore they 147 * These variables are not registered in any GNode, therefore they
@@ -446,27 +446,30 @@ VarFind(const char *name, GNode *ctxt, B @@ -446,27 +446,30 @@ VarFind(const char *name, GNode *ctxt, B
446 * v the variable 446 * v the variable
447 * freeValue true if the variable value should be freed as well 447 * freeValue true if the variable value should be freed as well
448 * 448 *
449 * Results: 449 * Results:
450 * TRUE if it is an environment variable, FALSE otherwise. 450 * TRUE if it is an environment variable, FALSE otherwise.
451 */ 451 */
452static Boolean 452static Boolean
453VarFreeEnv(Var *v, Boolean freeValue) 453VarFreeEnv(Var *v, Boolean freeValue)
454{ 454{
455 if (!(v->flags & VAR_FROM_ENV)) 455 if (!(v->flags & VAR_FROM_ENV))
456 return FALSE; 456 return FALSE;
457 457
458 FStr_Done(&v->name); 458 FStr_Done(&v->name);
459 Buf_Destroy(&v->val, freeValue); 459 if (freeValue)
 460 Buf_Done(&v->val);
 461 else
 462 Buf_DoneData(&v->val);
460 free(v); 463 free(v);
461 return TRUE; 464 return TRUE;
462} 465}
463 466
464/* 467/*
465 * Add a new variable of the given name and value to the given context. 468 * Add a new variable of the given name and value to the given context.
466 * The name and val arguments are duplicated so they may safely be freed. 469 * The name and val arguments are duplicated so they may safely be freed.
467 */ 470 */
468static void 471static void
469VarAdd(const char *name, const char *val, GNode *ctxt, VarSetFlags flags) 472VarAdd(const char *name, const char *val, GNode *ctxt, VarSetFlags flags)
470{ 473{
471 HashEntry *he = HashTable_CreateEntry(&ctxt->vars, name, NULL); 474 HashEntry *he = HashTable_CreateEntry(&ctxt->vars, name, NULL);
472 Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), val, 475 Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), val,
@@ -489,27 +492,27 @@ Var_DeleteVar(const char *varname, GNode @@ -489,27 +492,27 @@ Var_DeleteVar(const char *varname, GNode
489 if (he == NULL) { 492 if (he == NULL) {
490 DEBUG2(VAR, "%s:delete %s (not found)\n", ctxt->name, varname); 493 DEBUG2(VAR, "%s:delete %s (not found)\n", ctxt->name, varname);
491 return; 494 return;
492 } 495 }
493 496
494 DEBUG2(VAR, "%s:delete %s\n", ctxt->name, varname); 497 DEBUG2(VAR, "%s:delete %s\n", ctxt->name, varname);
495 v = HashEntry_Get(he); 498 v = HashEntry_Get(he);
496 if (v->flags & VAR_EXPORTED) 499 if (v->flags & VAR_EXPORTED)
497 unsetenv(v->name.str); 500 unsetenv(v->name.str);
498 if (strcmp(v->name.str, MAKE_EXPORTED) == 0) 501 if (strcmp(v->name.str, MAKE_EXPORTED) == 0)
499 var_exportedVars = VAR_EXPORTED_NONE; 502 var_exportedVars = VAR_EXPORTED_NONE;
500 assert(v->name.freeIt == NULL); 503 assert(v->name.freeIt == NULL);
501 HashTable_DeleteEntry(&ctxt->vars, he); 504 HashTable_DeleteEntry(&ctxt->vars, he);
502 Buf_Destroy(&v->val, TRUE); 505 Buf_Done(&v->val);
503 free(v); 506 free(v);
504} 507}
505 508
506/* 509/*
507 * Remove a variable from a context, freeing all related memory as well. 510 * Remove a variable from a context, freeing all related memory as well.
508 * The variable name is expanded once. 511 * The variable name is expanded once.
509 */ 512 */
510void 513void
511Var_Delete(const char *name, GNode *ctxt) 514Var_Delete(const char *name, GNode *ctxt)
512{ 515{
513 FStr varname = FStr_InitRefer(name); 516 FStr varname = FStr_InitRefer(name);
514 517
515 if (strchr(varname.str, '$') != NULL) { 518 if (strchr(varname.str, '$') != NULL) {
@@ -1204,29 +1207,29 @@ SepBuf_AddBytes(SepBuf *buf, const char  @@ -1204,29 +1207,29 @@ SepBuf_AddBytes(SepBuf *buf, const char
1204static void 1207static void
1205SepBuf_AddBytesBetween(SepBuf *buf, const char *start, const char *end) 1208SepBuf_AddBytesBetween(SepBuf *buf, const char *start, const char *end)
1206{ 1209{
1207 SepBuf_AddBytes(buf, start, (size_t)(end - start)); 1210 SepBuf_AddBytes(buf, start, (size_t)(end - start));
1208} 1211}
1209 1212
1210static void 1213static void
1211SepBuf_AddStr(SepBuf *buf, const char *str) 1214SepBuf_AddStr(SepBuf *buf, const char *str)
1212{ 1215{
1213 SepBuf_AddBytes(buf, str, strlen(str)); 1216 SepBuf_AddBytes(buf, str, strlen(str));
1214} 1217}
1215 1218
1216static char * 1219static char *
1217SepBuf_Destroy(SepBuf *buf, Boolean free_buf) 1220SepBuf_DoneData(SepBuf *buf)
1218{ 1221{
1219 return Buf_Destroy(&buf->buf, free_buf); 1222 return Buf_DoneData(&buf->buf);
1220} 1223}
1221 1224
1222 1225
1223/* 1226/*
1224 * This callback for ModifyWords gets a single word from a variable expression 1227 * This callback for ModifyWords gets a single word from a variable expression
1225 * and typically adds a modification of this word to the buffer. It may also 1228 * and typically adds a modification of this word to the buffer. It may also
1226 * do nothing or add several words. 1229 * do nothing or add several words.
1227 * 1230 *
1228 * For example, in ${:Ua b c:M*2}, the callback is called 3 times, once for 1231 * For example, in ${:Ua b c:M*2}, the callback is called 3 times, once for
1229 * each word of "a b c". 1232 * each word of "a b c".
1230 */ 1233 */
1231typedef void (*ModifyWordsCallback)(const char *word, SepBuf *buf, void *data); 1234typedef void (*ModifyWordsCallback)(const char *word, SepBuf *buf, void *data);
1232 1235
@@ -1676,27 +1679,27 @@ VarSelectWords(char sep, Boolean oneBigW @@ -1676,27 +1679,27 @@ VarSelectWords(char sep, Boolean oneBigW
1676 } else { 1679 } else {
1677 start = first < 1 ? 0 : first - 1; 1680 start = first < 1 ? 0 : first - 1;
1678 end = last > len ? len : last; 1681 end = last > len ? len : last;
1679 step = 1; 1682 step = 1;
1680 } 1683 }
1681 1684
1682 for (i = start; (step < 0) == (i >= end); i += step) { 1685 for (i = start; (step < 0) == (i >= end); i += step) {
1683 SepBuf_AddStr(&buf, words.words[i]); 1686 SepBuf_AddStr(&buf, words.words[i]);
1684 SepBuf_Sep(&buf); 1687 SepBuf_Sep(&buf);
1685 } 1688 }
1686 1689
1687 Words_Free(words); 1690 Words_Free(words);
1688 1691
1689 return SepBuf_Destroy(&buf, FALSE); 1692 return SepBuf_DoneData(&buf);
1690} 1693}
1691 1694
1692 1695
1693/* 1696/*
1694 * Callback for ModifyWords to implement the :tA modifier. 1697 * Callback for ModifyWords to implement the :tA modifier.
1695 * Replace each word with the result of realpath() if successful. 1698 * Replace each word with the result of realpath() if successful.
1696 */ 1699 */
1697/*ARGSUSED*/ 1700/*ARGSUSED*/
1698static void 1701static void
1699ModifyWord_Realpath(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED) 1702ModifyWord_Realpath(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
1700{ 1703{
1701 struct stat st; 1704 struct stat st;
1702 char rbuf[MAXPATHLEN]; 1705 char rbuf[MAXPATHLEN];
@@ -1721,67 +1724,67 @@ ModifyWord_Realpath(const char *word, Se @@ -1721,67 +1724,67 @@ ModifyWord_Realpath(const char *word, Se
1721 */ 1724 */
1722static char * 1725static char *
1723ModifyWords(const char *str, 1726ModifyWords(const char *str,
1724 ModifyWordsCallback modifyWord, void *modifyWord_args, 1727 ModifyWordsCallback modifyWord, void *modifyWord_args,
1725 Boolean oneBigWord, char sep) 1728 Boolean oneBigWord, char sep)
1726{ 1729{
1727 SepBuf result; 1730 SepBuf result;
1728 Words words; 1731 Words words;
1729 size_t i; 1732 size_t i;
1730 1733
1731 if (oneBigWord) { 1734 if (oneBigWord) {
1732 SepBuf_Init(&result, sep); 1735 SepBuf_Init(&result, sep);
1733 modifyWord(str, &result, modifyWord_args); 1736 modifyWord(str, &result, modifyWord_args);
1734 return SepBuf_Destroy(&result, FALSE); 1737 return SepBuf_DoneData(&result);
1735 } 1738 }
1736 1739
1737 SepBuf_Init(&result, sep); 1740 SepBuf_Init(&result, sep);
1738 1741
1739 words = Str_Words(str, FALSE); 1742 words = Str_Words(str, FALSE);
1740 1743
1741 DEBUG2(VAR, "ModifyWords: split \"%s\" into %u words\n", 1744 DEBUG2(VAR, "ModifyWords: split \"%s\" into %u words\n",
1742 str, (unsigned)words.len); 1745 str, (unsigned)words.len);
1743 1746
1744 for (i = 0; i < words.len; i++) { 1747 for (i = 0; i < words.len; i++) {
1745 modifyWord(words.words[i], &result, modifyWord_args); 1748 modifyWord(words.words[i], &result, modifyWord_args);
1746 if (Buf_Len(&result.buf) > 0) 1749 if (Buf_Len(&result.buf) > 0)
1747 SepBuf_Sep(&result); 1750 SepBuf_Sep(&result);
1748 } 1751 }
1749 1752
1750 Words_Free(words); 1753 Words_Free(words);
1751 1754
1752 return SepBuf_Destroy(&result, FALSE); 1755 return SepBuf_DoneData(&result);
1753} 1756}
1754 1757
1755 1758
1756static char * 1759static char *
1757Words_JoinFree(Words words) 1760Words_JoinFree(Words words)
1758{ 1761{
1759 Buffer buf; 1762 Buffer buf;
1760 size_t i; 1763 size_t i;
1761 1764
1762 Buf_Init(&buf); 1765 Buf_Init(&buf);
1763 1766
1764 for (i = 0; i < words.len; i++) { 1767 for (i = 0; i < words.len; i++) {
1765 if (i != 0) { 1768 if (i != 0) {
1766 /* XXX: Use st->sep instead of ' ', for consistency. */ 1769 /* XXX: Use st->sep instead of ' ', for consistency. */
1767 Buf_AddByte(&buf, ' '); 1770 Buf_AddByte(&buf, ' ');
1768 } 1771 }
1769 Buf_AddStr(&buf, words.words[i]); 1772 Buf_AddStr(&buf, words.words[i]);
1770 } 1773 }
1771 1774
1772 Words_Free(words); 1775 Words_Free(words);
1773 1776
1774 return Buf_Destroy(&buf, FALSE); 1777 return Buf_DoneData(&buf);
1775} 1778}
1776 1779
1777/* Remove adjacent duplicate words. */ 1780/* Remove adjacent duplicate words. */
1778static char * 1781static char *
1779VarUniq(const char *str) 1782VarUniq(const char *str)
1780{ 1783{
1781 Words words = Str_Words(str, FALSE); 1784 Words words = Str_Words(str, FALSE);
1782 1785
1783 if (words.len > 1) { 1786 if (words.len > 1) {
1784 size_t i, j; 1787 size_t i, j;
1785 for (j = 0, i = 1; i < words.len; i++) 1788 for (j = 0, i = 1; i < words.len; i++)
1786 if (strcmp(words.words[i], words.words[j]) != 0 && 1789 if (strcmp(words.words[i], words.words[j]) != 0 &&
1787 (++j != i)) 1790 (++j != i))
@@ -1808,27 +1811,27 @@ VarQuote(const char *str, Boolean quoteD @@ -1808,27 +1811,27 @@ VarQuote(const char *str, Boolean quoteD
1808 const char *newline = Shell_GetNewline(); 1811 const char *newline = Shell_GetNewline();
1809 if (newline == NULL) 1812 if (newline == NULL)
1810 newline = "\\\n"; 1813 newline = "\\\n";
1811 Buf_AddStr(&buf, newline); 1814 Buf_AddStr(&buf, newline);
1812 continue; 1815 continue;
1813 } 1816 }
1814 if (ch_isspace(*str) || is_shell_metachar((unsigned char)*str)) 1817 if (ch_isspace(*str) || is_shell_metachar((unsigned char)*str))
1815 Buf_AddByte(&buf, '\\'); 1818 Buf_AddByte(&buf, '\\');
1816 Buf_AddByte(&buf, *str); 1819 Buf_AddByte(&buf, *str);
1817 if (quoteDollar && *str == '$') 1820 if (quoteDollar && *str == '$')
1818 Buf_AddStr(&buf, "\\$"); 1821 Buf_AddStr(&buf, "\\$");
1819 } 1822 }
1820 1823
1821 return Buf_Destroy(&buf, FALSE); 1824 return Buf_DoneData(&buf);
1822} 1825}
1823 1826
1824/* 1827/*
1825 * Compute the 32-bit hash of the given string, using the MurmurHash3 1828 * Compute the 32-bit hash of the given string, using the MurmurHash3
1826 * algorithm. Output is encoded as 8 hex digits, in Little Endian order. 1829 * algorithm. Output is encoded as 8 hex digits, in Little Endian order.
1827 */ 1830 */
1828static char * 1831static char *
1829VarHash(const char *str) 1832VarHash(const char *str)
1830{ 1833{
1831 static const char hexdigits[16] = "0123456789abcdef"; 1834 static const char hexdigits[16] = "0123456789abcdef";
1832 const unsigned char *ustr = (const unsigned char *)str; 1835 const unsigned char *ustr = (const unsigned char *)str;
1833 1836
1834 uint32_t h = 0x971e137bU; 1837 uint32_t h = 0x971e137bU;
@@ -2154,27 +2157,27 @@ ParseModifierPartSubst( @@ -2154,27 +2157,27 @@ ParseModifierPartSubst(
2154 2157
2155 if (*p != delim) { 2158 if (*p != delim) {
2156 *pp = p; 2159 *pp = p;
2157 Error("Unfinished modifier for %s ('%c' missing)", 2160 Error("Unfinished modifier for %s ('%c' missing)",
2158 st->var->name.str, delim); 2161 st->var->name.str, delim);
2159 *out_part = NULL; 2162 *out_part = NULL;
2160 return VPR_ERR; 2163 return VPR_ERR;
2161 } 2164 }
2162 2165
2163 *pp = ++p; 2166 *pp = ++p;
2164 if (out_length != NULL) 2167 if (out_length != NULL)
2165 *out_length = Buf_Len(&buf); 2168 *out_length = Buf_Len(&buf);
2166 2169
2167 *out_part = Buf_Destroy(&buf, FALSE); 2170 *out_part = Buf_DoneData(&buf);
2168 DEBUG1(VAR, "Modifier part: \"%s\"\n", *out_part); 2171 DEBUG1(VAR, "Modifier part: \"%s\"\n", *out_part);
2169 return VPR_OK; 2172 return VPR_OK;
2170} 2173}
2171 2174
2172/* 2175/*
2173 * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or 2176 * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or
2174 * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and 2177 * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and
2175 * including the next unescaped delimiter. The delimiter, as well as the 2178 * including the next unescaped delimiter. The delimiter, as well as the
2176 * backslash or the dollar, can be escaped with a backslash. 2179 * backslash or the dollar, can be escaped with a backslash.
2177 * 2180 *
2178 * Return the parsed (and possibly expanded) string, or NULL if no delimiter 2181 * Return the parsed (and possibly expanded) string, or NULL if no delimiter
2179 * was found. On successful return, the parsing position pp points right 2182 * was found. On successful return, the parsing position pp points right
2180 * after the delimiter. The delimiter is not included in the returned 2183 * after the delimiter. The delimiter is not included in the returned
@@ -2355,30 +2358,30 @@ ApplyModifier_Defined(const char **pp, c @@ -2355,30 +2358,30 @@ ApplyModifier_Defined(const char **pp, c
2355 FStr_Done(&nested_val); 2358 FStr_Done(&nested_val);
2356 continue; 2359 continue;
2357 } 2360 }
2358 2361
2359 /* Ordinary text */ 2362 /* Ordinary text */
2360 Buf_AddByte(&buf, *p); 2363 Buf_AddByte(&buf, *p);
2361 p++; 2364 p++;
2362 } 2365 }
2363 *pp = p; 2366 *pp = p;
2364 2367
2365 ApplyModifiersState_Define(st); 2368 ApplyModifiersState_Define(st);
2366 2369
2367 if (eflags & VARE_WANTRES) { 2370 if (eflags & VARE_WANTRES) {
2368 st->newVal = FStr_InitOwn(Buf_Destroy(&buf, FALSE)); 2371 st->newVal = FStr_InitOwn(Buf_DoneData(&buf));
2369 } else { 2372 } else {
2370 st->newVal = FStr_InitRefer(val); 2373 st->newVal = FStr_InitRefer(val);
2371 Buf_Destroy(&buf, TRUE); 2374 Buf_Done(&buf);
2372 } 2375 }
2373 return AMR_OK; 2376 return AMR_OK;
2374} 2377}
2375 2378
2376/* :L */ 2379/* :L */
2377static ApplyModifierResult 2380static ApplyModifierResult
2378ApplyModifier_Literal(const char **pp, ApplyModifiersState *st) 2381ApplyModifier_Literal(const char **pp, ApplyModifiersState *st)
2379{ 2382{
2380 ApplyModifiersState_Define(st); 2383 ApplyModifiersState_Define(st);
2381 st->newVal = FStr_InitOwn(bmake_strdup(st->var->name.str)); 2384 st->newVal = FStr_InitOwn(bmake_strdup(st->var->name.str));
2382 (*pp)++; 2385 (*pp)++;
2383 return AMR_OK; 2386 return AMR_OK;
2384} 2387}
@@ -2553,27 +2556,27 @@ ApplyModifier_Range(const char **pp, con @@ -2553,27 +2556,27 @@ ApplyModifier_Range(const char **pp, con
2553 Words_Free(words); 2556 Words_Free(words);
2554 } 2557 }
2555 2558
2556 Buf_Init(&buf); 2559 Buf_Init(&buf);
2557 2560
2558 for (i = 0; i < n; i++) { 2561 for (i = 0; i < n; i++) {
2559 if (i != 0) { 2562 if (i != 0) {
2560 /* XXX: Use st->sep instead of ' ', for consistency. */ 2563 /* XXX: Use st->sep instead of ' ', for consistency. */
2561 Buf_AddByte(&buf, ' '); 2564 Buf_AddByte(&buf, ' ');
2562 } 2565 }
2563 Buf_AddInt(&buf, 1 + (int)i); 2566 Buf_AddInt(&buf, 1 + (int)i);
2564 } 2567 }
2565 2568
2566 st->newVal = FStr_InitOwn(Buf_Destroy(&buf, FALSE)); 2569 st->newVal = FStr_InitOwn(Buf_DoneData(&buf));
2567 return AMR_OK; 2570 return AMR_OK;
2568} 2571}
2569 2572
2570/* :Mpattern or :Npattern */ 2573/* :Mpattern or :Npattern */
2571static ApplyModifierResult 2574static ApplyModifierResult
2572ApplyModifier_Match(const char **pp, const char *val, ApplyModifiersState *st) 2575ApplyModifier_Match(const char **pp, const char *val, ApplyModifiersState *st)
2573{ 2576{
2574 const char *mod = *pp; 2577 const char *mod = *pp;
2575 Boolean copy = FALSE; /* pattern should be, or has been, copied */ 2578 Boolean copy = FALSE; /* pattern should be, or has been, copied */
2576 Boolean needSubst = FALSE; 2579 Boolean needSubst = FALSE;
2577 const char *endpat; 2580 const char *endpat;
2578 char *pattern; 2581 char *pattern;
2579 ModifyWordsCallback callback; 2582 ModifyWordsCallback callback;
@@ -2978,27 +2981,27 @@ ApplyModifier_Words(const char **pp, con @@ -2978,27 +2981,27 @@ ApplyModifier_Words(const char **pp, con
2978 if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */ 2981 if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */
2979 if (st->oneBigWord) { 2982 if (st->oneBigWord) {
2980 st->newVal = FStr_InitRefer("1"); 2983 st->newVal = FStr_InitRefer("1");
2981 } else { 2984 } else {
2982 Buffer buf; 2985 Buffer buf;
2983 2986
2984 Words words = Str_Words(val, FALSE); 2987 Words words = Str_Words(val, FALSE);
2985 size_t ac = words.len; 2988 size_t ac = words.len;
2986 Words_Free(words); 2989 Words_Free(words);
2987 2990
2988 /* 3 digits + '\0' is usually enough */ 2991 /* 3 digits + '\0' is usually enough */
2989 Buf_InitSize(&buf, 4); 2992 Buf_InitSize(&buf, 4);
2990 Buf_AddInt(&buf, (int)ac); 2993 Buf_AddInt(&buf, (int)ac);
2991 st->newVal = FStr_InitOwn(Buf_Destroy(&buf, FALSE)); 2994 st->newVal = FStr_InitOwn(Buf_DoneData(&buf));
2992 } 2995 }
2993 goto ok; 2996 goto ok;
2994 } 2997 }
2995 2998
2996 if (estr[0] == '*' && estr[1] == '\0') { 2999 if (estr[0] == '*' && estr[1] == '\0') {
2997 /* Found ":[*]" */ 3000 /* Found ":[*]" */
2998 st->oneBigWord = TRUE; 3001 st->oneBigWord = TRUE;
2999 st->newVal = FStr_InitRefer(val); 3002 st->newVal = FStr_InitRefer(val);
3000 goto ok; 3003 goto ok;
3001 } 3004 }
3002 3005
3003 if (estr[0] == '@' && estr[1] == '\0') { 3006 if (estr[0] == '@' && estr[1] == '\0') {
3004 /* Found ":[@]" */ 3007 /* Found ":[@]" */
@@ -3793,27 +3796,27 @@ ParseVarname(const char **pp, char start @@ -3793,27 +3796,27 @@ ParseVarname(const char **pp, char start
3793 if (*p == '$') { 3796 if (*p == '$') {
3794 FStr nested_val; 3797 FStr nested_val;
3795 (void)Var_Parse(&p, ctxt, eflags, &nested_val); 3798 (void)Var_Parse(&p, ctxt, eflags, &nested_val);
3796 /* TODO: handle errors */ 3799 /* TODO: handle errors */
3797 Buf_AddStr(&buf, nested_val.str); 3800 Buf_AddStr(&buf, nested_val.str);
3798 FStr_Done(&nested_val); 3801 FStr_Done(&nested_val);
3799 } else { 3802 } else {
3800 Buf_AddByte(&buf, *p); 3803 Buf_AddByte(&buf, *p);
3801 p++; 3804 p++;
3802 } 3805 }
3803 } 3806 }
3804 *pp = p; 3807 *pp = p;
3805 *out_varname_len = Buf_Len(&buf); 3808 *out_varname_len = Buf_Len(&buf);
3806 return Buf_Destroy(&buf, FALSE); 3809 return Buf_DoneData(&buf);
3807} 3810}
3808 3811
3809static VarParseResult 3812static VarParseResult
3810ValidShortVarname(char varname, const char *start) 3813ValidShortVarname(char varname, const char *start)
3811{ 3814{
3812 switch (varname) { 3815 switch (varname) {
3813 case '\0': 3816 case '\0':
3814 case ')': 3817 case ')':
3815 case '}': 3818 case '}':
3816 case ':': 3819 case ':':
3817 case '$': 3820 case '$':
3818 break; /* and continue below */ 3821 break; /* and continue below */
3819 default: 3822 default:
@@ -4060,27 +4063,27 @@ ParseVarnameLong( @@ -4060,27 +4063,27 @@ ParseVarnameLong(
4060 4063
4061 *out_TRUE_endc = endc; 4064 *out_TRUE_endc = endc;
4062 *out_TRUE_p = p; 4065 *out_TRUE_p = p;
4063 *out_TRUE_v = v; 4066 *out_TRUE_v = v;
4064 *out_TRUE_haveModifier = haveModifier; 4067 *out_TRUE_haveModifier = haveModifier;
4065 *out_TRUE_dynamic = dynamic; 4068 *out_TRUE_dynamic = dynamic;
4066 return TRUE; 4069 return TRUE;
4067} 4070}
4068 4071
4069/* Free the environment variable now since we own it. */ 4072/* Free the environment variable now since we own it. */
4070static void 4073static void
4071FreeEnvVar(void **out_val_freeIt, Var *v, const char *value) 4074FreeEnvVar(void **out_val_freeIt, Var *v, const char *value)
4072{ 4075{
4073 char *varValue = Buf_Destroy(&v->val, FALSE); 4076 char *varValue = Buf_DoneData(&v->val);
4074 if (value == varValue) 4077 if (value == varValue)
4075 *out_val_freeIt = varValue; 4078 *out_val_freeIt = varValue;
4076 else 4079 else
4077 free(varValue); 4080 free(varValue);
4078 4081
4079 FStr_Done(&v->name); 4082 FStr_Done(&v->name);
4080 free(v); 4083 free(v);
4081} 4084}
4082 4085
4083/* 4086/*
4084 * Given the start of a variable expression (such as $v, $(VAR), 4087 * Given the start of a variable expression (such as $v, $(VAR),
4085 * ${VAR:Mpattern}), extract the variable name and value, and the modifiers, 4088 * ${VAR:Mpattern}), extract the variable name and value, and the modifiers,
4086 * if any. While doing that, apply the modifiers to the value of the 4089 * if any. While doing that, apply the modifiers to the value of the
@@ -4231,27 +4234,27 @@ Var_Parse(const char **pp, GNode *ctxt,  @@ -4231,27 +4234,27 @@ Var_Parse(const char **pp, GNode *ctxt,
4231 if (dynamic) { 4234 if (dynamic) {
4232 value = FStr_InitOwn(bmake_strsedup(start, p)); 4235 value = FStr_InitOwn(bmake_strsedup(start, p));
4233 } else { 4236 } else {
4234 /* 4237 /*
4235 * The expression is still undefined, 4238 * The expression is still undefined,
4236 * therefore discard the actual value and 4239 * therefore discard the actual value and
4237 * return an error marker instead. 4240 * return an error marker instead.
4238 */ 4241 */
4239 value = FStr_InitRefer(eflags & VARE_UNDEFERR 4242 value = FStr_InitRefer(eflags & VARE_UNDEFERR
4240 ? var_Error : varUndefined); 4243 ? var_Error : varUndefined);
4241 } 4244 }
4242 } 4245 }
4243 if (value.str != Buf_GetAll(&v->val, NULL)) 4246 if (value.str != Buf_GetAll(&v->val, NULL))
4244 Buf_Destroy(&v->val, TRUE); 4247 Buf_Done(&v->val);
4245 FStr_Done(&v->name); 4248 FStr_Done(&v->name);
4246 free(v); 4249 free(v);
4247 } 4250 }
4248 *out_val = (FStr){ value.str, value.freeIt }; 4251 *out_val = (FStr){ value.str, value.freeIt };
4249 return VPR_OK; /* XXX: Is not correct in all cases */ 4252 return VPR_OK; /* XXX: Is not correct in all cases */
4250} 4253}
4251 4254
4252static void 4255static void
4253VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalFlags eflags) 4256VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalFlags eflags)
4254{ 4257{
4255 /* 4258 /*
4256 * A dollar sign may be escaped with another dollar 4259 * A dollar sign may be escaped with another dollar
4257 * sign. 4260 * sign.
@@ -4355,27 +4358,27 @@ Var_Subst(const char *str, GNode *ctxt,  @@ -4355,27 +4358,27 @@ Var_Subst(const char *str, GNode *ctxt,
4355 4358
4356 Buf_Init(&res); 4359 Buf_Init(&res);
4357 errorReported = FALSE; 4360 errorReported = FALSE;
4358 4361
4359 while (*p != '\0') { 4362 while (*p != '\0') {
4360 if (p[0] == '$' && p[1] == '$') 4363 if (p[0] == '$' && p[1] == '$')
4361 VarSubstDollarDollar(&p, &res, eflags); 4364 VarSubstDollarDollar(&p, &res, eflags);
4362 else if (p[0] == '$') 4365 else if (p[0] == '$')
4363 VarSubstExpr(&p, &res, ctxt, eflags, &errorReported); 4366 VarSubstExpr(&p, &res, ctxt, eflags, &errorReported);
4364 else 4367 else
4365 VarSubstPlain(&p, &res); 4368 VarSubstPlain(&p, &res);
4366 } 4369 }
4367 4370
4368 *out_res = Buf_DestroyCompact(&res); 4371 *out_res = Buf_DoneDataCompact(&res);
4369 return VPR_OK; 4372 return VPR_OK;
4370} 4373}
4371 4374
4372/* Initialize the variables module. */ 4375/* Initialize the variables module. */
4373void 4376void
4374Var_Init(void) 4377Var_Init(void)
4375{ 4378{
4376 VAR_INTERNAL = GNode_New("Internal"); 4379 VAR_INTERNAL = GNode_New("Internal");
4377 VAR_GLOBAL = GNode_New("Global"); 4380 VAR_GLOBAL = GNode_New("Global");
4378 VAR_CMDLINE = GNode_New("Command"); 4381 VAR_CMDLINE = GNode_New("Command");
4379} 4382}
4380 4383
4381/* Clean up the variables module. */ 4384/* Clean up the variables module. */