Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### Eclipse Workspace Patch 1.0
- #P make-patched
- Index: expand.c
- ===================================================================
- RCS file: /sources/make/make/expand.c,v
- retrieving revision 1.62
- diff -u -r1.62 expand.c
- --- expand.c 5 Mar 2012 14:10:43 -0000 1.62
- +++ expand.c 15 Mar 2012 21:19:13 -0000
- @@ -16,13 +16,12 @@
- #include "make.h"
- -#include <assert.h>
- -
- #include "filedef.h"
- #include "job.h"
- #include "commands.h"
- #include "variable.h"
- #include "rule.h"
- +#include "/usr/include/assert.h"
- /* Initially, any errors reported when expanding strings will be reported
- against the file where the error appears. */
- @@ -31,8 +30,6 @@
- /* The next two describe the variable output buffer.
- This buffer is used to hold the variable-expansion of a line of the
- makefile. It is made bigger with realloc whenever it is too small.
- - variable_buffer_length is the size currently allocated.
- - variable_buffer is the address of the buffer.
- For efficiency, it's guaranteed that the buffer will always have
- VARIABLE_BUFFER_ZONE extra bytes allocated. This allows you to add a few
- @@ -40,115 +37,121 @@
- these bytes unless you're _sure_ you have room (you know when the buffer
- length was last checked. */
- +static struct vbuffer *expansion_vbuf;
- +
- #define VARIABLE_BUFFER_ZONE 5
- -static unsigned int variable_buffer_length;
- -char *variable_buffer;
- +struct vbuffer *
- +vbuffer_init (struct vbuffer *vbuf)
- +{
- + vbuf->size = 50;
- + vbuf->ptr = vbuf->buffer = xmalloc (vbuf->size);
- -/* Subroutine of variable_expand and friends:
- - The text to add is LENGTH chars starting at STRING to the variable_buffer.
- - The text is added to the buffer at PTR, and the updated pointer into
- - the buffer is returned as the value. Thus, the value returned by
- - each call to variable_buffer_output should be the first argument to
- - the following call. */
- +// memset(vbuf->buffer, 0x7f, vbuf->size);
- + *vbuf->ptr = '\0';
- -char *
- -variable_buffer_output (char *ptr, const char *string, unsigned int length)
- + return vbuf;
- +}
- +
- +struct vbuffer *
- +vbuffer_reset (struct vbuffer *vbuf)
- {
- - register unsigned int newlen = length + (ptr - variable_buffer);
- + vbuf->ptr = vbuf->buffer;
- - if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
- - {
- - unsigned int offset = ptr - variable_buffer;
- - variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
- - ? newlen + 100
- - : 2 * variable_buffer_length);
- - variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
- - ptr = variable_buffer + offset;
- - }
- + *vbuf->ptr = '\0';
- - memcpy (ptr, string, length);
- - return ptr + length;
- + return vbuf;
- }
- -/* Return a pointer to the beginning of the variable buffer. */
- +#ifdef __GNUC__
- +__inline
- +#endif
- +static void
- +vbuffer_grow (struct vbuffer *vbuf, size_t newlen)
- +{
- + size_t oldlen = vbuf->size;
- + size_t offset = vbuf->ptr - vbuf->buffer;
- -static char *
- -initialize_variable_output (void)
- + newlen = newlen + 100 > 2 * oldlen
- + ? newlen + 100 : 2 * oldlen;
- +
- + vbuf->buffer = xrealloc (vbuf->buffer, newlen);
- + vbuf->ptr = vbuf->buffer + offset;
- +// memset(vbuf->ptr + 1, 0x7f, vbuf->size - offset - 1);
- + vbuf->size = newlen;
- +}
- +
- +#ifdef __GNUC__
- +__inline
- +#endif
- +size_t
- +vbuffer_reserve (struct vbuffer *o, size_t length)
- {
- - /* If we don't have a variable output buffer yet, get one. */
- + size_t newoff = (o->ptr - o->buffer) + length;
- - if (variable_buffer == 0)
- - {
- - variable_buffer_length = 200;
- - variable_buffer = xmalloc (variable_buffer_length);
- - variable_buffer[0] = '\0';
- - }
- + if ((newoff + VARIABLE_BUFFER_ZONE) > o->size)
- + vbuffer_grow (o, newoff);
- - return variable_buffer;
- + return o->size - newoff;
- }
- -
- -/* Recursively expand V. The returned string is malloc'd. */
- -static char *allocated_variable_append (const struct variable *v);
- +/* Writes byte stream pointed by STR into VBUF.
- + The optional LEN argument can be used to limit the amount of bytes to copy.
- + Otherwise (if LEN is a negative number) STR is treated as a null-terminated
- + string and copied accordingly.
- -char *
- -recursively_expand_for_file (struct variable *v, struct file *file)
- + Returns the actual number of bytes copied,
- + that is LEN argument if it is non-negative and strlen (STR) otherwise.
- +
- + As like all the other vbuffer methods it leaves the internal buffer
- + of the VBUF null-terminated. */
- +
- +#ifdef __GNUC__
- +__inline
- +#endif
- +size_t
- +vbuffer_write (struct vbuffer *o, const char *str, ssize_t len)
- {
- - char *value;
- - const struct floc *this_var;
- - const struct floc **saved_varp;
- - struct variable_set_list *save = 0;
- - int set_reading = 0;
- + size_t length = len < 0 ? strlen(str) : (size_t) len;
- - /* Don't install a new location if this location is empty.
- - This can happen for command-line variables, builtin variables, etc. */
- - saved_varp = expanding_var;
- - if (v->fileinfo.filenm)
- - {
- - this_var = &v->fileinfo;
- - expanding_var = &this_var;
- - }
- +// if ((*vbuf->ptr != '\0')
- +// || (vbuf->ptr > vbuf->buffer + strlen(vbuf->buffer))
- +// || strchr(vbuf->buffer, 0x7f)) {
- +// error (reading_file, "buffer: %s", vbuf->buffer);
- +// error (reading_file, " ptr: %s", vbuf->ptr);
- +// assert (0);
- +// }
- - /* If we have no other file-reading context, use the variable's context. */
- - if (!reading_file)
- - {
- - set_reading = 1;
- - reading_file = &v->fileinfo;
- - }
- + vbuffer_reserve (o, length);
- - if (v->expanding)
- - {
- - if (!v->exp_count)
- - /* Expanding V causes infinite recursion. Lose. */
- - fatal (*expanding_var,
- - _("Recursive variable '%s' references itself (eventually)"),
- - v->name);
- - --v->exp_count;
- - }
- + memcpy (o->ptr, str, length);
- + o->ptr += length;
- - if (file)
- - {
- - save = current_variable_set_list;
- - current_variable_set_list = file->variables;
- - }
- + *o->ptr = '\0';
- - v->expanding = 1;
- - if (v->append)
- - value = allocated_variable_append (v);
- - else
- - value = allocated_variable_expand (v->value);
- - v->expanding = 0;
- + return length;
- +}
- - if (set_reading)
- - reading_file = 0;
- +/* Moves the pointer of the VBUF back on the LEN bytes.
- + If LEN is negative, or if moving the pointer would lead to an underflow,
- + then sets the pointer to the start of the buffer.
- - if (file)
- - current_variable_set_list = save;
- + Returns the actual number of discarded bytes. */
- - expanding_var = saved_varp;
- +size_t
- +vbuffer_unwrite (struct vbuffer *o, ssize_t len)
- +{
- + size_t oldoff = o->ptr - o->buffer;
- + size_t length = len < 0 ? oldoff : (size_t) len;
- +
- + if (length > oldoff)
- + length = oldoff;
- - return value;
- + o->ptr -= length;
- +
- + *o->ptr = '\0';
- +
- + return length;
- }
- /* Expand a simple reference to variable NAME, which is LENGTH chars long. */
- @@ -156,75 +159,130 @@
- #ifdef __GNUC__
- __inline
- #endif
- -static char *
- -reference_variable (char *o, const char *name, unsigned int length)
- +static size_t
- +expand_variable_reference (struct vbuffer *o, const char *name, size_t length)
- {
- struct variable *v;
- - char *value;
- v = lookup_variable (name, length);
- + o->ptr[0] = 0;
- if (v == 0)
- warn_undefined (name, length);
- /* If there's no variable by that name or it has no value, stop now. */
- if (v == 0 || (*v->value == '\0' && !v->append))
- - return o;
- -
- - value = (v->recursive ? recursively_expand (v) : v->value);
- -
- - o = variable_buffer_output (o, value, strlen (value));
- + return 0;
- if (v->recursive)
- - free (value);
- -
- - return o;
- + return vbuffer_expand_variable (o, v);
- + else
- + return vbuffer_write (o, v->value, -1);
- }
- -
- -/* Scan STRING for variable references and expansion-function calls. Only
- - LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until
- - a null byte is found.
- -
- - Write the results to LINE, which must point into 'variable_buffer'. If
- - LINE is NULL, start at the beginning of the buffer.
- - Return a pointer to LINE, or to the beginning of the buffer if LINE is
- - NULL.
- - */
- -char *
- -variable_expand_string (char *line, const char *string, long length)
- +
- +
- +#ifdef __GNUC__
- +__inline
- +#endif
- +static int
- +handle_subst_reference (struct vbuffer *o, char *beg, char *end)
- {
- + size_t result = 0;
- struct variable *v;
- - const char *p, *p1;
- - char *save;
- - char *o;
- - unsigned int line_offset;
- -
- - if (!line)
- - line = initialize_variable_output();
- - o = line;
- - line_offset = line - variable_buffer;
- + const char *subst_beg, *subst_end, *replace_beg, *replace_end;
- + char *colon = lindex (beg, end, ':');
- +
- + if (colon == 0)
- + return -1;
- +
- + subst_beg = colon + 1;
- + subst_end = lindex (subst_beg, end, '=');
- + if (subst_end == 0)
- + /* There is no = in sight. Punt on the substitution reference and treat
- + this as a variable name containing a colon. */
- + return -1;
- +
- + /* This looks like a valid substitution reference: $(FOO:A=B). */
- + replace_beg = subst_end + 1;
- + replace_end = end;
- +
- + /* Extract the variable name before the colon and look up that variable. */
- + v = lookup_variable (beg, colon - beg);
- + if (v == 0)
- + warn_undefined (beg, colon - beg);
- - if (length == 0)
- + /* If the variable is not empty, perform the substitution. */
- + if (v != 0 && *v->value != '\0')
- {
- - variable_buffer_output (o, "", 1);
- - return (variable_buffer);
- + char *pattern, *replace, *ppercent, *rpercent;
- + char *value = (v->recursive
- + ? recursively_expand(v)
- + : v->value);
- +
- + /* Copy the pattern and the replacement. Add in an extra % at the
- + beginning to use in case there isn't one in the pattern. */
- + pattern = alloca (subst_end - subst_beg + 2);
- + *(pattern++) = '%';
- + memcpy (pattern, subst_beg, subst_end - subst_beg);
- + pattern[subst_end - subst_beg] = '\0';
- +
- + replace = alloca (replace_end - replace_beg + 2);
- + *(replace++) = '%';
- + memcpy (replace, replace_beg, replace_end - replace_beg);
- + replace[replace_end - replace_beg] = '\0';
- +
- + /* Look for %. Set the percent pointers properly
- + based on whether we find one or not. */
- + ppercent = find_percent (pattern);
- + if (ppercent)
- + {
- + ++ppercent;
- + rpercent = find_percent (replace);
- + if (rpercent)
- + ++rpercent;
- + }
- + else
- + {
- + ppercent = pattern--;
- + rpercent = replace--;
- + }
- +
- + *o->ptr = '\0';
- +
- + result = patsubst_expand_pat (o, value,
- + pattern, replace, ppercent, rpercent);
- +
- + if (v->recursive)
- + free (value);
- }
- - /* We need a copy of STRING: due to eval, it's possible that it will get
- - freed as we process it (it might be the value of a variable that's reset
- - for example). Also having a nil-terminated string is handy. */
- - save = length < 0 ? xstrdup (string) : xstrndup (string, length);
- - p = save;
- + return result;
- +}
- +
- +size_t
- +vbuffer_expand (struct vbuffer *o, char *str, ssize_t len)
- +{
- + size_t result = 0;
- + char *p, *p1;
- +
- + if (len == 0)
- + return 0;
- + if (len > 0)
- + str[len] = '\0';
- +
- + p = str;
- while (1)
- {
- /* Copy all following uninteresting chars all at once to the
- - variable output buffer, and skip them. Uninteresting chars end
- + variable output buffer, and skip them. Uninteresting chars end
- at the next $ or the end of the input. */
- p1 = strchr (p, '$');
- - o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
- + /* In case when P1 is nil,
- + 'vbuffer_write' writes the whole string pointed by P. */
- + result += vbuffer_write (o, p, p1 - p);
- if (p1 == 0)
- break;
- @@ -236,27 +294,23 @@
- {
- case '$':
- /* $$ seen means output one $ to the variable output buffer. */
- - o = variable_buffer_output (o, p, 1);
- + result += vbuffer_write (o, p, 1);
- break;
- case '(':
- case '{':
- /* $(...) or ${...} is the general case of substitution. */
- {
- + int handle_ret;
- char openparen = *p;
- char closeparen = (openparen == '(') ? ')' : '}';
- - const char *begp;
- - const char *beg = p + 1;
- - char *op;
- - char *abeg = NULL;
- - const char *end, *colon;
- -
- - op = o;
- - begp = p;
- - if (handle_function (&op, &begp))
- + char *beg = p + 1;
- + char *end;
- +
- + handle_ret = handle_function (o, &p);
- + if (handle_ret >= 0)
- {
- - o = op;
- - p = begp;
- + result += handle_ret;
- break;
- }
- @@ -265,8 +319,8 @@
- end = strchr (beg, closeparen);
- if (end == 0)
- - /* Unterminated variable reference. */
- - fatal (*expanding_var, _("unterminated variable reference"));
- + fatal (*expanding_var, _("unterminated variable reference"));
- +
- p1 = lindex (beg, end, '$');
- if (p1 != 0)
- {
- @@ -285,102 +339,40 @@
- such as '$($(a)'. */
- if (count < 0)
- {
- - abeg = expand_argument (beg, p); /* Expand the name. */
- - beg = abeg;
- - end = strchr (beg, '\0');
- + /* Expand the name.
- + As a little optimization we reuse the same vbuffer. */
- + size_t name_len = vbuffer_expand (o, beg, p - beg);
- + *p = closeparen;
- +
- + /* We don't use 'vbuffer_unwrite' here because it would
- + reset the first byte of the computed name to nil. */
- + o->ptr -= name_len;
- +
- + beg = o->ptr;
- + end = beg + name_len;
- +
- }
- }
- else
- /* Advance P to the end of this reference. After we are
- - finished expanding this one, P will be incremented to
- - continue the scan. */
- + finished expanding this one, P will be incremented to
- + continue the scan. */
- p = end;
- /* This is not a reference to a built-in function and
- any variable references inside are now expanded.
- Is the resultant text a substitution reference? */
- - colon = lindex (beg, end, ':');
- - if (colon)
- + handle_ret = handle_subst_reference(o, beg, end);
- + if (handle_ret >= 0)
- {
- - /* This looks like a substitution reference: $(FOO:A=B). */
- - const char *subst_beg, *subst_end, *replace_beg, *replace_end;
- -
- - subst_beg = colon + 1;
- - subst_end = lindex (subst_beg, end, '=');
- - if (subst_end == 0)
- - /* There is no = in sight. Punt on the substitution
- - reference and treat this as a variable name containing
- - a colon, in the code below. */
- - colon = 0;
- - else
- - {
- - replace_beg = subst_end + 1;
- - replace_end = end;
- -
- - /* Extract the variable name before the colon
- - and look up that variable. */
- - v = lookup_variable (beg, colon - beg);
- - if (v == 0)
- - warn_undefined (beg, colon - beg);
- -
- - /* If the variable is not empty, perform the
- - substitution. */
- - if (v != 0 && *v->value != '\0')
- - {
- - char *pattern, *replace, *ppercent, *rpercent;
- - char *value = (v->recursive
- - ? recursively_expand (v)
- - : v->value);
- -
- - /* Copy the pattern and the replacement. Add in an
- - extra % at the beginning to use in case there
- - isn't one in the pattern. */
- - pattern = alloca (subst_end - subst_beg + 2);
- - *(pattern++) = '%';
- - memcpy (pattern, subst_beg, subst_end - subst_beg);
- - pattern[subst_end - subst_beg] = '\0';
- -
- - replace = alloca (replace_end - replace_beg + 2);
- - *(replace++) = '%';
- - memcpy (replace, replace_beg,
- - replace_end - replace_beg);
- - replace[replace_end - replace_beg] = '\0';
- -
- - /* Look for %. Set the percent pointers properly
- - based on whether we find one or not. */
- - ppercent = find_percent (pattern);
- - if (ppercent)
- - {
- - ++ppercent;
- - rpercent = find_percent (replace);
- - if (rpercent)
- - ++rpercent;
- - }
- - else
- - {
- - ppercent = pattern;
- - rpercent = replace;
- - --pattern;
- - --replace;
- - }
- -
- - o = patsubst_expand_pat (o, value, pattern, replace,
- - ppercent, rpercent);
- -
- - if (v->recursive)
- - free (value);
- - }
- - }
- + result += handle_ret;
- + break;
- }
- - if (colon == 0)
- - /* This is an ordinary variable reference.
- - Look up the value of the variable. */
- - o = reference_variable (o, beg, end - beg);
- -
- - if (abeg)
- - free (abeg);
- + /* This is an ordinary variable reference.
- + Look up the value of the variable. */
- + result += expand_variable_reference(o, beg, end - beg);
- }
- break;
- @@ -393,7 +385,7 @@
- /* A $ followed by a random char is a variable reference:
- $a is equivalent to $(a). */
- - o = reference_variable (o, p, 1);
- + result += expand_variable_reference(o, p, 1);
- break;
- }
- @@ -404,69 +396,19 @@
- ++p;
- }
- - free (save);
- -
- - variable_buffer_output (o, "", 1);
- - return (variable_buffer + line_offset);
- -}
- -
- -/* Scan LINE for variable references and expansion-function calls.
- - Build in 'variable_buffer' the result of expanding the references and calls.
- - Return the address of the resulting string, which is null-terminated
- - and is valid only until the next time this function is called. */
- -
- -char *
- -variable_expand (const char *line)
- -{
- - return variable_expand_string(NULL, line, (long)-1);
- -}
- -
- -/* Expand an argument for an expansion function.
- - The text starting at STR and ending at END is variable-expanded
- - into a null-terminated string that is returned as the value.
- - This is done without clobbering 'variable_buffer' or the current
- - variable-expansion that is in progress. */
- -
- -char *
- -expand_argument (const char *str, const char *end)
- -{
- - char *tmp, *alloc = NULL;
- - char *r;
- -
- - if (str == end)
- - return xstrdup("");
- -
- - if (!end || *end == '\0')
- - return allocated_variable_expand (str);
- -
- - if (end - str + 1 > 1000)
- - tmp = alloc = xmalloc (end - str + 1);
- - else
- - tmp = alloca (end - str + 1);
- -
- - memcpy (tmp, str, end - str);
- - tmp[end - str] = '\0';
- -
- - r = allocated_variable_expand (tmp);
- -
- - if (alloc)
- - free (alloc);
- + return result;
- - return r;
- }
- -
- -/* Expand LINE for FILE. Error messages refer to the file and line where
- - FILE's commands were found. Expansion uses FILE's variable set list. */
- -char *
- -variable_expand_for_file (const char *line, struct file *file)
- -{
- - char *result;
- +size_t
- +vbuffer_expand_for_file (struct vbuffer *o, char *str, ssize_t len,
- + struct file *file) {
- + size_t result = 0;
- struct variable_set_list *savev;
- const struct floc *savef;
- if (file == 0)
- - return variable_expand (line);
- + return vbuffer_expand (o, str, len);
- savev = current_variable_set_list;
- current_variable_set_list = file->variables;
- @@ -477,124 +419,248 @@
- else
- reading_file = 0;
- - result = variable_expand (line);
- + result = vbuffer_expand (o, str, len);
- current_variable_set_list = savev;
- reading_file = savef;
- return result;
- }
- -
- +
- /* Like allocated_variable_expand, but for += target-specific variables.
- First recursively construct the variable value from its appended parts in
- any upper variable sets. Then expand the resulting value. */
- -static char *
- -variable_append (const char *name, unsigned int length,
- - const struct variable_set_list *set, int local)
- +static size_t
- +expand_variable_append (struct vbuffer *o,
- + const char *name, unsigned int length,
- + const struct variable_set_list *set_list,
- + int local)
- {
- + size_t ret = 0;
- const struct variable *v;
- - char *buf = 0;
- - /* If this set is local and the next is not a parent, then next is local. */
- - int nextlocal = local && set->next_is_parent == 0;
- + int nextlocal;
- /* If there's nothing left to check, return the empty buffer. */
- - if (!set)
- - return initialize_variable_output ();
- + if (!set_list)
- + return 0;
- +
- + /* If this set is local and the next is not a parent, then next is local. */
- + nextlocal = local && set_list->next_is_parent == 0;
- /* Try to find the variable in this variable set. */
- - v = lookup_variable_in_set (name, length, set->set);
- + v = lookup_variable_in_set (name, length, set_list->set);
- /* If there isn't one, or this one is private, try the set above us. */
- if (!v || (!local && v->private_var))
- - return variable_append (name, length, set->next, nextlocal);
- + return expand_variable_append (o, name, length,
- + set_list->next, nextlocal);
- /* If this variable type is append, first get any upper values.
- If not, initialize the buffer. */
- if (v->append)
- - buf = variable_append (name, length, set->next, nextlocal);
- - else
- - buf = initialize_variable_output ();
- + ret += expand_variable_append (o, name, length,
- + set_list->next, nextlocal);
- /* Append this value to the buffer, and return it.
- If we already have a value, first add a space. */
- - if (buf > variable_buffer)
- - buf = variable_buffer_output (buf, " ", 1);
- + if (ret != 0)
- + ret += vbuffer_write (o, " ", 1);
- /* Either expand it or copy it, depending. */
- - if (! v->recursive)
- - return variable_buffer_output (buf, v->value, strlen (v->value));
- + if (v->recursive)
- + {
- + char *value = xstrdup (v->value);
- + ret += vbuffer_expand (o, value, -1);
- + free (value);
- + }
- + else
- + ret += vbuffer_write (o, v->value, -1);
- +
- + return ret;
- +}
- +
- +size_t
- +vbuffer_expand_variable_for_file (struct vbuffer *o, struct variable *v,
- + struct file *file)
- +{
- + size_t ret = 0;
- + const struct floc *this_var;
- + const struct floc **saved_varp;
- + struct variable_set_list *save = 0;
- + int set_reading = 0;
- +
- + /* Don't install a new location if this location is empty.
- + This can happen for command-line variables, builtin variables, etc. */
- + saved_varp = expanding_var;
- + if (v->fileinfo.filenm)
- + {
- + this_var = &v->fileinfo;
- + expanding_var = &this_var;
- + }
- +
- + /* If we have no other file-reading context, use the variable's context. */
- + if (!reading_file)
- + {
- + set_reading = 1;
- + reading_file = &v->fileinfo;
- + }
- +
- + if (v->expanding)
- + {
- + if (!v->exp_count)
- + /* Expanding V causes infinite recursion. Lose. */
- + fatal (*expanding_var,
- + _("Recursive variable '%s' references itself (eventually)"),
- + v->name);
- + --v->exp_count;
- + }
- +
- + if (file)
- + {
- + save = current_variable_set_list;
- + current_variable_set_list = file->variables;
- + }
- +
- + v->expanding = 1;
- + if (v->append)
- + ret += expand_variable_append (o, v->name, strlen (v->name),
- + current_variable_set_list, 1);
- + else
- + {
- + /* We need a copy of STRING: due to eval, it's possible that it will get
- + freed as we process it (it might be the value of a variable that's
- + reset, for example). Also having a nil-terminated string is handy. */
- + char *value = xstrdup (v->value);
- + ret += vbuffer_expand (o, value, -1);
- + free (value);
- + }
- + v->expanding = 0;
- +
- + if (set_reading)
- + reading_file = 0;
- +
- + if (file)
- + current_variable_set_list = save;
- - buf = variable_expand_string (buf, v->value, strlen (v->value));
- - return (buf + strlen (buf));
- + expanding_var = saved_varp;
- +
- + return ret;
- }
- +size_t
- +vbuffer_expand_ro (struct vbuffer *o, const char *str, ssize_t len)
- +{
- + size_t ret;
- + char *string = len < 0 ? xstrdup (str) : xstrndup (str, len);
- + ret = vbuffer_expand (o, string, -1);
- + free (string);
- + return ret;
- +}
- -static char *
- -allocated_variable_append (const struct variable *v)
- +size_t
- +vbuffer_expand_ro_for_file (struct vbuffer *o, const char *str, ssize_t len,
- + struct file *file)
- {
- - char *val;
- + size_t ret;
- + char *string = len < 0 ? xstrdup (str) : xstrndup (str, len);
- + ret = vbuffer_expand_for_file (o, string, -1, file);
- + free (string);
- + return ret;
- +}
- +
- +/* Install a new expansion vbuffer, returning the current one. */
- - /* Construct the appended variable value. */
- +struct vbuffer *
- +install_new_expansion_vbuffer (void)
- +{
- + struct vbuffer *old_vbuf = expansion_vbuf;
- - char *obuf = variable_buffer;
- - unsigned int olen = variable_buffer_length;
- + expansion_vbuf = xmalloc(sizeof(struct vbuffer));
- + vbuffer_init(expansion_vbuf);
- - variable_buffer = 0;
- + return old_vbuf;
- +}
- - val = variable_append (v->name, strlen (v->name),
- - current_variable_set_list, 1);
- - variable_buffer_output (val, "", 1);
- - val = variable_buffer;
- +/* Restore a previously-saved vbuffer setting freeing the current one. */
- - variable_buffer = obuf;
- - variable_buffer_length = olen;
- +void
- +restore_expansion_vbuffer (struct vbuffer *old_vbuf)
- +{
- + vbuffer_free(expansion_vbuf);
- + free(expansion_vbuf);
- - return val;
- + expansion_vbuf = old_vbuf;
- }
- -/* Like variable_expand_for_file, but the returned string is malloc'd.
- - This function is called a lot. It wants to be efficient. */
- +/* Expand an argument for an expansion function.
- + The text starting at STR and ending at END is variable-expanded
- + into a null-terminated string that is returned as the value.
- + This is done without clobbering 'variable_buffer' or the current
- + variable-expansion that is in progress. */
- char *
- -allocated_variable_expand_for_file (const char *line, struct file *file)
- +expand_argument (const char *str, const char *end)
- {
- - char *value;
- + struct vbuffer vbuf;
- - char *obuf = variable_buffer;
- - unsigned int olen = variable_buffer_length;
- + vbuffer_expand_ro (vbuffer_init(&vbuf), str, end - str);
- - variable_buffer = 0;
- + return vbuf.buffer;
- +}
- - value = variable_expand_for_file (line, file);
- +/* Scan LINE for variable references and expansion-function calls.
- + Build in 'variable_buffer' the result of expanding the references and calls.
- + Return the address of the resulting string, which is null-terminated
- + and is valid only until the next time this function is called. */
- - variable_buffer = obuf;
- - variable_buffer_length = olen;
- +char *
- +variable_expand (const char *line)
- +{
- + vbuffer_expand_ro (vbuffer_reset(expansion_vbuf), line, -1);
- - return value;
- + return expansion_vbuf->buffer;
- }
- -/* Install a new variable_buffer context, returning the current one for
- - safe-keeping. */
- +/* Expand LINE for FILE. Error messages refer to the file and line where
- + FILE's commands were found. Expansion uses FILE's variable set list. */
- -void
- -install_variable_buffer (char **bufp, unsigned int *lenp)
- +char *
- +variable_expand_for_file (const char *line, struct file *file)
- {
- - *bufp = variable_buffer;
- - *lenp = variable_buffer_length;
- + vbuffer_expand_ro_for_file (vbuffer_reset(expansion_vbuf), line, -1, file);
- - variable_buffer = 0;
- - initialize_variable_output ();
- + return expansion_vbuf->buffer;
- }
- -/* Restore a previously-saved variable_buffer setting (free the current one).
- - */
- +char *
- +allocated_variable_expand (const char *line)
- +{
- + struct vbuffer vbuf;
- -void
- -restore_variable_buffer (char *buf, unsigned int len)
- + vbuffer_expand_ro (vbuffer_init(&vbuf), line, -1);
- +
- + return vbuf.buffer;
- +}
- +
- +/* Like variable_expand_for_file, but the returned string is malloc'd. */
- +
- +char *
- +allocated_variable_expand_for_file (const char *line, struct file *file)
- {
- - free (variable_buffer);
- + struct vbuffer vbuf;
- +
- + vbuffer_expand_ro_for_file (vbuffer_init(&vbuf), line, -1, file);
- +
- + return vbuf.buffer;
- +}
- +
- +char *
- +recursively_expand_for_file (struct variable *v, struct file *file)
- +{
- + struct vbuffer vbuf;
- +
- + vbuffer_expand_variable_for_file (vbuffer_init(&vbuf), v, file);
- - variable_buffer = buf;
- - variable_buffer_length = len;
- + return vbuf.buffer;
- }
- Index: file.c
- ===================================================================
- RCS file: /sources/make/make/file.c,v
- retrieving revision 1.105
- diff -u -r1.105 file.c
- --- file.c 5 Mar 2012 14:10:43 -0000 1.105
- +++ file.c 15 Mar 2012 21:19:13 -0000
- @@ -467,63 +467,66 @@
- if (stem)
- {
- const char *pattern = "%";
- - char *buffer = variable_expand ("");
- + struct vbuffer vbuf;
- struct dep *dp = deps, *dl = 0;
- + vbuffer_init (&vbuf);
- +
- while (dp != 0)
- - {
- - char *percent;
- - int nl = strlen (dp->name) + 1;
- - char *nm = alloca (nl);
- - memcpy (nm, dp->name, nl);
- - percent = find_percent (nm);
- - if (percent)
- - {
- - char *o;
- -
- - /* We have to handle empty stems specially, because that
- - would be equivalent to $(patsubst %,dp->name,) which
- - will always be empty. */
- - if (stem[0] == '\0')
- - {
- - memmove (percent, percent+1, strlen (percent));
- - o = variable_buffer_output (buffer, nm, strlen (nm) + 1);
- - }
- - else
- - o = patsubst_expand_pat (buffer, stem, pattern, nm,
- - pattern+1, percent+1);
- -
- - /* If the name expanded to the empty string, ignore it. */
- - if (buffer[0] == '\0')
- - {
- - struct dep *df = dp;
- - if (dp == deps)
- - dp = deps = deps->next;
- - else
- - dp = dl->next = dp->next;
- - free_dep (df);
- - continue;
- - }
- -
- - /* Save the name. */
- - dp->name = strcache_add_len (buffer, o - buffer);
- - }
- - dp->stem = stem;
- - dp->staticpattern = 1;
- - dl = dp;
- - dp = dp->next;
- - }
- + {
- + char *percent;
- + int nl = strlen (dp->name) + 1;
- + char *nm = alloca (nl);
- + memcpy (nm, dp->name, nl);
- + percent = find_percent (nm);
- + if (percent)
- + {
- + size_t len;
- +
- + /* We have to handle empty stems specially, because that
- + would be equivalent to $(patsubst %,dp->name,) which
- + will always be empty. */
- + if (*stem == '\0')
- + {
- + memmove (percent, percent+1, strlen (percent));
- + len = vbuffer_write (vbuffer_reset (&vbuf), nm, -1);
- + }
- + else
- + len = patsubst_expand_pat (vbuffer_reset (&vbuf), stem,
- + pattern, nm,
- + pattern+1, percent+1);
- +
- + /* If the name expanded to the empty string, ignore it. */
- + if (len == 0)
- + {
- + struct dep *df = dp;
- + if (dp == deps)
- + dp = deps = deps->next;
- + else
- + dp = dl->next = dp->next;
- + free_dep (df);
- + continue;
- + }
- +
- + /* Save the name. */
- + dp->name = strcache_add_len (vbuf.buffer, len);
- + }
- + dp->stem = stem;
- + dp->staticpattern = 1;
- + dl = dp;
- + dp = dp->next;
- + }
- }
- /* Enter them as files, unless they need a 2nd expansion. */
- for (d1 = deps; d1 != 0; d1 = d1->next)
- {
- if (d1->need_2nd_expansion)
- - continue;
- + continue;
- d1->file = lookup_file (d1->name);
- if (d1->file == 0)
- - d1->file = enter_file (d1->name);
- + d1->file = enter_file (d1->name);
- d1->staticpattern = 0;
- d1->name = 0;
- }
- @@ -573,12 +576,10 @@
- "$*" so they'll expand properly. */
- if (d->staticpattern)
- {
- - char *o;
- - d->name = o = variable_expand ("");
- - o = subst_expand (o, name, "%", "$*", 1, 2, 0);
- - *o = '\0';
- + struct vbuffer vbuf;
- + subst_expand (vbuffer_init(&vbuf), name, "%", "$*", 1, 2, 0);
- free (name);
- - d->name = name = xstrdup (d->name);
- + d->name = name = xstrdup (vbuf.buffer);
- d->staticpattern = 0;
- }
- Index: function.c
- ===================================================================
- RCS file: /sources/make/make/function.c,v
- retrieving revision 1.133
- diff -u -r1.133 function.c
- --- function.c 5 Mar 2012 14:10:43 -0000 1.133
- +++ function.c 15 Mar 2012 21:19:14 -0000
- @@ -34,7 +34,7 @@
- unsigned char minimum_args;
- unsigned char maximum_args;
- char expand_args;
- - char *(*func_ptr) (char *output, char **argv, const char *fname);
- + size_t (*func_ptr) (struct vbuffer *output, char **argv, const char *fname);
- };
- static unsigned long
- @@ -71,20 +71,23 @@
- nonzero, substitutions are done only on matches which are complete
- whitespace-delimited words. */
- -char *
- -subst_expand (char *o, const char *text, const char *subst, const char *replace,
- - unsigned int slen, unsigned int rlen, int by_word)
- +size_t
- +subst_expand (struct vbuffer *o, const char *text, const char *subst,
- + const char *replace, unsigned int slen, unsigned int rlen,
- + int by_word)
- {
- + size_t result = 0;
- +
- const char *t = text;
- const char *p;
- if (slen == 0 && !by_word)
- {
- /* The first occurrence of "" in any string is its end. */
- - o = variable_buffer_output (o, t, strlen (t));
- + result += vbuffer_write (o, t, -1);
- if (rlen > 0)
- - o = variable_buffer_output (o, replace, rlen);
- - return o;
- + result += vbuffer_write (o, replace, rlen);
- + return result;
- }
- do
- @@ -99,14 +102,14 @@
- if (p == 0)
- {
- /* No more matches. Output everything left on the end. */
- - o = variable_buffer_output (o, t, strlen (t));
- - return o;
- + result += vbuffer_write (o, t, -1);
- + return result;
- }
- }
- /* Output everything before this occurrence of the string to replace. */
- if (p > t)
- - o = variable_buffer_output (o, t, p - t);
- + result += vbuffer_write (o, t, p - t);
- /* If we're substituting only by fully matched words,
- or only at the ends of words, check that this case qualifies. */
- @@ -115,16 +118,16 @@
- || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
- /* Struck out. Output the rest of the string that is
- no longer to be replaced. */
- - o = variable_buffer_output (o, subst, slen);
- + result += vbuffer_write (o, subst, slen);
- else if (rlen > 0)
- /* Output the replacement string. */
- - o = variable_buffer_output (o, replace, rlen);
- + result += vbuffer_write (o, replace, rlen);
- /* Advance T past the string to be replaced. */
- t = p + slen;
- } while (*t != '\0');
- - return o;
- + return result;
- }
- @@ -138,16 +141,17 @@
- character _AFTER_ the %, not to the % itself.
- */
- -char *
- -patsubst_expand_pat (char *o, const char *text,
- +size_t
- +patsubst_expand_pat (struct vbuffer *o, const char *text,
- const char *pattern, const char *replace,
- const char *pattern_percent, const char *replace_percent)
- {
- + size_t result = 0;
- +
- unsigned int pattern_prepercent_len, pattern_postpercent_len;
- unsigned int replace_prepercent_len, replace_postpercent_len;
- const char *t;
- unsigned int len;
- - int doneany = 0;
- /* Record the length of REPLACE before and after the % so we don't have to
- compute these lengths more than once. */
- @@ -197,40 +201,34 @@
- if (fail)
- /* It didn't match. Output the string. */
- - o = variable_buffer_output (o, t, len);
- + result += vbuffer_write (o, t, len);
- else
- {
- /* It matched. Output the replacement. */
- /* Output the part of the replacement before the %. */
- - o = variable_buffer_output (o, replace, replace_prepercent_len);
- + result += vbuffer_write (o, replace, replace_prepercent_len);
- if (replace_percent != 0)
- {
- /* Output the part of the matched string that
- matched the % in the pattern. */
- - o = variable_buffer_output (o, t + pattern_prepercent_len,
- - len - (pattern_prepercent_len
- + result += vbuffer_write (o, t + pattern_prepercent_len,
- + len - (pattern_prepercent_len
- + pattern_postpercent_len));
- /* Output the part of the replacement after the %. */
- - o = variable_buffer_output (o, replace_percent,
- - replace_postpercent_len);
- + result += vbuffer_write (o, replace_percent,
- + replace_postpercent_len);
- }
- }
- /* Output a space, but not if the replacement is "". */
- if (fail || replace_prepercent_len > 0
- || (replace_percent != 0 && len + replace_postpercent_len > 0))
- - {
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- - }
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill the last space. */
- - --o;
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- /* Store into VARIABLE_BUFFER at O the result of scanning TEXT
- @@ -243,8 +241,9 @@
- character _AFTER_ the %, not to the % itself.
- */
- -char *
- -patsubst_expand (char *o, const char *text, char *pattern, char *replace)
- +size_t
- +patsubst_expand (struct vbuffer *o, const char *text, char *pattern,
- + char *replace)
- {
- const char *pattern_percent = find_percent (pattern);
- const char *replace_percent = find_percent (replace);
- @@ -256,7 +255,7 @@
- ++pattern_percent;
- return patsubst_expand_pat (o, text, pattern, replace,
- - pattern_percent, replace_percent);
- + pattern_percent, replace_percent);
- }
- @@ -310,38 +309,6 @@
- }
- -/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
- - ENDPARENtheses), starting at PTR before END. Return a pointer to
- - next character.
- -
- - If no next argument is found, return NULL.
- -*/
- -
- -static char *
- -find_next_argument (char startparen, char endparen,
- - const char *ptr, const char *end)
- -{
- - int count = 0;
- -
- - for (; ptr < end; ++ptr)
- - if (*ptr == startparen)
- - ++count;
- -
- - else if (*ptr == endparen)
- - {
- - --count;
- - if (count < 0)
- - return NULL;
- - }
- -
- - else if (*ptr == ',' && !count)
- - return (char *)ptr;
- -
- - /* We didn't find anything. */
- - return NULL;
- -}
- -
- -
- /* Glob-expand LINE. The returned pointer is
- only good until the next call to string_glob. */
- @@ -399,18 +366,17 @@
- Builtin functions
- */
- -static char *
- -func_patsubst (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_patsubst (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- - o = patsubst_expand (o, argv[2], argv[0], argv[1]);
- - return o;
- + return patsubst_expand (o, argv[2], argv[0], argv[1]);
- }
- -static char *
- -func_join (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_join (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- - int doneany = 0;
- + size_t result = 0;
- /* Write each word of the first argument directly followed
- by the corresponding word of the second argument.
- @@ -420,87 +386,87 @@
- const char *pp;
- const char *list1_iterator = argv[0];
- const char *list2_iterator = argv[1];
- +
- do
- {
- unsigned int len1, len2;
- tp = find_next_token (&list1_iterator, &len1);
- if (tp != 0)
- - o = variable_buffer_output (o, tp, len1);
- + result += vbuffer_write (o, tp, len1);
- pp = find_next_token (&list2_iterator, &len2);
- if (pp != 0)
- - o = variable_buffer_output (o, pp, len2);
- + result += vbuffer_write (o, pp, len2);
- if (tp != 0 || pp != 0)
- - {
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- - }
- + result += vbuffer_write (o, " ", 1);
- }
- while (tp != 0 || pp != 0);
- - if (doneany)
- - /* Kill the last blank. */
- - --o;
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_origin (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_origin (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* Expand the argument. */
- struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
- +
- if (v == 0)
- - o = variable_buffer_output (o, "undefined", 9);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("undefined"));
- else
- switch (v->origin)
- {
- - default:
- - case o_invalid:
- - abort ();
- - break;
- case o_default:
- - o = variable_buffer_output (o, "default", 7);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("default"));
- break;
- case o_env:
- - o = variable_buffer_output (o, "environment", 11);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("environment"));
- break;
- case o_file:
- - o = variable_buffer_output (o, "file", 4);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("file"));
- break;
- case o_env_override:
- - o = variable_buffer_output (o, "environment override", 20);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("environment override"));
- break;
- case o_command:
- - o = variable_buffer_output (o, "command line", 12);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("command line"));
- break;
- case o_override:
- - o = variable_buffer_output (o, "override", 8);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("override"));
- break;
- case o_automatic:
- - o = variable_buffer_output (o, "automatic", 9);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("automatic"));
- + break;
- + case o_invalid:
- + default:
- + abort ();
- break;
- }
- - return o;
- + return result;
- }
- -static char *
- -func_flavor (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_flavor (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
- if (v == 0)
- - o = variable_buffer_output (o, "undefined", 9);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("undefined"));
- else
- if (v->recursive)
- - o = variable_buffer_output (o, "recursive", 9);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("recursive"));
- else
- - o = variable_buffer_output (o, "simple", 6);
- + result += vbuffer_write (o, STRING_SIZE_TUPLE("simple"));
- - return o;
- + return result;
- }
- #ifdef VMS
- @@ -514,14 +480,15 @@
- #endif
- -static char *
- -func_notdir_suffix (char *o, char **argv, const char *funcname)
- +static size_t
- +func_notdir_suffix (struct vbuffer *o, char **argv, const char *funcname)
- {
- + size_t result = 0;
- +
- /* Expand the argument. */
- const char *list_iterator = argv[0];
- const char *p2;
- - int doneany =0;
- - unsigned int len=0;
- + unsigned int len = 0;
- int is_suffix = funcname[0] == 's';
- int is_notdir = !is_suffix;
- @@ -529,7 +496,6 @@
- {
- const char *p = p2 + len;
- -
- while (p >= p2 && (!is_suffix || *p != '.'))
- {
- if (IS_PATHSEP (*p))
- @@ -543,41 +509,35 @@
- ++p;
- else if (*p != '.')
- continue;
- - o = variable_buffer_output (o, p, len - (p - p2));
- + result += vbuffer_write (o, p, len - (p - p2));
- }
- #ifdef HAVE_DOS_PATHS
- /* Handle the case of "d:foo/bar". */
- else if (is_notdir && p2[0] && p2[1] == ':')
- {
- p = p2 + 2;
- - o = variable_buffer_output (o, p, len - (p - p2));
- + result += vbuffer_write (o, p, len - (p - p2));
- }
- #endif
- else if (is_notdir)
- - o = variable_buffer_output (o, p2, len);
- + result += vbuffer_write (o, p2, len);
- if (is_notdir || p >= p2)
- - {
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- - }
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill last space. */
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_basename_dir (char *o, char **argv, const char *funcname)
- +static size_t
- +func_basename_dir (struct vbuffer *o, char **argv, const char *funcname)
- {
- + size_t result = 0;
- +
- /* Expand the argument. */
- const char *p3 = argv[0];
- const char *p2;
- - int doneany = 0;
- unsigned int len = 0;
- int is_basename = funcname[0] == 'b';
- @@ -594,111 +554,105 @@
- }
- if (p >= p2 && (is_dir))
- - o = variable_buffer_output (o, p2, ++p - p2);
- + result += vbuffer_write (o, p2, ++p - p2);
- else if (p >= p2 && (*p == '.'))
- - o = variable_buffer_output (o, p2, p - p2);
- + result += vbuffer_write (o, p2, p - p2);
- #ifdef HAVE_DOS_PATHS
- /* Handle the "d:foobar" case */
- else if (p2[0] && p2[1] == ':' && is_dir)
- - o = variable_buffer_output (o, p2, 2);
- + result += vbuffer_write (o, p2, 2);
- #endif
- else if (is_dir)
- #ifdef VMS
- - o = variable_buffer_output (o, "[]", 2);
- + result += vbuffer_write (o, "[]", 2);
- #else
- #ifndef _AMIGA
- - o = variable_buffer_output (o, "./", 2);
- + result += vbuffer_write (o, "./", 2);
- #else
- ; /* Just a nop... */
- #endif /* AMIGA */
- #endif /* !VMS */
- else
- /* The entire name is the basename. */
- - o = variable_buffer_output (o, p2, len);
- + result += vbuffer_write (o, p2, len);
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill last space. */
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
- +static size_t
- +func_addsuffix_addprefix (struct vbuffer *o, char **argv, const char *funcname)
- {
- + size_t result = 0;
- +
- int fixlen = strlen (argv[0]);
- const char *list_iterator = argv[1];
- - int is_addprefix = funcname[3] == 'p';
- + int is_addprefix = funcname[CSTRLEN("add")] == 'p';
- int is_addsuffix = !is_addprefix;
- - int doneany = 0;
- const char *p;
- unsigned int len;
- while ((p = find_next_token (&list_iterator, &len)) != 0)
- {
- if (is_addprefix)
- - o = variable_buffer_output (o, argv[0], fixlen);
- - o = variable_buffer_output (o, p, len);
- + result += vbuffer_write (o, argv[0], fixlen);
- + result += vbuffer_write (o, p, len);
- if (is_addsuffix)
- - o = variable_buffer_output (o, argv[0], fixlen);
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, argv[0], fixlen);
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill last space. */
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_subst (char *o, char **argv, const char *funcname UNUSED)
- -{
- - o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
- - strlen (argv[1]), 0);
- - return o;
- +static size_t
- +func_subst (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- +{
- + return subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
- + strlen (argv[1]), 0);
- }
- -static char *
- -func_firstword (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_firstword (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- - unsigned int i;
- + size_t result = 0;
- +
- + unsigned int len;
- const char *words = argv[0]; /* Use a temp variable for find_next_token */
- - const char *p = find_next_token (&words, &i);
- + const char *p = find_next_token (&words, &len);
- if (p != 0)
- - o = variable_buffer_output (o, p, i);
- + result += vbuffer_write (o, p, len);
- - return o;
- + return result;
- }
- -static char *
- -func_lastword (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_lastword (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- - unsigned int i;
- + size_t result = 0;
- +
- + unsigned int len;
- const char *words = argv[0]; /* Use a temp variable for find_next_token */
- const char *p = NULL;
- const char *t;
- - while ((t = find_next_token (&words, &i)))
- + while ((t = find_next_token (&words, &len)))
- p = t;
- if (p != 0)
- - o = variable_buffer_output (o, p, i);
- + result += vbuffer_write (o, p, len);
- - return o;
- + return result;
- }
- -static char *
- -func_words (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_words (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- int i = 0;
- const char *word_iterator = argv[0];
- @@ -708,9 +662,8 @@
- ++i;
- sprintf (buf, "%d", i);
- - o = variable_buffer_output (o, buf, strlen (buf));
- - return o;
- + return vbuffer_write (o, buf, -1);
- }
- /* Set begpp to point to the first non-whitespace character of the string,
- @@ -744,10 +697,11 @@
- }
- -
- -static char *
- -func_word (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_word (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- const char *end_p;
- const char *p;
- int i;
- @@ -766,14 +720,17 @@
- break;
- if (i == 0)
- - o = variable_buffer_output (o, p, end_p - p);
- + result += vbuffer_write (o, p, end_p - p);
- - return o;
- + return result;
- }
- -static char *
- -func_wordlist (char *o, char **argv, const char *funcname UNUSED)
- +
- +static size_t
- +func_wordlist (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- int start, count;
- /* Check the arguments. */
- @@ -805,32 +762,35 @@
- ;
- /* Return the stuff in the middle. */
- - o = variable_buffer_output (o, p, end_p - p);
- + result += vbuffer_write (o, p, end_p - p);
- }
- }
- - return o;
- + return result;
- }
- -static char *
- -func_findstring (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_findstring (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* Find the first occurrence of the first string in the second. */
- if (strstr (argv[1], argv[0]) != 0)
- - o = variable_buffer_output (o, argv[0], strlen (argv[0]));
- + result += vbuffer_write (o, argv[0], strlen (argv[0]));
- - return o;
- + return result;
- }
- -static char *
- -func_foreach (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_foreach (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* expand only the first two. */
- char *varname = expand_argument (argv[0], NULL);
- char *list = expand_argument (argv[1], NULL);
- const char *body = argv[2];
- - int doneany = 0;
- const char *list_iterator = list;
- const char *p;
- unsigned int len;
- @@ -842,28 +802,24 @@
- /* loop through LIST, put the value in VAR and expand BODY */
- while ((p = find_next_token (&list_iterator, &len)) != 0)
- {
- - char *result = 0;
- + char *expansion = 0;
- free (var->value);
- var->value = xstrndup (p, len);
- - result = allocated_variable_expand (body);
- + expansion = allocated_variable_expand (body);
- - o = variable_buffer_output (o, result, strlen (result));
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- - free (result);
- - }
- + result += vbuffer_write (o, expansion, strlen (expansion));
- + result += vbuffer_write (o, " ", 1);
- - if (doneany)
- - /* Kill the last space. */
- - --o;
- + free (expansion);
- + }
- pop_variable_scope ();
- free (varname);
- free (list);
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- struct a_word
- @@ -905,9 +861,11 @@
- int length;
- };
- -static char *
- -func_filter_filterout (char *o, char **argv, const char *funcname)
- +static size_t
- +func_filter_filterout (struct vbuffer *o, char **argv, const char *funcname)
- {
- + size_t result = 0;
- +
- struct a_word *wordhead;
- struct a_word **wordtail;
- struct a_word *wp;
- @@ -989,8 +947,6 @@
- if (words)
- {
- - int doneany = 0;
- -
- /* Run each pattern through the words, killing words. */
- for (pp = pathead; pp != 0; pp = pp->next)
- {
- @@ -1019,28 +975,25 @@
- for (wp = wordhead; wp != 0; wp = wp->next)
- if (is_filter ? wp->matched : !wp->matched)
- {
- - o = variable_buffer_output (o, wp->str, strlen (wp->str));
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, wp->str, -1);
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill the last space. */
- - --o;
- }
- if (hashing)
- hash_free (&a_word_table, 0);
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_strip (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_strip (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- const char *p = argv[0];
- - int doneany = 0;
- while (*p != '\0')
- {
- @@ -1051,26 +1004,21 @@
- ++p;
- word_start = p;
- for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
- - {}
- + ;
- if (!i)
- break;
- - o = variable_buffer_output (o, word_start, i);
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, word_start, i);
- + result += vbuffer_write (o, " ", 1);
- }
- - if (doneany)
- - /* Kill the last space. */
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- /*
- Print a warning or fatal message.
- */
- -static char *
- -func_error (char *o, char **argv, const char *funcname)
- +size_t
- +func_error (struct vbuffer *o UNUSED, char **argv, const char *funcname)
- {
- char **argvp;
- char *msg, *p;
- @@ -1111,16 +1059,18 @@
- }
- /* The warning function expands to the empty string. */
- - return o;
- + return 0;
- }
- /*
- chop argv[0] into words, and sort them.
- */
- -static char *
- -func_sort (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_sort (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- const char *t;
- char **words;
- int wordi;
- @@ -1133,7 +1083,8 @@
- wordi = 0;
- while ((p = find_next_token (&t, NULL)) != 0)
- {
- - ++t;
- + if (*t != '\0')
- + ++t;
- ++wordi;
- }
- @@ -1144,7 +1095,8 @@
- wordi = 0;
- while ((p = find_next_token (&t, &len)) != 0)
- {
- - ++t;
- + if (*t != '\0')
- + ++t;
- p[len] = '\0';
- words[wordi++] = p;
- }
- @@ -1161,18 +1113,18 @@
- if (i == wordi - 1 || strlen (words[i + 1]) != len
- || strcmp (words[i], words[i + 1]))
- {
- - o = variable_buffer_output (o, words[i], len);
- - o = variable_buffer_output (o, " ", 1);
- + result += vbuffer_write (o, words[i], len);
- + result += vbuffer_write (o, " ", 1);
- }
- }
- /* Kill the last space. */
- - --o;
- + result -= vbuffer_unwrite (o, 1);
- }
- free (words);
- - return o;
- + return result;
- }
- /*
- @@ -1187,9 +1139,11 @@
- example).
- */
- -static char *
- -func_if (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_if (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t ret = 0;
- +
- const char *begp = argv[0];
- const char *endp = begp + strlen (argv[0]) - 1;
- int result = 0;
- @@ -1218,12 +1172,12 @@
- {
- char *expansion = expand_argument (*argv, NULL);
- - o = variable_buffer_output (o, expansion, strlen (expansion));
- + ret += vbuffer_write (o, expansion, strlen (expansion));
- free (expansion);
- }
- - return o;
- + return ret;
- }
- /*
- @@ -1240,15 +1194,17 @@
- (short-circuiting).
- */
- -static char *
- -func_or (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_or (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t ret = 0;
- +
- for ( ; *argv ; ++argv)
- {
- const char *begp = *argv;
- const char *endp = begp + strlen (*argv) - 1;
- char *expansion;
- - int result = 0;
- + int result;
- /* Find the result of the condition: if it's false keep going. */
- @@ -1268,12 +1224,12 @@
- }
- /* It's true! Keep this result and return. */
- - o = variable_buffer_output (o, expansion, result);
- + ret += vbuffer_write (o, expansion, result);
- free (expansion);
- break;
- }
- - return o;
- + return ret;
- }
- /*
- @@ -1290,21 +1246,23 @@
- (short-circuiting).
- */
- -static char *
- -func_and (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_and (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t ret = 0;
- +
- char *expansion;
- - int result;
- while (1)
- {
- const char *begp = *argv;
- const char *endp = begp + strlen (*argv) - 1;
- + int result;
- /* An empty condition is always false. */
- strip_whitespace (&begp, &endp);
- if (begp > endp)
- - return o;
- + return 0;
- expansion = expand_argument (begp, endp+1);
- result = strlen (expansion);
- @@ -1320,26 +1278,29 @@
- free (expansion);
- else
- {
- - o = variable_buffer_output (o, expansion, result);
- + ret += vbuffer_write (o, expansion, result);
- break;
- }
- }
- free (expansion);
- - return o;
- + return ret;
- }
- -static char *
- -func_wildcard (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_wildcard (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- #ifdef _AMIGA
- o = wildcard_expansion (argv[0], o);
- #else
- char *p = string_glob (argv[0]);
- - o = variable_buffer_output (o, p, strlen (p));
- + result += vbuffer_write (o, p, strlen (p));
- #endif
- - return o;
- +
- + return result;
- }
- /*
- @@ -1350,36 +1311,38 @@
- Treat the arguments as a segment of makefile, and parse them.
- */
- -static char *
- -func_eval (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_eval (struct vbuffer *o UNUSED, char **argv, const char *funcname UNUSED)
- {
- - char *buf;
- - unsigned int len;
- + struct vbuffer *vbuf;
- /* Eval the buffer. Pop the current variable buffer setting so that the
- eval'd code can use its own without conflicting. */
- - install_variable_buffer (&buf, &len);
- + vbuf = install_new_expansion_vbuffer ();
- eval_buffer (argv[0]);
- - restore_variable_buffer (buf, len);
- + restore_expansion_vbuffer (vbuf);
- - return o;
- + /* Eval always expands to nothing. */
- + return 0;
- }
- -static char *
- -func_value (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_value (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* Look up the variable. */
- struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
- /* Copy its value into the output buffer without expanding it. */
- if (v)
- - o = variable_buffer_output (o, v->value, strlen(v->value));
- + result += vbuffer_write (o, v->value, -1);
- - return o;
- + return result;
- }
- /*
- @@ -1619,9 +1582,10 @@
- #else
- #ifndef _AMIGA
- -char *
- -func_shell_base (char *o, char **argv, int trim_newlines)
- +size_t
- +func_shell_base (struct vbuffer *o, char **argv, int trim_newlines)
- {
- + size_t result = 0;
- char *batch_filename = NULL;
- #ifdef __MSDOS__
- @@ -1650,7 +1614,7 @@
- #ifdef WINDOWS32
- just_print_flag = j_p_f;
- #endif
- - return o;
- + return 0;
- }
- #endif
- @@ -1683,7 +1647,7 @@
- if (pipedes[0] < 0)
- {
- perror_with_name (error_prefix, "pipe");
- - return o;
- + return 0;
- }
- #elif defined(WINDOWS32)
- windows32_openpipe (pipedes, &pid, command_argv, envp);
- @@ -1694,14 +1658,14 @@
- {
- /* Open of the pipe failed, mark as failed execution. */
- shell_function_completed = -1;
- - return o;
- + return 0;
- }
- else
- #else
- if (pipe (pipedes) < 0)
- {
- perror_with_name (error_prefix, "pipe");
- - return o;
- + return 0;
- }
- # ifdef __EMX__
- @@ -1800,13 +1764,13 @@
- /* The child finished normally. Replace all newlines in its output
- with spaces, and put that in the variable output buffer. */
- fold_newlines (buffer, &i, trim_newlines);
- - o = variable_buffer_output (o, buffer, i);
- + result += vbuffer_write (o, buffer, i);
- }
- free (buffer);
- }
- - return o;
- + return result;
- }
- #else /* _AMIGA */
- @@ -1892,14 +1856,14 @@
- Close (child_stdout);
- fold_newlines (buffer, &i, trim_newlines);
- - o = variable_buffer_output (o, buffer, i);
- + result += vbuffer_write (o, buffer, i);
- free (buffer);
- return o;
- }
- #endif /* _AMIGA */
- -char *
- -func_shell (char *o, char **argv, const char *funcname UNUSED)
- +size_t
- +func_shell (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- return func_shell_base (o, argv, 1);
- }
- @@ -1914,8 +1878,7 @@
- func_eq (char *o, char **argv, char *funcname UNUSED)
- {
- int result = ! strcmp (argv[0], argv[1]);
- - o = variable_buffer_output (o, result ? "1" : "", result);
- - return o;
- + return vbuffer_write (o, result ? "1" : "", result);
- }
- @@ -1930,8 +1893,7 @@
- while (isspace ((unsigned char)*s))
- s++;
- result = ! (*s);
- - o = variable_buffer_output (o, result ? "1" : "", result);
- - return o;
- + return vbuffer_write (o, result ? "1" : "", result);
- }
- #endif
- @@ -2058,13 +2020,14 @@
- }
- -static char *
- -func_realpath (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_realpath (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* Expand the argument. */
- const char *p = argv[0];
- const char *path = 0;
- - int doneany = 0;
- unsigned int len = 0;
- #ifndef HAVE_REALPATH
- struct stat st;
- @@ -2087,22 +2050,17 @@
- #endif
- )
- {
- - o = variable_buffer_output (o, out, strlen (out));
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, out, -1);
- + result += vbuffer_write (o, " ", 1);
- }
- }
- }
- - /* Kill last space. */
- - if (doneany)
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- -static char *
- -func_file (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_file (struct vbuffer *o UNUSED, char **argv, const char *funcname UNUSED)
- {
- char *fn = argv[0];
- @@ -2137,16 +2095,17 @@
- else
- fatal (reading_file, _("Invalid file operation: %s"), fn);
- - return o;
- + return 0;
- }
- -static char *
- -func_abspath (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_abspath (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- /* Expand the argument. */
- const char *p = argv[0];
- const char *path = 0;
- - int doneany = 0;
- unsigned int len = 0;
- PATH_VAR (in);
- PATH_VAR (out);
- @@ -2160,18 +2119,13 @@
- if (abspath (in, out))
- {
- - o = variable_buffer_output (o, out, strlen (out));
- - o = variable_buffer_output (o, " ", 1);
- - doneany = 1;
- + result += vbuffer_write (o, out, strlen (out));
- + result += vbuffer_write (o, " ", 1);
- }
- }
- }
- - /* Kill last space. */
- - if (doneany)
- - --o;
- -
- - return o;
- + return result - vbuffer_unwrite (o, !!result);
- }
- /* Lookup table for builtin functions.
- @@ -2186,7 +2140,7 @@
- EXPAND_ARGS means that all arguments should be expanded before invocation.
- Functions that do namespace tricks (foreach) don't automatically expand. */
- -static char *func_call (char *o, char **argv, const char *funcname);
- +static size_t func_call (struct vbuffer *o, char **argv, const char *funcname);
- static struct function_table_entry function_table_init[] =
- @@ -2239,8 +2193,8 @@
- /* These must come after the definition of function_table. */
- -static char *
- -expand_builtin_function (char *o, int argc, char **argv,
- +static size_t
- +expand_builtin_function (struct vbuffer *o, int argc, char **argv,
- const struct function_table_entry *entry_p)
- {
- if (argc < (int)entry_p->minimum_args)
- @@ -2253,7 +2207,7 @@
- rather than in each one. We can change it later if necessary. */
- if (!argc)
- - return o;
- + return 0;
- if (!entry_p->func_ptr)
- fatal (*expanding_var,
- @@ -2265,45 +2219,64 @@
- /* Check for a function invocation in *STRINGP. *STRINGP points at the
- opening ( or { and is not null-terminated. If a function invocation
- is found, expand it into the buffer at *OP, updating *OP, incrementing
- - *STRINGP past the reference and returning nonzero. If not, return zero. */
- + *STRINGP past the reference and returning the amount of bytes written.
- + If not, return -1. */
- int
- -handle_function (char **op, const char **stringp)
- +handle_function (struct vbuffer *o, char **stringp)
- {
- + size_t result = 0;
- +
- const struct function_table_entry *entry_p;
- char openparen = (*stringp)[0];
- char closeparen = openparen == '(' ? ')' : '}';
- - const char *beg;
- - const char *end;
- - int count = 0;
- - char *abeg = NULL;
- + char *beg;
- + char *end;
- + int count;
- char **argv, **argvp;
- - int nargs;
- + int nargs, maxargs;
- + struct vbuffer argbuf;
- beg = *stringp + 1;
- entry_p = lookup_function (beg);
- if (!entry_p)
- - return 0;
- + return -1;
- +
- + vbuffer_init(&argbuf);
- /* We found a builtin function. Find the beginning of its arguments (skip
- whitespace after the name). */
- beg = next_token (beg + entry_p->len);
- + maxargs = entry_p->maximum_args;
- /* Find the end of the function invocation, counting nested use of
- whichever kind of parens we use. Since we're looking, count commas
- to get a rough estimate of how many arguments we might have. The
- count might be high, but it'll never be low. */
- - for (nargs=1, end=beg; *end != '\0'; ++end)
- - if (*end == ',')
- - ++nargs;
- - else if (*end == openparen)
- +
- + nargs=1;
- + *((char **) argbuf.ptr) = beg;
- + argbuf.ptr += sizeof (char *);
- +
- + count = 0;
- + for (end=beg; *end != '\0'; ++end)
- + if (*end == openparen)
- ++count;
- else if (*end == closeparen && --count < 0)
- break;
- + else if (count == 0 && *end == ',' && nargs != maxargs)
- + {
- + *end = '\0';
- + nargs++;
- +
- + vbuffer_reserve(&argbuf, sizeof (char *));
- + *((char **) argbuf.ptr) = end + 1;
- + argbuf.ptr += sizeof (char *);
- + }
- if (count >= 0)
- fatal (*expanding_var,
- @@ -2312,8 +2285,14 @@
- *stringp = end;
- - /* Get some memory to store the arg pointers. */
- - argvp = argv = alloca (sizeof (char *) * (nargs + 2));
- + *end = '\0';
- +
- + /* NULL-terminate the arg vector. */
- + vbuffer_reserve(&argbuf, sizeof (char *));
- + *((char **) argbuf.ptr) = NULL;
- + argbuf.ptr += sizeof (char *);
- +
- + argv = (char **) argbuf.buffer;
- /* Chop the string into arguments, then a nul. As soon as we hit
- MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
- @@ -2325,59 +2304,30 @@
- if (entry_p->expand_args)
- {
- - const char *p;
- - for (p=beg, nargs=0; p <= end; ++argvp)
- - {
- - const char *next;
- -
- - ++nargs;
- -
- - if (nargs == entry_p->maximum_args
- - || (! (next = find_next_argument (openparen, closeparen, p, end))))
- - next = end;
- -
- - *argvp = expand_argument (p, next);
- - p = next + 1;
- - }
- - }
- - else
- - {
- - int len = end - beg;
- - char *p, *aend;
- -
- - abeg = xmalloc (len+1);
- - memcpy (abeg, beg, len);
- - abeg[len] = '\0';
- - aend = abeg + len;
- -
- - for (p=abeg, nargs=0; p <= aend; ++argvp)
- - {
- - char *next;
- -
- - ++nargs;
- -
- - if (nargs == entry_p->maximum_args
- - || (! (next = find_next_argument (openparen, closeparen, p, aend))))
- - next = aend;
- -
- - *argvp = p;
- - *next = '\0';
- - p = next + 1;
- - }
- + int i;
- + size_t *offs = alloca ((nargs + 1) * sizeof (size_t));
- + argv = memcpy (alloca ((nargs + 1) * sizeof (char *)),
- + argv, (nargs + 1) * sizeof (char *));
- +
- + vbuffer_reset(&argbuf);
- + offs[0] = 0;
- + for (i=0, argvp=argv; *argvp != 0; ++argvp, ++i)
- + {
- + offs[i + 1] = offs[i] + vbuffer_expand (&argbuf, *argvp, -1) + 1;
- + *argbuf.ptr++ = '\0';
- + }
- + for (i=0, argvp=argv; *argvp != 0; ++argvp, ++i)
- + *argvp = argbuf.buffer + offs[i];
- }
- - *argvp = NULL;
- /* Finally! Run the function... */
- - *op = expand_builtin_function (*op, nargs, argv, entry_p);
- + result += expand_builtin_function (o, nargs, argv, entry_p);
- - /* Free memory. */
- - if (entry_p->expand_args)
- - for (argvp=argv; *argvp != 0; ++argvp)
- - free (*argvp);
- - else if (abeg)
- - free (abeg);
- + *end = closeparen;
- - return 1;
- + vbuffer_free(&argbuf);
- +
- + return result;
- }
- @@ -2385,9 +2335,11 @@
- function or a make variable, in the context of the rest of the arguments
- assigned to $1, $2, ... $N. $0 is the name of the function. */
- -static char *
- -func_call (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_call (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- static int max_args = 0;
- char *fname;
- char *cp;
- @@ -2411,7 +2363,7 @@
- /* Calling nothing is a no-op */
- if (*fname == '\0')
- - return o;
- + return 0;
- /* Are we invoking a builtin function? */
- @@ -2434,7 +2386,7 @@
- warn_undefined (fname, flen);
- if (v == 0 || *v->value == '\0')
- - return o;
- + return 0;
- body = alloca (flen + 4);
- body[0] = '$';
- @@ -2475,20 +2427,20 @@
- saved_args = max_args;
- max_args = i;
- - o = variable_expand_string (o, body, flen+3);
- + result += vbuffer_expand (o, body, flen+3);
- max_args = saved_args;
- v->exp_count = 0;
- pop_variable_scope ();
- - return o + strlen (o);
- + return result;
- }
- void
- define_new_function(const struct floc *flocp,
- const char *name, int min, int max, int expand,
- - char *(*func)(char *, char **, const char *))
- + size_t (*func)(struct vbuffer *, char **, const char *))
- {
- size_t len = strlen (name);
- struct function_table_entry *ent = xmalloc (sizeof (struct function_table_entry));
- Index: guile.c
- ===================================================================
- RCS file: /sources/make/make/guile.c,v
- retrieving revision 2.5
- diff -u -r2.5 guile.c
- --- guile.c 5 Mar 2012 14:10:44 -0000 2.5
- +++ guile.c 15 Mar 2012 21:19:14 -0000
- @@ -86,20 +86,22 @@
- }
- /* This is the function registered with make */
- -static char *
- -func_guile (char *o, char **argv, const char *funcname UNUSED)
- +static size_t
- +func_guile (struct vbuffer *o, char **argv, const char *funcname UNUSED)
- {
- + size_t result = 0;
- +
- if (argv[0] && argv[0][0] != '\0')
- {
- char *str = scm_with_guile (internal_guile_eval, argv[0]);
- if (str)
- {
- - o = variable_buffer_output (o, str, strlen (str));
- + result += vbuffer_write (o, str, -1);
- free (str);
- }
- }
- - return o;
- + return result;
- }
- /* ----- Public interface ----- */
- Index: main.c
- ===================================================================
- RCS file: /sources/make/make/main.c,v
- retrieving revision 1.256
- diff -u -r1.256 main.c
- --- main.c 5 Mar 2012 14:10:44 -0000 1.256
- +++ main.c 15 Mar 2012 21:19:15 -0000
- @@ -1104,6 +1104,8 @@
- initialize_global_hash_tables ();
- + install_new_expansion_vbuffer();
- +
- /* Figure out where we are. */
- #ifdef WINDOWS32
- @@ -2277,12 +2279,7 @@
- if (default_goal_var->recursive)
- p = variable_expand (default_goal_var->value);
- else
- - {
- - p = variable_buffer_output (variable_buffer, default_goal_var->value,
- - strlen (default_goal_var->value));
- - *p = '\0';
- - p = variable_buffer;
- - }
- + p = default_goal_var->value;
- if (*p != '\0')
- {
- Index: read.c
- ===================================================================
- RCS file: /sources/make/make/read.c,v
- retrieving revision 1.210
- diff -u -r1.210 read.c
- --- read.c 5 Mar 2012 14:10:44 -0000 1.210
- +++ read.c 15 Mar 2012 21:19:15 -0000
- @@ -566,6 +566,7 @@
- const char *pattern_percent;
- struct floc *fstart;
- struct floc fi;
- + struct vbuffer vbuf;
- #define record_waiting_files() \
- do \
- @@ -583,6 +584,8 @@
- pattern = 0; \
- } while (0)
- + vbuffer_init(&vbuf);
- +
- pattern_percent = 0;
- cmds_started = tgts_started = 1;
- @@ -893,6 +896,7 @@
- {
- enum make_word_type wtype;
- char *cmdleft, *semip, *lb_next;
- + unsigned int llen = 0;
- unsigned int plen = 0;
- char *colonp;
- const char *end, *beg; /* Helpers for whitespace stripping. */
- @@ -943,42 +947,44 @@
- break;
- }
- - p2 = variable_expand_string(NULL, lb_next, wlen);
- -
- - while (1)
- - {
- - lb_next += wlen;
- - if (cmdleft == 0)
- - {
- - /* Look for a semicolon in the expanded line. */
- - cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
- + vbuffer_expand_ro (vbuffer_reset(&vbuf), lb_next, wlen);
- + p2 = vbuf.buffer;
- - if (cmdleft != 0)
- - {
- - unsigned long p2_off = p2 - variable_buffer;
- - unsigned long cmd_off = cmdleft - variable_buffer;
- - char *pend = p2 + strlen(p2);
- -
- - /* Append any remnants of lb, then cut the line short
- - at the semicolon. */
- - *cmdleft = '\0';
- -
- - /* One school of thought says that you shouldn't expand
- - here, but merely copy, since now you're beyond a ";"
- - and into a command script. However, the old parser
- - expanded the whole line, so we continue that for
- - backwards-compatiblity. Also, it wouldn't be
- - entirely consistent, since we do an unconditional
- - expand below once we know we don't have a
- - target-specific variable. */
- - (void)variable_expand_string(pend, lb_next, (long)-1);
- - lb_next += strlen(lb_next);
- - p2 = variable_buffer + p2_off;
- - cmdleft = variable_buffer + cmd_off + 1;
- - }
- - }
- + while (1)
- + {
- + lb_next += wlen;
- + if (cmdleft == 0)
- + {
- + /* Look for a semicolon in the expanded line. */
- + cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
- +
- + if (cmdleft != 0)
- + {
- + unsigned long p2_off = p2 - vbuf.buffer;
- + unsigned long cmd_off = cmdleft - vbuf.buffer;
- +
- + /* Append any remnants of lb, then cut the line short
- + at the semicolon. */
- + *cmdleft = '\0';
- +
- + /* One school of thought says that you shouldn't expand
- + here, but merely copy, since now you're beyond a ";"
- + and into a command script. However, the old parser
- + expanded the whole line, so we continue that for
- + backwards-compatibility. Also, it wouldn't be
- + entirely consistent, since we do an unconditional
- + expand below once we know we don't have a
- + target-specific variable. */
- + vbuffer_expand_ro (&vbuf, lb_next, -1);
- +
- + p2 = vbuf.buffer + p2_off;
- + cmdleft = vbuf.buffer + cmd_off + 1;
- +
- + lb_next += strlen(lb_next);
- + }
- + }
- - colonp = find_char_unquote(p2, ':', 0, 0, 0);
- + colonp = find_char_unquote(p2, ':', 0, 0, 0);
- #ifdef HAVE_DOS_PATHS
- /* The drive spec brain-damage strikes again... */
- /* Note that the only separators of targets in this context
- @@ -989,118 +995,119 @@
- (colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
- colonp = find_char_unquote(colonp + 1, ':', 0, 0, 0);
- #endif
- - if (colonp != 0)
- - break;
- -
- - wtype = get_next_mword(lb_next, NULL, &lb_next, &wlen);
- - if (wtype == w_eol)
- - break;
- -
- - p2 += strlen(p2);
- - *(p2++) = ' ';
- - p2 = variable_expand_string(p2, lb_next, wlen);
- - /* We don't need to worry about cmdleft here, because if it was
- - found in the variable_buffer the entire buffer has already
- - been expanded... we'll never get here. */
- - }
- -
- - p2 = next_token (variable_buffer);
- + if (colonp != 0)
- + break;
- - /* If the word we're looking at is EOL, see if there's _anything_
- - on the line. If not, a variable expanded to nothing, so ignore
- - it. If so, we can't parse this line so punt. */
- - if (wtype == w_eol)
- - {
- - if (*p2 != '\0')
- - /* There's no need to be ivory-tower about this: check for
- - one of the most common bugs found in makefiles... */
- - fatal (fstart, _("missing separator%s"),
- - (cmd_prefix == '\t' && !strneq (line, " ", 8))
- - ? "" : _(" (did you mean TAB instead of 8 spaces?)"));
- - continue;
- - }
- + wtype = get_next_mword(lb_next, NULL, &lb_next, &wlen);
- + if (wtype == w_eol)
- + break;
- - /* Make the colon the end-of-string so we know where to stop
- - looking for targets. Start there again once we're done. */
- - *colonp = '\0';
- - filenames = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, 0);
- - *colonp = ':';
- - p2 = colonp;
- + vbuffer_write(&vbuf, " ", 1);
- + plen = vbuffer_expand_ro (&vbuf, lb_next, wlen);
- + p2 = vbuf.ptr - plen;
- +
- + /* We don't need to worry about cmdleft here, because if it was
- + found in the variable_buffer the entire buffer has already
- + been expanded... we'll never get here. */
- + }
- - if (!filenames)
- - {
- - /* We accept and ignore rules without targets for
- - compatibility with SunOS 4 make. */
- - no_targets = 1;
- - continue;
- - }
- - /* This should never be possible; we handled it above. */
- - assert (*p2 != '\0');
- - ++p2;
- -
- - /* Is this a one-colon or two-colon entry? */
- - two_colon = *p2 == ':';
- - if (two_colon)
- - p2++;
- -
- - /* Test to see if it's a target-specific variable. Copy the rest
- - of the buffer over, possibly temporarily (we'll expand it later
- - if it's not a target-specific variable). PLEN saves the length
- - of the unparsed section of p2, for later. */
- - if (*lb_next != '\0')
- - {
- - unsigned int l = p2 - variable_buffer;
- - plen = strlen (p2);
- - variable_buffer_output (p2+plen, lb_next, strlen (lb_next)+1);
- - p2 = variable_buffer + l;
- - }
- + p2 = next_token (vbuf.buffer);
- - p2 = parse_var_assignment (p2, &vmod);
- - if (vmod.assign_v)
- - {
- - /* If there was a semicolon found, add it back, plus anything
- - after it. */
- - if (semip)
- - {
- - unsigned int l = p - variable_buffer;
- - *(--semip) = ';';
- - collapse_continuations (semip);
- - variable_buffer_output (p2 + strlen (p2),
- - semip, strlen (semip)+1);
- - p = variable_buffer + l;
- - }
- - record_target_var (filenames, p2,
- - vmod.override_v ? o_override : o_file,
- - &vmod, fstart);
- - filenames = 0;
- - continue;
- - }
- -
- - /* This is a normal target, _not_ a target-specific variable.
- - Unquote any = in the dependency list. */
- - find_char_unquote (lb_next, '=', 0, 0, 0);
- + /* If the word we're looking at is EOL, see if there's _anything_
- + on the line. If not, a variable expanded to nothing, so ignore
- + it. If so, we can't parse this line so punt. */
- + if (wtype == w_eol)
- + {
- + if (*p2 != '\0')
- + /* There's no need to be ivory-tower about this: check for
- + one of the most common bugs found in makefiles... */
- + fatal (fstart, _("missing separator%s"),
- + (cmd_prefix == '\t' && !strneq (line, " ", 8))
- + ? "" : _(" (did you mean TAB instead of 8 spaces?)"));
- + continue;
- + }
- - /* Remember the command prefix for this target. */
- - prefix = cmd_prefix;
- + /* Make the colon the end-of-string so we know where to stop
- + looking for targets. Start there again once we're done. */
- + *colonp = '\0';
- + filenames = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, 0);
- + *colonp = ':';
- + p2 = colonp;
- - /* We have some targets, so don't ignore the following commands. */
- - no_targets = 0;
- + if (!filenames)
- + {
- + /* We accept and ignore rules without targets for
- + compatibility with SunOS 4 make. */
- + no_targets = 1;
- + continue;
- + }
- + /* This should never be possible; we handled it above. */
- + assert (*p2 != '\0');
- + ++p2;
- +
- + /* Is this a one-colon or two-colon entry? */
- + two_colon = *p2 == ':';
- + if (two_colon)
- + p2++;
- +
- + /* Test to see if it's a target-specific variable. Copy the rest
- + of the buffer over, possibly temporarily (we'll expand it later
- + if it's not a target-specific variable). LLEN saves the length
- + of the copied string, to know how many bytes to discard later. */
- + if (*lb_next != '\0')
- + {
- + unsigned long p2_off = p2 - vbuf.buffer;
- + llen = vbuffer_write (&vbuf, lb_next, -1);
- + p2 = vbuf.buffer + p2_off;
- + }
- - /* Expand the dependencies, etc. */
- - if (*lb_next != '\0')
- - {
- - unsigned int l = p2 - variable_buffer;
- - (void) variable_expand_string (p2 + plen, lb_next, (long)-1);
- - p2 = variable_buffer + l;
- + p2 = parse_var_assignment (p2, &vmod);
- + if (vmod.assign_v)
- + {
- + /* If there was a semicolon found, add it back, plus anything
- + after it. */
- + if (semip)
- + {
- + unsigned long p2_off = p2 - vbuf.buffer;
- + *(--semip) = ';';
- + collapse_continuations (semip);
- + vbuffer_write (&vbuf, semip, -1);
- + p2 = vbuf.buffer + p2_off;
- + }
- + record_target_var (filenames, p2,
- + vmod.override_v ? o_override : o_file,
- + &vmod, fstart);
- + filenames = 0;
- + continue;
- + }
- - /* Look for a semicolon in the expanded line. */
- - if (cmdleft == 0)
- - {
- - cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
- - if (cmdleft != 0)
- - *(cmdleft++) = '\0';
- - }
- - }
- + /* This is a normal target, _not_ a target-specific variable.
- + Unquote any = in the dependency list. */
- + find_char_unquote (lb_next, '=', 0, 0, 0);
- +
- + /* Remember the command prefix for this target. */
- + prefix = cmd_prefix;
- +
- + /* We have some targets, so don't ignore the following commands. */
- + no_targets = 0;
- +
- + /* Expand the dependencies, etc.
- + P2 still point past the colon. */
- + if (*lb_next != '\0')
- + {
- + unsigned long p2_off = p2 - vbuf.buffer;
- + vbuffer_unwrite (&vbuf, llen);
- + vbuffer_expand_ro (&vbuf, lb_next, -1);
- + p2 = vbuf.buffer + p2_off;
- +
- + /* Look for a semicolon in the expanded line. */
- + if (cmdleft == 0)
- + {
- + cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
- + if (cmdleft != 0)
- + *(cmdleft++) = '\0';
- + }
- + }
- /* Is this a static pattern rule: 'target: %targ: %dep; ...'? */
- p = strchr (p2, ':');
- @@ -1281,8 +1288,6 @@
- record_waiting_files ();
- }
- -#undef word1eq
- -
- if (conditionals->if_cmds)
- fatal (fstart, _("missing 'endif'"));
- @@ -1292,7 +1297,13 @@
- if (collapsed)
- free (collapsed);
- free (commands);
- +
- + vbuffer_free(&vbuf);
- +
- +#undef record_waiting_files
- }
- +
- +#undef word1eq
- /* Remove comments from LINE.
- @@ -1842,6 +1853,7 @@
- struct dep *deps;
- const char *implicit_percent;
- const char *name;
- + struct vbuffer patbuf;
- /* If we've already snapped deps, that means we're in an eval being
- resolved after the makefiles have been read in. We can't add more rules
- @@ -1945,6 +1957,7 @@
- return;
- }
- + vbuffer_init (&patbuf);
- /* Walk through each target and create it in the database.
- We already set up the first target, above. */
- @@ -2057,10 +2070,12 @@
- if (pattern)
- {
- static const char *percent = "%";
- - char *buffer = variable_expand ("");
- - char *o = patsubst_expand_pat (buffer, name, pattern, percent,
- - pattern_percent+1, percent+1);
- - f->stem = strcache_add_len (buffer, o - buffer);
- + size_t len;
- +
- + len = patsubst_expand_pat (vbuffer_reset(&patbuf), name,
- + pattern, percent,
- + pattern_percent+1, percent+1);
- + f->stem = strcache_add_len (patbuf.buffer, len);
- if (this)
- {
- if (! this->need_2nd_expansion)
- @@ -2112,6 +2127,8 @@
- if (find_percent_cached (&name))
- fatal (flocp, _("mixed implicit and normal rules"));
- }
- +
- + vbuffer_free (&patbuf);
- }
- /* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero).
- Index: remake.c
- ===================================================================
- RCS file: /sources/make/make/remake.c,v
- retrieving revision 1.153
- diff -u -r1.153 remake.c
- --- remake.c 5 Mar 2012 14:10:45 -0000 1.153
- +++ remake.c 15 Mar 2012 21:19:16 -0000
- @@ -1534,12 +1534,14 @@
- const char *p2;
- unsigned int len;
- unsigned int liblen;
- + struct vbuffer vbuf;
- /* Information about the earliest (in the vpath sequence) match. */
- unsigned int best_vpath = 0, best_path = 0;
- char **dp;
- + vbuffer_init(&vbuf);
- libpatterns = xstrdup (variable_expand ("$(.LIBPATTERNS)"));
- /* Skip the '-l'. */
- @@ -1556,28 +1558,30 @@
- static unsigned int buflen = 0;
- static int libdir_maxlen = -1;
- static unsigned int std_dirs = 0;
- - char *libbuf = variable_expand ("");
- + char *libbuf;
- /* Expand the pattern using LIB as a replacement. */
- {
- char c = p[len];
- - char *p3, *p4;
- + char *percent;
- p[len] = '\0';
- - p3 = find_percent (p);
- - if (!p3)
- + percent = find_percent (p);
- + if (!percent)
- {
- /* Give a warning if there is no pattern. */
- error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
- p[len] = c;
- continue;
- }
- - p4 = variable_buffer_output (libbuf, p, p3-p);
- - p4 = variable_buffer_output (p4, lib, liblen);
- - p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
- + vbuffer_write (&vbuf, p, percent-p);
- + vbuffer_write (&vbuf, lib, liblen);
- + vbuffer_write (&vbuf, percent+1, len - (percent-p));
- p[len] = c;
- }
- + libbuf = vbuf.buffer;
- +
- /* Look first for 'libNAME.a' in the current directory. */
- mtime = name_mtime (libbuf);
- if (mtime != NONEXISTENT_MTIME)
- @@ -1660,5 +1664,7 @@
- }
- free (libpatterns);
- + vbuffer_free(&vbuf);
- +
- return file;
- }
- Index: variable.c
- ===================================================================
- RCS file: /sources/make/make/variable.c,v
- retrieving revision 1.112
- diff -u -r1.112 variable.c
- --- variable.c 5 Mar 2012 14:10:45 -0000 1.112
- +++ variable.c 15 Mar 2012 21:19:16 -0000
- @@ -966,6 +966,7 @@
- struct variable makelevel_key;
- char **result_0;
- char **result;
- + struct vbuffer vbuf;
- if (file == 0)
- set_list = current_variable_set_list;
- @@ -1053,6 +1054,8 @@
- result = result_0 = xmalloc ((table.ht_fill + 2) * sizeof (char *));
- + vbuffer_init (&vbuf);
- +
- v_slot = (struct variable **) table.ht_vec;
- v_end = v_slot + table.ht_size;
- for ( ; v_slot < v_end; v_slot++)
- @@ -1060,32 +1063,30 @@
- {
- struct variable *v = *v_slot;
- + vbuffer_reset (&vbuf);
- +
- + vbuffer_write (&vbuf, v->name, -1);
- + vbuffer_write (&vbuf, "=", 1);
- +
- /* If V is recursively expanded and didn't come from the environment,
- expand its value. If it came from the environment, it should
- go back into the environment unchanged. */
- if (v->recursive
- && v->origin != o_env && v->origin != o_env_override)
- - {
- - char *value = recursively_expand_for_file (v, file);
- -#ifdef WINDOWS32
- - if (strcmp(v->name, "Path") == 0 ||
- - strcmp(v->name, "PATH") == 0)
- - convert_Path_to_windows32(value, ';');
- -#endif
- - *result++ = xstrdup (concat (3, v->name, "=", value));
- - free (value);
- - }
- + vbuffer_expand_variable_for_file (&vbuf, v, file);
- else
- - {
- + vbuffer_write (&vbuf, v->value, -1);
- +
- #ifdef WINDOWS32
- - if (strcmp(v->name, "Path") == 0 ||
- - strcmp(v->name, "PATH") == 0)
- - convert_Path_to_windows32(v->value, ';');
- + if (strcmp(v->name, "Path") == 0 ||
- + strcmp(v->name, "PATH") == 0)
- + convert_Path_to_windows32(value, ';');
- #endif
- - *result++ = xstrdup (concat (3, v->name, "=", v->value));
- - }
- + *result++ = xstrdup (vbuf.buffer);
- }
- + vbuffer_free (&vbuf);
- +
- *result = xmalloc (100);
- sprintf (*result, "%s=%u", MAKELEVEL_NAME, makelevel + 1);
- *++result = 0;
- @@ -1116,20 +1117,14 @@
- char *
- shell_result (const char *p)
- {
- - char *buf;
- - unsigned int len;
- + struct vbuffer vbuf;
- char *args[2];
- - char *result;
- -
- - install_variable_buffer (&buf, &len);
- args[0] = (char *) p;
- args[1] = NULL;
- - variable_buffer_output (func_shell_base (variable_buffer, args, 0), "\0", 1);
- - result = strdup (variable_buffer);
- + func_shell_base (vbuffer_init(&vbuf), args, 0);
- - restore_variable_buffer (buf, len);
- - return result;
- + return vbuf.buffer;
- }
- /* Given a variable, a value, and a flavor, define the variable.
- Index: variable.h
- ===================================================================
- RCS file: /sources/make/make/variable.h,v
- retrieving revision 1.51
- diff -u -r1.51 variable.h
- --- variable.h 5 Mar 2012 14:10:45 -0000 1.51
- +++ variable.h 15 Mar 2012 21:19:16 -0000
- @@ -107,38 +107,68 @@
- struct variable variable;
- };
- -extern char *variable_buffer;
- +/* Structure used for pattern-specific variables. */
- +
- +struct vbuffer
- + {
- + char *ptr; /* Current position pointing inside the buffer. */
- + char *buffer; /* Start of the entire buffer. */
- + size_t size; /* Size of the allocated buffer. */
- + };
- +
- extern struct variable_set_list *current_variable_set_list;
- extern struct variable *default_goal_var;
- +struct vbuffer *vbuffer_init (struct vbuffer *vbuf);
- +struct vbuffer *vbuffer_reset (struct vbuffer *vbuf);
- +
- +#define vbuffer_free(vbuf) \
- + free ((vbuf)->buffer)
- +
- +size_t vbuffer_reserve (struct vbuffer *o, size_t len);
- +
- +size_t vbuffer_write (struct vbuffer *o, const char *str, ssize_t len);
- +size_t vbuffer_unwrite (struct vbuffer *o, ssize_t len);
- +
- +size_t vbuffer_expand (struct vbuffer *o, char *str, ssize_t len);
- +size_t vbuffer_expand_for_file (struct vbuffer *o, char *str, ssize_t len,
- + struct file *file);
- +
- +size_t vbuffer_expand_ro (struct vbuffer *o, const char *str, ssize_t len);
- +size_t vbuffer_expand_ro_for_file (struct vbuffer *o, const char *str,
- + ssize_t len, struct file *file);
- +
- +#define vbuffer_expand_variable(o, v) \
- + vbuffer_expand_variable_for_file (o, v, NULL)
- +size_t vbuffer_expand_variable_for_file (struct vbuffer *o,
- + struct variable *v,
- + struct file *file);
- +
- +struct vbuffer *install_new_expansion_vbuffer (void);
- +void restore_expansion_vbuffer (struct vbuffer *old_vbuf);
- +
- /* expand.c */
- -char *variable_buffer_output (char *ptr, const char *string, unsigned int length);
- +char *expand_argument (const char *str, const char *end);
- char *variable_expand (const char *line);
- char *variable_expand_for_file (const char *line, struct file *file);
- +char *allocated_variable_expand (const char *line);
- char *allocated_variable_expand_for_file (const char *line, struct file *file);
- -#define allocated_variable_expand(line) \
- - allocated_variable_expand_for_file (line, (struct file *) 0)
- -char *expand_argument (const char *str, const char *end);
- -char *variable_expand_string (char *line, const char *string, long length);
- -void install_variable_buffer (char **bufp, unsigned int *lenp);
- -void restore_variable_buffer (char *buf, unsigned int len);
- +#define recursively_expand(v) recursively_expand_for_file (v, NULL)
- +char *recursively_expand_for_file (struct variable *v, struct file *file);
- /* function.c */
- -int handle_function (char **op, const char **stringp);
- +int handle_function (struct vbuffer *vbuf, char **stringp);
- int pattern_matches (const char *pattern, const char *percent, const char *str);
- -char *subst_expand (char *o, const char *text, const char *subst,
- - const char *replace, unsigned int slen, unsigned int rlen,
- - int by_word);
- -char *patsubst_expand_pat (char *o, const char *text, const char *pattern,
- - const char *replace, const char *pattern_percent,
- - const char *replace_percent);
- -char *patsubst_expand (char *o, const char *text, char *pattern, char *replace);
- -char *func_shell_base (char *o, char **argv, int trim_newlines);
- -
- -
- -/* expand.c */
- -char *recursively_expand_for_file (struct variable *v, struct file *file);
- -#define recursively_expand(v) recursively_expand_for_file (v, NULL)
- +size_t subst_expand (struct vbuffer *vbuf, const char *text, const char *subst,
- + const char *replace, unsigned int slen, unsigned int rlen,
- + int by_word);
- +size_t patsubst_expand_pat (struct vbuffer *vbuf, const char *text,
- + const char *pattern, const char *replace,
- + const char *pattern_percent,
- + const char *replace_percent);
- +size_t patsubst_expand (struct vbuffer *vbuf, const char *text, char *pattern,
- + char *replace);
- +size_t func_shell_base (struct vbuffer *vbuf, char **argv, int trim_newlines);
- /* variable.c */
- struct variable_set_list *create_new_variable_set (void);
- @@ -167,7 +197,7 @@
- void hash_init_function_table (void);
- void define_new_function(const struct floc *flocp,
- const char *name, int min, int max, int expand,
- - char *(*func)(char *, char **, const char *));
- + size_t (*func)(struct vbuffer *, char **, const char *));
- struct variable *lookup_variable (const char *name, unsigned int length);
- struct variable *lookup_variable_in_set (const char *name, unsigned int length,
- const struct variable_set *set);
Advertisement
Add Comment
Please, Sign In to add comment