VirtualBox

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

Last change on this file since 1606 was 1606, checked in by bird, 17 years ago

Fixed bug in append_expand_string_to_variable() where variables expansions that referenced them selves in some way would get confused by the half updated variable value. The fix temporarily switches the separtor space for a null terminator, or, in the case of an empty value, make it point to a static empty string.

  • Property svn:eol-style set to native
File size: 20.6 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
47static unsigned int variable_buffer_length;
48char *variable_buffer;
49
50/* Subroutine of variable_expand and friends:
51 The text to add is LENGTH chars starting at STRING to the variable_buffer.
52 The text is added to the buffer at PTR, and the updated pointer into
53 the buffer is returned as the value. Thus, the value returned by
54 each call to variable_buffer_output should be the first argument to
55 the following call. */
56
57char *
58variable_buffer_output (char *ptr, const char *string, unsigned int length)
59{
60 register unsigned int newlen = length + (ptr - variable_buffer);
61
62 if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
63 {
64 unsigned int offset = ptr - variable_buffer;
65#ifdef KMK
66 variable_buffer_length = variable_buffer_length <= 1024
67 ? 2048 : variable_buffer_length * 4;
68 if (variable_buffer_length < newlen + 100)
69 variable_buffer_length = (newlen + 100 + 1023) & ~1023U;
70#else
71 variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
72 ? newlen + 100
73 : 2 * variable_buffer_length);
74#endif
75 variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
76 ptr = variable_buffer + offset;
77 }
78
79 memcpy (ptr, string, length);
80 return ptr + length;
81}
82
83/* Return a pointer to the beginning of the variable buffer. */
84
85static char *
86initialize_variable_output (void)
87{
88 /* If we don't have a variable output buffer yet, get one. */
89
90 if (variable_buffer == 0)
91 {
92#ifdef KMK
93 variable_buffer_length = 384;
94#else
95 variable_buffer_length = 200;
96#endif
97 variable_buffer = xmalloc (variable_buffer_length);
98 variable_buffer[0] = '\0';
99 }
100
101 return variable_buffer;
102}
103
104
105/* Recursively expand V. The returned string is malloc'd. */
106
107static char *allocated_variable_append (const struct variable *v);
108
109char *
110recursively_expand_for_file (struct variable *v, struct file *file)
111{
112 char *value;
113 const struct floc *this_var;
114 const struct floc **saved_varp;
115 struct variable_set_list *save = 0;
116 int set_reading = 0;
117
118 /* Don't install a new location if this location is empty.
119 This can happen for command-line variables, builtin variables, etc. */
120 saved_varp = expanding_var;
121 if (v->fileinfo.filenm)
122 {
123 this_var = &v->fileinfo;
124 expanding_var = &this_var;
125 }
126
127 /* If we have no other file-reading context, use the variable's context. */
128 if (!reading_file)
129 {
130 set_reading = 1;
131 reading_file = &v->fileinfo;
132 }
133
134 if (v->expanding)
135 {
136 if (!v->exp_count)
137 /* Expanding V causes infinite recursion. Lose. */
138 fatal (*expanding_var,
139 _("Recursive variable `%s' references itself (eventually)"),
140 v->name);
141 --v->exp_count;
142 }
143
144 if (file)
145 {
146 save = current_variable_set_list;
147 current_variable_set_list = file->variables;
148 }
149
150 v->expanding = 1;
151 if (v->append)
152 value = allocated_variable_append (v);
153 else
154 value = allocated_variable_expand (v->value);
155 v->expanding = 0;
156
157 if (set_reading)
158 reading_file = 0;
159
160 if (file)
161 current_variable_set_list = save;
162
163 expanding_var = saved_varp;
164
165 return value;
166}
167
168/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
169
170#if defined(__GNUC__) || defined(_MSC_VER) /* bird added MSC */
171__inline
172#endif
173static char *
174reference_variable (char *o, const char *name, unsigned int length)
175{
176 struct variable *v;
177 char *value;
178
179 v = lookup_variable (name, length);
180
181 if (v == 0)
182 warn_undefined (name, length);
183
184 /* If there's no variable by that name or it has no value, stop now. */
185 if (v == 0 || (*v->value == '\0' && !v->append))
186 return o;
187
188#ifdef CONFIG_WITH_VALUE_LENGTH
189 if (!v->recursive)
190 {
191 assert (v->value_length == strlen (v->value));
192 o = variable_buffer_output (o, v->value, v->value_length);
193 }
194 else
195 {
196 value = recursively_expand (v);
197 o = variable_buffer_output (o, value, strlen (value));
198 free (value);
199 }
200#else /* !CONFIG_WITH_VALUE_LENGTH */
201 value = (v->recursive ? recursively_expand (v) : v->value);
202
203 o = variable_buffer_output (o, value, strlen (value));
204
205 if (v->recursive)
206 free (value);
207#endif /* !CONFIG_WITH_VALUE_LENGTH */
208
209 return o;
210}
211
212
213/* Scan STRING for variable references and expansion-function calls. Only
214 LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until
215 a null byte is found.
216
217 Write the results to LINE, which must point into `variable_buffer'. If
218 LINE is NULL, start at the beginning of the buffer.
219 Return a pointer to LINE, or to the beginning of the buffer if LINE is
220 NULL.
221 */
222char *
223variable_expand_string (char *line, const char *string, long length)
224{
225 struct variable *v;
226 const char *p, *p1;
227 char *abuf = NULL;
228 char *o;
229 unsigned int line_offset;
230
231 if (!line)
232 line = initialize_variable_output();
233 o = line;
234 line_offset = line - variable_buffer;
235
236 if (length == 0)
237 {
238 variable_buffer_output (o, "", 1);
239 return (variable_buffer);
240 }
241
242 /* If we want a subset of the string, allocate a temporary buffer for it.
243 Most of the functions we use here don't work with length limits. */
244 if (length > 0 && string[length] != '\0')
245 {
246 abuf = xmalloc(length+1);
247 memcpy(abuf, string, length);
248 abuf[length] = '\0';
249 string = abuf;
250 }
251 p = string;
252
253 while (1)
254 {
255 /* Copy all following uninteresting chars all at once to the
256 variable output buffer, and skip them. Uninteresting chars end
257 at the next $ or the end of the input. */
258
259 p1 = strchr (p, '$');
260
261 o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
262
263 if (p1 == 0)
264 break;
265 p = p1 + 1;
266
267 /* Dispatch on the char that follows the $. */
268
269 switch (*p)
270 {
271 case '$':
272 /* $$ seen means output one $ to the variable output buffer. */
273 o = variable_buffer_output (o, p, 1);
274 break;
275
276 case '(':
277 case '{':
278 /* $(...) or ${...} is the general case of substitution. */
279 {
280 char openparen = *p;
281 char closeparen = (openparen == '(') ? ')' : '}';
282 const char *begp;
283 const char *beg = p + 1;
284 char *op;
285 char *abeg = NULL;
286 const char *end, *colon;
287
288 op = o;
289 begp = p;
290 if (handle_function (&op, &begp))
291 {
292 o = op;
293 p = begp;
294 break;
295 }
296
297 /* Is there a variable reference inside the parens or braces?
298 If so, expand it before expanding the entire reference. */
299
300 end = strchr (beg, closeparen);
301 if (end == 0)
302 /* Unterminated variable reference. */
303 fatal (*expanding_var, _("unterminated variable reference"));
304 p1 = lindex (beg, end, '$');
305 if (p1 != 0)
306 {
307 /* BEG now points past the opening paren or brace.
308 Count parens or braces until it is matched. */
309 int count = 0;
310 for (p = beg; *p != '\0'; ++p)
311 {
312 if (*p == openparen)
313 ++count;
314 else if (*p == closeparen && --count < 0)
315 break;
316 }
317 /* If COUNT is >= 0, there were unmatched opening parens
318 or braces, so we go to the simple case of a variable name
319 such as `$($(a)'. */
320 if (count < 0)
321 {
322 abeg = expand_argument (beg, p); /* Expand the name. */
323 beg = abeg;
324 end = strchr (beg, '\0');
325 }
326 }
327 else
328 /* Advance P to the end of this reference. After we are
329 finished expanding this one, P will be incremented to
330 continue the scan. */
331 p = end;
332
333 /* This is not a reference to a built-in function and
334 any variable references inside are now expanded.
335 Is the resultant text a substitution reference? */
336
337 colon = lindex (beg, end, ':');
338 if (colon)
339 {
340 /* This looks like a substitution reference: $(FOO:A=B). */
341 const char *subst_beg, *subst_end, *replace_beg, *replace_end;
342
343 subst_beg = colon + 1;
344 subst_end = lindex (subst_beg, end, '=');
345 if (subst_end == 0)
346 /* There is no = in sight. Punt on the substitution
347 reference and treat this as a variable name containing
348 a colon, in the code below. */
349 colon = 0;
350 else
351 {
352 replace_beg = subst_end + 1;
353 replace_end = end;
354
355 /* Extract the variable name before the colon
356 and look up that variable. */
357 v = lookup_variable (beg, colon - beg);
358 if (v == 0)
359 warn_undefined (beg, colon - beg);
360
361 /* If the variable is not empty, perform the
362 substitution. */
363 if (v != 0 && *v->value != '\0')
364 {
365 char *pattern, *replace, *ppercent, *rpercent;
366 char *value = (v->recursive
367 ? recursively_expand (v)
368 : v->value);
369
370 /* Copy the pattern and the replacement. Add in an
371 extra % at the beginning to use in case there
372 isn't one in the pattern. */
373 pattern = alloca (subst_end - subst_beg + 2);
374 *(pattern++) = '%';
375 memcpy (pattern, subst_beg, subst_end - subst_beg);
376 pattern[subst_end - subst_beg] = '\0';
377
378 replace = alloca (replace_end - replace_beg + 2);
379 *(replace++) = '%';
380 memcpy (replace, replace_beg,
381 replace_end - replace_beg);
382 replace[replace_end - replace_beg] = '\0';
383
384 /* Look for %. Set the percent pointers properly
385 based on whether we find one or not. */
386 ppercent = find_percent (pattern);
387 if (ppercent)
388 {
389 ++ppercent;
390 rpercent = find_percent (replace);
391 if (rpercent)
392 ++rpercent;
393 }
394 else
395 {
396 ppercent = pattern;
397 rpercent = replace;
398 --pattern;
399 --replace;
400 }
401
402 o = patsubst_expand_pat (o, value, pattern, replace,
403 ppercent, rpercent);
404
405 if (v->recursive)
406 free (value);
407 }
408 }
409 }
410
411 if (colon == 0)
412 /* This is an ordinary variable reference.
413 Look up the value of the variable. */
414 o = reference_variable (o, beg, end - beg);
415
416 if (abeg)
417 free (abeg);
418 }
419 break;
420
421 case '\0':
422 break;
423
424 default:
425 if (isblank ((unsigned char)p[-1]))
426 break;
427
428 /* A $ followed by a random char is a variable reference:
429 $a is equivalent to $(a). */
430 o = reference_variable (o, p, 1);
431
432 break;
433 }
434
435 if (*p == '\0')
436 break;
437 else
438 ++p;
439 }
440
441 if (abuf)
442 free (abuf);
443
444 variable_buffer_output (o, "", 1);
445 return (variable_buffer + line_offset);
446}
447
448
449/* Scan LINE for variable references and expansion-function calls.
450 Build in `variable_buffer' the result of expanding the references and calls.
451 Return the address of the resulting string, which is null-terminated
452 and is valid only until the next time this function is called. */
453
454char *
455variable_expand (const char *line)
456{
457 return variable_expand_string(NULL, line, (long)-1);
458}
459
460
461/* Expand an argument for an expansion function.
462 The text starting at STR and ending at END is variable-expanded
463 into a null-terminated string that is returned as the value.
464 This is done without clobbering `variable_buffer' or the current
465 variable-expansion that is in progress. */
466
467char *
468expand_argument (const char *str, const char *end)
469{
470 char *tmp;
471
472 if (str == end)
473 return xstrdup("");
474
475 if (!end || *end == '\0')
476 return allocated_variable_expand (str);
477
478#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
479 {
480 const char saved_char = *end;
481 *(char *)end = '\0';
482 tmp = allocated_variable_expand ((char *)str);
483 *(char *)end = saved_char;
484 return tmp;
485 }
486#else
487 tmp = alloca (end - str + 1);
488 memcpy (tmp, str, end - str);
489 tmp[end - str] = '\0';
490
491 return allocated_variable_expand (tmp);
492#endif
493}
494
495
496/* Expand LINE for FILE. Error messages refer to the file and line where
497 FILE's commands were found. Expansion uses FILE's variable set list. */
498
499char *
500variable_expand_for_file (const char *line, struct file *file)
501{
502 char *result;
503 struct variable_set_list *save;
504
505 if (file == 0)
506 return variable_expand (line);
507
508 save = current_variable_set_list;
509 current_variable_set_list = file->variables;
510 if (file->cmds && file->cmds->fileinfo.filenm)
511 reading_file = &file->cmds->fileinfo;
512 else
513 reading_file = 0;
514 result = variable_expand (line);
515 current_variable_set_list = save;
516 reading_file = 0;
517
518 return result;
519}
520
521
522#ifdef CONFIG_WITH_COMMANDS_FUNC
523/* Expand LINE for FILE. Error messages refer to the file and line where
524 FILE's commands were found. Expansion uses FILE's variable set list.
525
526 Differs from variable_expand_for_file in that it takes a pointer to
527 where in the variable buffer to start outputting the expanded string. */
528
529char *
530variable_expand_for_file_2 (char *o, const char *line, struct file *file)
531{
532 char *result;
533 struct variable_set_list *save;
534 const struct floc *reading_file_saved;
535
536 if (file == 0)
537 return variable_expand_string (o, line, (long)-1);
538
539 save = current_variable_set_list;
540 current_variable_set_list = file->variables;
541 reading_file_saved = reading_file;
542 if (file->cmds && file->cmds->fileinfo.filenm)
543 reading_file = &file->cmds->fileinfo;
544 else
545 reading_file = 0;
546 result = variable_expand_string (o, line, (long)-1);
547 current_variable_set_list = save;
548 reading_file = reading_file_saved;
549
550 return result;
551}
552
553
554#endif /* CONFIG_WITH_COMMANDS_FUNC */
555/* Like allocated_variable_expand, but for += target-specific variables.
556 First recursively construct the variable value from its appended parts in
557 any upper variable sets. Then expand the resulting value. */
558
559static char *
560variable_append (const char *name, unsigned int length,
561 const struct variable_set_list *set)
562{
563 const struct variable *v;
564 char *buf = 0;
565
566 /* If there's nothing left to check, return the empty buffer. */
567 if (!set)
568 return initialize_variable_output ();
569
570 /* Try to find the variable in this variable set. */
571 v = lookup_variable_in_set (name, length, set->set);
572
573 /* If there isn't one, look to see if there's one in a set above us. */
574 if (!v)
575 return variable_append (name, length, set->next);
576
577 /* If this variable type is append, first get any upper values.
578 If not, initialize the buffer. */
579 if (v->append)
580 buf = variable_append (name, length, set->next);
581 else
582 buf = initialize_variable_output ();
583
584 /* Append this value to the buffer, and return it.
585 If we already have a value, first add a space. */
586 if (buf > variable_buffer)
587 buf = variable_buffer_output (buf, " ", 1);
588#ifdef CONFIG_WITH_VALUE_LENGTH
589 assert (v->value_length == strlen (v->value));
590#endif
591
592 /* Either expand it or copy it, depending. */
593 if (! v->recursive)
594#ifdef CONFIG_WITH_VALUE_LENGTH
595 return variable_buffer_output (buf, v->value, v->value_length);
596#else
597 return variable_buffer_output (buf, v->value, strlen (v->value));
598#endif
599
600#ifdef CONFIG_WITH_VALUE_LENGTH
601 buf = variable_expand_string (buf, v->value, v->value_length);
602#else
603 buf = variable_expand_string (buf, v->value, strlen (v->value));
604#endif
605 return (buf + strlen (buf));
606}
607
608#ifdef CONFIG_WITH_VALUE_LENGTH
609/* Expands the specified string, appending it to the specified variable value. */
610void
611append_expanded_string_to_variable (struct variable *v, const char *value)
612{
613 static char const empty_string[] = "";
614 unsigned int original_value_length = v->value_length;
615 char *p;
616
617 /* Switch the variable buffer to the variable value buffer. */
618 char *saved_buffer = variable_buffer;
619 unsigned int saved_buffer_length = variable_buffer_length;
620 variable_buffer = v->value;
621 variable_buffer_length = v->value_alloc_len;
622
623 /* Mark the variable as being expanding. */
624 if (v->value_alloc_len == -42)
625 fatal (*expanding_var, _("var=%s"), v->name);
626 assert (v->value_alloc_len >= 0);
627 v->value_alloc_len = -42;
628
629 /* Skip the current value and start appending a '\0' / space before
630 expanding the string so recursive references are handled correctly.
631 Alternatively, if it's an empty value, replace the value with a fixed
632 empty string. */
633 p = v->value + original_value_length;
634 if (original_value_length)
635 {
636 p = variable_buffer_output (p, " ", 1);
637 p[-1] = '\0';
638 }
639 else
640 v->value = (char *)&empty_string[0];
641 p = variable_expand_string (p, value, (long)-1);
642
643 /* Replace the '\0' with the space separator. */
644 if (original_value_length)
645 {
646 assert (variable_buffer[original_value_length] == '\0');
647 variable_buffer[original_value_length] = ' ';
648 }
649 else
650 {
651 assert (v->value == (char *)&empty_string[0]);
652 assert (empty_string[0] == '\0');
653 }
654
655 /* Update the variable. (mind the variable_expand_string() return) */
656 p = strchr (p, '\0');
657 v->value = variable_buffer;
658 v->value_length = p - v->value;
659 v->value_alloc_len = variable_buffer_length;
660
661 /* Restore the variable buffer. */
662 variable_buffer = saved_buffer;
663 variable_buffer_length = saved_buffer_length;
664}
665#endif /* CONFIG_WITH_VALUE_LENGTH */
666
667static char *
668allocated_variable_append (const struct variable *v)
669{
670 char *val;
671
672 /* Construct the appended variable value. */
673
674 char *obuf = variable_buffer;
675 unsigned int olen = variable_buffer_length;
676
677 variable_buffer = 0;
678
679 val = variable_append (v->name, strlen (v->name), current_variable_set_list);
680 variable_buffer_output (val, "", 1);
681 val = variable_buffer;
682
683 variable_buffer = obuf;
684 variable_buffer_length = olen;
685
686 return val;
687}
688
689/* Like variable_expand_for_file, but the returned string is malloc'd.
690 This function is called a lot. It wants to be efficient. */
691
692char *
693allocated_variable_expand_for_file (const char *line, struct file *file)
694{
695 char *value;
696
697 char *obuf = variable_buffer;
698 unsigned int olen = variable_buffer_length;
699
700 variable_buffer = 0;
701
702 value = variable_expand_for_file (line, file);
703
704#if 0
705 /* Waste a little memory and save time. */
706 value = xrealloc (value, strlen (value))
707#endif
708
709 variable_buffer = obuf;
710 variable_buffer_length = olen;
711
712 return value;
713}
714
715/* Install a new variable_buffer context, returning the current one for
716 safe-keeping. */
717
718void
719install_variable_buffer (char **bufp, unsigned int *lenp)
720{
721 *bufp = variable_buffer;
722 *lenp = variable_buffer_length;
723
724 variable_buffer = 0;
725 initialize_variable_output ();
726}
727
728/* Restore a previously-saved variable_buffer setting (free the current one).
729 */
730
731void
732restore_variable_buffer (char *buf, unsigned int len)
733{
734 free (variable_buffer);
735
736 variable_buffer = buf;
737 variable_buffer_length = len;
738}
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