VirtualBox

source: kBuild/trunk/src/kmk/expand.c@ 1928

Last change on this file since 1928 was 1928, checked in by bird, 16 years ago

expand.c: added allocated_variable_expand_3 and recycle_variable_buffer in order to avoid some frequent free() and xmalloc() calls during variable expansion in variable_expand_string_2.

  • Property svn:eol-style set to native
File size: 32.9 KB
Line 
1/* Variable expansion functions for GNU Make.
2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4Foundation, Inc.
5This file is part of GNU Make.
6
7GNU Make is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 2, or (at your option) any later version.
10
11GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16GNU Make; see the file COPYING. If not, write to the Free Software
17Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
18
19#include "make.h"
20
21#include <assert.h>
22
23#include "filedef.h"
24#include "job.h"
25#include "commands.h"
26#include "variable.h"
27#include "rule.h"
28
29/* Initially, any errors reported when expanding strings will be reported
30 against the file where the error appears. */
31const struct floc **expanding_var = &reading_file;
32
33/* The next two describe the variable output buffer.
34 This buffer is used to hold the variable-expansion of a line of the
35 makefile. It is made bigger with realloc whenever it is too small.
36 variable_buffer_length is the size currently allocated.
37 variable_buffer is the address of the buffer.
38
39 For efficiency, it's guaranteed that the buffer will always have
40 VARIABLE_BUFFER_ZONE extra bytes allocated. This allows you to add a few
41 extra chars without having to call a function. Note you should never use
42 these bytes unless you're _sure_ you have room (you know when the buffer
43 length was last checked. */
44
45#define VARIABLE_BUFFER_ZONE 5
46
47#ifndef KMK
48static unsigned int variable_buffer_length;
49#else
50unsigned int variable_buffer_length;
51#endif
52char *variable_buffer;
53
54
55#ifdef CONFIG_WITH_VALUE_LENGTH
56struct recycled_buffer
57{
58 struct recycled_buffer *next;
59 unsigned int length;
60};
61struct recycled_buffer *recycled_head;
62static char *
63allocated_variable_expand_3 (const char *line, unsigned int length,
64 unsigned int *value_lenp,
65 unsigned int *buffer_lengthp);
66static void
67recycle_variable_buffer (char *buffer, unsigned int length);
68
69#endif
70
71
72
73#ifndef KMK
74/* Subroutine of variable_expand and friends:
75 The text to add is LENGTH chars starting at STRING to the variable_buffer.
76 The text is added to the buffer at PTR, and the updated pointer into
77 the buffer is returned as the value. Thus, the value returned by
78 each call to variable_buffer_output should be the first argument to
79 the following call. */
80
81char *
82variable_buffer_output (char *ptr, const char *string, unsigned int length)
83{
84 register unsigned int newlen = length + (ptr - variable_buffer);
85
86 if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
87 {
88 unsigned int offset = ptr - variable_buffer;
89 variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
90 ? newlen + 100
91 : 2 * variable_buffer_length);
92 variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
93 ptr = variable_buffer + offset;
94 }
95
96 memcpy (ptr, string, length);
97 return ptr + length;
98}
99#endif
100
101/* Return a pointer to the beginning of the variable buffer. */
102
103static char *
104initialize_variable_output (void)
105{
106 /* If we don't have a variable output buffer yet, get one. */
107
108#ifdef CONFIG_WITH_VALUE_LENGTH
109 if (variable_buffer == 0)
110 {
111 struct recycled_buffer *recycled = recycled_head;
112 if (recycled)
113 {
114 recycled_head = recycled->next;
115 variable_buffer_length = recycled->length;
116 variable_buffer = (char *)recycled;
117 }
118 else
119 {
120 variable_buffer_length = 384;
121 variable_buffer = xmalloc (variable_buffer_length);
122 }
123 variable_buffer[0] = '\0';
124 }
125#else
126 if (variable_buffer == 0)
127 {
128 variable_buffer_length = 200;
129 variable_buffer = xmalloc (variable_buffer_length);
130 variable_buffer[0] = '\0';
131 }
132#endif
133
134 return variable_buffer;
135}
136
137
138/* Recursively expand V. The returned string is malloc'd. */
139
140static char *allocated_variable_append (const struct variable *v);
141
142char *
143#ifndef CONFIG_WITH_VALUE_LENGTH
144recursively_expand_for_file (struct variable *v, struct file *file)
145#else
146recursively_expand_for_file (struct variable *v, struct file *file,
147 unsigned int *value_lenp)
148#endif
149{
150 char *value;
151 const struct floc *this_var;
152 const struct floc **saved_varp;
153 struct variable_set_list *save = 0;
154 int set_reading = 0;
155
156 /* Don't install a new location if this location is empty.
157 This can happen for command-line variables, builtin variables, etc. */
158 saved_varp = expanding_var;
159 if (v->fileinfo.filenm)
160 {
161 this_var = &v->fileinfo;
162 expanding_var = &this_var;
163 }
164
165 /* If we have no other file-reading context, use the variable's context. */
166 if (!reading_file)
167 {
168 set_reading = 1;
169 reading_file = &v->fileinfo;
170 }
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
182 if (file)
183 {
184 save = current_variable_set_list;
185 current_variable_set_list = file->variables;
186 }
187
188 v->expanding = 1;
189#ifndef CONFIG_WITH_VALUE_LENGTH
190 if (v->append)
191 value = allocated_variable_append (v);
192 else
193 value = allocated_variable_expand (v->value);
194#else /* CONFIG_WITH_VALUE_LENGTH */
195 if (!v->append)
196 value = allocated_variable_expand_2 (v->value, v->value_length, value_lenp);
197 else
198 {
199 value = allocated_variable_append (v);
200 if (value_lenp)
201 *value_lenp = strlen (value);
202 }
203#endif /* CONFIG_WITH_VALUE_LENGTH */
204 v->expanding = 0;
205
206 if (set_reading)
207 reading_file = 0;
208
209 if (file)
210 current_variable_set_list = save;
211
212 expanding_var = saved_varp;
213
214 return value;
215}
216
217/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
218
219#if defined(__GNUC__) || defined(_MSC_VER) /* bird added MSC */
220__inline
221#endif
222static char *
223reference_variable (char *o, const char *name, unsigned int length)
224{
225 struct variable *v;
226 char *value;
227
228 v = lookup_variable (name, length);
229
230 if (v == 0)
231 warn_undefined (name, length);
232
233 /* If there's no variable by that name or it has no value, stop now. */
234 if (v == 0 || (*v->value == '\0' && !v->append))
235 return o;
236
237#ifdef CONFIG_WITH_VALUE_LENGTH
238 assert ((unsigned int)v->value_length == strlen (v->value));
239 if (!v->recursive)
240 o = variable_buffer_output (o, v->value, v->value_length);
241 else
242 {
243 unsigned int value_len;
244
245 value = recursively_expand_for_file (v, NULL, &value_len);
246 o = variable_buffer_output (o, value, value_len);
247 free (value);
248 }
249#else /* !CONFIG_WITH_VALUE_LENGTH */
250 value = (v->recursive ? recursively_expand (v) : v->value);
251
252 o = variable_buffer_output (o, value, strlen (value));
253
254 if (v->recursive)
255 free (value);
256#endif /* !CONFIG_WITH_VALUE_LENGTH */
257
258 return o;
259}
260
261
262#ifndef CONFIG_WITH_VALUE_LENGTH /* Only using variable_expand_string_2! */
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 */
272char *
273variable_expand_string (char *line, const char *string, long length)
274{
275 struct variable *v;
276 const char *p, *p1;
277 char *abuf = NULL;
278 char *o;
279 unsigned int line_offset;
280
281 if (!line)
282 line = initialize_variable_output();
283 o = line;
284 line_offset = line - variable_buffer;
285
286 if (length == 0)
287 {
288 variable_buffer_output (o, "", 1);
289 return (variable_buffer);
290 }
291
292 /* If we want a subset of the string, allocate a temporary buffer for it.
293 Most of the functions we use here don't work with length limits. */
294 if (length > 0 && string[length] != '\0')
295 {
296 abuf = xmalloc(length+1);
297 memcpy(abuf, string, length);
298 abuf[length] = '\0';
299 string = abuf;
300 }
301 p = string;
302
303 while (1)
304 {
305 /* Copy all following uninteresting chars all at once to the
306 variable output buffer, and skip them. Uninteresting chars end
307 at the next $ or the end of the input. */
308
309 p1 = strchr (p, '$');
310
311 o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
312
313 if (p1 == 0)
314 break;
315 p = p1 + 1;
316
317 /* Dispatch on the char that follows the $. */
318
319 switch (*p)
320 {
321 case '$':
322 /* $$ seen means output one $ to the variable output buffer. */
323 o = variable_buffer_output (o, p, 1);
324 break;
325
326 case '(':
327 case '{':
328 /* $(...) or ${...} is the general case of substitution. */
329 {
330 char openparen = *p;
331 char closeparen = (openparen == '(') ? ')' : '}';
332 const char *begp;
333 const char *beg = p + 1;
334 char *op;
335 char *abeg = NULL;
336 const char *end, *colon;
337
338 op = o;
339 begp = p;
340 if (handle_function (&op, &begp))
341 {
342 o = op;
343 p = begp;
344 break;
345 }
346
347 /* Is there a variable reference inside the parens or braces?
348 If so, expand it before expanding the entire reference. */
349
350 end = strchr (beg, closeparen);
351 if (end == 0)
352 /* Unterminated variable reference. */
353 fatal (*expanding_var, _("unterminated variable reference"));
354 p1 = lindex (beg, end, '$');
355 if (p1 != 0)
356 {
357 /* BEG now points past the opening paren or brace.
358 Count parens or braces until it is matched. */
359 int count = 0;
360 for (p = beg; *p != '\0'; ++p)
361 {
362 if (*p == openparen)
363 ++count;
364 else if (*p == closeparen && --count < 0)
365 break;
366 }
367 /* If COUNT is >= 0, there were unmatched opening parens
368 or braces, so we go to the simple case of a variable name
369 such as `$($(a)'. */
370 if (count < 0)
371 {
372 abeg = expand_argument (beg, p); /* Expand the name. */
373 beg = abeg;
374 end = strchr (beg, '\0');
375 }
376 }
377 else
378 /* Advance P to the end of this reference. After we are
379 finished expanding this one, P will be incremented to
380 continue the scan. */
381 p = end;
382
383 /* This is not a reference to a built-in function and
384 any variable references inside are now expanded.
385 Is the resultant text a substitution reference? */
386
387 colon = lindex (beg, end, ':');
388 if (colon)
389 {
390 /* This looks like a substitution reference: $(FOO:A=B). */
391 const char *subst_beg, *subst_end, *replace_beg, *replace_end;
392
393 subst_beg = colon + 1;
394 subst_end = lindex (subst_beg, end, '=');
395 if (subst_end == 0)
396 /* There is no = in sight. Punt on the substitution
397 reference and treat this as a variable name containing
398 a colon, in the code below. */
399 colon = 0;
400 else
401 {
402 replace_beg = subst_end + 1;
403 replace_end = end;
404
405 /* Extract the variable name before the colon
406 and look up that variable. */
407 v = lookup_variable (beg, colon - beg);
408 if (v == 0)
409 warn_undefined (beg, colon - beg);
410
411 /* If the variable is not empty, perform the
412 substitution. */
413 if (v != 0 && *v->value != '\0')
414 {
415 char *pattern, *replace, *ppercent, *rpercent;
416 char *value = (v->recursive
417 ? recursively_expand (v)
418 : v->value);
419
420 /* Copy the pattern and the replacement. Add in an
421 extra % at the beginning to use in case there
422 isn't one in the pattern. */
423 pattern = alloca (subst_end - subst_beg + 2);
424 *(pattern++) = '%';
425 memcpy (pattern, subst_beg, subst_end - subst_beg);
426 pattern[subst_end - subst_beg] = '\0';
427
428 replace = alloca (replace_end - replace_beg + 2);
429 *(replace++) = '%';
430 memcpy (replace, replace_beg,
431 replace_end - replace_beg);
432 replace[replace_end - replace_beg] = '\0';
433
434 /* Look for %. Set the percent pointers properly
435 based on whether we find one or not. */
436 ppercent = find_percent (pattern);
437 if (ppercent)
438 {
439 ++ppercent;
440 rpercent = find_percent (replace);
441 if (rpercent)
442 ++rpercent;
443 }
444 else
445 {
446 ppercent = pattern;
447 rpercent = replace;
448 --pattern;
449 --replace;
450 }
451
452 o = patsubst_expand_pat (o, value, pattern, replace,
453 ppercent, rpercent);
454
455 if (v->recursive)
456 free (value);
457 }
458 }
459 }
460
461 if (colon == 0)
462 /* This is an ordinary variable reference.
463 Look up the value of the variable. */
464 o = reference_variable (o, beg, end - beg);
465
466 if (abeg)
467 free (abeg);
468 }
469 break;
470
471 case '\0':
472 break;
473
474 default:
475 if (isblank ((unsigned char)p[-1]))
476 break;
477
478 /* A $ followed by a random char is a variable reference:
479 $a is equivalent to $(a). */
480 o = reference_variable (o, p, 1);
481
482 break;
483 }
484
485 if (*p == '\0')
486 break;
487 else
488 ++p;
489 }
490
491 if (abuf)
492 free (abuf);
493
494 variable_buffer_output (o, "", 1);
495 return (variable_buffer + line_offset);
496}
497
498#else /* CONFIG_WITH_VALUE_LENGTH */
499/* Scan STRING for variable references and expansion-function calls. Only
500 LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until
501 a null byte is found.
502
503 Write the results to LINE, which must point into `variable_buffer'. If
504 LINE is NULL, start at the beginning of the buffer.
505 Return a pointer to LINE, or to the beginning of the buffer if LINE is
506 NULL. Set EOLP to point to the string terminator.
507 */
508char *
509variable_expand_string_2 (char *line, const char *string, long length, char **eolp)
510{
511 struct variable *v;
512 const char *p, *p1, *eos;
513 char *o;
514 unsigned int line_offset;
515
516 if (!line)
517 line = initialize_variable_output();
518 o = line;
519 line_offset = line - variable_buffer;
520
521 if (length < 0)
522 length = strlen (string);
523 else
524 MY_ASSERT_MSG (string + length == (p1 = memchr (string, '\0', length)) || !p1, ("len=%ld p1=%p %s\n", length, p1, line));
525
526 /* Simple 1: Emptry string. */
527
528 if (length == 0)
529 {
530 o = variable_buffer_output (o, "\0", 2);
531 *eolp = o - 2;
532 return (variable_buffer + line_offset);
533 }
534
535 /* Simple 2: Nothing to expand. ~50% if the kBuild calls. */
536
537 p1 = (const char *)memchr (string, '$', length);
538 if (p1 == 0)
539 {
540 o = variable_buffer_output (o, string, length);
541 o = variable_buffer_output (o, "\0", 2);
542 *eolp = o - 2;
543 assert (strchr (variable_buffer + line_offset, '\0') == *eolp);
544 return (variable_buffer + line_offset);
545 }
546
547 p = string;
548 eos = p + length;
549
550 while (1)
551 {
552 /* Copy all following uninteresting chars all at once to the
553 variable output buffer, and skip them. Uninteresting chars end
554 at the next $ or the end of the input. */
555
556 o = variable_buffer_output (o, p, p1 != 0 ? (p1 - p) : (eos - p));
557
558 if (p1 == 0)
559 break;
560 p = p1 + 1;
561
562 /* Dispatch on the char that follows the $. */
563
564 switch (*p)
565 {
566 case '$':
567 /* $$ seen means output one $ to the variable output buffer. */
568 o = variable_buffer_output (o, p, 1);
569 break;
570
571 case '(':
572 case '{':
573 /* $(...) or ${...} is the general case of substitution. */
574 {
575 char openparen = *p;
576 char closeparen = (openparen == '(') ? ')' : '}';
577 const char *begp;
578 const char *beg = p + 1;
579 char *op;
580 char *abeg = NULL;
581 unsigned int alen = 0;
582 const char *end, *colon;
583
584 op = o;
585 begp = p;
586 end = may_be_function_name (p + 1, eos);
587 if ( end
588 && handle_function (&op, &begp, end, eos))
589 {
590 o = op;
591 p = begp;
592 MY_ASSERT_MSG (!(p1 = memchr (variable_buffer + line_offset, '\0', o - (variable_buffer + line_offset))),
593 ("line=%p o/exp_end=%p act_end=%p\n", variable_buffer + line_offset, o, p1));
594 break;
595 }
596
597 /* Is there a variable reference inside the parens or braces?
598 If so, expand it before expanding the entire reference. */
599
600 end = memchr (beg, closeparen, eos - beg);
601 if (end == 0)
602 /* Unterminated variable reference. */
603 fatal (*expanding_var, _("unterminated variable reference"));
604 p1 = lindex (beg, end, '$');
605 if (p1 != 0)
606 {
607 /* BEG now points past the opening paren or brace.
608 Count parens or braces until it is matched. */
609 int count = 0;
610 for (p = beg; p < eos; ++p)
611 {
612 if (*p == openparen)
613 ++count;
614 else if (*p == closeparen && --count < 0)
615 break;
616 }
617 /* If COUNT is >= 0, there were unmatched opening parens
618 or braces, so we go to the simple case of a variable name
619 such as `$($(a)'. */
620 if (count < 0)
621 {
622 unsigned int len;
623 char saved;
624
625 /* Expand the name. */
626 saved = *p;
627 *(char *)p = '\0'; /* XXX: proove that this is safe! XXX2: shouldn't be necessary any longer! */
628 abeg = allocated_variable_expand_3 (beg, p - beg, &len, &alen);
629 beg = abeg;
630 end = beg + len;
631 *(char *)p = saved;
632 }
633 }
634 else
635 /* Advance P to the end of this reference. After we are
636 finished expanding this one, P will be incremented to
637 continue the scan. */
638 p = end;
639
640 /* This is not a reference to a built-in function and
641 any variable references inside are now expanded.
642 Is the resultant text a substitution reference? */
643
644 colon = lindex (beg, end, ':');
645 if (colon)
646 {
647 /* This looks like a substitution reference: $(FOO:A=B). */
648 const char *subst_beg, *subst_end, *replace_beg, *replace_end;
649
650 subst_beg = colon + 1;
651 subst_end = lindex (subst_beg, end, '=');
652 if (subst_end == 0)
653 /* There is no = in sight. Punt on the substitution
654 reference and treat this as a variable name containing
655 a colon, in the code below. */
656 colon = 0;
657 else
658 {
659 replace_beg = subst_end + 1;
660 replace_end = end;
661
662 /* Extract the variable name before the colon
663 and look up that variable. */
664 v = lookup_variable (beg, colon - beg);
665 if (v == 0)
666 warn_undefined (beg, colon - beg);
667
668 /* If the variable is not empty, perform the
669 substitution. */
670 if (v != 0 && *v->value != '\0')
671 {
672 char *pattern, *replace, *ppercent, *rpercent;
673 char *value = (v->recursive
674 ? recursively_expand (v)
675 : v->value);
676
677 /* Copy the pattern and the replacement. Add in an
678 extra % at the beginning to use in case there
679 isn't one in the pattern. */
680 pattern = alloca (subst_end - subst_beg + 2);
681 *(pattern++) = '%';
682 memcpy (pattern, subst_beg, subst_end - subst_beg);
683 pattern[subst_end - subst_beg] = '\0';
684
685 replace = alloca (replace_end - replace_beg + 2);
686 *(replace++) = '%';
687 memcpy (replace, replace_beg,
688 replace_end - replace_beg);
689 replace[replace_end - replace_beg] = '\0';
690
691 /* Look for %. Set the percent pointers properly
692 based on whether we find one or not. */
693 ppercent = find_percent (pattern);
694 if (ppercent)
695 {
696 ++ppercent;
697 rpercent = find_percent (replace);
698 if (rpercent)
699 ++rpercent;
700 }
701 else
702 {
703 ppercent = pattern;
704 rpercent = replace;
705 --pattern;
706 --replace;
707 }
708
709 o = patsubst_expand_pat (o, value, pattern, replace,
710 ppercent, rpercent);
711
712 if (v->recursive)
713 free (value);
714 }
715 }
716 }
717
718 if (colon == 0)
719 /* This is an ordinary variable reference.
720 Look up the value of the variable. */
721 o = reference_variable (o, beg, end - beg);
722
723 if (abeg)
724 recycle_variable_buffer (abeg, alen);
725 }
726 break;
727
728 case '\0':
729 assert (p == eos);
730 break;
731
732 default:
733 if (isblank ((unsigned char)p[-1])) /* XXX: This looks incorrect, previous is '$' */
734 break;
735
736 /* A $ followed by a random char is a variable reference:
737 $a is equivalent to $(a). */
738 o = reference_variable (o, p, 1);
739
740 break;
741 }
742
743 if (++p >= eos)
744 break;
745 p1 = memchr (p, '$', eos - p);
746 }
747
748 o = variable_buffer_output (o, "\0", 2); /* KMK: compensate for the strlen + 1 that was removed above. */
749 *eolp = o - 2;
750 MY_ASSERT_MSG (strchr (variable_buffer + line_offset, '\0') == *eolp,
751 ("expected=%d actual=%d\nlength=%ld string=%.*s\n",
752 (int)(*eolp - variable_buffer + line_offset), (int)strlen(variable_buffer + line_offset),
753 length, (int)length, string));
754 return (variable_buffer + line_offset);
755}
756#endif /* CONFIG_WITH_VALUE_LENGTH */
757
758
759/* Scan LINE for variable references and expansion-function calls.
760 Build in `variable_buffer' the result of expanding the references and calls.
761 Return the address of the resulting string, which is null-terminated
762 and is valid only until the next time this function is called. */
763
764char *
765variable_expand (const char *line)
766{
767#ifndef CONFIG_WITH_VALUE_LENGTH
768 return variable_expand_string(NULL, line, (long)-1);
769#else
770 char *s;
771
772 /* this function is abused a lot like this: variable_expand(""). */
773 if (!*line)
774 {
775 s = variable_buffer_output (initialize_variable_output (), "\0", 2);
776 return s - 2;
777 }
778 return variable_expand_string_2 (NULL, line, (long)-1, &s);
779#endif
780}
781
782
783/* Expand an argument for an expansion function.
784 The text starting at STR and ending at END is variable-expanded
785 into a null-terminated string that is returned as the value.
786 This is done without clobbering `variable_buffer' or the current
787 variable-expansion that is in progress. */
788
789char *
790expand_argument (const char *str, const char *end)
791{
792#ifndef CONFIG_WITH_VALUE_LENGTH
793 char *tmp;
794#endif
795
796 if (str == end)
797 return xstrdup("");
798
799#ifndef CONFIG_WITH_VALUE_LENGTH
800 if (!end || *end == '\0')
801 return allocated_variable_expand (str);
802 tmp = alloca (end - str + 1);
803 memcpy (tmp, str, end - str);
804 tmp[end - str] = '\0';
805 return allocated_variable_expand (tmp);
806#else /* CONFIG_WITH_VALUE_LENGTH */
807 if (!end)
808 return allocated_variable_expand_2 (str, ~0U, NULL);
809 return allocated_variable_expand_2 (str, end - str, NULL);
810#endif /* CONFIG_WITH_VALUE_LENGTH */
811}
812
813
814/* Expand LINE for FILE. Error messages refer to the file and line where
815 FILE's commands were found. Expansion uses FILE's variable set list. */
816
817char *
818variable_expand_for_file (const char *line, struct file *file)
819{
820 char *result;
821 struct variable_set_list *save;
822
823 if (file == 0)
824 return variable_expand (line);
825
826 save = current_variable_set_list;
827 current_variable_set_list = file->variables;
828 if (file->cmds && file->cmds->fileinfo.filenm)
829 reading_file = &file->cmds->fileinfo;
830 else
831 reading_file = 0;
832 result = variable_expand (line);
833 current_variable_set_list = save;
834 reading_file = 0;
835
836 return result;
837}
838
839
840#ifdef CONFIG_WITH_COMMANDS_FUNC
841/* Expand LINE for FILE. Error messages refer to the file and line where
842 FILE's commands were found. Expansion uses FILE's variable set list.
843
844 Differs from variable_expand_for_file in that it takes a pointer to
845 where in the variable buffer to start outputting the expanded string,
846 and that it can returned the length of the string if you wish. */
847
848char *
849variable_expand_for_file_2 (char *o, const char *line, unsigned int length,
850 struct file *file, unsigned int *value_lenp)
851{
852 char *result;
853 struct variable_set_list *save;
854 const struct floc *reading_file_saved;
855 long len = length == ~0U ? (long)-1 : (long)length;
856 char *eol;
857
858 if (!o)
859 o = initialize_variable_output();
860
861 if (file == 0)
862 result = variable_expand_string_2 (o, line, len, &eol);
863 else
864 {
865 save = current_variable_set_list;
866 current_variable_set_list = file->variables;
867 reading_file_saved = reading_file;
868 if (file->cmds && file->cmds->fileinfo.filenm)
869 reading_file = &file->cmds->fileinfo;
870 else
871 reading_file = 0;
872 result = variable_expand_string_2 (o, line, len, &eol);
873 current_variable_set_list = save;
874 reading_file = reading_file_saved;
875 }
876
877 if (value_lenp)
878 *value_lenp = eol - result;
879
880 return result;
881}
882
883
884#endif /* CONFIG_WITH_COMMANDS_FUNC */
885/* Like allocated_variable_expand, but for += target-specific variables.
886 First recursively construct the variable value from its appended parts in
887 any upper variable sets. Then expand the resulting value. */
888
889static char *
890variable_append (const char *name, unsigned int length,
891 const struct variable_set_list *set)
892{
893 const struct variable *v;
894 char *buf = 0;
895
896 /* If there's nothing left to check, return the empty buffer. */
897 if (!set)
898 return initialize_variable_output ();
899
900 /* Try to find the variable in this variable set. */
901 v = lookup_variable_in_set (name, length, set->set);
902
903 /* If there isn't one, look to see if there's one in a set above us. */
904 if (!v)
905 return variable_append (name, length, set->next);
906
907 /* If this variable type is append, first get any upper values.
908 If not, initialize the buffer. */
909 if (v->append)
910 buf = variable_append (name, length, set->next);
911 else
912 buf = initialize_variable_output ();
913
914 /* Append this value to the buffer, and return it.
915 If we already have a value, first add a space. */
916 if (buf > variable_buffer)
917 buf = variable_buffer_output (buf, " ", 1);
918#ifdef CONFIG_WITH_VALUE_LENGTH
919 assert ((unsigned int)v->value_length == strlen (v->value)); /* FIXME */
920#endif
921
922 /* Either expand it or copy it, depending. */
923 if (! v->recursive)
924#ifdef CONFIG_WITH_VALUE_LENGTH
925 return variable_buffer_output (buf, v->value, v->value_length);
926#else
927 return variable_buffer_output (buf, v->value, strlen (v->value));
928#endif
929
930#ifdef CONFIG_WITH_VALUE_LENGTH
931 variable_expand_string_2 (buf, v->value, v->value_length, &buf);
932 return buf;
933#else
934 buf = variable_expand_string (buf, v->value, strlen (v->value));
935 return (buf + strlen (buf));
936#endif
937}
938
939#ifdef CONFIG_WITH_VALUE_LENGTH
940/* Expands the specified string, appending it to the specified
941 variable value. */
942void
943append_expanded_string_to_variable (struct variable *v, const char *value,
944 unsigned int value_len, int append)
945{
946 char *p = (char *) memchr (value, '$', value_len);
947 if (!p)
948 /* fast path */
949 append_string_to_variable (v,value, value_len, append);
950 else if (value_len)
951 {
952 unsigned int off_dollar = p - (char *)value;
953
954 /* Install a fresh variable buffer. */
955 char *saved_buffer;
956 unsigned int saved_buffer_length;
957 install_variable_buffer (&saved_buffer, &saved_buffer_length);
958
959 p = variable_buffer;
960 if (append || !v->value_length)
961 {
962 /* Copy the current value into it and append a space. */
963 if (v->value_length)
964 {
965 p = variable_buffer_output (p, v->value, v->value_length);
966 p = variable_buffer_output (p, " ", 1);
967 }
968
969 /* Append the assignment value. */
970 p = variable_buffer_output (p, value, off_dollar);
971 variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
972 }
973 else
974 {
975 /* Expand the assignemnt value. */
976 p = variable_buffer_output (p, value, off_dollar);
977 variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
978
979 /* Append a space followed by the old value. */
980 p = variable_buffer_output (p, " ", 1);
981 p = variable_buffer_output (p, v->value, v->value_length + 1) - 1;
982 }
983
984 /* Replace the variable with the variable buffer. */
985 free (v->value);
986 v->value = variable_buffer;
987 v->value_length = p - v->value;
988 v->value_alloc_len = variable_buffer_length;
989
990 /* Restore the variable buffer, but without freeing the current. */
991 variable_buffer = NULL;
992 restore_variable_buffer (saved_buffer, saved_buffer_length);
993 }
994 /* else: Drop empty strings. Use $(NO_SUCH_VARIABLE) if a space is wanted. */
995}
996#endif /* CONFIG_WITH_VALUE_LENGTH */
997
998static char *
999allocated_variable_append (const struct variable *v)
1000{
1001 char *val;
1002
1003 /* Construct the appended variable value. */
1004
1005 char *obuf = variable_buffer;
1006 unsigned int olen = variable_buffer_length;
1007
1008 variable_buffer = 0;
1009
1010 assert (v->length == strlen (v->name));
1011 val = variable_append (v->name, strlen (v->name), current_variable_set_list);
1012 variable_buffer_output (val, "", 1);
1013 val = variable_buffer;
1014
1015 variable_buffer = obuf;
1016 variable_buffer_length = olen;
1017
1018 return val;
1019}
1020
1021/* Like variable_expand_for_file, but the returned string is malloc'd.
1022 This function is called a lot. It wants to be efficient. */
1023
1024char *
1025allocated_variable_expand_for_file (const char *line, struct file *file)
1026{
1027 char *value;
1028
1029 char *obuf = variable_buffer;
1030 unsigned int olen = variable_buffer_length;
1031
1032 variable_buffer = 0;
1033
1034 value = variable_expand_for_file (line, file);
1035
1036#if 0
1037 /* Waste a little memory and save time. */
1038 value = xrealloc (value, strlen (value))
1039#endif
1040
1041 variable_buffer = obuf;
1042 variable_buffer_length = olen;
1043
1044 return value;
1045}
1046
1047#ifdef CONFIG_WITH_VALUE_LENGTH
1048/* Handle the most common case in allocated_variable_expand_for_file
1049 specially and provide some additional string lenght features. */
1050
1051char *
1052allocated_variable_expand_2 (const char *line, unsigned int length,
1053 unsigned int *value_lenp)
1054{
1055 char *value;
1056 char *obuf = variable_buffer;
1057 unsigned int olen = variable_buffer_length;
1058 long len = length == ~0U ? -1L : (long)length;
1059 char *eol;
1060
1061 variable_buffer = 0;
1062
1063 value = variable_expand_string_2 (NULL, line, len, &eol);
1064 if (value_lenp)
1065 *value_lenp = eol - value;
1066
1067 variable_buffer = obuf;
1068 variable_buffer_length = olen;
1069
1070 return value;
1071}
1072
1073/* Handles a special case for variable_expand_string2 where the variable
1074 name is expanded. This variant allows the variable_buffer to
1075 be recycled and thus avoid bothering with a slow free implementation
1076 (darwin is horrible here). */
1077
1078static char *
1079allocated_variable_expand_3 (const char *line, unsigned int length,
1080 unsigned int *value_lenp,
1081 unsigned int *buffer_lengthp)
1082{
1083 char *obuf = variable_buffer;
1084 unsigned int olen = variable_buffer_length;
1085 long len = (long)length;
1086 char *value;
1087 char *eol;
1088
1089 variable_buffer = 0;
1090
1091 value = variable_expand_string_2 (NULL, line, len, &eol);
1092 *value_lenp = eol - value;
1093 *buffer_lengthp = variable_buffer_length;
1094
1095 variable_buffer = obuf;
1096 variable_buffer_length = olen;
1097
1098 return value;
1099}
1100
1101/* recycle a buffer. */
1102static void
1103recycle_variable_buffer (char *buffer, unsigned int length)
1104{
1105 struct recycled_buffer *recycled = (struct recycled_buffer *)buffer;
1106
1107 assert (!(length & 31));
1108 assert (length >= 384);
1109 recycled->length = length;
1110 recycled->next = recycled_head;
1111 recycled_head = recycled;
1112}
1113
1114#endif /* CONFIG_WITH_VALUE_LENGTH */
1115
1116/* Install a new variable_buffer context, returning the current one for
1117 safe-keeping. */
1118
1119void
1120install_variable_buffer (char **bufp, unsigned int *lenp)
1121{
1122 *bufp = variable_buffer;
1123 *lenp = variable_buffer_length;
1124
1125 variable_buffer = 0;
1126 initialize_variable_output ();
1127}
1128
1129/* Restore a previously-saved variable_buffer setting (free the current one).
1130 */
1131
1132void
1133restore_variable_buffer (char *buf, unsigned int len)
1134{
1135 free (variable_buffer);
1136
1137 variable_buffer = buf;
1138 variable_buffer_length = len;
1139}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette