View difference between Paste ID: UGs6aawV and vvUTeaBD
SHOW: | | - or go back to the newest paste.
1
### Eclipse Workspace Patch 1.0
2
#P make-patched
3
Index: expand.c
4
===================================================================
5
RCS file: /sources/make/make/expand.c,v
6
retrieving revision 1.62
7
diff -u -r1.62 expand.c
8
--- expand.c	5 Mar 2012 14:10:43 -0000	1.62
9-
+++ expand.c	9 Apr 2012 09:50:04 -0000
9+
+++ expand.c	9 Apr 2012 13:34:41 -0000
10
@@ -16,8 +16,6 @@
11
 
12
 #include "make.h"
13
 
14
-#include <assert.h>
15
-
16
 #include "filedef.h"
17
 #include "job.h"
18
 #include "commands.h"
19
@@ -30,125 +28,121 @@
20
 
21
 /* The next two describe the variable output buffer.
22
    This buffer is used to hold the variable-expansion of a line of the
23
-   makefile.  It is made bigger with realloc whenever it is too small.
24
-   variable_buffer_length is the size currently allocated.
25
-   variable_buffer is the address of the buffer.
26
+   makefile.  It is made bigger with realloc whenever it is too small.  */
27
+
28
+static struct vbuffer *expansion_vbuf;
29
 
30
-   For efficiency, it's guaranteed that the buffer will always have
31
+/* For efficiency, it's guaranteed that the buffer will always have
32
    VARIABLE_BUFFER_ZONE extra bytes allocated.  This allows you to add a few
33
    extra chars without having to call a function.  Note you should never use
34
    these bytes unless you're _sure_ you have room (you know when the buffer
35
    length was last checked.  */
36
+#define VARIABLE_BUFFER_ZONE    (2 * sizeof (char *))
37
 
38
-#define VARIABLE_BUFFER_ZONE    5
39
+struct vbuffer *
40
+vbuffer_init (struct vbuffer *vbuf)
41
+{
42
+  vbuf->size = 100;
43
+  vbuf->ptr = vbuf->buffer = xmalloc (vbuf->size);
44
 
45
-static unsigned int variable_buffer_length;
46
-char *variable_buffer;
47
+  *vbuf->ptr = '\0';
48
 
49
-/* Subroutine of variable_expand and friends:
50
-   The text to add is LENGTH chars starting at STRING to the variable_buffer.
51
-   The text is added to the buffer at PTR, and the updated pointer into
52
-   the buffer is returned as the value.  Thus, the value returned by
53
-   each call to variable_buffer_output should be the first argument to
54
-   the following call.  */
55
+  return vbuf;
56
+}
57
 
58
-char *
59
-variable_buffer_output (char *ptr, const char *string, unsigned int length)
60
+struct vbuffer *
61
+vbuffer_reset (struct vbuffer *vbuf)
62
 {
63
-  register unsigned int newlen = length + (ptr - variable_buffer);
64
+  vbuf->ptr = vbuf->buffer;
65
 
66
-  if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
67
-    {
68
-      unsigned int offset = ptr - variable_buffer;
69
-      variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
70
-				? newlen + 100
71
-				: 2 * variable_buffer_length);
72
-      variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
73
-      ptr = variable_buffer + offset;
74
-    }
75
+  *vbuf->ptr = '\0';
76
 
77
-  memcpy (ptr, string, length);
78
-  return ptr + length;
79
+  return vbuf;
80
 }
81
 
82
-/* Return a pointer to the beginning of the variable buffer.  */
83
+#ifdef __GNUC__
84
+__inline
85
+#endif
86
+static void
87
+vbuffer_grow (struct vbuffer *vbuf, size_t newlen)
88
+{
89
+  size_t oldlen = vbuf->size;
90
+  size_t offset = vbuf->ptr - vbuf->buffer;
91
+
92
+  newlen = newlen + 100 > 2 * oldlen
93
+	 ? newlen + 100 : 2 * oldlen;
94
+
95
+  vbuf->buffer = xrealloc (vbuf->buffer, newlen);
96
+  vbuf->ptr = vbuf->buffer + offset;
97
+  vbuf->size = newlen;
98
+}
99
 
100
-static char *
101
-initialize_variable_output (void)
102
+#ifdef __GNUC__
103
+__inline
104
+#endif
105
+size_t
106
+vbuffer_reserve (struct vbuffer *o, size_t length)
107
 {
108
-  /* If we don't have a variable output buffer yet, get one.  */
109
+  size_t newoff = (o->ptr - o->buffer) + length;
110
 
111
-  if (variable_buffer == 0)
112
-    {
113
-      variable_buffer_length = 200;
114
-      variable_buffer = xmalloc (variable_buffer_length);
115
-      variable_buffer[0] = '\0';
116
-    }
117
+  if ((newoff + VARIABLE_BUFFER_ZONE) > o->size)
118
+    vbuffer_grow (o, newoff);
119
 
120
-  return variable_buffer;
121
+  return o->size - newoff;
122
 }
123
-
124
-/* Recursively expand V.  The returned string is malloc'd.  */
125
 
126
-static char *allocated_variable_append (const struct variable *v);
127
+/* Writes byte stream pointed by STR into VBUF.
128
+   The optional LEN argument can be used to limit the amount of bytes to copy.
129
+   Otherwise (if LEN is a negative number) STR is treated as a null-terminated
130
+   string and copied accordingly.
131
 
132
-char *
133
-recursively_expand_for_file (struct variable *v, struct file *file)
134
+   Returns the actual number of bytes copied,
135
+   that is LEN argument if it is non-negative and strlen (STR) otherwise.
136
+
137
+   As like all the other vbuffer methods it leaves the internal buffer
138
+   of the VBUF null-terminated.   */
139
+
140
+#ifdef __GNUC__
141
+__inline
142
+#endif
143
+size_t
144
+vbuffer_write (struct vbuffer *o, const char *str, ssize_t len)
145
 {
146
-  char *value;
147
-  const struct floc *this_var;
148
-  const struct floc **saved_varp;
149
-  struct variable_set_list *save = 0;
150
-  int set_reading = 0;
151
+  size_t length = len < 0 ? strlen (str) : (size_t) len;
152
 
153
-  /* Don't install a new location if this location is empty.
154
-     This can happen for command-line variables, builtin variables, etc.  */
155
-  saved_varp = expanding_var;
156
-  if (v->fileinfo.filenm)
157
-    {
158
-      this_var = &v->fileinfo;
159
-      expanding_var = &this_var;
160
-    }
161
+  if (length == 0)
162
+    return 0;
163
 
164
-  /* If we have no other file-reading context, use the variable's context. */
165
-  if (!reading_file)
166
-    {
167
-      set_reading = 1;
168
-      reading_file = &v->fileinfo;
169
-    }
170
+  vbuffer_reserve (o, length);
171
 
172
-  if (v->expanding)
173
-    {
174
-      if (!v->exp_count)
175
-        /* Expanding V causes infinite recursion.  Lose.  */
176
-        fatal (*expanding_var,
177
-               _("Recursive variable '%s' references itself (eventually)"),
178
-               v->name);
179
-      --v->exp_count;
180
-    }
181
+  memcpy (o->ptr, str, length);
182
+  o->ptr += length;
183
 
184
-  if (file)
185
-    {
186
-      save = current_variable_set_list;
187
-      current_variable_set_list = file->variables;
188
-    }
189
+  *o->ptr = '\0';
190
 
191
-  v->expanding = 1;
192
-  if (v->append)
193
-    value = allocated_variable_append (v);
194
-  else
195
-    value = allocated_variable_expand (v->value);
196
-  v->expanding = 0;
197
+  return length;
198
+}
199
 
200
-  if (set_reading)
201
-    reading_file = 0;
202
+/* Moves the pointer of the VBUF back on the LEN bytes.
203
+   If LEN is negative, or if moving the pointer would lead to an underflow,
204
+   then sets the pointer to the start of the buffer.
205
 
206
-  if (file)
207
-    current_variable_set_list = save;
208
+   Returns the actual number of discarded bytes.  */
209
 
210
-  expanding_var = saved_varp;
211
+size_t
212
+vbuffer_unwrite (struct vbuffer *o, ssize_t len)
213
+{
214
+  size_t oldoff = o->ptr - o->buffer;
215
+  size_t length = len < 0 ? oldoff : (size_t) len;
216
 
217
-  return value;
218
+  if (length > oldoff)
219
+    length = oldoff;
220
+
221
+  o->ptr -= length;
222
+
223
+  *o->ptr = '\0';
224
+
225
+  return length;
226
 }
227
 
228
 /* Expand a simple reference to variable NAME, which is LENGTH chars long.  */
229
@@ -156,11 +150,10 @@
230
 #ifdef __GNUC__
231
 __inline
232
 #endif
233
-static char *
234
-reference_variable (char *o, const char *name, unsigned int length)
235
+static size_t
236
+expand_variable_reference (struct vbuffer *o, const char *name, size_t length)
237
 {
238
   struct variable *v;
239
-  char *value;
240
 
241
   v = lookup_variable (name, length);
242
 
243
@@ -169,62 +162,117 @@
244
 
245
   /* If there's no variable by that name or it has no value, stop now.  */
246
   if (v == 0 || (*v->value == '\0' && !v->append))
247
-    return o;
248
-
249
-  value = (v->recursive ? recursively_expand (v) : v->value);
250
-
251
-  o = variable_buffer_output (o, value, strlen (value));
252
+    return 0;
253
 
254
   if (v->recursive)
255
-    free (value);
256
-
257
-  return o;
258
+    return vbuffer_expand_variable (o, v);
259
+  else
260
+    return vbuffer_write (o, v->value, -1);
261
 }
262
-
263
-/* Scan STRING for variable references and expansion-function calls.  Only
264
-   LENGTH bytes of STRING are actually scanned.  If LENGTH is -1, scan until
265
-   a null byte is found.
266
-
267
-   Write the results to LINE, which must point into 'variable_buffer'.  If
268
-   LINE is NULL, start at the beginning of the buffer.
269
-   Return a pointer to LINE, or to the beginning of the buffer if LINE is
270
-   NULL.
271
- */
272
-char *
273
-variable_expand_string (char *line, const char *string, long length)
274
+
275
+
276
+#ifdef __GNUC__
277
+__inline
278
+#endif
279
+static int
280
+handle_subst_reference (struct vbuffer *o, char *beg, char *end)
281
 {
282
+  size_t result = 0;
283
   struct variable *v;
284
-  const char *p, *p1;
285
-  char *save;
286
-  char *o;
287
-  unsigned int line_offset;
288
-
289
-  if (!line)
290
-    line = initialize_variable_output();
291
-  o = line;
292
-  line_offset = line - variable_buffer;
293
+  const char *subst_beg, *subst_end, *replace_beg, *replace_end;
294
+  char *colon = lindex (beg, end, ':');
295
 
296
-  if (length == 0)
297
+  if (colon == 0)
298
+    return -1;
299
+
300
+  subst_beg = colon + 1;
301
+  subst_end = lindex (subst_beg, end, '=');
302
+  if (subst_end == 0)
303
+    /* There is no = in sight.  Punt on the substitution reference and treat
304
+       this as a variable name containing a colon.  */
305
+    return -1;
306
+
307
+  /* This looks like a valid substitution reference: $(FOO:A=B).  */
308
+  replace_beg = subst_end + 1;
309
+  replace_end = end;
310
+
311
+  /* Extract the variable name before the colon and look up that variable.  */
312
+  v = lookup_variable (beg, colon - beg);
313
+  if (v == 0)
314
+    warn_undefined (beg, colon - beg);
315
+
316
+  /* If the variable is not empty, perform the substitution.  */
317
+  if (v != 0 && *v->value != '\0')
318
     {
319
-      variable_buffer_output (o, "", 1);
320
-      return (variable_buffer);
321
+      char *pattern, *replace, *ppercent, *rpercent;
322
+      char *value = (v->recursive
323
+		     ? recursively_expand(v)
324
+		     : v->value);
325
+
326
+      /* Copy the pattern and the replacement.  Add in an extra % at the
327
+         beginning to use in case there isn't one in the pattern.  */
328
+      pattern = alloca (subst_end - subst_beg + 2);
329
+      *(pattern++) = '%';
330
+      memcpy (pattern, subst_beg, subst_end - subst_beg);
331
+      pattern[subst_end - subst_beg] = '\0';
332
+
333
+      replace = alloca (replace_end - replace_beg + 2);
334
+      *(replace++) = '%';
335
+      memcpy (replace, replace_beg, replace_end - replace_beg);
336
+      replace[replace_end - replace_beg] = '\0';
337
+
338
+      /* Look for %.  Set the percent pointers properly
339
+	 based on whether we find one or not.  */
340
+      ppercent = find_percent (pattern);
341
+      if (ppercent)
342
+	{
343
+	  ++ppercent;
344
+	  rpercent = find_percent (replace);
345
+	  if (rpercent)
346
+	    ++rpercent;
347
+	}
348
+      else
349
+	{
350
+	  ppercent = pattern--;
351
+	  rpercent = replace--;
352
+	}
353
+
354
+      *o->ptr = '\0';
355
+
356
+      result = patsubst_expand_pat (o, value,
357
+				    pattern, replace, ppercent, rpercent);
358
+
359
+      if (v->recursive)
360
+	free (value);
361
     }
362
 
363
-  /* We need a copy of STRING: due to eval, it's possible that it will get
364
-     freed as we process it (it might be the value of a variable that's reset
365
-     for example).  Also having a nil-terminated string is handy.  */
366
-  save = length < 0 ? xstrdup (string) : xstrndup (string, length);
367
-  p = save;
368
+  return result;
369
+}
370
 
371
+size_t
372
+vbuffer_expand (struct vbuffer *o, char *str, ssize_t len)
373
+{
374
+  size_t result = 0;
375
+  char *p, *p1;
376
+
377
+  if (len == 0)
378
+    return 0;
379
+
380
+  if (len > 0)
381
+    str[len] = '\0';
382
+
383
+  p = str;
384
   while (1)
385
     {
386
       /* Copy all following uninteresting chars all at once to the
387
-         variable output buffer, and skip them.  Uninteresting chars end
388
+	 variable output buffer, and skip them.  Uninteresting chars end
389
 	 at the next $ or the end of the input.  */
390
 
391
       p1 = strchr (p, '$');
392
 
393
-      o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
394
+      /* In case when P1 is nil,
395
+         'vbuffer_write' writes the whole string pointed by P.  */
396
+      result += vbuffer_write (o, p, p1 ? p1 - p : -1);
397
 
398
       if (p1 == 0)
399
 	break;
400
@@ -236,27 +284,23 @@
401
 	{
402
 	case '$':
403
 	  /* $$ seen means output one $ to the variable output buffer.  */
404
-	  o = variable_buffer_output (o, p, 1);
405
+	  result += vbuffer_write (o, p, 1);
406
 	  break;
407
 
408
 	case '(':
409
 	case '{':
410
 	  /* $(...) or ${...} is the general case of substitution.  */
411
 	  {
412
+	    int handle_ret;
413
 	    char openparen = *p;
414
 	    char closeparen = (openparen == '(') ? ')' : '}';
415
-            const char *begp;
416
-	    const char *beg = p + 1;
417
-	    char *op;
418
-            char *abeg = NULL;
419
-	    const char *end, *colon;
420
-
421
-	    op = o;
422
-	    begp = p;
423
-	    if (handle_function (&op, &begp))
424
+	    char *beg = p + 1;
425
+	    char *end;
426
+
427
+	    handle_ret = handle_function (o, &p);
428
+	    if (handle_ret >= 0)
429
 	      {
430
-		o = op;
431
-		p = begp;
432
+		result += handle_ret;
433
 		break;
434
 	      }
435
 
436
@@ -265,8 +309,8 @@
437
 
438
 	    end = strchr (beg, closeparen);
439
 	    if (end == 0)
440
-              /* Unterminated variable reference.  */
441
-              fatal (*expanding_var, _("unterminated variable reference"));
442
+	      fatal (*expanding_var, _("unterminated variable reference"));
443
+
444
 	    p1 = lindex (beg, end, '$');
445
 	    if (p1 != 0)
446
 	      {
447
@@ -285,102 +329,41 @@
448
 		   such as '$($(a)'.  */
449
 		if (count < 0)
450
 		  {
451
-		    abeg = expand_argument (beg, p); /* Expand the name.  */
452
-		    beg = abeg;
453
-		    end = strchr (beg, '\0');
454
+		    /* Expand the name.
455
+		       As a little optimization we reuse the same vbuffer.  */
456
+		    size_t name_len = vbuffer_expand (o, beg, p - beg);
457
+		    *p = closeparen;
458
+
459
+		    /* We don't use 'vbuffer_unwrite' here because it would
460
+		       reset the first byte of the computed name to nil.  */
461
+		    o->ptr -= name_len;
462
+
463
+		    beg = o->ptr;
464
+		    end = beg + name_len;
465
+
466
 		  }
467
 	      }
468
 	    else
469
 	      /* Advance P to the end of this reference.  After we are
470
-                 finished expanding this one, P will be incremented to
471
-                 continue the scan.  */
472
+		 finished expanding this one, P will be incremented to
473
+		 continue the scan.  */
474
 	      p = end;
475
 
476
 	    /* This is not a reference to a built-in function and
477
 	       any variable references inside are now expanded.
478
 	       Is the resultant text a substitution reference?  */
479
 
480
-	    colon = lindex (beg, end, ':');
481
-	    if (colon)
482
+	    handle_ret = handle_subst_reference (o, beg, end);
483
+	    if (handle_ret >= 0)
484
 	      {
485
-		/* This looks like a substitution reference: $(FOO:A=B).  */
486
-		const char *subst_beg, *subst_end, *replace_beg, *replace_end;
487
-
488
-		subst_beg = colon + 1;
489
-		subst_end = lindex (subst_beg, end, '=');
490
-		if (subst_end == 0)
491
-		  /* There is no = in sight.  Punt on the substitution
492
-		     reference and treat this as a variable name containing
493
-		     a colon, in the code below.  */
494
-		  colon = 0;
495
-		else
496
-		  {
497
-		    replace_beg = subst_end + 1;
498
-		    replace_end = end;
499
-
500
-		    /* Extract the variable name before the colon
501
-		       and look up that variable.  */
502
-		    v = lookup_variable (beg, colon - beg);
503
-		    if (v == 0)
504
-		      warn_undefined (beg, colon - beg);
505
-
506
-                    /* If the variable is not empty, perform the
507
-                       substitution.  */
508
-		    if (v != 0 && *v->value != '\0')
509
-		      {
510
-			char *pattern, *replace, *ppercent, *rpercent;
511
-			char *value = (v->recursive
512
-                                       ? recursively_expand (v)
513
-				       : v->value);
514
-
515
-                        /* Copy the pattern and the replacement.  Add in an
516
-                           extra % at the beginning to use in case there
517
-                           isn't one in the pattern.  */
518
-                        pattern = alloca (subst_end - subst_beg + 2);
519
-                        *(pattern++) = '%';
520
-                        memcpy (pattern, subst_beg, subst_end - subst_beg);
521
-                        pattern[subst_end - subst_beg] = '\0';
522
-
523
-                        replace = alloca (replace_end - replace_beg + 2);
524
-                        *(replace++) = '%';
525
-                        memcpy (replace, replace_beg,
526
-                               replace_end - replace_beg);
527
-                        replace[replace_end - replace_beg] = '\0';
528
-
529
-                        /* Look for %.  Set the percent pointers properly
530
-                           based on whether we find one or not.  */
531
-			ppercent = find_percent (pattern);
532
-			if (ppercent)
533
-                          {
534
-                            ++ppercent;
535
-                            rpercent = find_percent (replace);
536
-                            if (rpercent)
537
-                              ++rpercent;
538
-                          }
539
-			else
540
-                          {
541
-                            ppercent = pattern;
542
-                            rpercent = replace;
543
-                            --pattern;
544
-                            --replace;
545
-                          }
546
-
547
-                        o = patsubst_expand_pat (o, value, pattern, replace,
548
-                                                 ppercent, rpercent);
549
-
550
-			if (v->recursive)
551
-			  free (value);
552
-		      }
553
-		  }
554
+		result += handle_ret;
555
+		break;
556
 	      }
557
 
558
-	    if (colon == 0)
559
-	      /* This is an ordinary variable reference.
560
-		 Look up the value of the variable.  */
561
-		o = reference_variable (o, beg, end - beg);
562
-
563
-	  if (abeg)
564
-	    free (abeg);
565
+	    /* This is an ordinary variable reference.
566
+	       Look up the value of the variable.  */
567
+	    result += expand_variable_reference (o, beg, end - beg);
568
+	    *o->ptr = '\0';
569
 	  }
570
 	  break;
571
 
572
@@ -393,7 +376,7 @@
573
 
574
 	  /* A $ followed by a random char is a variable reference:
575
 	     $a is equivalent to $(a).  */
576
-          o = reference_variable (o, p, 1);
577
+	  result += expand_variable_reference (o, p, 1);
578
 
579
 	  break;
580
 	}
581
@@ -404,69 +387,19 @@
582
       ++p;
583
     }
584
 
585
-  free (save);
586
-
587
-  variable_buffer_output (o, "", 1);
588
-  return (variable_buffer + line_offset);
589
-}
590
-
591
-/* Scan LINE for variable references and expansion-function calls.
592
-   Build in 'variable_buffer' the result of expanding the references and calls.
593
-   Return the address of the resulting string, which is null-terminated
594
-   and is valid only until the next time this function is called.  */
595
-
596
-char *
597
-variable_expand (const char *line)
598
-{
599
-  return variable_expand_string(NULL, line, (long)-1);
600
-}
601
-
602
-/* Expand an argument for an expansion function.
603
-   The text starting at STR and ending at END is variable-expanded
604
-   into a null-terminated string that is returned as the value.
605
-   This is done without clobbering 'variable_buffer' or the current
606
-   variable-expansion that is in progress.  */
607
-
608
-char *
609
-expand_argument (const char *str, const char *end)
610
-{
611
-  char *tmp, *alloc = NULL;
612
-  char *r;
613
-
614
-  if (str == end)
615
-    return xstrdup("");
616
-
617
-  if (!end || *end == '\0')
618
-    return allocated_variable_expand (str);
619
-
620
-  if (end - str + 1 > 1000)
621
-    tmp = alloc = xmalloc (end - str + 1);
622
-  else
623
-    tmp = alloca (end - str + 1);
624
-
625
-  memcpy (tmp, str, end - str);
626
-  tmp[end - str] = '\0';
627
-
628
-  r = allocated_variable_expand (tmp);
629
-
630
-  if (alloc)
631
-    free (alloc);
632
+  return result;
633
 
634
-  return r;
635
 }
