summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2023-03-25 19:15:20 -0400
committerPaul Smith <psmith@gnu.org>2023-04-01 11:13:12 -0400
commit78c8c44326f644da612088fa05c8a77c5ca17a5e (patch)
treec349118557f24adae4438fe231e3ceee78e2f548
parentcaf1d4c28fd96f1b3efec10f3978c45e5cf57aa4 (diff)
downloadmake-git-78c8c44326f644da612088fa05c8a77c5ca17a5e.tar.gz
Add functions to directly expand variables by name
Replace all locally-created "$("+varname+")" and similar constructs with calls to these new functions. * src/expand.c (expand_variable_output): Call expand_string_output() on the expansion of a variable value. Replaces reference_variable(). (expand_variable_buf): Like expand_variable_output() but return the starting location of the result. (allocated_expand_variable): Like expand_variable_buf() but return an allocated string. (expand_string_buf): Call expand_variable_output(). * src/variable.h: Declare the new functions. * src/function.c (func_call): Call expand_variable_output() instead of expand_string_buf(). * src/main.c (decode_env_switches): Call expand_variable() instead of expand_string(). * src/remake.c (library_search): Call allocated_expand_variable() instead of expand_string() plus xstrdup(). * src/vpath.c (build_vpath_lists): Expand VPATH and GPATH using expand_variable() instead of expand_string(). * src/w32/subproc/sub_proc.c (process_begin): Use expand_variable() to expand SHELL. Also use alloc() in case the result is larger than PATH_MAX.
-rw-r--r--src/expand.c97
-rw-r--r--src/function.c12
-rw-r--r--src/job.c6
-rw-r--r--src/main.c9
-rw-r--r--src/read.c4
-rw-r--r--src/remake.c2
-rw-r--r--src/variable.h6
-rw-r--r--src/vpath.c6
-rw-r--r--src/w32/subproc/sub_proc.c7
9 files changed, 103 insertions, 46 deletions
diff --git a/src/expand.c b/src/expand.c
index 25c71153..a72dfff7 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -83,7 +83,7 @@ initialize_variable_output ()
{
/* If we don't have a variable output buffer yet, get one. */
- if (variable_buffer == NULL)
+ if (!variable_buffer)
{
variable_buffer_length = 200;
variable_buffer = xmalloc (variable_buffer_length);
@@ -221,42 +221,105 @@ recursively_expand_for_file (struct variable *v, struct file *file)
return value;
}
-/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
+/* Expand a simple reference to variable NAME, which is LENGTH chars long.
+ The result is written to PTR which must point into the variable_buffer.
+ Returns a pointer to the new end of the variable_buffer. */
-#ifdef __GNUC__
-__inline
-#endif
-static char *
-reference_variable (char *o, const char *name, size_t length)
+char *
+expand_variable_output (char *ptr, const char *name, size_t length)
{
struct variable *v;
char *value;
v = lookup_variable (name, length);
- if (v == 0)
+ if (!v)
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;
+ if (!v || (v->value[0] == '\0' && !v->append))
+ return ptr;
- value = (v->recursive ? recursively_expand (v) : v->value);
+ value = v->recursive ? recursively_expand (v) : v->value;
- o = variable_buffer_output (o, value, strlen (value));
+ ptr = variable_buffer_output (ptr, value, strlen (value));
if (v->recursive)
free (value);
- return o;
+ return ptr;
+}
+
+/* Expand a simple reference to variable NAME, which is LENGTH chars long.
+ The result is written to BUF which must point into the variable_buffer.
+ If BUF is NULL, start at the beginning of the current variable_buffer.
+ Returns BUF, or the beginning of the buffer if BUF is NULL. */
+
+char *
+expand_variable_buf (char *buf, const char *name, size_t length)
+{
+ if (!buf)
+ buf = initialize_variable_output ();
+
+ expand_variable_output (buf, name, length);
+
+ return buf;
+}
+
+/* Expand a simple reference to variable NAME, which is LENGTH chars long.
+ Returns an allocated buffer containing the value. */
+
+char *
+allocated_expand_variable (const char *name, size_t length)
+{
+ char *obuf;
+ size_t olen;
+
+ install_variable_buffer (&obuf, &olen);
+
+ expand_variable_output (variable_buffer, name, length);
+
+ return swap_variable_buffer (obuf, olen);
+}
+
+/* Expand a simple reference to variable NAME, which is LENGTH chars long.
+ Error messages refer to the file and line where FILE's commands were found.
+ Expansion uses FILE's variable set list.
+ Returns an allocated buffer containing the value. */
+
+char *
+allocated_expand_variable_for_file (const char *name, size_t length, struct file *file)
+{
+ char *result;
+ struct variable_set_list *savev;
+ const floc *savef;
+
+ if (!file)
+ return allocated_expand_variable (name, length);
+
+ savev = current_variable_set_list;
+ current_variable_set_list = file->variables;
+
+ savef = reading_file;
+ if (file->cmds && file->cmds->fileinfo.filenm)
+ reading_file = &file->cmds->fileinfo;
+ else
+ reading_file = NULL;
+
+ result = allocated_expand_variable (name, length);
+
+ current_variable_set_list = savev;
+ reading_file = savef;
+
+ return result;
}
/* Scan STRING for variable references and expansion-function calls. Only
LENGTH bytes of STRING are actually scanned.
If LENGTH is SIZE_MAX, scan until a null byte is found.
- Write the results to BUF, which must point into 'variable_buffer'. If
- BUF is NULL, start at the beginning of the current 'variable_buffer'.
+ Write the results to BUF, which must point into variable_buffer. If
+ BUF is NULL, start at the beginning of the current variable_buffer.
Return a pointer to BUF, or to the beginning of the new buffer if BUF is
NULL.
@@ -445,7 +508,7 @@ expand_string_buf (char *buf, const char *string, size_t length)
if (colon == 0)
/* This is an ordinary variable reference.
Look up the value of the variable. */
- o = reference_variable (o, beg, end - beg);
+ o = expand_variable_output (o, beg, end - beg);
free (abeg);
}
@@ -457,7 +520,7 @@ expand_string_buf (char *buf, const char *string, size_t length)
/* A $ followed by a random char is a variable reference:
$a is equivalent to $(a). */
- o = reference_variable (o, p, 1);
+ o = expand_variable_output (o, p, 1);
break;
}
diff --git a/src/function.c b/src/function.c
index 8f46ec60..5ca28f85 100644
--- a/src/function.c
+++ b/src/function.c
@@ -2613,7 +2613,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
{
static unsigned int max_args = 0;
char *fname;
- char *body;
size_t flen;
unsigned int i;
int saved_args;
@@ -2651,13 +2650,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
if (v == 0 || *v->value == '\0')
return o;
- body = alloca (flen + 4);
- body[0] = '$';
- body[1] = '(';
- memcpy (body + 2, fname, flen);
- body[flen+2] = ')';
- body[flen+3] = '\0';
-
/* Set up arguments $(1) .. $(N). $(0) is the function name. */
push_new_variable_scope ();
@@ -2683,14 +2675,14 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
define_variable (num, strlen (num), "", o_automatic, 0);
}
- /* Expand the body in the context of the arguments, adding the result to
+ /* Expand the function in the context of the arguments, adding the result to
the variable buffer. */
v->exp_count = EXP_COUNT_MAX;
saved_args = max_args;
max_args = i;
- o = expand_string_buf (o, body, flen+3);
+ o = expand_variable_output (o, fname, flen);
max_args = saved_args;
v->exp_count = 0;
diff --git a/src/job.c b/src/job.c
index c7313fdb..d7b584f5 100644
--- a/src/job.c
+++ b/src/job.c
@@ -1882,7 +1882,7 @@ new_job (struct file *file)
nm, c->file->name);
else
{
- char *newer = allocated_expand_string_for_file ("$?", c->file);
+ char *newer = allocated_expand_variable_for_file (STRING_SIZE_TUPLE ("?"), c->file);
if (newer[0] != '\0')
{
OSSS (message, 0, _("%s: update target '%s' due to: %s"),
@@ -3637,7 +3637,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
int save = warn_undefined_variables_flag;
warn_undefined_variables_flag = 0;
- shell = allocated_expand_string_for_file ("$(SHELL)", file);
+ shell = allocated_expand_variable_for_file (STRING_SIZE_TUPLE ("SHELL"), file);
#if MK_OS_W32
/*
* Convert to forward slashes so that construct_command_argv_internal()
@@ -3702,7 +3702,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
else
shellflags = allocated_expand_string_for_file (var->value, file);
- ifs = allocated_expand_string_for_file ("$(IFS)", file);
+ ifs = allocated_expand_variable_for_file (STRING_SIZE_TUPLE ("IFS"), file);
warn_undefined_variables_flag = save;
}
diff --git a/src/main.c b/src/main.c
index 86497e70..16bbb83a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3328,19 +3328,12 @@ decode_switches (int argc, const char **argv, enum variable_origin origin)
static void
decode_env_switches (const char *envar, size_t len, enum variable_origin origin)
{
- char *varref = alloca (2 + len + 2);
char *value, *p, *buf;
int argc;
const char **argv;
/* Get the variable's value. */
- p = varref;
- *(p++) = '$';
- *(p++) = '(';
- p = mempcpy (p, envar, len);
- *(p++) = ')';
- *p = '\0';
- value = expand_string (varref);
+ value = expand_variable (envar, len);
/* Skip whitespace, and check for an empty value. */
NEXT_TOKEN (value);
diff --git a/src/read.c b/src/read.c
index 14f9dcee..bae836f2 100644
--- a/src/read.c
+++ b/src/read.c
@@ -186,7 +186,7 @@ read_all_makefiles (const char **makefiles)
char *name, *p;
size_t length;
- value = allocated_expand_string ("$(MAKEFILES)");
+ value = allocated_expand_variable (STRING_SIZE_TUPLE ("MAKEFILES"));
/* Set NAME to the start of next token and LENGTH to its length.
MAKEFILES is updated for finding remaining tokens. */
@@ -3071,7 +3071,7 @@ tilde_expand (const char *name)
int save = warn_undefined_variables_flag;
warn_undefined_variables_flag = 0;
- home_dir = allocated_expand_string ("$(HOME)");
+ home_dir = allocated_expand_variable (STRING_SIZE_TUPLE ("HOME"));
warn_undefined_variables_flag = save;
}
diff --git a/src/remake.c b/src/remake.c
index 7c841f5d..d5cd3b38 100644
--- a/src/remake.c
+++ b/src/remake.c
@@ -1717,7 +1717,7 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
const char **dp;
- libpatterns = xstrdup (expand_string ("$(.LIBPATTERNS)"));
+ libpatterns = allocated_expand_variable (STRING_SIZE_TUPLE (".LIBPATTERNS"));
/* Skip the '-l'. */
lib += 2;
diff --git a/src/variable.h b/src/variable.h
index 195cc360..bfba63f5 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -136,6 +136,12 @@ char *expand_argument (const char *str, const char *end);
char *recursively_expand_for_file (struct variable *v, struct file *file);
#define recursively_expand(v) recursively_expand_for_file ((v), NULL)
+char *expand_variable_output (char *ptr, const char *name, size_t length);
+char *expand_variable_buf (char *buf, const char *name, size_t length);
+#define expand_variable(n,l) expand_variable_buf (NULL, (n), (l));
+char *allocated_expand_variable (const char *name, size_t length);
+char *allocated_expand_variable_for_file (const char *name, size_t length, struct file *file);
+
/* function.c */
int handle_function (char **op, const char **stringp);
int pattern_matches (const char *pattern, const char *percent, const char *str);
diff --git a/src/vpath.c b/src/vpath.c
index 873a9c94..25c41e30 100644
--- a/src/vpath.c
+++ b/src/vpath.c
@@ -71,7 +71,8 @@ build_vpath_lists (void)
/* If there is a VPATH variable with a nonnull expanded value, construct the
general VPATH list from it. */
- p = expand_string ("$(strip $(VPATH))");
+ p = expand_variable ("VPATH", 5);
+ NEXT_TOKEN (p);
if (*p != '\0')
{
@@ -95,7 +96,8 @@ build_vpath_lists (void)
/* If there is a GPATH variable with a nonnull expanded value, construct the
GPATH list from it. */
- p = expand_string ("$(strip $(GPATH))");
+ p = expand_variable ("GPATH", 5);
+ NEXT_TOKEN (p);
if (*p != '\0')
{
diff --git a/src/w32/subproc/sub_proc.c b/src/w32/subproc/sub_proc.c
index be32d9ef..4c1611d3 100644
--- a/src/w32/subproc/sub_proc.c
+++ b/src/w32/subproc/sub_proc.c
@@ -566,10 +566,10 @@ process_begin(
char *shell_name = 0;
int file_not_found=0;
HANDLE exec_handle;
- char exec_fname[MAX_PATH];
+ char exec_fname[MAX_PATH+1];
const char *path_var = NULL;
char **ep;
- char buf[MAX_PATH];
+ char buf[MAX_PATH+1];
DWORD bytes_returned;
DWORD flags;
char *command_line;
@@ -614,8 +614,9 @@ process_begin(
char *new_argv0;
char **argvi = argv;
size_t arglen = 0;
+ char *exp = expand_variable ("SHELL", 5);
- strcpy(buf, expand_string ("$(SHELL)"));
+ memcpy (buf, exp, strlen(exp) + 1);
shell_name = &buf[0];
strcpy(exec_fname, "-c");
/* Construct a single command string in argv[0]. */