636
-
637
-/* Expand LINE for FILE.  Error messages refer to the file and line where
638
-   FILE's commands were found.  Expansion uses FILE's variable set list.  */
639
 
640
-char *
641
-variable_expand_for_file (const char *line, struct file *file)
642
-{
643
-  char *result;
644
+size_t
645
+vbuffer_expand_for_file (struct vbuffer *o, char *str, ssize_t len,
646
+                         struct file *file) {
647
+  size_t result = 0;
648
   struct variable_set_list *savev;
649
   const struct floc *savef;
650
 
651
   if (file == 0)
652
-    return variable_expand (line);
653
+    return vbuffer_expand (o, str, len);
654
 
655
   savev = current_variable_set_list;
656
   current_variable_set_list = file->variables;
657
@@ -477,124 +410,251 @@
658
   else
659
     reading_file = 0;
660
 
661
-  result = variable_expand (line);
662
+  result = vbuffer_expand (o, str, len);
663
 
664
   current_variable_set_list = savev;
665
   reading_file = savef;
666
 
667
   return result;
668
 }
669
-
670
+
671
 /* Like allocated_variable_expand, but for += target-specific variables.
672
    First recursively construct the variable value from its appended parts in
673
    any upper variable sets.  Then expand the resulting value.  */
674
 
675
-static char *
676
-variable_append (const char *name, unsigned int length,
677
-                 const struct variable_set_list *set, int local)
678
+static size_t
679
+expand_variable_append (struct vbuffer *o,
680
+			const char *name, unsigned int length,
681
+			const struct variable_set_list *set_list,
682
+			int local)
683
 {
684
+  size_t ret = 0;
685
   const struct variable *v;
686
-  char *buf = 0;
687
-  /* If this set is local and the next is not a parent, then next is local.  */
688
-  int nextlocal = local && set->next_is_parent == 0;
689
+  int nextlocal;
690
 
691
   /* If there's nothing left to check, return the empty buffer.  */
692
-  if (!set)
693
-    return initialize_variable_output ();
694
+  if (!set_list)
695
+    return 0;
696
+
697
+  /* If this set is local and the next is not a parent, then next is local.  */
698
+  nextlocal = local && set_list->next_is_parent == 0;
699
 
700
   /* Try to find the variable in this variable set.  */
701
-  v = lookup_variable_in_set (name, length, set->set);
702
+  v = lookup_variable_in_set (name, length, set_list->set);
703
 
704
   /* If there isn't one, or this one is private, try the set above us.  */
705
   if (!v || (!local && v->private_var))
706
-    return variable_append (name, length, set->next, nextlocal);
707
+    return expand_variable_append (o, name, length,
708
+				   set_list->next, nextlocal);
709
 
710
   /* If this variable type is append, first get any upper values.
711
      If not, initialize the buffer.  */
712
   if (v->append)
713
-    buf = variable_append (name, length, set->next, nextlocal);
714
-  else
715
-    buf = initialize_variable_output ();
716
+    ret += expand_variable_append (o, name, length,
717
+				   set_list->next, nextlocal);
718
 
719
   /* Append this value to the buffer, and return it.
720
      If we already have a value, first add a space.  */
721
-  if (buf > variable_buffer)
722
-    buf = variable_buffer_output (buf, " ", 1);
723
+  if (ret != 0)
724
+    ret += vbuffer_write (o, " ", 1);
725
 
726
   /* Either expand it or copy it, depending.  */
727
-  if (! v->recursive)
728
-    return variable_buffer_output (buf, v->value, strlen (v->value));
729
+  if (v->recursive)
730
+    ret += vbuffer_expand_ro (o, v->value, -1);
731
+  else
732
+    ret += vbuffer_write (o, v->value, -1);
733
 
734
-  buf = variable_expand_string (buf, v->value, strlen (v->value));
735
-  return (buf + strlen (buf));
736
+  return ret;
737
 }
738
 
739
+size_t
740
+vbuffer_expand_variable_for_file (struct vbuffer *o, struct variable *v,
741
+				  struct file *file)
742
+{
743
+  size_t ret = 0;
744
+  const struct floc *this_var;
745
+  const struct floc **saved_varp;
746
+  struct variable_set_list *save = 0;
747
+  int set_reading = 0;
748
+
749
+  /* Don't install a new location if this location is empty.
750
+     This can happen for command-line variables, builtin variables, etc.  */
751
+  saved_varp = expanding_var;
752
+  if (v->fileinfo.filenm)
753
+    {
754
+      this_var = &v->fileinfo;
755
+      expanding_var = &this_var;
756
+    }
757
+
758
+  /* If we have no other file-reading context, use the variable's context. */
759
+  if (!reading_file)
760
+    {
761
+      set_reading = 1;
762
+      reading_file = &v->fileinfo;
763
+    }
764
+
765
+  if (v->expanding)
766
+    {
767
+      if (!v->exp_count)
768
+        /* Expanding V causes infinite recursion.  Lose.  */
769
+        fatal (*expanding_var,
770
+               _("Recursive variable '%s' references itself (eventually)"),
771
+               v->name);
772
+      --v->exp_count;
773
+    }
774
+
775
+  if (file)
776
+    {
777
+      save = current_variable_set_list;
778
+      current_variable_set_list = file->variables;
779
+    }
780
+
781
+  v->expanding = 1;
782
+
783
+  if (v->append)
784
+    ret += expand_variable_append (o, v->name, strlen (v->name),
785
+				   current_variable_set_list, 1);
786
+  else
787
+    /* We need a copy of STRING: due to eval, it's possible that it will get
788
+       freed as we process it (it might be the value of a variable that's
789
+       reset, for example).  Also having a nil-terminated string is handy.  */
790
+    ret += vbuffer_expand_ro (o, v->value, -1);
791
 
792
-static char *
793
-allocated_variable_append (const struct variable *v)
794
+  v->expanding = 0;
795
+
796
+  if (set_reading)
797
+    reading_file = 0;
798
+
799
+  if (file)
800
+    current_variable_set_list = save;
801
+
802
+  expanding_var = saved_varp;
803
+
804
+  return ret;
805
+}
806
+
807
+size_t
808
+vbuffer_expand_ro (struct vbuffer *o, const char *str, ssize_t len)
809
+{
810
+  size_t ret;
811
+  size_t length = len < 0 ? strlen (str) : (size_t) len;
812
+
813
+  char *alloc = 0;
814
+  char *value = length > MAX_ALLOCA_SIZE
815
+		? (alloc = xmalloc (length + 1))
816
+		: alloca (length + 1);
817
+
818
+  ret = vbuffer_expand (o, memcpy (value, str, length + 1), length);
819
+
820
+  if (alloc)
821
+    free (alloc);
822
+
823
+  return ret;
824
+}
825
+
826
+size_t
827
+vbuffer_expand_ro_for_file (struct vbuffer *o, const char *str, ssize_t len,
828
+			    struct file *file)
829
 {
830
-  char *val;
831
+  size_t ret;
832
+  char *string = len < 0 ? xstrdup (str) : xstrndup (str, len);
833
+  ret = vbuffer_expand_for_file (o, string, -1, file);
834
+  free (string);
835
+  return ret;
836
+}
837
 
838
-  /* Construct the appended variable value.  */
839
+/* Install a new expansion vbuffer, returning the current one.  */
840
+
841
+struct vbuffer *
842
+install_new_expansion_vbuffer (void)
843
+{
844
+  struct vbuffer *old_vbuf = expansion_vbuf;
845
 
846
-  char *obuf = variable_buffer;
847
-  unsigned int olen = variable_buffer_length;
848
+  expansion_vbuf = xmalloc(sizeof(struct vbuffer));
849
+  vbuffer_init(expansion_vbuf);
850
 
851
-  variable_buffer = 0;
852
+  return old_vbuf;
853
+}
854
 
855
-  val = variable_append (v->name, strlen (v->name),
856
-                         current_variable_set_list, 1);
857
-  variable_buffer_output (val, "", 1);
858
-  val = variable_buffer;
859
+/* Restore a previously-saved vbuffer setting freeing the current one.  */
860
 
861
-  variable_buffer = obuf;
862
-  variable_buffer_length = olen;
863
+void
864
+restore_expansion_vbuffer (struct vbuffer *old_vbuf)
865
+{
866
+  vbuffer_free(expansion_vbuf);
867
+  free(expansion_vbuf);
868
 
869
-  return val;
870
+  expansion_vbuf = old_vbuf;
871
 }
872
 
873
-/* Like variable_expand_for_file, but the returned string is malloc'd.
874
-   This function is called a lot.  It wants to be efficient.  */
875
+/* Expand an argument for an expansion function.
876
+   The text starting at STR and ending at END is variable-expanded
877
+   into a null-terminated string that is returned as the value.
878
+   This is done without clobbering 'variable_buffer' or the current
879
+   variable-expansion that is in progress.  */
880
 
881
 char *
882
-allocated_variable_expand_for_file (const char *line, struct file *file)
883
+expand_argument (const char *str, const char *end)
884
 {
885
-  char *value;
886
+  struct vbuffer vbuf;
887
 
888
-  char *obuf = variable_buffer;
889
-  unsigned int olen = variable_buffer_length;
890
+  vbuffer_expand_ro (vbuffer_init(&vbuf), str, end - str);
891
 
892
-  variable_buffer = 0;
893
+  return vbuf.buffer;
894
+}
895
 
896
-  value = variable_expand_for_file (line, file);
897
+/* Scan LINE for variable references and expansion-function calls.
898
+   Build in 'variable_buffer' the result of expanding the references and calls.
899
+   Return the address of the resulting string, which is null-terminated
900
+   and is valid only until the next time this function is called.  */
901
 
902
-  variable_buffer = obuf;
903
-  variable_buffer_length = olen;
904
+char *
905
+variable_expand (const char *line)
906
+{
907
+  vbuffer_expand_ro (vbuffer_reset(expansion_vbuf), line, -1);
908
 
909
-  return value;
910
+  return expansion_vbuf->buffer;
911
 }
912
 
913
-/* Install a new variable_buffer context, returning the current one for
914
-   safe-keeping.  */
915
+/* Expand LINE for FILE.  Error messages refer to the file and line where
916
+   FILE's commands were found.  Expansion uses FILE's variable set list.  */
917
 
918
-void
919
-install_variable_buffer (char **bufp, unsigned int *lenp)
920
+char *
921
+variable_expand_for_file (const char *line, struct file *file)
922
+{
923
+  vbuffer_expand_ro_for_file (vbuffer_reset(expansion_vbuf), line, -1, file);
924
+
925
+  return expansion_vbuf->buffer;
926
+}
927
+
928
+char *
929
+allocated_variable_expand (const char *line)
930
 {
931
-  *bufp = variable_buffer;
932
-  *lenp = variable_buffer_length;
933
+  struct vbuffer vbuf;
934
 
935
-  variable_buffer = 0;
936
-  initialize_variable_output ();
937
+  vbuffer_expand_ro (vbuffer_init(&vbuf), line, -1);
938
+
939
+  return vbuf.buffer;
940
 }
941
 
942
-/* Restore a previously-saved variable_buffer setting (free the current one).
943
- */
944
+/* Like variable_expand_for_file, but the returned string is malloc'd.  */
945
 
946
-void
947
-restore_variable_buffer (char *buf, unsigned int len)
948
+char *
949
+allocated_variable_expand_for_file (const char *line, struct file *file)
950
 {
951
-  free (variable_buffer);
952
+  struct vbuffer vbuf;
953
+
954
+  vbuffer_expand_ro_for_file (vbuffer_init(&vbuf), line, -1, file);
955
+
956
+  return vbuf.buffer;
957
+}
958
+
959
+char *
960
+recursively_expand_for_file (struct variable *v, struct file *file)
961
+{
962
+  struct vbuffer vbuf;
963
+
964
+  vbuffer_expand_variable_for_file (vbuffer_init(&vbuf), v, file);
965
 
966
-  variable_buffer = buf;
967
-  variable_buffer_length = len;
968
+  return vbuf.buffer;
969
 }
970
Index: file.c
971
===================================================================
972
RCS file: /sources/make/make/file.c,v
973
retrieving revision 1.105
974
diff -u -r1.105 file.c
975
--- file.c	5 Mar 2012 14:10:43 -0000	1.105
976-
+++ file.c	9 Apr 2012 09:50:04 -0000
976+
+++ file.c	9 Apr 2012 13:34:41 -0000
977
@@ -467,9 +467,11 @@
978
   if (stem)
979
     {
980
       const char *pattern = "%";
981
-      char *buffer = variable_expand ("");
982
+      struct vbuffer vbuf;
983
       struct dep *dp = deps, *dl = 0;
984
 
985
+      vbuffer_init (&vbuf);
986
+
987
       while (dp != 0)
988
         {
989
           char *percent;
990
@@ -479,22 +481,23 @@
991
           percent = find_percent (nm);
992
           if (percent)
993
             {
994
-              char *o;
995
+              size_t len;
996
 
997
               /* We have to handle empty stems specially, because that
998
                  would be equivalent to $(patsubst %,dp->name,) which
999
                  will always be empty.  */
1000
-              if (stem[0] == '\0')
1001
+              if (*stem == '\0')
1002
                 {
1003
                   memmove (percent, percent+1, strlen (percent));
1004
-                  o = variable_buffer_output (buffer, nm, strlen (nm) + 1);
1005
+                  len = vbuffer_write (vbuffer_reset (&vbuf), nm, -1);
1006
                 }
1007
               else
1008
-                o = patsubst_expand_pat (buffer, stem, pattern, nm,
1009
-                                         pattern+1, percent+1);
1010
+                len = patsubst_expand_pat (vbuffer_reset (&vbuf), stem,
1011
+                                           pattern, nm,
1012
+                                           pattern+1, percent+1);
1013
 
1014
               /* If the name expanded to the empty string, ignore it.  */
1015
-              if (buffer[0] == '\0')
1016
+              if (len == 0)
1017
                 {
1018
                   struct dep *df = dp;
1019
                   if (dp == deps)
1020
@@ -506,24 +509,26 @@
1021
                 }
1022
 
1023
               /* Save the name.  */
1024
-              dp->name = strcache_add_len (buffer, o - buffer);
1025
+              dp->name = strcache_add_len (vbuf.buffer, len);
1026
             }
1027
           dp->stem = stem;
1028
           dp->staticpattern = 1;
1029
           dl = dp;
1030
           dp = dp->next;
1031
         }
1032
+
1033
+        vbuffer_free (&vbuf);
1034
     }
1035
 
1036
   /* Enter them as files, unless they need a 2nd expansion.  */
1037
   for (d1 = deps; d1 != 0; d1 = d1->next)
1038
     {
1039
       if (d1->need_2nd_expansion)
1040
-        continue;
1041
+	continue;
1042
 
1043
       d1->file = lookup_file (d1->name);
1044
       if (d1->file == 0)
1045
-        d1->file = enter_file (d1->name);
1046
+	d1->file = enter_file (d1->name);
1047
       d1->staticpattern = 0;
1048
       d1->name = 0;
1049
     }
1050
@@ -573,12 +578,10 @@
1051
          "$*" so they'll expand properly.  */
1052
       if (d->staticpattern)
1053
         {
1054
-          char *o;
1055
-          d->name = o = variable_expand ("");
1056
-          o = subst_expand (o, name, "%", "$*", 1, 2, 0);
1057
-          *o = '\0';
1058
+	  struct vbuffer vbuf;
1059
+          subst_expand (vbuffer_init(&vbuf), name, "%", "$*", 1, 2, 0);
1060
           free (name);
1061
-          d->name = name = xstrdup (d->name);
1062
+          d->name = name = xstrdup (vbuf.buffer);
1063
           d->staticpattern = 0;
1064
         }
1065
 
1066
Index: function.c
1067
===================================================================
1068
RCS file: /sources/make/make/function.c,v
1069
retrieving revision 1.133
1070
diff -u -r1.133 function.c
1071
--- function.c	5 Mar 2012 14:10:43 -0000	1.133
1072-
+++ function.c	9 Apr 2012 09:50:04 -0000
1072+
+++ function.c	9 Apr 2012 13:34:41 -0000
1073
@@ -15,6 +15,9 @@
1074
 this program.  If not, see <http://www.gnu.org/licenses/>.  */
1075
 
1076
 #include "make.h"
1077
+
1078
+#include <assert.h>
1079
+
1080
 #include "filedef.h"
1081
 #include "variable.h"
1082
 #include "dep.h"
1083
@@ -34,7 +37,7 @@
1084
     unsigned char minimum_args;
1085
     unsigned char maximum_args;
1086
     char expand_args;
1087
-    char *(*func_ptr) (char *output, char **argv, const char *fname);
1088
+   size_t (*func_ptr) (struct vbuffer *output, char **argv, const char *fname);
1089
   };
1090
 
1091
 static unsigned long
1092
@@ -65,26 +68,29 @@
1093
 static struct hash_table function_table;
1094
 
1095
 
1096
-/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
1097
+/* Store into VBUFFER at O the result of scanning TEXT and replacing
1098
    each occurrence of SUBST with REPLACE. TEXT is null-terminated.  SLEN is
1099
    the length of SUBST and RLEN is the length of REPLACE.  If BY_WORD is
1100
    nonzero, substitutions are done only on matches which are complete
1101
    whitespace-delimited words.  */
1102
 
1103
-char *
1104
-subst_expand (char *o, const char *text, const char *subst, const char *replace,
1105
-              unsigned int slen, unsigned int rlen, int by_word)
1106
+size_t
1107
+subst_expand (struct vbuffer *o, const char *text, const char *subst,
1108
+              const char *replace, unsigned int slen, unsigned int rlen,
1109
+              int by_word)
1110
 {
1111
+  size_t result = 0;
1112
+
1113
   const char *t = text;
1114
   const char *p;
1115
 
1116
   if (slen == 0 && !by_word)
1117
     {
1118
       /* The first occurrence of "" in any string is its end.  */
1119
-      o = variable_buffer_output (o, t, strlen (t));
1120
+      result += vbuffer_write (o, t, -1);
1121
       if (rlen > 0)
1122
-	o = variable_buffer_output (o, replace, rlen);
1123
-      return o;
1124
+	result += vbuffer_write (o, replace, rlen);
1125
+      return result;
1126
     }
1127
 
1128
   do
1129
@@ -99,14 +105,14 @@
1130
 	  if (p == 0)
1131
 	    {
1132
 	      /* No more matches.  Output everything left on the end.  */
1133
-	      o = variable_buffer_output (o, t, strlen (t));
1134
-	      return o;
1135
+	      result += vbuffer_write (o, t, -1);
1136
+	      return result;
1137
 	    }
1138
 	}
1139
 
1140
       /* Output everything before this occurrence of the string to replace.  */
1141
       if (p > t)
1142
-	o = variable_buffer_output (o, t, p - t);
1143
+	result += vbuffer_write (o, t, p - t);
1144
 
1145
       /* If we're substituting only by fully matched words,
1146
 	 or only at the ends of words, check that this case qualifies.  */
1147
@@ -115,20 +121,21 @@
1148
               || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
1149
 	/* Struck out.  Output the rest of the string that is
1150
 	   no longer to be replaced.  */
1151
-	o = variable_buffer_output (o, subst, slen);
1152
+	result += vbuffer_write (o, subst, slen);
1153
       else if (rlen > 0)
1154
 	/* Output the replacement string.  */
1155
-	o = variable_buffer_output (o, replace, rlen);
1156
+	result += vbuffer_write (o, replace, rlen);
1157
 
1158
       /* Advance T past the string to be replaced.  */
1159
       t = p + slen;
1160
-    } while (*t != '\0');
1161
+    }
1162
+  while (*t != '\0');
1163
 
1164
-  return o;
1165
+  return result;
1166
 }
1167
 
1168
 
1169
-/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
1170
+/* Store into VBUFFER at O the result of scanning TEXT
1171
    and replacing strings matching PATTERN with REPLACE.
1172
    If PATTERN_PERCENT is not nil, PATTERN has already been
1173
    run through find_percent, and PATTERN_PERCENT is the result.
1174
@@ -138,16 +145,17 @@
1175
    character _AFTER_ the %, not to the % itself.
1176
 */
1177
 
1178
-char *
1179
-patsubst_expand_pat (char *o, const char *text,
1180
+size_t
1181
+patsubst_expand_pat (struct vbuffer *o, const char *text,
1182
                      const char *pattern, const char *replace,
1183
                      const char *pattern_percent, const char *replace_percent)
1184
 {
1185
+  size_t ret = 0;
1186
+
1187
   unsigned int pattern_prepercent_len, pattern_postpercent_len;
1188
   unsigned int replace_prepercent_len, replace_postpercent_len;
1189
   const char *t;
1190
   unsigned int len;
1191
-  int doneany = 0;
1192
 
1193
   /* Record the length of REPLACE before and after the % so we don't have to
1194
      compute these lengths more than once.  */
1195
@@ -197,43 +205,37 @@
1196
 
1197
       if (fail)
1198
 	/* It didn't match.  Output the string.  */
1199
-	o = variable_buffer_output (o, t, len);
1200
+	ret += vbuffer_write (o, t, len);
1201
       else
1202
 	{
1203
 	  /* It matched.  Output the replacement.  */
1204
 
1205
 	  /* Output the part of the replacement before the %.  */
1206
-	  o = variable_buffer_output (o, replace, replace_prepercent_len);
1207
+	  ret += vbuffer_write (o, replace, replace_prepercent_len);
1208
 
1209
 	  if (replace_percent != 0)
1210
 	    {
1211
 	      /* Output the part of the matched string that
1212
 		 matched the % in the pattern.  */
1213
-	      o = variable_buffer_output (o, t + pattern_prepercent_len,
1214
-					  len - (pattern_prepercent_len
1215
+	      ret += vbuffer_write (o, t + pattern_prepercent_len,
1216
+				       len - (pattern_prepercent_len
1217
 						 + pattern_postpercent_len));
1218
 	      /* Output the part of the replacement after the %.  */
1219
-	      o = variable_buffer_output (o, replace_percent,
1220
-					  replace_postpercent_len);
1221
+	      ret += vbuffer_write (o, replace_percent,
1222
+				       replace_postpercent_len);
1223
 	    }
1224
 	}
1225
 
1226
       /* Output a space, but not if the replacement is "".  */
1227
       if (fail || replace_prepercent_len > 0
1228
 	  || (replace_percent != 0 && len + replace_postpercent_len > 0))
1229
-	{
1230
-	  o = variable_buffer_output (o, " ", 1);
1231
-	  doneany = 1;
1232
-	}
1233
+	ret += vbuffer_write (o, " ", 1);
1234
     }
1235
-  if (doneany)
1236
-    /* Kill the last space.  */
1237
-    --o;
1238
 
1239
-  return o;
1240
+  return ret - vbuffer_unwrite (o, !!ret);
1241
 }
1242
 
1243
-/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
1244
+/* Store into VBUFFER at O the result of scanning TEXT
1245
    and replacing strings matching PATTERN with REPLACE.
1246
    If PATTERN_PERCENT is not nil, PATTERN has already been
1247
    run through find_percent, and PATTERN_PERCENT is the result.
1248
@@ -243,8 +245,9 @@
1249
    character _AFTER_ the %, not to the % itself.
1250
 */
1251
 
1252
-char *
1253
-patsubst_expand (char *o, const char *text, char *pattern, char *replace)
1254
+size_t
1255
+patsubst_expand (struct vbuffer *o, const char *text, char *pattern,
1256
+                 char *replace)
1257
 {
1258
   const char *pattern_percent = find_percent (pattern);
1259
   const char *replace_percent = find_percent (replace);
1260
@@ -256,28 +259,7 @@
1261
     ++pattern_percent;
1262
 
1263
   return patsubst_expand_pat (o, text, pattern, replace,
1264
-                              pattern_percent, replace_percent);
1265
-}
1266
-
1267
-
1268
-/* Look up a function by name.  */
1269
-
1270
-static const struct function_table_entry *
1271
-lookup_function (const char *s)
1272
-{
1273
-  const char *e = s;
1274
-
1275
-  while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
1276
-    e++;
1277
-  if (*e == '\0' || isblank ((unsigned char) *e))
1278
-    {
1279
-      struct function_table_entry function_table_entry_key;
1280
-      function_table_entry_key.name = s;
1281
-      function_table_entry_key.len = e - s;
1282
-
1283
-      return hash_find_item (&function_table, &function_table_entry_key);
1284
-    }
1285
-  return 0;
1286
+			      pattern_percent, replace_percent);
1287
 }
1288
 
1289
 
1290
@@ -310,48 +292,16 @@
1291
 }
1292
 
1293
 
1294
-/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
1295
-   ENDPARENtheses), starting at PTR before END.  Return a pointer to
1296
-   next character.
1297
-
1298
-   If no next argument is found, return NULL.
1299
-*/
1300
-
1301
-static char *
1302
-find_next_argument (char startparen, char endparen,
1303
-                    const char *ptr, const char *end)
1304
-{
1305
-  int count = 0;
1306
-
1307
-  for (; ptr < end; ++ptr)
1308
-    if (*ptr == startparen)
1309
-      ++count;
1310
-
1311
-    else if (*ptr == endparen)
1312
-      {
1313
-	--count;
1314
-	if (count < 0)
1315
-	  return NULL;
1316
-      }
1317
-
1318
-    else if (*ptr == ',' && !count)
1319
-      return (char *)ptr;
1320
-
1321
-  /* We didn't find anything.  */
1322
-  return NULL;
1323
-}
1324
-
1325
-
1326
-/* Glob-expand LINE.  The returned pointer is
1327
-   only good until the next call to string_glob.  */
1328
+/* Glob-expand the LINE writing the result into O.  */
1329
 
1330
-static char *
1331
-string_glob (char *line)
1332
+#ifdef __GNUC__
1333
+__inline
1334
+#endif
1335
+static size_t
1336
+string_glob (struct vbuffer *o, char *line)
1337
 {
1338
-  static char *result = 0;
1339
-  static unsigned int length;
1340
+  size_t ret = 0;
1341
   struct nameseq *chain;
1342
-  unsigned int idx;
1343
 
1344
   chain = PARSE_FILE_SEQ (&line, struct nameseq, '\0', NULL,
1345
                           /* We do not want parse_file_seq to strip './'s.
1346
@@ -359,58 +309,53 @@
1347
                              $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)).  */
1348
                           PARSEFS_NOSTRIP|PARSEFS_NOCACHE|PARSEFS_EXISTS);
1349
 
1350
-  if (result == 0)
1351
-    {
1352
-      length = 100;
1353
-      result = xmalloc (100);
1354
-    }
1355
-
1356
-  idx = 0;
1357
   while (chain != 0)
1358
     {
1359
       struct nameseq *next = chain->next;
1360
-      unsigned int len = strlen (chain->name);
1361
 
1362
-      if (idx + len + 1 > length)
1363
-        {
1364
-          length += (len + 1) * 2;
1365
-          result = xrealloc (result, length);
1366
-        }
1367
-      memcpy (&result[idx], chain->name, len);
1368
-      idx += len;
1369
-      result[idx++] = ' ';
1370
+      ret += vbuffer_write (o, chain->name, -1);
1371
+      ret += vbuffer_write (o, " ", 1);
1372
 
1373
       /* Because we used PARSEFS_NOCACHE above, we have to free() NAME.  */
1374
       free ((char *)chain->name);
1375
       free (chain);
1376
+
1377
       chain = next;
1378
     }
1379
 
1380
-  /* Kill the last space and terminate the string.  */
1381
-  if (idx == 0)
1382
-    result[0] = '\0';
1383
-  else
1384
-    result[idx - 1] = '\0';
1385
+  return ret - vbuffer_unwrite (o, !!ret);
1386
+}
1387
 
1388
-  return result;
1389
+static size_t
1390
+func_wildcard (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1391
+{
1392
+  size_t ret = 0;
1393
+
1394
+#ifdef _AMIGA
1395
+   o = wildcard_expansion (argv[0], o);
1396
+#else
1397
+   ret += string_glob (o, argv[0]);
1398
+#endif
1399
+
1400
+   return ret;
1401
 }
1402
+
1403
 
1404
 /*
1405
   Builtin functions
1406
  */
1407
 
1408
-static char *
1409
-func_patsubst (char *o, char **argv, const char *funcname UNUSED)
1410
+static size_t
1411
+func_patsubst (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1412
 {
1413
-  o = patsubst_expand (o, argv[2], argv[0], argv[1]);
1414
-  return o;
1415
+  return patsubst_expand (o, argv[2], argv[0], argv[1]);
1416
 }
1417
 
1418
 
1419
-static char *
1420
-func_join (char *o, char **argv, const char *funcname UNUSED)
1421
+static size_t
1422
+func_join (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1423
 {
1424
-  int doneany = 0;
1425
+  size_t ret = 0;
1426
 
1427
   /* Write each word of the first argument directly followed
1428
      by the corresponding word of the second argument.
1429
@@ -420,87 +365,84 @@
1430
   const char *pp;
1431
   const char *list1_iterator = argv[0];
1432
   const char *list2_iterator = argv[1];
1433
+
1434
   do
1435
     {
1436
       unsigned int len1, len2;
1437
 
1438
       tp = find_next_token (&list1_iterator, &len1);
1439
       if (tp != 0)
1440
-	o = variable_buffer_output (o, tp, len1);
1441
+	ret += vbuffer_write (o, tp, len1);
1442
 
1443
       pp = find_next_token (&list2_iterator, &len2);
1444
       if (pp != 0)
1445
-	o = variable_buffer_output (o, pp, len2);
1446
+	ret += vbuffer_write (o, pp, len2);
1447
 
1448
       if (tp != 0 || pp != 0)
1449
-	{
1450
-	  o = variable_buffer_output (o, " ", 1);
1451
-	  doneany = 1;
1452
-	}
1453
+	ret += vbuffer_write (o, " ", 1);
1454
     }
1455
   while (tp != 0 || pp != 0);
1456
-  if (doneany)
1457
-    /* Kill the last blank.  */
1458
-    --o;
1459
 
1460
-  return o;
1461
+  return ret - vbuffer_unwrite (o, !!ret);
1462
 }
1463
 
1464
 
1465
-static char *
1466
-func_origin (char *o, char **argv, const char *funcname UNUSED)
1467
+static size_t
1468
+func_origin (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1469
 {
1470
-  /* Expand the argument.  */
1471
+  size_t ret = 0;
1472
   struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1473
+
1474
   if (v == 0)
1475
-    o = variable_buffer_output (o, "undefined", 9);
1476
+    ret += vbuffer_write (o, STRING_SIZE_TUPLE("undefined"));
1477
   else
1478
     switch (v->origin)
1479
       {
1480
-      default:
1481
-      case o_invalid:
1482
-	abort ();
1483
-	break;
1484
       case o_default:
1485
-	o = variable_buffer_output (o, "default", 7);
1486
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("default"));
1487
 	break;
1488
       case o_env:
1489
-	o = variable_buffer_output (o, "environment", 11);
1490
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("environment"));
1491
 	break;
1492
       case o_file:
1493
-	o = variable_buffer_output (o, "file", 4);
1494
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("file"));
1495
 	break;
1496
       case o_env_override:
1497
-	o = variable_buffer_output (o, "environment override", 20);
1498
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("environment override"));
1499
 	break;
1500
       case o_command:
1501
-	o = variable_buffer_output (o, "command line", 12);
1502
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("command line"));
1503
 	break;
1504
       case o_override:
1505
-	o = variable_buffer_output (o, "override", 8);
1506
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("override"));
1507
 	break;
1508
       case o_automatic:
1509
-	o = variable_buffer_output (o, "automatic", 9);
1510
+	ret += vbuffer_write (o, STRING_SIZE_TUPLE("automatic"));
1511
+	break;
1512
+      case o_invalid:
1513
+      default:
1514
+	abort ();
1515
 	break;
1516
       }
1517
 
1518
-  return o;
1519
+  return ret;
1520
 }
1521
 
1522
-static char *
1523
-func_flavor (char *o, char **argv, const char *funcname UNUSED)
1524
+static size_t
1525
+func_flavor (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1526
 {
1527
+  size_t ret = 0;
1528
   struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1529
 
1530
   if (v == 0)
1531
-    o = variable_buffer_output (o, "undefined", 9);
1532
+    ret += vbuffer_write (o, STRING_SIZE_TUPLE("undefined"));
1533
   else
1534
     if (v->recursive)
1535
-      o = variable_buffer_output (o, "recursive", 9);
1536
+      ret += vbuffer_write (o, STRING_SIZE_TUPLE("recursive"));
1537
     else
1538
-      o = variable_buffer_output (o, "simple", 6);
1539
+      ret += vbuffer_write (o, STRING_SIZE_TUPLE("simple"));
1540
 
1541
-  return o;
1542
+  return ret;
1543
 }
1544
 
1545
 #ifdef VMS
1546
@@ -514,14 +456,15 @@
1547
 #endif
1548
 
1549
 
1550
-static char *
1551
-func_notdir_suffix (char *o, char **argv, const char *funcname)
1552
+static size_t
1553
+func_notdir_suffix (struct vbuffer *o, char **argv, const char *funcname)
1554
 {
1555
+  size_t ret = 0;
1556
+
1557
   /* Expand the argument.  */
1558
   const char *list_iterator = argv[0];
1559
   const char *p2;
1560
-  int doneany =0;
1561
-  unsigned int len=0;
1562
+  unsigned int len = 0;
1563
 
1564
   int is_suffix = funcname[0] == 's';
1565
   int is_notdir = !is_suffix;
1566
@@ -529,7 +472,6 @@
1567
     {
1568
       const char *p = p2 + len;
1569
 
1570
-
1571
       while (p >= p2 && (!is_suffix || *p != '.'))
1572
 	{
1573
 	  if (IS_PATHSEP (*p))
1574
@@ -543,41 +485,35 @@
1575
 	    ++p;
1576
 	  else if (*p != '.')
1577
 	    continue;
1578
-	  o = variable_buffer_output (o, p, len - (p - p2));
1579
+	  ret += vbuffer_write (o, p, len - (p - p2));
1580
 	}
1581
 #ifdef HAVE_DOS_PATHS
1582
       /* Handle the case of "d:foo/bar".  */
1583
       else if (is_notdir && p2[0] && p2[1] == ':')
1584
 	{
1585
 	  p = p2 + 2;
1586
-	  o = variable_buffer_output (o, p, len - (p - p2));
1587
+	  ret += vbuffer_write (o, p, len - (p - p2));
1588
 	}
1589
 #endif
1590
       else if (is_notdir)
1591
-	o = variable_buffer_output (o, p2, len);
1592
+	ret += vbuffer_write (o, p2, len);
1593
 
1594
       if (is_notdir || p >= p2)
1595
-	{
1596
-	  o = variable_buffer_output (o, " ", 1);
1597
-	  doneany = 1;
1598
-	}
1599
+	ret += vbuffer_write (o, " ", 1);
1600
     }
1601
 
1602
-  if (doneany)
1603
-    /* Kill last space.  */
1604
-    --o;
1605
-
1606
-  return o;
1607
+  return ret - vbuffer_unwrite (o, !!ret);
1608
 }
1609
 
1610
 
1611
-static char *
1612
-func_basename_dir (char *o, char **argv, const char *funcname)
1613
+static size_t
1614
+func_basename_dir (struct vbuffer *o, char **argv, const char *funcname)
1615
 {
1616
+  size_t ret = 0;
1617
+
1618
   /* Expand the argument.  */
1619
   const char *p3 = argv[0];
1620
   const char *p2;
1621
-  int doneany = 0;
1622
   unsigned int len = 0;
1623
 
1624
   int is_basename = funcname[0] == 'b';
1625
@@ -594,111 +530,105 @@
1626
         }
1627
 
1628
       if (p >= p2 && (is_dir))
1629
-        o = variable_buffer_output (o, p2, ++p - p2);
1630
+        ret += vbuffer_write (o, p2, ++p - p2);
1631
       else if (p >= p2 && (*p == '.'))
1632
-        o = variable_buffer_output (o, p2, p - p2);
1633
+        ret += vbuffer_write (o, p2, p - p2);
1634
 #ifdef HAVE_DOS_PATHS
1635
       /* Handle the "d:foobar" case */
1636
       else if (p2[0] && p2[1] == ':' && is_dir)
1637
-        o = variable_buffer_output (o, p2, 2);
1638
+	ret += vbuffer_write (o, p2, 2);
1639
 #endif
1640
       else if (is_dir)
1641
 #ifdef VMS
1642
-        o = variable_buffer_output (o, "[]", 2);
1643
+	ret += vbuffer_write (o, "[]", 2);
1644
 #else
1645
 #ifndef _AMIGA
1646
-      o = variable_buffer_output (o, "./", 2);
1647
+      ret += vbuffer_write (o, "./", 2);
1648
 #else
1649
       ; /* Just a nop...  */
1650
 #endif /* AMIGA */
1651
 #endif /* !VMS */
1652
       else
1653
         /* The entire name is the basename.  */
1654
-        o = variable_buffer_output (o, p2, len);
1655
+        ret += vbuffer_write (o, p2, len);
1656
 
1657
-      o = variable_buffer_output (o, " ", 1);
1658
-      doneany = 1;
1659
+      ret += vbuffer_write (o, " ", 1);
1660
     }
1661
 
1662
-  if (doneany)
1663
-    /* Kill last space.  */
1664
-    --o;
1665
-
1666
-  return o;
1667
+  return ret - vbuffer_unwrite (o, !!ret);
1668
 }
1669
 
1670
-static char *
1671
-func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
1672
+static size_t
1673
+func_addsuffix_addprefix (struct vbuffer *o, char **argv, const char *funcname)
1674
 {
1675
+  size_t ret = 0;
1676
+
1677
   int fixlen = strlen (argv[0]);
1678
   const char *list_iterator = argv[1];
1679
-  int is_addprefix = funcname[3] == 'p';
1680
+  int is_addprefix = funcname[CSTRLEN("add")] == 'p';
1681
   int is_addsuffix = !is_addprefix;
1682
 
1683
-  int doneany = 0;
1684
   const char *p;
1685
   unsigned int len;
1686
 
1687
   while ((p = find_next_token (&list_iterator, &len)) != 0)
1688
     {
1689
       if (is_addprefix)
1690
-	o = variable_buffer_output (o, argv[0], fixlen);
1691
-      o = variable_buffer_output (o, p, len);
1692
+	ret += vbuffer_write (o, argv[0], fixlen);
1693
+      ret += vbuffer_write (o, p, len);
1694
       if (is_addsuffix)
1695
-	o = variable_buffer_output (o, argv[0], fixlen);
1696
-      o = variable_buffer_output (o, " ", 1);
1697
-      doneany = 1;
1698
+	ret += vbuffer_write (o, argv[0], fixlen);
1699
+      ret += vbuffer_write (o, " ", 1);
1700
     }
1701
 
1702
-  if (doneany)
1703
-    /* Kill last space.  */
1704
-    --o;
1705
-
1706
-  return o;
1707
+  return ret - vbuffer_unwrite (o, !!ret);
1708
 }
1709
 
1710
-static char *
1711
-func_subst (char *o, char **argv, const char *funcname UNUSED)
1712
-{
1713
-  o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
1714
-		    strlen (argv[1]), 0);
1715
 
1716
-  return o;
1717
+static size_t
1718
+func_subst (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1719
+{
1720
+  return subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
1721
+		       strlen (argv[1]), 0);
1722
 }
1723
 
1724
 
1725
-static char *
1726
-func_firstword (char *o, char **argv, const char *funcname UNUSED)
1727
+static size_t
1728
+func_firstword (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1729
 {
1730
-  unsigned int i;
1731
+  size_t ret = 0;
1732
+
1733
+  unsigned int len;
1734
   const char *words = argv[0];    /* Use a temp variable for find_next_token */
1735
-  const char *p = find_next_token (&words, &i);
1736
+  const char *p = find_next_token (&words, &len);
1737
 
1738
   if (p != 0)
1739
-    o = variable_buffer_output (o, p, i);
1740
+    ret += vbuffer_write (o, p, len);
1741
 
1742
-  return o;
1743
+  return ret;
1744
 }
1745
 
1746
-static char *
1747
-func_lastword (char *o, char **argv, const char *funcname UNUSED)
1748
+static size_t
1749
+func_lastword (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1750
 {
1751
-  unsigned int i;
1752
+  size_t ret = 0;
1753
+
1754
+  unsigned int len;
1755
   const char *words = argv[0];    /* Use a temp variable for find_next_token */
1756
   const char *p = NULL;
1757
   const char *t;
1758
 
1759
-  while ((t = find_next_token (&words, &i)))
1760
+  while ((t = find_next_token (&words, &len)))
1761
     p = t;
1762
 
1763
   if (p != 0)
1764
-    o = variable_buffer_output (o, p, i);
1765
+    ret += vbuffer_write (o, p, len);
1766
 
1767
-  return o;
1768
+  return ret;
1769
 }
1770
 
1771
-static char *
1772
-func_words (char *o, char **argv, const char *funcname UNUSED)
1773
+static size_t
1774
+func_words (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1775
 {
1776
   int i = 0;
1777
   const char *word_iterator = argv[0];
1778
@@ -708,9 +638,8 @@
1779
     ++i;
1780
 
1781
   sprintf (buf, "%d", i);
1782
-  o = variable_buffer_output (o, buf, strlen (buf));
1783
 
1784
-  return o;
1785
+  return vbuffer_write (o, buf, -1);
1786
 }
1787
 
1788
 /* Set begpp to point to the first non-whitespace character of the string,
1789
@@ -744,10 +673,11 @@
1790
 }
1791
 
1792
 
1793
-
1794
-static char *
1795
-func_word (char *o, char **argv, const char *funcname UNUSED)
1796
+static size_t
1797
+func_word (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1798
 {
1799
+  size_t ret = 0;
1800
+
1801
   const char *end_p;
1802
   const char *p;
1803
   int i;
1804
@@ -766,14 +696,17 @@
1805
       break;
1806
 
1807
   if (i == 0)
1808
-    o = variable_buffer_output (o, p, end_p - p);
1809
+    ret += vbuffer_write (o, p, end_p - p);
1810
 
1811
-  return o;
1812
+  return ret;
1813
 }
1814
 
1815
-static char *
1816
-func_wordlist (char *o, char **argv, const char *funcname UNUSED)
1817
+
1818
+static size_t
1819
+func_wordlist (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1820
 {
1821
+  size_t ret = 0;
1822
+
1823
   int start, count;
1824
 
1825
   /* Check the arguments.  */
1826
@@ -805,67 +738,102 @@
1827
             ;
1828
 
1829
           /* Return the stuff in the middle.  */
1830
-          o = variable_buffer_output (o, p, end_p - p);
1831
+          ret += vbuffer_write (o, p, end_p - p);
1832
         }
1833
     }
1834
 
1835
-  return o;
1836
+  return ret;
1837
 }
1838
 
1839
-static char *
1840
-func_findstring (char *o, char **argv, const char *funcname UNUSED)
1841
+static size_t
1842
+func_findstring (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1843
 {
1844
+  size_t ret = 0;
1845
+
1846
   /* Find the first occurrence of the first string in the second.  */
1847
   if (strstr (argv[1], argv[0]) != 0)
1848
-    o = variable_buffer_output (o, argv[0], strlen (argv[0]));
1849
+    ret += vbuffer_write (o, argv[0], -1);
1850
 
1851
-  return o;
1852
+  return ret;
1853
 }
1854
 
1855
-static char *
1856
-func_foreach (char *o, char **argv, const char *funcname UNUSED)
1857
+static size_t
1858
+func_foreach (struct vbuffer *o, char **argv, const char *funcname UNUSED)
1859
 {
1860
-  /* expand only the first two.  */
1861
-  char *varname = expand_argument (argv[0], NULL);
1862
-  char *list = expand_argument (argv[1], NULL);
1863
-  const char *body = argv[2];
1864
+  size_t ret = 0;
1865
 
1866
-  int doneany = 0;
1867
-  const char *list_iterator = list;
1868
-  const char *p;
1869
+  char *p;
1870
   unsigned int len;
1871
-  struct variable *var;
1872
+  char *varname;
1873
+  char *list;
1874
+  char *body;
1875
+  size_t varname_len;
1876
+  size_t list_len;
1877
+  size_t body_len = strlen (argv[2]);
1878
+  struct vbuffer argbuf;
1879
 
1880
-  push_new_variable_scope ();
1881
-  var = define_variable (varname, strlen (varname), "", o_automatic, 0);
1882
+  /* Expand the list and the variable name into a dedicated vbuffer.  */
1883
 
1884
-  /* loop through LIST,  put the value in VAR and expand BODY */
1885
-  while ((p = find_next_token (&list_iterator, &len)) != 0)
1886
+  vbuffer_init (&argbuf);
1887
+
1888
+  list_len = vbuffer_expand (&argbuf, argv[1], -1);
1889
+  *(++argbuf.ptr) = '\0';
1890
+  /* Add an extra nil to iterate over the list more efficiently.  */
1891
+  *(++argbuf.ptr) = '\0';
1892
+
1893
+  varname_len = vbuffer_expand (&argbuf, argv[0], -1);
1894
+  *(++argbuf.ptr) = '\0';
1895
+
1896
+  /* Also get a room for an unexpanded body.  */
1897
+
1898
+  vbuffer_reserve (&argbuf, body_len + 1);
1899
+
1900
+  list = argbuf.buffer;
1901
+  varname = list + list_len + 2;
1902
+  body = varname + varname_len + 1;
1903
+  body[body_len] = ' ';
1904
+
1905
+  if ((p = find_next_token ((const char **) &list, &len)) != 0)
1906
     {
1907
-      char *result = 0;
1908
+      struct variable var;
1909
+      struct variable *saved_var;
1910
+      char **argp;
1911
+      char *saved_arg = NULL;
1912
 
1913
-      free (var->value);
1914
-      var->value = xstrndup (p, len);
1915
+      argp = lookup_call_argument_value (varname, varname_len);
1916
+      if (argp && *argp)
1917
+	{
1918
+	  /* Variable name is a numeric value and there is a call argument
1919
+	     that would hide a pushed variable.
1920
+	     Make a "hole" in the current call frame so that the new variable
1921
+	     becomes visible.  */
1922
+	  saved_arg = *argp;
1923
+	  *argp = NULL;
1924
+	}
1925
+      saved_var = push_scoped_variable (&var, varname, varname_len);
1926
 
1927
-      result = allocated_variable_expand (body);
1928
+      /* loop through LIST,  put the value in VAR and expand BODY */
1929
+      do
1930
+	{
1931
+	  p[len] = '\0';
1932
+	  var.value = p;
1933
+	  ret += vbuffer_expand (o, memcpy (body, argv[2], body_len),
1934
+				 body_len + 1);
1935
+	  ++list;
1936
+	}
1937
+      while ((p = find_next_token ((const char **) &list, &len)) != 0);
1938
 
1939
-      o = variable_buffer_output (o, result, strlen (result));
1940
-      o = variable_buffer_output (o, " ", 1);
1941
-      doneany = 1;
1942
-      free (result);
1943
+      pop_scoped_variable (&var, saved_var);
1944
+      if (saved_arg)
1945
+	*argp = saved_arg;
1946
     }
1947
 
1948
-  if (doneany)
1949
-    /* Kill the last space.  */
1950
-    --o;
1951
-
1952
-  pop_variable_scope ();
1953
-  free (varname);
1954
-  free (list);
1955
+  vbuffer_free (&argbuf);
1956
 
1957
-  return o;
1958
+  return ret - vbuffer_unwrite (o, !!ret);
1959
 }
1960
 
1961
+
1962
 struct a_word
1963
 {
1964
   struct a_word *next;
1965
@@ -905,9 +873,11 @@
1966
   int length;
1967
 };
1968
 
1969
-static char *
1970
-func_filter_filterout (char *o, char **argv, const char *funcname)
1971
+static size_t
1972
+func_filter_filterout (struct vbuffer *o, char **argv, const char *funcname)
1973
 {
1974
+  size_t ret = 0;
1975
+
1976
   struct a_word *wordhead;
1977
   struct a_word **wordtail;
1978
   struct a_word *wp;
1979
@@ -989,8 +959,6 @@
1980
 
1981
   if (words)
1982
     {
1983
-      int doneany = 0;
1984
-
1985
       /* Run each pattern through the words, killing words.  */
1986
       for (pp = pathead; pp != 0; pp = pp->next)
1987
 	{
1988
@@ -1019,58 +987,42 @@
1989
       for (wp = wordhead; wp != 0; wp = wp->next)
1990
 	if (is_filter ? wp->matched : !wp->matched)
1991
 	  {
1992
-	    o = variable_buffer_output (o, wp->str, strlen (wp->str));
1993
-	    o = variable_buffer_output (o, " ", 1);
1994
-	    doneany = 1;
1995
+	    ret += vbuffer_write (o, wp->str, -1);
1996
+	    ret += vbuffer_write (o, " ", 1);
1997
 	  }
1998
 
1999
-      if (doneany)
2000
-	/* Kill the last space.  */
2001
-	--o;
2002
     }
2003
 
2004
   if (hashing)
2005
     hash_free (&a_word_table, 0);
2006
 
2007
-  return o;
2008
+  return ret - vbuffer_unwrite (o, !!ret);
2009
 }
2010
 
2011
 
2012
-static char *
2013
-func_strip (char *o, char **argv, const char *funcname UNUSED)
2014
+static size_t
2015
+func_strip (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2016
 {
2017
-  const char *p = argv[0];
2018
-  int doneany = 0;
2019
+  size_t result = 0;
2020
 
2021
-  while (*p != '\0')
2022
-    {
2023
-      int i=0;
2024
-      const char *word_start;
2025
+  unsigned int len;
2026
+  const char *words = argv[0];    /* Use a temp variable for find_next_token */
2027
+  const char *p;
2028
 
2029
-      while (isspace ((unsigned char)*p))
2030
-	++p;
2031
-      word_start = p;
2032
-      for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
2033
-	{}
2034
-      if (!i)
2035
-	break;
2036
-      o = variable_buffer_output (o, word_start, i);
2037
-      o = variable_buffer_output (o, " ", 1);
2038
-      doneany = 1;
2039
+  while ((p = find_next_token (&words, &len)) != 0)
2040
+    {
2041
+      result += vbuffer_write (o, p, len + 1);
2042
+      o->ptr[-1] = ' ';
2043
     }
2044
 
2045
-  if (doneany)
2046
-    /* Kill the last space.  */
2047
-    --o;
2048
-
2049
-  return o;
2050
+  return result - vbuffer_unwrite (o, !!result);
2051
 }
2052
 
2053
 /*
2054
   Print a warning or fatal message.
2055
 */
2056
-static char *
2057
-func_error (char *o, char **argv, const char *funcname)
2058
+size_t
2059
+func_error (struct vbuffer *o UNUSED, char **argv, const char *funcname)
2060
 {
2061
   char **argvp;
2062
   char *msg, *p;
2063
@@ -1111,16 +1063,18 @@
2064
   }
2065
 
2066
   /* The warning function expands to the empty string.  */
2067
-  return o;
2068
+  return 0;
2069
 }
2070
 
2071
 
2072
 /*
2073
   chop argv[0] into words, and sort them.
2074
  */
2075
-static char *
2076
-func_sort (char *o, char **argv, const char *funcname UNUSED)
2077
+static size_t
2078
+func_sort (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2079
 {
2080
+  size_t result = 0;
2081
+
2082
   const char *t;
2083
   char **words;
2084
   int wordi;
2085
@@ -1133,7 +1087,8 @@
2086
   wordi = 0;
2087
   while ((p = find_next_token (&t, NULL)) != 0)
2088
     {
2089
-      ++t;
2090
+      if (*t != '\0')
2091
+	++t;
2092
       ++wordi;
2093
     }
2094
 
2095
@@ -1144,7 +1099,8 @@
2096
   wordi = 0;
2097
   while ((p = find_next_token (&t, &len)) != 0)
2098
     {
2099
-      ++t;
2100
+      if (*t != '\0')
2101
+	++t;
2102
       p[len] = '\0';
2103
       words[wordi++] = p;
2104
     }
2105
@@ -1161,18 +1117,18 @@
2106
           if (i == wordi - 1 || strlen (words[i + 1]) != len
2107
               || strcmp (words[i], words[i + 1]))
2108
             {
2109
-              o = variable_buffer_output (o, words[i], len);
2110
-              o = variable_buffer_output (o, " ", 1);
2111
+              result += vbuffer_write (o, words[i], len);
2112
+              result += vbuffer_write (o, " ", 1);
2113
             }
2114
         }
2115
 
2116
       /* Kill the last space.  */
2117
-      --o;
2118
+      result -= vbuffer_unwrite (o, 1);
2119
     }
2120
 
2121
   free (words);
2122
 
2123
-  return o;
2124
+  return result;
2125
 }
2126
 
2127
 /*
2128
@@ -1187,9 +1143,11 @@
2129
   example).
2130
 */
2131
 
2132
-static char *
2133
-func_if (char *o, char **argv, const char *funcname UNUSED)
2134
+static size_t
2135
+func_if (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2136
 {
2137
+  size_t ret = 0;
2138
+
2139
   const char *begp = argv[0];
2140
   const char *endp = begp + strlen (argv[0]) - 1;
2141
   int result = 0;
2142
@@ -1201,12 +1159,9 @@
2143
   strip_whitespace (&begp, &endp);
2144
 
2145
   if (begp <= endp)
2146
-    {
2147
-      char *expansion = expand_argument (begp, endp+1);
2148
+    result = vbuffer_expand (o, (char *) begp, endp+1 - begp);
2149
 
2150
-      result = strlen (expansion);
2151
-      free (expansion);
2152
-    }
2153
+  vbuffer_unwrite (o, result);
2154
 
2155
   /* If the result is true (1) we want to eval the first argument, and if
2156
      it's false (0) we want to eval the second.  If the argument doesn't
2157
@@ -1215,15 +1170,9 @@
2158
   argv += 1 + !result;
2159
 
2160
   if (*argv)
2161
-    {
2162
-      char *expansion = expand_argument (*argv, NULL);
2163
+    ret += vbuffer_expand (o, *argv, -1);
2164
 
2165
-      o = variable_buffer_output (o, expansion, strlen (expansion));
2166
-
2167
-      free (expansion);
2168
-    }
2169
-
2170
-  return o;
2171
+  return ret;
2172
 }
2173
 
2174
 /*
2175
@@ -1240,15 +1189,15 @@
2176
   (short-circuiting).
2177
 */
2178
 
2179
-static char *
2180
-func_or (char *o, char **argv, const char *funcname UNUSED)
2181
+static size_t
2182
+func_or (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2183
 {
2184
   for ( ; *argv ; ++argv)
2185
     {
2186
+      size_t result;
2187
+
2188
       const char *begp = *argv;
2189
       const char *endp = begp + strlen (*argv) - 1;
2190
-      char *expansion;
2191
-      int result = 0;
2192
 
2193
       /* Find the result of the condition: if it's false keep going.  */
2194
 
2195
@@ -1257,23 +1206,14 @@
2196
       if (begp > endp)
2197
         continue;
2198
 
2199
-      expansion = expand_argument (begp, endp+1);
2200
-      result = strlen (expansion);
2201
+      result = vbuffer_expand (o, (char *) begp, endp+1 - begp);
2202
 
2203
       /* If the result is false keep going.  */
2204
-      if (!result)
2205
-        {
2206
-          free (expansion);
2207
-          continue;
2208
-        }
2209
-
2210
-      /* It's true!  Keep this result and return.  */
2211
-      o = variable_buffer_output (o, expansion, result);
2212
-      free (expansion);
2213
-      break;
2214
+      if (result)
2215
+	return result;
2216
     }
2217
 
2218
-  return o;
2219
+    return 0;
2220
 }
2221
 
2222
 /*
2223
@@ -1290,56 +1230,37 @@
2224
   (short-circuiting).
2225
 */
2226
 
2227
-static char *
2228
-func_and (char *o, char **argv, const char *funcname UNUSED)
2229
+static size_t
2230
+func_and (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2231
 {
2232
-  char *expansion;
2233
-  int result;
2234
-
2235
   while (1)
2236
     {
2237
+      size_t result;
2238
+
2239
       const char *begp = *argv;
2240
       const char *endp = begp + strlen (*argv) - 1;
2241
 
2242
       /* An empty condition is always false.  */
2243
       strip_whitespace (&begp, &endp);
2244
       if (begp > endp)
2245
-        return o;
2246
+        return 0;
2247
 
2248
-      expansion = expand_argument (begp, endp+1);
2249
-      result = strlen (expansion);
2250
+      result = vbuffer_expand (o, (char *) begp, endp+1 - begp);
2251
 
2252
       /* If the result is false, stop here: we're done.  */
2253
       if (!result)
2254
-        break;
2255
+        return 0;
2256
 
2257
       /* Otherwise the result is true.  If this is the last one, keep this
2258
          result and quit.  Otherwise go on to the next one!  */
2259
 
2260
       if (*(++argv))
2261
-        free (expansion);
2262
+	vbuffer_unwrite (o, result);
2263
       else
2264
-        {
2265
-          o = variable_buffer_output (o, expansion, result);
2266
-          break;
2267
-        }
2268
+	return result;
2269
     }
2270
 
2271
-  free (expansion);
2272
-
2273
-  return o;
2274
-}
2275
-
2276
-static char *
2277
-func_wildcard (char *o, char **argv, const char *funcname UNUSED)
2278
-{
2279
-#ifdef _AMIGA
2280
-   o = wildcard_expansion (argv[0], o);
2281
-#else
2282
-   char *p = string_glob (argv[0]);
2283
-   o = variable_buffer_output (o, p, strlen (p));
2284
-#endif
2285
-   return o;
2286
+    return 0;
2287
 }
2288
 
2289
 /*
2290
@@ -1350,36 +1271,38 @@
2291
   Treat the arguments as a segment of makefile, and parse them.
2292
 */
2293
 
2294
-static char *
2295
-func_eval (char *o, char **argv, const char *funcname UNUSED)
2296
+static size_t
2297
+func_eval (struct vbuffer *o UNUSED, char **argv, const char *funcname UNUSED)
2298
 {
2299
-  char *buf;
2300
-  unsigned int len;
2301
+  struct vbuffer *vbuf;
2302
 
2303
   /* Eval the buffer.  Pop the current variable buffer setting so that the
2304
      eval'd code can use its own without conflicting.  */
2305
 
2306
-  install_variable_buffer (&buf, &len);
2307
+  vbuf = install_new_expansion_vbuffer ();
2308
 
2309
   eval_buffer (argv[0]);
2310
 
2311
-  restore_variable_buffer (buf, len);
2312
+  restore_expansion_vbuffer (vbuf);
2313
 
2314
-  return o;
2315
+  /* Eval always expands to nothing. */
2316
+  return 0;
2317
 }
2318
 
2319
 
2320
-static char *
2321
-func_value (char *o, char **argv, const char *funcname UNUSED)
2322
+static size_t
2323
+func_value (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2324
 {
2325
+  size_t result = 0;
2326
+
2327
   /* Look up the variable.  */
2328
   struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2329
 
2330
   /* Copy its value into the output buffer without expanding it.  */
2331
   if (v)
2332
-    o = variable_buffer_output (o, v->value, strlen(v->value));
2333
+    result += vbuffer_write (o, v->value, -1);
2334
 
2335
-  return o;
2336
+  return result;
2337
 }
2338
 
2339
 /*
2340
@@ -1619,9 +1542,10 @@
2341
 
2342
 #else
2343
 #ifndef _AMIGA
2344
-char *
2345
-func_shell_base (char *o, char **argv, int trim_newlines)
2346
+size_t
2347
+func_shell_base (struct vbuffer *o, char **argv, int trim_newlines)
2348
 {
2349
+  size_t result = 0;
2350
   char *batch_filename = NULL;
2351
 
2352
 #ifdef __MSDOS__
2353
@@ -1650,7 +1574,7 @@
2354
 #ifdef WINDOWS32
2355
       just_print_flag = j_p_f;
2356
 #endif
2357
-      return o;
2358
+      return 0;
2359
     }
2360
 #endif
2361
 
2362
@@ -1683,7 +1607,7 @@
2363
   if (pipedes[0] < 0)
2364
     {
2365
       perror_with_name (error_prefix, "pipe");
2366
-      return o;
2367
+      return 0;
2368
     }
2369
 #elif defined(WINDOWS32)
2370
   windows32_openpipe (pipedes, &pid, command_argv, envp);
2371
@@ -1694,14 +1618,14 @@
2372
     {
2373
       /* Open of the pipe failed, mark as failed execution.  */
2374
       shell_function_completed = -1;
2375
-      return o;
2376
+      return 0;
2377
     }
2378
   else
2379
 #else
2380
   if (pipe (pipedes) < 0)
2381
     {
2382
       perror_with_name (error_prefix, "pipe");
2383
-      return o;
2384
+      return 0;
2385
     }
2386
 
2387
 # ifdef __EMX__
2388
@@ -1800,13 +1724,13 @@
2389
 	  /* The child finished normally.  Replace all newlines in its output
2390
 	     with spaces, and put that in the variable output buffer.  */
2391
 	  fold_newlines (buffer, &i, trim_newlines);
2392
-	  o = variable_buffer_output (o, buffer, i);
2393
+	  result += vbuffer_write (o, buffer, i);
2394
 	}
2395
 
2396
       free (buffer);
2397
     }
2398
 
2399
-  return o;
2400
+  return result;
2401
 }
2402
 
2403
 #else	/* _AMIGA */
2404
@@ -1892,14 +1816,14 @@
2405
   Close (child_stdout);
2406
 
2407
   fold_newlines (buffer, &i, trim_newlines);
2408
-  o = variable_buffer_output (o, buffer, i);
2409
+  result += vbuffer_write (o, buffer, i);
2410
   free (buffer);
2411
   return o;
2412
 }
2413
 #endif  /* _AMIGA */
2414
 
2415
-char *
2416
-func_shell (char *o, char **argv, const char *funcname UNUSED)
2417
+size_t
2418
+func_shell (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2419
 {
2420
   return func_shell_base (o, argv, 1);
2421
 }
2422
@@ -1914,8 +1838,7 @@
2423
 func_eq (char *o, char **argv, char *funcname UNUSED)
2424
 {
2425
   int result = ! strcmp (argv[0], argv[1]);
2426
-  o = variable_buffer_output (o,  result ? "1" : "", result);
2427
-  return o;
2428
+  return vbuffer_write (o,  result ? "1" : "", result);
2429
 }
2430
 
2431
 
2432
@@ -1930,8 +1853,7 @@
2433
   while (isspace ((unsigned char)*s))
2434
     s++;
2435
   result = ! (*s);
2436
-  o = variable_buffer_output (o,  result ? "1" : "", result);
2437
-  return o;
2438
+  return vbuffer_write (o,  result ? "1" : "", result);
2439
 }
2440
 #endif
2441
 
2442
@@ -2058,13 +1980,14 @@
2443
 }
2444
 
2445
 
2446
-static char *
2447
-func_realpath (char *o, char **argv, const char *funcname UNUSED)
2448
+static size_t
2449
+func_realpath (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2450
 {
2451
+  size_t result = 0;
2452
+
2453
   /* Expand the argument.  */
2454
   const char *p = argv[0];
2455
   const char *path = 0;
2456
-  int doneany = 0;
2457
   unsigned int len = 0;
2458
 #ifndef HAVE_REALPATH
2459
   struct stat st;
2460
@@ -2087,22 +2010,17 @@
2461
 #endif
2462
              )
2463
             {
2464
-              o = variable_buffer_output (o, out, strlen (out));
2465
-              o = variable_buffer_output (o, " ", 1);
2466
-              doneany = 1;
2467
+              result += vbuffer_write (o, out, -1);
2468
+              result += vbuffer_write (o, " ", 1);
2469
             }
2470
         }
2471
     }
2472
 
2473
-  /* Kill last space.  */
2474
-  if (doneany)
2475
-    --o;
2476
-
2477
-  return o;
2478
+  return result - vbuffer_unwrite (o, !!result);
2479
 }
2480
 
2481
-static char *
2482
-func_file (char *o, char **argv, const char *funcname UNUSED)
2483
+static size_t
2484
+func_file (struct vbuffer *o UNUSED, char **argv, const char *funcname UNUSED)
2485
 {
2486
   char *fn = argv[0];
2487
 
2488
@@ -2137,16 +2055,17 @@
2489
   else
2490
     fatal (reading_file, _("Invalid file operation: %s"), fn);
2491
 
2492
-  return o;
2493
+  return 0;
2494
 }
2495
 
2496
-static char *
2497
-func_abspath (char *o, char **argv, const char *funcname UNUSED)
2498
+static size_t
2499
+func_abspath (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2500
 {
2501
+  size_t result = 0;
2502
+
2503
   /* Expand the argument.  */
2504
   const char *p = argv[0];
2505
   const char *path = 0;
2506
-  int doneany = 0;
2507
   unsigned int len = 0;
2508
   PATH_VAR (in);
2509
   PATH_VAR (out);
2510
@@ -2160,25 +2079,18 @@
2511
 
2512
           if (abspath (in, out))
2513
             {
2514
-              o = variable_buffer_output (o, out, strlen (out));
2515
-              o = variable_buffer_output (o, " ", 1);
2516
-              doneany = 1;
2517
+              result += vbuffer_write (o, out, strlen (out));
2518
+              result += vbuffer_write (o, " ", 1);
2519
             }
2520
         }
2521
     }
2522
 
2523
-  /* Kill last space.  */
2524
-  if (doneany)
2525
-    --o;
2526
-
2527
-  return o;
2528
+  return result - vbuffer_unwrite (o, !!result);
2529
 }
2530
 
2531
 /* Lookup table for builtin functions.
2532
 
2533
-   This doesn't have to be sorted; we use a straight lookup.  We might gain
2534
-   some efficiency by moving most often used functions to the start of the
2535
-   table.
2536
+   This doesn't have to be sorted; we use hash table to perform a lookup.
2537
 
2538
    If MAXIMUM_ARGS is 0, that means there is no maximum and all
2539
    comma-separated values are treated as arguments.
2540
@@ -2186,7 +2098,7 @@
2541
    EXPAND_ARGS means that all arguments should be expanded before invocation.
2542
    Functions that do namespace tricks (foreach) don't automatically expand.  */
2543
 
2544
-static char *func_call (char *o, char **argv, const char *funcname);
2545
+static size_t func_call (struct vbuffer *o, char **argv, const char *funcname);
2546
 
2547
 
2548
 static struct function_table_entry function_table_init[] =
2549
@@ -2237,10 +2149,26 @@
2550
 #define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
2551
 
2552
 
2553
+/* Look up a function by name.  */
2554
+
2555
+#ifdef __GNUC__
2556
+__inline
2557
+#endif
2558
+static const struct function_table_entry *
2559
+lookup_function (const char *name, unsigned int length)
2560
+{
2561
+  struct function_table_entry function_table_entry_key;
2562
+  function_table_entry_key.name = name;
2563
+  function_table_entry_key.len = length;
2564
+
2565
+  return hash_find_item (&function_table, &function_table_entry_key);
2566
+}
2567
+
2568
+
2569
 /* These must come after the definition of function_table.  */
2570
 
2571
-static char *
2572
-expand_builtin_function (char *o, int argc, char **argv,
2573
+static size_t
2574
+expand_builtin_function (struct vbuffer *o, int argc, char **argv,
2575
                          const struct function_table_entry *entry_p)
2576
 {
2577
   if (argc < (int)entry_p->minimum_args)
2578
@@ -2253,7 +2181,7 @@
2579
      rather than in each one.  We can change it later if necessary.  */
2580
 
2581
   if (!argc)
2582
-    return o;
2583
+    return 0;
2584
 
2585
   if (!entry_p->func_ptr)
2586
     fatal (*expanding_var,
2587
@@ -2264,120 +2192,134 @@
2588
 
2589
 /* Check for a function invocation in *STRINGP.  *STRINGP points at the
2590
    opening ( or { and is not null-terminated.  If a function invocation
2591
-   is found, expand it into the buffer at *OP, updating *OP, incrementing
2592
-   *STRINGP past the reference and returning nonzero.  If not, return zero.  */
2593
+   is found, expand it into the buffer O, incrementing *STRINGP past the
2594
+   reference and returning the amount of bytes written.
2595
+   Note, that in this case the string between the parens is destroyed.
2596
+
2597
+   If no function call is recognized, return -1.  */
2598
 
2599
 int
2600
-handle_function (char **op, const char **stringp)
2601
+handle_function (struct vbuffer *o, char **stringp)
2602
 {
2603
+  size_t ret = 0;
2604
+
2605
   const struct function_table_entry *entry_p;
2606
   char openparen = (*stringp)[0];
2607
   char closeparen = openparen == '(' ? ')' : '}';
2608
-  const char *beg;
2609
-  const char *end;
2610
-  int count = 0;
2611
-  char *abeg = NULL;
2612
+  char *beg;
2613
+  char *end;
2614
+  int count;
2615
   char **argv, **argvp;
2616
-  int nargs;
2617
+  int nargs, maxargs;
2618
+  struct vbuffer argbuf;
2619
+  size_t reserved;
2620
 
2621
   beg = *stringp + 1;
2622
 
2623
-  entry_p = lookup_function (beg);
2624
+  end = beg;
2625
+  while ((*end >= 'a' && *end <= 'z') || *end == '-')
2626
+    end++;
2627
+  if (*end != ' ' && *end != '\t')
2628
+    return -1;
2629
 
2630
+  entry_p = lookup_function (beg, end - beg);
2631
   if (!entry_p)
2632
-    return 0;
2633
+    return -1;
2634
 
2635
   /* We found a builtin function.  Find the beginning of its arguments (skip
2636
      whitespace after the name).  */
2637
 
2638
-  beg = next_token (beg + entry_p->len);
2639
+  beg = next_token (end);
2640
+  maxargs = entry_p->maximum_args;
2641
 
2642
   /* Find the end of the function invocation, counting nested use of
2643
-     whichever kind of parens we use.  Since we're looking, count commas
2644
-     to get a rough estimate of how many arguments we might have.  The
2645
-     count might be high, but it'll never be low.  */
2646
-
2647
-  for (nargs=1, end=beg; *end != '\0'; ++end)
2648
-    if (*end == ',')
2649
-      ++nargs;
2650
-    else if (*end == openparen)
2651
+     whichever kind of parens we use and isolating arguments.
2652
+     As soon as we hit up to MAXARGS (if it is positive) assume the rest of
2653
+     the string is part of the last argument. For each argument, we save
2654
+     a pointer into the ARGBUF and NULL-terminate the argument value.  */
2655
+#define VBUFFER_WRITE_PTR(o, value) \
2656
+  *((char **) (((o)->ptr += sizeof (char *)) - sizeof (char *))) = (value)
2657
+
2658
+  vbuffer_init (&argbuf);
2659-
+  reserved = argbuf.size;
2659+
+  reserved = argbuf.size - sizeof (char *);
2660
+
2661
+  VBUFFER_WRITE_PTR (&argbuf, beg);
2662-
+  VBUFFER_WRITE_PTR(&argbuf, beg);
2662+
2663
+  nargs=1;
2664
+  count = 0;
2665
+  for (end=beg; *end != '\0'; ++end)
2666
+    if (*end == openparen)
2667
       ++count;
2668
     else if (*end == closeparen && --count < 0)
2669
       break;
2670
+    else if (count == 0 && *end == ',' && nargs != maxargs)
2671
+      {
2672
+	*end = '\0';
2673
+	nargs++;
2674
+
2675-
+	if (reserved < 2 * sizeof (char *))
2675+
+	if (reserved <= 2 * sizeof (char *))
2676
+	  reserved = vbuffer_reserve (&argbuf, 2 * sizeof (char *));
2677
+	else
2678
+	  reserved -= sizeof (char *);
2679
+
2680-
+	VBUFFER_WRITE_PTR(&argbuf, end+1);
2680+
+	VBUFFER_WRITE_PTR (&argbuf, end+1);
2681
+      }
2682
 
2683
   if (count >= 0)
2684
     fatal (*expanding_var,
2685
 	   _("unterminated call to function '%s': missing '%c'"),
2686
 	   entry_p->name, closeparen);
2687
 
2688
-  *stringp = end;
2689
+  /* NULL-terminate the last argument.  */
2690
+  *end = '\0';
2691
 
2692
-  /* Get some memory to store the arg pointers.  */
2693
-  argvp = argv = alloca (sizeof (char *) * (nargs + 2));
2694
+  /* NULL-terminate the arg vector (assume there was enough room reserved).  */
2695-
+  VBUFFER_WRITE_PTR(&argbuf, NULL);
2695+
+  VBUFFER_WRITE_PTR (&argbuf, NULL);
2696
 
2697
-  /* Chop the string into arguments, then a nul.  As soon as we hit
2698
-     MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
2699
-     last argument.
2700
-
2701
-     If we're expanding, store pointers to the expansion of each one.  If
2702
-     not, make a duplicate of the string and point into that, nul-terminating
2703
-     each argument.  */
2704
+  argv = (char **) argbuf.buffer;
2705
 
2706
-  if (entry_p->expand_args)
2707
-    {
2708
-      const char *p;
2709
-      for (p=beg, nargs=0; p <= end; ++argvp)
2710
-        {
2711
-          const char *next;
2712
+  /* If the function requires argument to be expanded, expand them into the
2713
+     same buffer as we used to for the arg vector, but store pointers to the
2714
+     expansion of each one into a new stack-allocated vector.
2715
 
2716
-          ++nargs;
2717
+     This, in turn, is performed in two steps:
2718
+       - First, we save position-independent offsets into a special buffer.
2719
+       - Next, build the final arg vector from the offsets buffer.
2720
 
2721
-          if (nargs == entry_p->maximum_args
2722
-              || (! (next = find_next_argument (openparen, closeparen, p, end))))
2723
-            next = end;
2724
+     Involving an intermediate buffer for the offsets is necessary because
2725
+     ARGBUF may grow while expanding an argument thus invalidating any
2726
+     previously stored pointers.  */
2727
 
2728
-          *argvp = expand_argument (p, next);
2729
-          p = next + 1;
2730
-        }
2731
-    }
2732
-  else
2733
+  if (entry_p->expand_args)
2734
     {
2735
-      int len = end - beg;
2736
-      char *p, *aend;
2737
-
2738
-      abeg = xmalloc (len+1);
2739
-      memcpy (abeg, beg, len);
2740
-      abeg[len] = '\0';
2741
-      aend = abeg + len;
2742
-
2743
-      for (p=abeg, nargs=0; p <= aend; ++argvp)
2744
-        {
2745
-          char *next;
2746
-
2747
-          ++nargs;
2748
-
2749
-          if (nargs == entry_p->maximum_args
2750
-              || (! (next = find_next_argument (openparen, closeparen, p, aend))))
2751
-            next = aend;
2752
-
2753
-          *argvp = p;
2754
-          *next = '\0';
2755
-          p = next + 1;
2756
-        }
2757
+      int i;
2758
+      size_t *offs = alloca ((nargs + 1) * sizeof (size_t));
2759
+      argv = memcpy (alloca ((nargs + 1) * sizeof (char *)),
2760
+		       argv, (nargs + 1) * sizeof (char *));
2761
+
2762
+      vbuffer_reset (&argbuf);
2763
+      offs[0] = 0;
2764
+      for (i=0, argvp=argv; *argvp != 0; ++argvp, ++i)
2765
+	{
2766
+	  offs[i + 1] = offs[i] + vbuffer_expand (&argbuf, *argvp, -1) + 1;
2767
+	  *(++argbuf.ptr) = '\0';
2768
+	}
2769
+      for (i=0, argvp=argv; *argvp != 0; ++argvp, ++i)
2770
+	*argvp = argbuf.buffer + offs[i];
2771
     }
2772
-  *argvp = NULL;
2773
 
2774
   /* Finally!  Run the function...  */
2775
-  *op = expand_builtin_function (*op, nargs, argv, entry_p);
2776
+  ret += expand_builtin_function (o, nargs, argv, entry_p);
2777
 
2778
-  /* Free memory.  */
2779
-  if (entry_p->expand_args)
2780
-    for (argvp=argv; *argvp != 0; ++argvp)
2781
-      free (*argvp);
2782
-  else if (abeg)
2783
-    free (abeg);
2784
+  /* Restore a paren after the last argument and advance the STRINGP.  */
2785
+  *end = closeparen;
2786
+  *stringp = end;
2787
+
2788
+  vbuffer_free (&argbuf);
2789
+
2790
+#undef VBUFFER_WRITE_PTR
2791
 
2792
-  return 1;
2793
+  return ret;
2794
 }
2795
 
2796
 
2797
@@ -2385,37 +2327,41 @@
2798
    function or a make variable, in the context of the rest of the arguments
2799
    assigned to $1, $2, ... $N.  $0 is the name of the function.  */
2800
 
2801
-static char *
2802
-func_call (char *o, char **argv, const char *funcname UNUSED)
2803
+static size_t
2804
+func_call (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2805
 {
2806
-  static int max_args = 0;
2807
+  size_t ret = 0;
2808
+
2809
   char *fname;
2810
   char *cp;
2811
-  char *body;
2812
   int flen;
2813
   int i;
2814
-  int saved_args;
2815
+  int argc;
2816
   const struct function_table_entry *entry_p;
2817
   struct variable *v;
2818
 
2819
   /* There is no way to define a variable with a space in the name, so strip
2820
-     leading and trailing whitespace as a favor to the user.  */
2821
+     trailing whitespace as a favor to the user.  */
2822
   fname = argv[0];
2823
   while (*fname != '\0' && isspace ((unsigned char)*fname))
2824
     ++fname;
2825
 
2826
-  cp = fname + strlen (fname) - 1;
2827
+  flen = strlen (fname);
2828
+
2829
+  cp = fname + flen - 1;
2830
   while (cp > fname && isspace ((unsigned char)*cp))
2831
     --cp;
2832
   cp[1] = '\0';
2833
 
2834
   /* Calling nothing is a no-op */
2835
   if (*fname == '\0')
2836
-    return o;
2837
+    return 0;
2838
 
2839
-  /* Are we invoking a builtin function?  */
2840
+  /* Fix up the length after stripping a trailing whitespace. */
2841
+  flen = cp - fname + 1;
2842
 
2843
-  entry_p = lookup_function (fname);
2844
+  /* Are we invoking a builtin function?  */
2845
+  entry_p = lookup_function (fname, flen);
2846
   if (entry_p)
2847
     {
2848
       /* How many arguments do we have?  */
2849
@@ -2426,7 +2372,6 @@
2850
 
2851
   /* Not a builtin, so the first argument is the name of a variable to be
2852
      expanded and interpreted as a function.  Find it.  */
2853
-  flen = strlen (fname);
2854
 
2855
   v = lookup_variable (fname, flen);
2856
 
2857
@@ -2434,61 +2379,42 @@
2858
     warn_undefined (fname, flen);
2859
 
2860
   if (v == 0 || *v->value == '\0')
2861
-    return o;
2862
-
2863
-  body = alloca (flen + 4);
2864
-  body[0] = '$';
2865
-  body[1] = '(';
2866
-  memcpy (body + 2, fname, flen);
2867
-  body[flen+2] = ')';
2868
-  body[flen+3] = '\0';
2869
-
2870
-  /* Set up arguments $(1) .. $(N).  $(0) is the function name.  */
2871
-
2872
-  push_new_variable_scope ();
2873
-
2874
-  for (i=0; *argv; ++i, ++argv)
2875
-    {
2876
-      char num[11];
2877
-
2878
-      sprintf (num, "%d", i);
2879
-      define_variable (num, strlen (num), *argv, o_automatic, 0);
2880
-    }
2881
-
2882
-  /* If the number of arguments we have is < max_args, it means we're inside
2883
-     a recursive invocation of $(call ...).  Fill in the remaining arguments
2884
-     in the new scope with the empty value, to hide them from this
2885
-     invocation.  */
2886
-
2887
-  for (; i < max_args; ++i)
2888
-    {
2889
-      char num[11];
2890
-
2891
-      sprintf (num, "%d", i);
2892
-      define_variable (num, strlen (num), "", o_automatic, 0);
2893
-    }
2894
+    return 0;
2895
 
2896
-  /* Expand the body in the context of the arguments, adding the result to
2897
-     the variable buffer.  */
2898
+  if (!v->recursive)
2899
+    return vbuffer_write(o, v->value, -1);
2900
 
2901
-  v->exp_count = EXP_COUNT_MAX;
2902
+  /* Count the arguments.  */
2903
+  argc = 0;
2904
+  while (argv[++argc])
2905
+    ;
2906
 
2907
-  saved_args = max_args;
2908
-  max_args = i;
2909
-  o = variable_expand_string (o, body, flen+3);
2910
-  max_args = saved_args;
2911
+  {
2912
+    struct call_frame new_frame;
2913
+    struct call_frame *saved_frame = current_call_frame;
2914
 
2915
-  v->exp_count = 0;
2916
+    /* Replace the current call frame with a new one.  */
2917
+    new_frame.argc = argc;
2918
+    new_frame.argv = argv;
2919
+    current_call_frame = &new_frame;
2920
+
2921
+    /* Expand the variable in the context of the arguments,
2922
+       writing the result into the variable buffer.  */
2923
+    v->exp_count = EXP_COUNT_MAX;
2924
+    ret += vbuffer_expand_variable (o, v);
2925
+    v->exp_count = 0;
2926
 
2927
-  pop_variable_scope ();
2928
+    current_call_frame = saved_frame;
2929
+  }
2930
 
2931
-  return o + strlen (o);
2932
+  return ret;
2933
 }
2934
 
2935
+
2936
 void
2937
 define_new_function(const struct floc *flocp,
2938
                     const char *name, int min, int max, int expand,
2939
-                    char *(*func)(char *, char **, const char *))
2940
+                    size_t (*func)(struct vbuffer *, char **, const char *))
2941
 {
2942
   size_t len = strlen (name);
2943
   struct function_table_entry *ent = xmalloc (sizeof (struct function_table_entry));
2944
Index: guile.c
2945
===================================================================
2946
RCS file: /sources/make/make/guile.c,v
2947
retrieving revision 2.5
2948
diff -u -r2.5 guile.c
2949
--- guile.c	5 Mar 2012 14:10:44 -0000	2.5
2950-
+++ guile.c	9 Apr 2012 09:50:04 -0000
2950+
+++ guile.c	9 Apr 2012 13:34:41 -0000
2951
@@ -86,20 +86,22 @@
2952
 }
2953
 
2954
 /* This is the function registered with make  */
2955
-static char *
2956
-func_guile (char *o, char **argv, const char *funcname UNUSED)
2957
+static size_t
2958
+func_guile (struct vbuffer *o, char **argv, const char *funcname UNUSED)
2959
 {
2960
+  size_t result = 0;
2961
+
2962
   if (argv[0] && argv[0][0] != '\0')
2963
     {
2964
       char *str = scm_with_guile (internal_guile_eval, argv[0]);
2965
       if (str)
2966
         {
2967
-          o = variable_buffer_output (o, str, strlen (str));
2968
+          result += vbuffer_write (o, str, -1);
2969
           free (str);
2970
         }
2971
     }
2972
 
2973
-  return o;
2974
+  return result;
2975
 }
2976
 
2977
 /* ----- Public interface ----- */
2978
Index: main.c
2979
===================================================================
2980
RCS file: /sources/make/make/main.c,v
2981
retrieving revision 1.256
2982
diff -u -r1.256 main.c
2983
--- main.c	5 Mar 2012 14:10:44 -0000	1.256
2984-
+++ main.c	9 Apr 2012 09:50:05 -0000
2984+
+++ main.c	9 Apr 2012 13:34:42 -0000
2985
@@ -1104,6 +1104,8 @@
2986
 
2987
   initialize_global_hash_tables ();
2988
 
2989
+  install_new_expansion_vbuffer();
2990
+
2991
   /* Figure out where we are.  */
2992
 
2993
 #ifdef WINDOWS32
2994
@@ -2277,12 +2279,7 @@
2995
       if (default_goal_var->recursive)
2996
         p = variable_expand (default_goal_var->value);
2997
       else
2998
-        {
2999
-          p = variable_buffer_output (variable_buffer, default_goal_var->value,
3000
-                                      strlen (default_goal_var->value));
3001
-          *p = '\0';
3002
-          p = variable_buffer;
3003
-        }
3004
+	p = default_goal_var->value;
3005
 
3006
       if (*p != '\0')
3007
         {
3008
@@ -2359,6 +2356,16 @@
3009
     if (clock_skew_detected)
3010
       error (NILF,
3011
              _("warning:  Clock skew detected.  Your build may be incomplete."));
3012
+//    error (NILF,
3013
+//	   "memory_usage: %10d total: %8d mallocs, %8d reallocs, %8d strdups",
3014
+//	   nr_mallocs + nr_reallocs + nr_strdups,
3015
+//	   nr_mallocs, nr_reallocs, nr_strdups);
3016
+//    error (NILF,
3017
+//	   "hash: %10d cmps, %8d hash1, %8d hash2",
3018
+//	   nr_cmps, nr_hash1, nr_hash2);
3019
+//    error (NILF,
3020
+//	   "max_lookup_depth: %10d, miss: %10d",
3021
+//	   max_lookup_depth, lookup_miss);
3022
 
3023
     /* Exit.  */
3024
     die (status);
3025
Index: make.h
3026
===================================================================
3027
RCS file: /sources/make/make/make.h,v
3028
retrieving revision 1.157
3029
diff -u -r1.157 make.h
3030
--- make.h	5 Mar 2012 14:10:44 -0000	1.157
3031-
+++ make.h	9 Apr 2012 09:50:05 -0000
3031+
+++ make.h	9 Apr 2012 13:34:42 -0000
3032
@@ -21,6 +21,9 @@
3033
 #undef  HAVE_CONFIG_H
3034
 #define HAVE_CONFIG_H 1
3035
 
3036
+extern int nr_mallocs, nr_reallocs, nr_strdups, nr_cmps, nr_hash1, nr_hash2;
3037
+extern int max_lookup_depth, lookup_miss;
3038
+
3039
 /* Specify we want GNU source code.  This must be defined before any
3040
    system headers are included.  */
3041
 
3042
@@ -406,11 +409,32 @@
3043
 void *xrealloc (void *, unsigned int);
3044
 char *xstrdup (const char *);
3045
 char *xstrndup (const char *, unsigned int);
3046
+
3047
 char *find_next_token (const char **, unsigned int *);
3048
-char *next_token (const char *);
3049
-char *end_of_token (const char *);
3050
+
3051
+/* The following three functions are used extremely frequently,
3052
+   so we try to inline them where possible.  */
3053
+#ifdef __GNUC__
3054
+
3055
+static __inline char *
3056
+next_token (const char *s)
3057
+  { return (char *) s + strspn (s, " \t"); }
3058
+
3059
+static __inline char *
3060
+end_of_token (const char *s)
3061
+  { return (char *) s + strcspn (s, " \t"); }
3062
+
3063
+static __inline char *
3064
+lindex (const char *s, const char *limit, int c)
3065
+  { return memchr (s, c, limit - s); }
3066
+
3067
+#else
3068
+char *next_token (const char *s);
3069
+char *end_of_token (const char *s);
3070
+char *lindex (const char *s, const char *limit, int c);
3071
+#endif /* __GNUC__ */
3072
+
3073
 void collapse_continuations (char *);
3074
-char *lindex (const char *, const char *, int);
3075
 int alpha_compare (const void *, const void *);
3076
 void print_spaces (unsigned int);
3077
 char *find_percent (char *);
3078
Index: misc.c
3079
===================================================================
3080
RCS file: /sources/make/make/misc.c,v
3081
retrieving revision 1.89
3082
diff -u -r1.89 misc.c
3083
--- misc.c	5 Mar 2012 14:10:44 -0000	1.89
3084-
+++ misc.c	9 Apr 2012 09:50:05 -0000
3084+
+++ misc.c	9 Apr 2012 13:34:42 -0000
3085
@@ -360,6 +360,8 @@
3086
 /* Like malloc but get fatal error if memory is exhausted.  */
3087
 /* Don't bother if we're using dmalloc; it provides these for us.  */
3088
 
3089
+int nr_mallocs, nr_reallocs, nr_strdups, nr_cmps, nr_hash1, nr_hash2;
3090
+
3091
 #ifndef HAVE_DMALLOC_H
3092
 
3093
 #undef xmalloc
3094
@@ -372,6 +374,7 @@
3095
 {
3096
   /* Make sure we don't allocate 0, for pre-ISO implementations.  */
3097
   void *result = malloc (size ? size : 1);
3098
+//  ++nr_mallocs;
3099
   if (result == 0)
3100
     fatal (NILF, _("virtual memory exhausted"));
3101
   return result;
3102
@@ -383,6 +386,7 @@
3103
 {
3104
   /* Make sure we don't allocate 0, for pre-ISO implementations.  */
3105
   void *result = calloc (size ? size : 1, 1);
3106
+//  ++nr_mallocs;
3107
   if (result == 0)
3108
     fatal (NILF, _("virtual memory exhausted"));
3109
   return result;
3110
@@ -393,6 +397,7 @@
3111
 xrealloc (void *ptr, unsigned int size)
3112
 {
3113
   void *result;
3114
+//  ++nr_reallocs;
3115
 
3116
   /* Some older implementations of realloc() don't conform to ISO.  */
3117
   if (! size)
3118
@@ -408,6 +413,7 @@
3119
 xstrdup (const char *ptr)
3120
 {
3121
   char *result;
3122
+//  ++nr_strdups;
3123
 
3124
 #ifdef HAVE_STRDUP
3125
   result = strdup (ptr);
3126
@@ -431,6 +437,7 @@
3127
 xstrndup (const char *str, unsigned int length)
3128
 {
3129
   char *result;
3130
+//  ++nr_strdups;
3131
 
3132
 #ifdef HAVE_STRNDUP
3133
   result = strndup (str, length);
3134
@@ -447,6 +454,7 @@
3135
 }
3136
 
3137
 
3138
+#ifndef __GNUC__
3139
 /* Limited INDEX:
3140
    Search through the string STRING, which ends at LIMIT, for the character C.
3141
    Returns a pointer to the first occurrence, or nil if none is found.
3142
@@ -456,11 +464,7 @@
3143
 char *
3144
 lindex (const char *s, const char *limit, int c)
3145
 {
3146
-  while (s < limit)
3147
-    if (*s++ == c)
3148
-      return (char *)(s - 1);
3149
-
3150
-  return 0;
3151
+  return memchr (s, c, limit - s);
3152
 }
3153
 
3154
 /* Return the address of the first whitespace or null in the string S.  */
3155
@@ -468,10 +472,9 @@
3156
 char *
3157
 end_of_token (const char *s)
3158
 {
3159
-  while (*s != '\0' && !isblank ((unsigned char)*s))
3160
-    ++s;
3161
-  return (char *)s;
3162
+  return (char *) s + strcspn (s, " \t");
3163
 }
3164
+#endif /* !__GNUC__ */
3165
 
3166
 #ifdef WINDOWS32
3167
 /*
3168
@@ -503,15 +506,15 @@
3169
 }
3170
 #endif
3171
 
3172
+#ifndef __GNUC__
3173
 /* Return the address of the first nonwhitespace or null in the string S.  */
3174
 
3175
 char *
3176
 next_token (const char *s)
3177
 {
3178
-  while (isblank ((unsigned char)*s))
3179
-    ++s;
3180
-  return (char *)s;
3181
+  return (char *) s + strspn (s, " \t");
3182
 }
3183
+#endif /* !__GNUC__ */
3184
 
3185
 /* Find the next token in PTR; return the address of it, and store the length
3186
    of the token into *LENGTHPTR if LENGTHPTR is not nil.  Set *PTR to the end
3187
Index: read.c
3188
===================================================================
3189
RCS file: /sources/make/make/read.c,v
3190
retrieving revision 1.210
3191
diff -u -r1.210 read.c
3192
--- read.c	5 Mar 2012 14:10:44 -0000	1.210
3193-
+++ read.c	9 Apr 2012 09:50:05 -0000
3193+
+++ read.c	9 Apr 2012 13:34:42 -0000
3194
@@ -566,6 +566,7 @@
3195
   const char *pattern_percent;
3196
   struct floc *fstart;
3197
   struct floc fi;
3198
+  struct vbuffer vbuf;
3199
 
3200
 #define record_waiting_files()						      \
3201
   do									      \
3202
@@ -583,6 +584,8 @@
3203
       pattern = 0;                                                            \
3204
     } while (0)
3205
 
3206
+  vbuffer_init(&vbuf);
3207
+
3208
   pattern_percent = 0;
3209
   cmds_started = tgts_started = 1;
3210
 
3211
@@ -893,6 +896,7 @@
3212
       {
3213
         enum make_word_type wtype;
3214
         char *cmdleft, *semip, *lb_next;
3215
+        unsigned int llen = 0;
3216
         unsigned int plen = 0;
3217
         char *colonp;
3218
         const char *end, *beg; /* Helpers for whitespace stripping. */
3219
@@ -943,7 +947,8 @@
3220
             break;
3221
           }
3222
 
3223
-        p2 = variable_expand_string(NULL, lb_next, wlen);
3224
+        vbuffer_expand_ro (vbuffer_reset(&vbuf), lb_next, wlen);
3225
+        p2 = vbuf.buffer;
3226
 
3227
         while (1)
3228
           {
3229
@@ -955,9 +960,8 @@
3230
 
3231
                 if (cmdleft != 0)
3232
                   {
3233
-                    unsigned long p2_off = p2 - variable_buffer;
3234
-                    unsigned long cmd_off = cmdleft - variable_buffer;
3235
-                    char *pend = p2 + strlen(p2);
3236
+                    unsigned long p2_off = p2 - vbuf.buffer;
3237
+                    unsigned long cmd_off = cmdleft - vbuf.buffer;
3238
 
3239
                     /* Append any remnants of lb, then cut the line short
3240
                        at the semicolon.  */
3241
@@ -967,14 +971,16 @@
3242
                        here, but merely copy, since now you're beyond a ";"
3243
                        and into a command script.  However, the old parser
3244
                        expanded the whole line, so we continue that for
3245
-                       backwards-compatiblity.  Also, it wouldn't be
3246
+                       backwards-compatibility.  Also, it wouldn't be
3247
                        entirely consistent, since we do an unconditional
3248
                        expand below once we know we don't have a
3249
                        target-specific variable. */
3250
-                    (void)variable_expand_string(pend, lb_next, (long)-1);
3251
+                    vbuffer_expand_ro (&vbuf, lb_next, -1);
3252
+
3253
+                    p2 = vbuf.buffer + p2_off;
3254
+                    cmdleft = vbuf.buffer + cmd_off + 1;
3255
+
3256
                     lb_next += strlen(lb_next);
3257
-                    p2 = variable_buffer + p2_off;
3258
-                    cmdleft = variable_buffer + cmd_off + 1;
3259
                   }
3260
               }
3261
 
3262
@@ -996,15 +1002,16 @@
3263
             if (wtype == w_eol)
3264
               break;
3265
 
3266
-            p2 += strlen(p2);
3267
-            *(p2++) = ' ';
3268
-            p2 = variable_expand_string(p2, lb_next, wlen);
3269
+            vbuffer_write(&vbuf, " ", 1);
3270
+            plen = vbuffer_expand_ro (&vbuf, lb_next, wlen);
3271
+            p2 = vbuf.ptr - plen;
3272
+
3273
             /* We don't need to worry about cmdleft here, because if it was
3274
                found in the variable_buffer the entire buffer has already
3275
                been expanded... we'll never get here.  */
3276
           }
3277
 
3278
-        p2 = next_token (variable_buffer);
3279
+        p2 = next_token (vbuf.buffer);
3280
 
3281
         /* If the word we're looking at is EOL, see if there's _anything_
3282
            on the line.  If not, a variable expanded to nothing, so ignore
3283
@@ -1045,14 +1052,13 @@
3284
 
3285
         /* Test to see if it's a target-specific variable.  Copy the rest
3286
            of the buffer over, possibly temporarily (we'll expand it later
3287
-           if it's not a target-specific variable).  PLEN saves the length
3288
-           of the unparsed section of p2, for later.  */
3289
+           if it's not a target-specific variable).  LLEN saves the length
3290
+           of the copied string, to know how many bytes to discard later.  */
3291
         if (*lb_next != '\0')
3292
           {
3293
-            unsigned int l = p2 - variable_buffer;
3294
-            plen = strlen (p2);
3295
-            variable_buffer_output (p2+plen, lb_next, strlen (lb_next)+1);
3296
-            p2 = variable_buffer + l;
3297
+            unsigned long p2_off = p2 - vbuf.buffer;
3298
+            llen = vbuffer_write (&vbuf, lb_next, -1);
3299
+            p2 = vbuf.buffer + p2_off;
3300
           }
3301
 
3302
         p2 = parse_var_assignment (p2, &vmod);
3303
@@ -1062,12 +1068,11 @@
3304
                after it.  */
3305
             if (semip)
3306
               {
3307
-                unsigned int l = p - variable_buffer;
3308
+                unsigned long p2_off = p2 - vbuf.buffer;
3309
                 *(--semip) = ';';
3310
                 collapse_continuations (semip);
3311
-                variable_buffer_output (p2 + strlen (p2),
3312
-                                        semip, strlen (semip)+1);
3313
-                p = variable_buffer + l;
3314
+                vbuffer_write (&vbuf, semip, -1);
3315
+                p2 = vbuf.buffer + p2_off;
3316
               }
3317
             record_target_var (filenames, p2,
3318
                                vmod.override_v ? o_override : o_file,
3319
@@ -1086,12 +1091,14 @@
3320
         /* We have some targets, so don't ignore the following commands.  */
3321
         no_targets = 0;
3322
 
3323
-        /* Expand the dependencies, etc.  */
3324
+        /* Expand the dependencies, etc.
3325
+           P2 still point past the colon.  */
3326
         if (*lb_next != '\0')
3327
           {
3328
-            unsigned int l = p2 - variable_buffer;
3329
-            (void) variable_expand_string (p2 + plen, lb_next, (long)-1);
3330
-            p2 = variable_buffer + l;
3331
+            unsigned long p2_off = p2 - vbuf.buffer;
3332
+            vbuffer_unwrite (&vbuf, llen);
3333
+            vbuffer_expand_ro (&vbuf, lb_next, -1);
3334
+            p2 = vbuf.buffer + p2_off;
3335
 
3336
             /* Look for a semicolon in the expanded line.  */
3337
             if (cmdleft == 0)
3338
@@ -1281,8 +1288,6 @@
3339
       record_waiting_files ();
3340
     }
3341
 
3342
-#undef word1eq
3343
-
3344
   if (conditionals->if_cmds)
3345
     fatal (fstart, _("missing 'endif'"));
3346
 
3347
@@ -1292,7 +1297,13 @@
3348
   if (collapsed)
3349
     free (collapsed);
3350
   free (commands);
3351
+
3352
+  vbuffer_free(&vbuf);
3353
+
3354
+#undef record_waiting_files
3355
 }
3356
+
3357
+#undef word1eq
3358
 
3359
 
3360
 /* Remove comments from LINE.
3361
@@ -1842,6 +1853,7 @@
3362
   struct dep *deps;
3363
   const char *implicit_percent;
3364
   const char *name;
3365
+  struct vbuffer patbuf;
3366
 
3367
   /* If we've already snapped deps, that means we're in an eval being
3368
      resolved after the makefiles have been read in.  We can't add more rules
3369
@@ -1945,6 +1957,7 @@
3370
       return;
3371
     }
3372
 
3373
+  vbuffer_init (&patbuf);
3374
 
3375
   /* Walk through each target and create it in the database.
3376
      We already set up the first target, above.  */
3377
@@ -2057,10 +2070,12 @@
3378
       if (pattern)
3379
         {
3380
           static const char *percent = "%";
3381
-          char *buffer = variable_expand ("");
3382
-          char *o = patsubst_expand_pat (buffer, name, pattern, percent,
3383
-                                         pattern_percent+1, percent+1);
3384
-          f->stem = strcache_add_len (buffer, o - buffer);
3385
+          size_t len;
3386
+
3387
+          len = patsubst_expand_pat (vbuffer_reset(&patbuf), name,
3388
+				     pattern, percent,
3389
+				     pattern_percent+1, percent+1);
3390
+          f->stem = strcache_add_len (patbuf.buffer, len);
3391
           if (this)
3392
             {
3393
               if (! this->need_2nd_expansion)
3394
@@ -2112,6 +2127,8 @@
3395
       if (find_percent_cached (&name))
3396
         fatal (flocp, _("mixed implicit and normal rules"));
3397
     }
3398
+
3399
+  vbuffer_free (&patbuf);
3400
 }
3401
 
3402
 /* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero).
3403
Index: remake.c
3404
===================================================================
3405
RCS file: /sources/make/make/remake.c,v
3406
retrieving revision 1.153
3407
diff -u -r1.153 remake.c
3408
--- remake.c	5 Mar 2012 14:10:45 -0000	1.153
3409-
+++ remake.c	9 Apr 2012 09:50:05 -0000
3409+
+++ remake.c	9 Apr 2012 13:34:42 -0000
3410
@@ -1534,12 +1534,14 @@
3411
   const char *p2;
3412
   unsigned int len;
3413
   unsigned int liblen;
3414
+  struct vbuffer vbuf;
3415
 
3416
   /* Information about the earliest (in the vpath sequence) match.  */
3417
   unsigned int best_vpath = 0, best_path = 0;
3418
 
3419
   char **dp;
3420
 
3421
+  vbuffer_init(&vbuf);
3422
   libpatterns = xstrdup (variable_expand ("$(.LIBPATTERNS)"));
3423
 
3424
   /* Skip the '-l'.  */
3425
@@ -1556,28 +1558,30 @@
3426
       static unsigned int buflen = 0;
3427
       static int libdir_maxlen = -1;
3428
       static unsigned int std_dirs = 0;
3429
-      char *libbuf = variable_expand ("");
3430
+      char *libbuf;
3431
 
3432
       /* Expand the pattern using LIB as a replacement.  */
3433
       {
3434
 	char c = p[len];
3435
-	char *p3, *p4;
3436
+	char *percent;
3437
 
3438
 	p[len] = '\0';
3439
-	p3 = find_percent (p);
3440
-	if (!p3)
3441
+	percent = find_percent (p);
3442
+	if (!percent)
3443
 	  {
3444
 	    /* Give a warning if there is no pattern.  */
3445
 	    error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
3446
             p[len] = c;
3447
 	    continue;
3448
 	  }
3449
-	p4 = variable_buffer_output (libbuf, p, p3-p);
3450
-	p4 = variable_buffer_output (p4, lib, liblen);
3451
-	p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
3452
+	vbuffer_write (&vbuf, p, percent-p);
3453
+	vbuffer_write (&vbuf, lib, liblen);
3454
+	vbuffer_write (&vbuf, percent+1, len - (percent-p));
3455
 	p[len] = c;
3456
       }
3457
 
3458
+      libbuf = vbuf.buffer;
3459
+
3460
       /* Look first for 'libNAME.a' in the current directory.  */
3461
       mtime = name_mtime (libbuf);
3462
       if (mtime != NONEXISTENT_MTIME)
3463
@@ -1660,5 +1664,7 @@
3464
     }
3465
 
3466
   free (libpatterns);
3467
+  vbuffer_free(&vbuf);
3468
+
3469
   return file;
3470
 }
3471
Index: variable.c
3472
===================================================================
3473
RCS file: /sources/make/make/variable.c,v
3474
retrieving revision 1.112
3475
diff -u -r1.112 variable.c
3476
--- variable.c	5 Mar 2012 14:10:45 -0000	1.112
3477-
+++ variable.c	9 Apr 2012 09:50:05 -0000
3477+
+++ variable.c	9 Apr 2012 13:34:42 -0000
3478
@@ -172,6 +172,7 @@
3479
 static struct variable_set_list global_setlist
3480
   = { 0, &global_variable_set, 0 };
3481
 struct variable_set_list *current_variable_set_list = &global_setlist;
3482
+
3483
 
3484
 /* Implement variables.  */
3485
 
3486
@@ -182,18 +183,19 @@
3487
 	     variable_hash_1, variable_hash_2, variable_hash_cmp);
3488
 }
3489
 
3490
-/* Define variable named NAME with value VALUE in SET.  VALUE is copied.
3491
+/* Define variable named NAME with value VALUE in SET.  VALUE is NOT copied,
3492
+   and after a call client must check whether the VALUE is assigned or not.
3493
    LENGTH is the length of NAME, which does not need to be null-terminated.
3494
    ORIGIN specifies the origin of the variable (makefile, command line
3495
    or environment).
3496
    If RECURSIVE is nonzero a flag is set in the variable saying
3497
    that it should be recursively re-expanded.  */
3498
 
3499
-struct variable *
3500
-define_variable_in_set (const char *name, unsigned int length,
3501
-                        const char *value, enum variable_origin origin,
3502
-                        int recursive, struct variable_set *set,
3503
-                        const struct floc *flocp)
3504
+static struct variable *
3505
+define_variable_in_set_allocated (const char *name, unsigned int length,
3506
+				  const char *value, enum variable_origin origin,
3507
+				  int recursive, struct variable_set *set,
3508
+				  const struct floc *flocp)
3509
 {
3510
   struct variable *v;
3511
   struct variable **var_slot;
3512
@@ -224,7 +226,7 @@
3513
 	{
3514
 	  if (v->value != 0)
3515
 	    free (v->value);
3516
-	  v->value = xstrdup (value);
3517
+	  v->value = (char *) value;
3518
           if (flocp != 0)
3519
             v->fileinfo = *flocp;
3520
           else
3521
@@ -241,7 +243,7 @@
3522
   v->name = xstrndup (name, length);
3523
   v->length = length;
3524
   hash_insert_at (&set->table, v, var_slot);
3525
-  v->value = xstrdup (value);
3526
+  v->value = (char *) value;
3527
   if (flocp != 0)
3528
     v->fileinfo = *flocp;
3529
   else
3530
@@ -254,6 +256,8 @@
3531
   v->per_target = 0;
3532
   v->append = 0;
3533
   v->private_var = 0;
3534
+  v->volatile_var = 0;
3535
+  v->global = set == &global_variable_set;
3536
   v->export = v_default;
3537
 
3538
   v->exportable = 1;
3539
@@ -275,6 +279,71 @@
3540
 }
3541
 
3542
 
3543
+struct variable *
3544
+define_variable_in_set (const char *name, unsigned int length,
3545
+                        const char *value, enum variable_origin origin,
3546
+                        int recursive, struct variable_set *set,
3547
+                        const struct floc *flocp)
3548
+{
3549
+  struct variable *v = define_variable_in_set_allocated (name, length, value,
3550
+							 origin, recursive,
3551
+							 set, flocp);
3552
+  /* Check if the new value was really assigned.  */
3553
+  if (v->value == value)
3554
+    v->value = xstrdup (value);
3555
+
3556
+  return v;
3557
+}
3558
+
3559
+struct variable *
3560
+push_scoped_variable (struct variable *v, char *name, unsigned int length)
3561
+{
3562
+  struct variable_set *set = current_variable_set_list->set;
3563
+  struct variable *old_var;
3564
+  struct variable **var_slot;
3565
+
3566
+  v->name   = name;
3567
+  v->length = length;
3568
+  var_slot = (struct variable **) hash_find_slot (&set->table, v);
3569
+
3570
+  old_var = *var_slot;
3571
+  if (HASH_VACANT (old_var))
3572
+    old_var = NULL;
3573
+
3574
+  hash_insert_at (&set->table, v, var_slot);
3575
+
3576
+  v->fileinfo.filenm = NULL;
3577
+  v->origin = o_automatic;
3578
+  v->recursive = 0;
3579
+  v->special = 0;
3580
+  v->expanding = 0;
3581
+  v->exp_count = 0;
3582
+  v->per_target = 0;
3583
+  v->append = 0;
3584
+  v->private_var = 0;
3585
+  v->volatile_var = 0;
3586
+  v->exportable = 0;
3587
+  v->export = v_default;
3588
+
3589
+  v->global = old_var ? old_var->global : 0;
3590
+
3591
+  return old_var;
3592
+}
3593
+
3594
+void
3595
+pop_scoped_variable (struct variable *v, struct variable *old_var)
3596
+{
3597
+  struct variable_set *set = current_variable_set_list->set;
3598
+  struct variable **var_slot;
3599
+
3600
+  var_slot = (struct variable **) hash_find_slot (&set->table, v);
3601
+
3602
+  if (old_var)
3603
+    hash_insert_at (&set->table, old_var, var_slot);
3604
+  else
3605
+    hash_delete_at (&set->table, var_slot);
3606
+}
3607
+
3608
 /* Undefine variable named NAME in SET. LENGTH is the length of NAME, which
3609
    does not need to be null-terminated. ORIGIN specifies the origin of the
3610
    variable (makefile, command line or environment). */
3611
@@ -361,7 +430,8 @@
3612
   */
3613
 
3614
   if (streq (var->name, ".VARIABLES")
3615
-      && global_variable_set.table.ht_fill != last_var_count)
3616
+//      && global_variable_set.table.ht_fill != last_var_count
3617
+      )
3618
     {
3619
       unsigned long max = EXPANSION_INCREMENT (strlen (var->value));
3620
       unsigned long len;
3621
@@ -381,6 +451,9 @@
3622
             struct variable *v = *vp;
3623
             int l = v->length;
3624
 
3625
+            if (!v->global)
3626
+              continue;
3627
+
3628
             len += l + 1;
3629
             if (len > max)
3630
               {
3631
@@ -408,26 +481,89 @@
3632
 }
3633
 
3634
 
3635
+static struct call_frame empty_call_frame;
3636
+struct call_frame *current_call_frame = &empty_call_frame;
3637
+
3638
+#ifdef __GNUC__
3639
+__inline
3640
+#endif
3641
+char **
3642
+lookup_call_argument_value (const char *name, unsigned int length)
3643
+{
3644
+  int num = 0;
3645
+  const char *p;
3646
+
3647
+  /* Hot path: a single digit.  */
3648
+  if (length == 1
3649
+      && (unsigned) *name - '0' < (unsigned) current_call_frame->argc)
3650
+    return current_call_frame->argv + (*name - '0');
3651
+
3652
+  /* Empty name or name with leading zeroes is not numeric.  */
3653
+  if (length == 0 || *name == '0')
3654
+    return NULL;
3655
+
3656
+  for (p=name; length != 0 && ISDIGIT(*p); --length, ++p)
3657
+    {
3658
+      num *= 10;
3659
+      num += *p - '0';
3660
+    }
3661
+
3662
+  if (length != 0 || num >= current_call_frame->argc)
3663
+    return NULL;
3664
+
3665
+  return current_call_frame->argv + num;
3666
+}
3667
+
3668
+#define CALL_ARGUMENT_INIT \
3669
+  { \
3670
+    /* name */ "",          /* value */ "",   \
3671
+    /* file */ { NULL, 0},  /* length */ 0,   \
3672
+    /* recursive   */ 0, /* append      */ 0, \
3673
+    /* conditional */ 0, /* per_target  */ 0, \
3674
+    /* special     */ 0, /* exportable  */ 0, \
3675
+    /* expanding   */ 0, /* private     */ 0, \
3676
+    /* volatile    */ 1, /* global      */ 0, \
3677
+    /* exp_count   */ 0,                      \
3678
+    f_simple, o_automatic, v_default,         \
3679
+  }
3680
+
3681
 /* Lookup a variable whose name is a string starting at NAME
3682
    and with LENGTH chars.  NAME need not be null-terminated.
3683
    Returns address of the 'struct variable' containing all info
3684
-   on the variable, or nil if no such variable is defined.  */
3685
+   on the variable, or nil if no such variable is defined.
3686
+   In case when the variable is an argument of the current call frame,
3687
+   the 'struct variable' refers to the shared statically allocated instance,
3688
+   and its 'volatile_var' field is set to 1.  */
3689
 
3690
 struct variable *
3691
 lookup_variable (const char *name, unsigned int length)
3692
 {
3693
+  static struct variable call_argument = CALL_ARGUMENT_INIT;
3694
   const struct variable_set_list *setlist;
3695
+  struct variable *v = NULL;
3696
   struct variable var_key;
3697
   int is_parent = 0;
3698
 
3699
   var_key.name = (char *) name;
3700
   var_key.length = length;
3701
 
3702
+  if (ISDIGIT(*name))
3703
+    {
3704
+      char **argp = lookup_call_argument_value (name, length);
3705
+      if (argp && *argp)
3706
+	{
3707
+	  v = &call_argument;
3708
+	  v->value = *argp;
3709
+	  v->name = (char *) name;
3710
+	  v->length = length;
3711
+	  return v;
3712
+	}
3713
+    }
3714
+
3715
   for (setlist = current_variable_set_list;
3716
        setlist != 0; setlist = setlist->next)
3717
     {
3718
       const struct variable_set *set = setlist->set;
3719
-      struct variable *v;
3720
 
3721
       v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
3722
       if (v && (!is_parent || !v->private_var))
3723
@@ -494,6 +630,7 @@
3724
 
3725
   return 0;
3726
 }
3727
+
3728
 
3729
 /* Lookup a variable whose name is a string starting at NAME
3730
    and with LENGTH chars in set SET.  NAME need not be null-terminated.
3731
@@ -512,6 +649,7 @@
3732
   return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
3733
 }
3734
 
3735
+
3736
 /* Initialize FILE's variable set list.  If FILE already has a variable set
3737
    list, the topmost variable set is left intact, but the the rest of the
3738
    chain is replaced with FILE->parent's setlist.  If FILE is a double-colon
3739
@@ -621,8 +759,6 @@
3740
     }
3741
 }
3742
 
3743
-/* Pop the top set off the current variable set list,
3744
-   and free all its storage.  */
3745
 
3746
 struct variable_set_list *
3747
 create_new_variable_set (void)
3748
@@ -660,66 +796,6 @@
3749
   free (list);
3750
 }
3751
 
3752
-/* Create a new variable set and push it on the current setlist.
3753
-   If we're pushing a global scope (that is, the current scope is the global
3754
-   scope) then we need to "push" it the other way: file variable sets point
3755
-   directly to the global_setlist so we need to replace that with the new one.
3756
- */
3757
-
3758
-struct variable_set_list *
3759
-push_new_variable_scope (void)
3760
-{
3761
-  current_variable_set_list = create_new_variable_set();
3762
-  if (current_variable_set_list->next == &global_setlist)
3763
-    {
3764
-      /* It was the global, so instead of new -> &global we want to replace
3765
-         &global with the new one and have &global -> new, with current still
3766
-         pointing to &global  */
3767
-      struct variable_set *set = current_variable_set_list->set;
3768
-      current_variable_set_list->set = global_setlist.set;
3769
-      global_setlist.set = set;
3770
-      current_variable_set_list->next = global_setlist.next;
3771
-      global_setlist.next = current_variable_set_list;
3772
-      current_variable_set_list = &global_setlist;
3773
-    }
3774
-  return (current_variable_set_list);
3775
-}
3776
-
3777
-void
3778
-pop_variable_scope (void)
3779
-{
3780
-  struct variable_set_list *setlist;
3781
-  struct variable_set *set;
3782
-
3783
-  /* Can't call this if there's no scope to pop!  */
3784
-  assert(current_variable_set_list->next != NULL);
3785
-
3786
-  if (current_variable_set_list != &global_setlist)
3787
-    {
3788
-      /* We're not pointing to the global setlist, so pop this one.  */
3789
-      setlist = current_variable_set_list;
3790
-      set = setlist->set;
3791
-      current_variable_set_list = setlist->next;
3792
-    }
3793
-  else
3794
-    {
3795
-      /* This set is the one in the global_setlist, but there is another global
3796
-         set beyond that.  We want to copy that set to global_setlist, then
3797
-         delete what used to be in global_setlist.  */
3798
-      setlist = global_setlist.next;
3799
-      set = global_setlist.set;
3800
-      global_setlist.set = setlist->set;
3801
-      global_setlist.next = setlist->next;
3802
-      global_setlist.next_is_parent = setlist->next_is_parent;
3803
-    }
3804
-
3805
-  /* Free the one we no longer need.  */
3806
-  free (setlist);
3807
-  hash_map (&set->table, free_variable_name_and_value);
3808
-  hash_free (&set->table, 1);
3809
-  free (set);
3810
-}
3811
-
3812
 /* Merge FROM_SET into TO_SET, freeing unused storage in FROM_SET.  */
3813
 
3814
 static void
3815
@@ -966,6 +1042,7 @@
3816
   struct variable makelevel_key;
3817
   char **result_0;
3818
   char **result;
3819
+  struct vbuffer vbuf;
3820
 
3821
   if (file == 0)
3822
     set_list = current_variable_set_list;
3823
@@ -1053,6 +1130,8 @@
3824
 
3825
   result = result_0 = xmalloc ((table.ht_fill + 2) * sizeof (char *));
3826
 
3827
+  vbuffer_init (&vbuf);
3828
+
3829
   v_slot = (struct variable **) table.ht_vec;
3830
   v_end = v_slot + table.ht_size;
3831
   for ( ; v_slot < v_end; v_slot++)
3832
@@ -1060,32 +1139,30 @@
3833
       {
3834
 	struct variable *v = *v_slot;
3835
 
3836
+	vbuffer_reset (&vbuf);
3837
+
3838
+	vbuffer_write (&vbuf, v->name, -1);
3839
+	vbuffer_write (&vbuf, "=", 1);
3840
+
3841
 	/* If V is recursively expanded and didn't come from the environment,
3842
 	   expand its value.  If it came from the environment, it should
3843
 	   go back into the environment unchanged.  */
3844
 	if (v->recursive
3845
 	    && v->origin != o_env && v->origin != o_env_override)
3846
-	  {
3847
-	    char *value = recursively_expand_for_file (v, file);
3848
-#ifdef WINDOWS32
3849
-	    if (strcmp(v->name, "Path") == 0 ||
3850
-		strcmp(v->name, "PATH") == 0)
3851
-	      convert_Path_to_windows32(value, ';');
3852
-#endif
3853
-	    *result++ = xstrdup (concat (3, v->name, "=", value));
3854
-	    free (value);
3855
-	  }
3856
+	  vbuffer_expand_variable_for_file (&vbuf, v, file);
3857
 	else
3858
-	  {
3859
+	  vbuffer_write (&vbuf, v->value, -1);
3860
+
3861
 #ifdef WINDOWS32
3862
-            if (strcmp(v->name, "Path") == 0 ||
3863
-                strcmp(v->name, "PATH") == 0)
3864
-              convert_Path_to_windows32(v->value, ';');
3865
+	if (strcmp(v->name, "Path") == 0 ||
3866
+	    strcmp(v->name, "PATH") == 0)
3867
+	  convert_Path_to_windows32(value, ';');
3868
 #endif
3869
-	    *result++ = xstrdup (concat (3, v->name, "=", v->value));
3870
-	  }
3871
+	*result++ = xstrdup (vbuf.buffer);
3872
       }
3873
 
3874
+  vbuffer_free (&vbuf);
3875
+
3876
   *result = xmalloc (100);
3877
   sprintf (*result, "%s=%u", MAKELEVEL_NAME, makelevel + 1);
3878
   *++result = 0;
3879
@@ -1116,20 +1193,14 @@
3880
 char *
3881
 shell_result (const char *p)
3882
 {
3883
-  char *buf;
3884
-  unsigned int len;
3885
+  struct vbuffer vbuf;
3886
   char *args[2];
3887
-  char *result;
3888
-
3889
-  install_variable_buffer (&buf, &len);
3890
 
3891
   args[0] = (char *) p;
3892
   args[1] = NULL;
3893
-  variable_buffer_output (func_shell_base (variable_buffer, args, 0), "\0", 1);
3894
-  result = strdup (variable_buffer);
3895
+  func_shell_base (vbuffer_init(&vbuf), args, 0);
3896
 
3897
-  restore_variable_buffer (buf, len);
3898
-  return result;
3899
+  return vbuf.buffer;
3900
 }
3901
 
3902
 /* Given a variable, a value, and a flavor, define the variable.
3903
@@ -1145,6 +1216,7 @@
3904
   struct variable *v;
3905
   int append = 0;
3906
   int conditional = 0;
3907
+  unsigned int varlen = strlen (varname);
3908
 
3909
   /* Calculate the variable's new value in VALUE.  */
3910
 
3911
@@ -1174,7 +1246,7 @@
3912
     case f_conditional:
3913
       /* A conditional variable definition "var ?= value".
3914
          The value is set IFF the variable is not defined yet. */
3915
-      v = lookup_variable (varname, strlen (varname));
3916
+      v = lookup_variable (varname, varlen);
3917
       if (v)
3918
         return v->special ? set_special_var (v) : v;
3919
 
3920
@@ -1193,7 +1265,7 @@
3921
         if (target_var)
3922
           {
3923
             append = 1;
3924
-            v = lookup_variable_in_set (varname, strlen (varname),
3925
+            v = lookup_variable_in_set (varname, varlen,
3926
                                         current_variable_set_list->set);
3927
 
3928
             /* Don't append from the global set if a previous non-appending
3929
@@ -1202,7 +1274,7 @@
3930
               append = 0;
3931
           }
3932
         else
3933
-          v = lookup_variable (varname, strlen (varname));
3934
+          v = lookup_variable (varname, varlen);
3935
 
3936
         if (v == 0)
3937
           {
3938
@@ -1274,7 +1346,7 @@
3939
             if (*tp == '\\')
3940
               *tp = '/';
3941
 
3942
-	  v = define_variable_loc (varname, strlen (varname),
3943
+	  v = define_variable_loc (varname, varlen,
3944
                                    shellpath, origin, flavor == f_recursive,
3945
                                    flocp);
3946
 	}
3947
@@ -1314,12 +1386,12 @@
3948
                 if (*tp == '\\')
3949
                   *tp = '/';
3950
 
3951
-	      v = define_variable_loc (varname, strlen (varname),
3952
+	      v = define_variable_loc (varname, varlen,
3953
                                        shellpath, origin,
3954
                                        flavor == f_recursive, flocp);
3955
 	    }
3956
 	  else
3957
-	    v = lookup_variable (varname, strlen (varname));
3958
+	    v = lookup_variable (varname, varlen);
3959
 
3960
 	  free (path_string);
3961
 	}
3962
@@ -1338,7 +1410,7 @@
3963
 
3964
       if (find_and_set_default_shell (p))
3965
         {
3966
-          v = define_variable_in_set (varname, strlen (varname), default_shell,
3967
+          v = define_variable_in_set (varname, varlen, default_shell,
3968
                                       origin, flavor == f_recursive,
3969
                                       (target_var
3970
                                        ? current_variable_set_list->set
3971
@@ -1354,7 +1426,7 @@
3972
 
3973
           if (find_and_set_default_shell (alloc_value))
3974
             {
3975
-              v = define_variable_in_set (varname, strlen (varname), p,
3976
+              v = define_variable_in_set (varname, varlen, p,
3977
                                           origin, flavor == f_recursive,
3978
                                           (target_var
3979
                                            ? current_variable_set_list->set
3980
@@ -1363,7 +1435,7 @@
3981
               no_default_sh_exe = 0;
3982
             }
3983
           else
3984
-            v = lookup_variable (varname, strlen (varname));
3985
+            v = lookup_variable (varname, varlen);
3986
 
3987
           if (tp)
3988
             free (tp);
3989
@@ -1372,17 +1444,29 @@
3990
   else
3991
 #endif
3992
 
3993
-  /* If we are defining variables inside an $(eval ...), we might have a
3994
-     different variable context pushed, not the global context (maybe we're
3995
-     inside a $(call ...) or something.  Since this function is only ever
3996
-     invoked in places where we want to define globally visible variables,
3997
-     make sure we define this variable in the global set.  */
3998
-
3999
-  v = define_variable_in_set (varname, strlen (varname), p,
4000
-                              origin, flavor == f_recursive,
4001
-                              (target_var
4002
-                               ? current_variable_set_list->set : NULL),
4003
-                              flocp);
4004
+    {
4005
+      /* If we are defining variables inside an $(eval ...), we might have a
4006
+	 different variable context pushed, not the global context (maybe we're
4007
+	 inside a $(call ...) or something.  Since this function is only ever
4008
+	 invoked in places where we want to define globally visible variables,
4009
+	 make sure we define this variable in the global set.  */
4010
+
4011
+      v = define_variable_in_set_allocated (varname, varlen, alloc_value,
4012
+					    origin, flavor == f_recursive,
4013
+					    (target_var
4014
+					     ? current_variable_set_list->set
4015
+					     : NULL),
4016
+					    flocp);
4017
+
4018
+      if (v->value == alloc_value)
4019
+	{
4020
+	  if (!alloc_value)
4021
+	    v->value = xstrdup (p);
4022
+	  else
4023
+	    alloc_value = NULL;
4024
+	}
4025
+    }
4026
+
4027
   v->append = append;
4028
   v->conditional = conditional;
4029
 
4030
Index: variable.h
4031
===================================================================
4032
RCS file: /sources/make/make/variable.h,v
4033
retrieving revision 1.51
4034
diff -u -r1.51 variable.h
4035
--- variable.h	5 Mar 2012 14:10:45 -0000	1.51
4036-
+++ variable.h	9 Apr 2012 09:50:05 -0000
4036+
+++ variable.h	9 Apr 2012 13:34:42 -0000
4037
@@ -44,9 +44,11 @@
4038
    Each bucket of the hash table is a chain of these,
4039
    chained through 'next'.  */
4040
 
4041
-#define EXP_COUNT_BITS  15      /* This gets all the bitfields into 32 bits */
4042
+#define EXP_COUNT_BITS  14      /* This gets all the bitfields into 32 bits */
4043
 #define EXP_COUNT_MAX   ((1<<EXP_COUNT_BITS)-1)
4044
 
4045
+#define MAX_ALLOCA_SIZE 1024
4046
+
4047
 struct variable
4048
   {
4049
     char *name;			/* Variable name.  */
4050
@@ -64,6 +66,10 @@
4051
     unsigned int expanding:1;	/* Nonzero if currently being expanded.  */
4052
     unsigned int private_var:1; /* Nonzero avoids inheritance of this
4053
                                    target-specific variable.  */
4054
+    unsigned int volatile_var:1;/* Nonzero if the state can change across
4055
+				   certain function calls.  */
4056
+    unsigned int global:1;      /* Nonzero if this should be included in
4057
+				   $(.VARIABLES) list.  */
4058
     unsigned int exp_count:EXP_COUNT_BITS;
4059
                                 /* If >1, allow this many self-referential
4060
                                    expansions.  */
4061
@@ -107,44 +113,80 @@
4062
     struct variable variable;
4063
   };
4064
 
4065
-extern char *variable_buffer;
4066
+/* Structure used to hold the result of variable expansion.  */
4067
+
4068
+struct vbuffer
4069
+  {
4070
+    char *ptr;    /* Current position pointing inside the buffer.  */
4071
+    char *buffer; /* Start of the entire buffer.  */
4072
+    size_t size;  /* Size of the allocated buffer.  */
4073
+  };
4074
+
4075
+struct call_frame
4076
+  {
4077
+    int argc;
4078
+    char **argv;
4079
+  };
4080
+
4081
 extern struct variable_set_list *current_variable_set_list;
4082
 extern struct variable *default_goal_var;
4083
 
4084
+extern struct call_frame *current_call_frame;
4085
+
4086
+struct vbuffer *vbuffer_init  (struct vbuffer *vbuf);
4087
+struct vbuffer *vbuffer_reset (struct vbuffer *vbuf);
4088
+
4089
+#define vbuffer_free(vbuf) \
4090
+  free ((vbuf)->buffer)
4091
+
4092
+size_t vbuffer_reserve (struct vbuffer *o, size_t len);
4093
+
4094
+size_t vbuffer_write (struct vbuffer *o, const char *str, ssize_t len);
4095
+size_t vbuffer_unwrite (struct vbuffer *o, ssize_t len);
4096
+
4097
+size_t vbuffer_expand (struct vbuffer *o, char *str, ssize_t len);
4098
+size_t vbuffer_expand_for_file (struct vbuffer *o, char *str, ssize_t len,
4099
+				struct file *file);
4100
+
4101
+size_t vbuffer_expand_ro (struct vbuffer *o, const char *str, ssize_t len);
4102
+size_t vbuffer_expand_ro_for_file (struct vbuffer *o, const char *str,
4103
+				   ssize_t len, struct file *file);
4104
+
4105
+#define vbuffer_expand_variable(o, v) \
4106
+  vbuffer_expand_variable_for_file (o, v, NULL)
4107
+size_t vbuffer_expand_variable_for_file (struct vbuffer *o,
4108
+                                         struct variable *v,
4109
+                                         struct file *file);
4110
+
4111
+struct vbuffer *install_new_expansion_vbuffer (void);
4112
+void restore_expansion_vbuffer (struct vbuffer *old_vbuf);
4113
+
4114
 /* expand.c */
4115
-char *variable_buffer_output (char *ptr, const char *string, unsigned int length);
4116
+char *expand_argument (const char *str, const char *end);
4117
 char *variable_expand (const char *line);
4118
 char *variable_expand_for_file (const char *line, struct file *file);
4119
+char *allocated_variable_expand (const char *line);
4120
 char *allocated_variable_expand_for_file (const char *line, struct file *file);
4121
-#define	allocated_variable_expand(line) \
4122
-  allocated_variable_expand_for_file (line, (struct file *) 0)
4123
-char *expand_argument (const char *str, const char *end);
4124
-char *variable_expand_string (char *line, const char *string, long length);
4125
-void install_variable_buffer (char **bufp, unsigned int *lenp);
4126
-void restore_variable_buffer (char *buf, unsigned int len);
4127
+#define recursively_expand(v)   recursively_expand_for_file (v, NULL)
4128
+char *recursively_expand_for_file (struct variable *v, struct file *file);
4129
 
4130
 /* function.c */
4131
-int handle_function (char **op, const char **stringp);
4132
+int handle_function (struct vbuffer *vbuf, char **stringp);
4133
 int pattern_matches (const char *pattern, const char *percent, const char *str);
4134
-char *subst_expand (char *o, const char *text, const char *subst,
4135
-                    const char *replace, unsigned int slen, unsigned int rlen,
4136
-                    int by_word);
4137
-char *patsubst_expand_pat (char *o, const char *text, const char *pattern,
4138
-                           const char *replace, const char *pattern_percent,
4139
-                           const char *replace_percent);
4140
-char *patsubst_expand (char *o, const char *text, char *pattern, char *replace);
4141
-char *func_shell_base (char *o, char **argv, int trim_newlines);
4142
-
4143
-
4144
-/* expand.c */
4145
-char *recursively_expand_for_file (struct variable *v, struct file *file);
4146
-#define recursively_expand(v)   recursively_expand_for_file (v, NULL)
4147
+size_t subst_expand (struct vbuffer *vbuf, const char *text, const char *subst,
4148
+                     const char *replace, unsigned int slen, unsigned int rlen,
4149
+                     int by_word);
4150
+size_t patsubst_expand_pat (struct vbuffer *vbuf, const char *text,
4151
+                            const char *pattern, const char *replace,
4152
+                            const char *pattern_percent,
4153
+                            const char *replace_percent);
4154
+size_t patsubst_expand (struct vbuffer *vbuf, const char *text, char *pattern,
4155
+                        char *replace);
4156
+size_t func_shell_base (struct vbuffer *vbuf, char **argv, int trim_newlines);
4157
 
4158
 /* variable.c */
4159
 struct variable_set_list *create_new_variable_set (void);
4160
 void free_variable_set (struct variable_set_list *);
4161
-struct variable_set_list *push_new_variable_scope (void);
4162
-void pop_variable_scope (void);
4163
 void define_automatic_variables (void);
4164
 void initialize_file_variables (struct file *file, int reading);
4165
 void print_file_variables (const struct file *file);
4166
@@ -167,10 +209,11 @@
4167
 void hash_init_function_table (void);
4168
 void define_new_function(const struct floc *flocp,
4169
                          const char *name, int min, int max, int expand,
4170
-                         char *(*func)(char *, char **, const char *));
4171
+                         size_t (*func)(struct vbuffer *, char **, const char *));
4172
 struct variable *lookup_variable (const char *name, unsigned int length);
4173
 struct variable *lookup_variable_in_set (const char *name, unsigned int length,
4174
                                          const struct variable_set *set);
4175
+char **lookup_call_argument_value (const char *name, unsigned int length);
4176
 
4177
 struct variable *define_variable_in_set (const char *name, unsigned int length,
4178
                                          const char *value,
4179
@@ -207,6 +250,10 @@
4180
 #define define_variable_for_file(n,l,v,o,r,f) \
4181
           define_variable_in_set((n),(l),(v),(o),(r),(f)->variables->set,NILF)
4182
 
4183
+struct variable *push_scoped_variable (struct variable *v,
4184
+				       char *name, unsigned int length);
4185
+void pop_scoped_variable (struct variable *v, struct variable *old_var);
4186
+
4187
 void undefine_variable_in_set (const char *name, unsigned int length,
4188
                                enum variable_origin origin,
4189
                                struct variable_set *set);