summaryrefslogtreecommitdiff
path: root/src/kmk/variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kmk/variable.c')
-rw-r--r--src/kmk/variable.c533
1 files changed, 319 insertions, 214 deletions
diff --git a/src/kmk/variable.c b/src/kmk/variable.c
index 73ec34e..125b8a5 100644
--- a/src/kmk/variable.c
+++ b/src/kmk/variable.c
@@ -1,7 +1,7 @@
/* Internals of variables for GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
-Foundation, Inc.
+1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+2010 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -46,28 +46,62 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
static struct pattern_var *pattern_vars;
-/* Pointer to last struct in the chain, so we can add onto the end. */
+/* Pointer to the last struct in the pack of a specific size, from 1 to 255.*/
-static struct pattern_var *last_pattern_var;
+static struct pattern_var *last_pattern_vars[256];
-/* Create a new pattern-specific variable struct. */
+/* Create a new pattern-specific variable struct. The new variable is
+ inserted into the PATTERN_VARS list in the shortest patterns first
+ order to support the shortest stem matching (the variables are
+ matched in the reverse order so the ones with the longest pattern
+ will be considered first). Variables with the same pattern length
+ are inserted in the definition order. */
struct pattern_var *
create_pattern_var (const char *target, const char *suffix)
{
+ register unsigned int len = strlen (target);
register struct pattern_var *p = xmalloc (sizeof (struct pattern_var));
- if (last_pattern_var != 0)
- last_pattern_var->next = p;
+ if (pattern_vars != 0)
+ {
+ if (len < 256 && last_pattern_vars[len] != 0)
+ {
+ p->next = last_pattern_vars[len]->next;
+ last_pattern_vars[len]->next = p;
+ }
+ else
+ {
+ /* Find the position where we can insert this variable. */
+ register struct pattern_var **v;
+
+ for (v = &pattern_vars; ; v = &(*v)->next)
+ {
+ /* Insert at the end of the pack so that patterns with the
+ same length appear in the order they were defined .*/
+
+ if (*v == 0 || (*v)->len > len)
+ {
+ p->next = *v;
+ *v = p;
+ break;
+ }
+ }
+ }
+ }
else
- pattern_vars = p;
- last_pattern_var = p;
- p->next = 0;
+ {
+ pattern_vars = p;
+ p->next = 0;
+ }
p->target = target;
- p->len = strlen (target);
+ p->len = len;
p->suffix = suffix + 1;
+ if (len < 256)
+ last_pattern_vars[len] = p;
+
return p;
}
@@ -168,7 +202,7 @@ variable_hash_cmp (const void *xv, const void *yv)
static struct variable_set global_variable_set;
static struct variable_set_list global_setlist
- = { 0, &global_variable_set };
+ = { 0, &global_variable_set, 0 };
struct variable_set_list *current_variable_set_list = &global_setlist;
/* Implement variables. */
@@ -341,7 +375,7 @@ define_variable_in_set (const char *name, unsigned int length,
v = alloccache_alloc (&variable_cache);
#endif
#ifndef CONFIG_WITH_STRCACHE2
- v->name = savestring (name, length);
+ v->name = xstrndup (name, length);
#else
v->name = name; /* already cached. */
#endif
@@ -384,6 +418,7 @@ define_variable_in_set (const char *name, unsigned int length,
v->exp_count = 0;
v->per_target = 0;
v->append = 0;
+ v->private_var = 0;
v->export = v_default;
MAKE_STATS_2(v->changes = 0);
MAKE_STATS_2(v->reallocs = 0);
@@ -411,6 +446,51 @@ define_variable_in_set (const char *name, unsigned int length,
return v;
}
+
+/* Undefine variable named NAME in SET. LENGTH is the length of NAME, which
+ does not need to be null-terminated. ORIGIN specifies the origin of the
+ variable (makefile, command line or environment). */
+
+static void
+free_variable_name_and_value (const void *item);
+
+void
+undefine_variable_in_set (const char *name, unsigned int length,
+ enum variable_origin origin,
+ struct variable_set *set)
+{
+ struct variable *v;
+ struct variable **var_slot;
+ struct variable var_key;
+
+ if (set == NULL)
+ set = &global_variable_set;
+
+ var_key.name = (char *) name;
+ var_key.length = length;
+ var_slot = (struct variable **) hash_find_slot (&set->table, &var_key);
+
+ if (env_overrides && origin == o_env)
+ origin = o_env_override;
+
+ v = *var_slot;
+ if (! HASH_VACANT (v))
+ {
+ if (env_overrides && v->origin == o_env)
+ /* V came from in the environment. Since it was defined
+ before the switches were parsed, it wasn't affected by -e. */
+ v->origin = o_env_override;
+
+ /* If the definition is from a stronger source than this one, don't
+ undefine it. */
+ if ((int) origin >= (int) v->origin)
+ {
+ hash_delete_at (&set->table, var_slot);
+ free_variable_name_and_value (v);
+ }
+ }
+}
+
/* If the variable passed in is "special", handle its special nature.
Currently there are two such variables, both used for introspection:
.VARIABLES expands to a list of all the variables defined in this instance
@@ -510,7 +590,7 @@ lookup_special_var (struct variable *var)
}
-#ifdef KMK /* bird: speed */
+#if 0 /*FIX THIS - def KMK*/ /* bird: speed */
MY_INLINE struct variable *
lookup_cached_variable (const char *name)
{
@@ -641,12 +721,13 @@ lookup_variable_for_assert (const char *name, unsigned int length)
struct variable *
lookup_variable (const char *name, unsigned int length)
{
-#ifndef KMK
+#if 1 /*FIX THIS - ndef KMK*/
const struct variable_set_list *setlist;
struct variable var_key;
#else /* KMK */
struct variable *v;
#endif /* KMK */
+ int is_parent = 0;
#ifdef CONFIG_WITH_STRCACHE2
const char *cached_name;
@@ -657,7 +738,7 @@ lookup_variable (const char *name, unsigned int length)
return NULL;
name = cached_name;
#endif /* CONFIG_WITH_STRCACHE2 */
-#ifndef KMK
+#if 1 /*FIX THIS - ndef KMK */
var_key.name = (char *) name;
var_key.length = length;
@@ -673,8 +754,10 @@ lookup_variable (const char *name, unsigned int length)
# else /* CONFIG_WITH_STRCACHE2 */
v = (struct variable *) hash_find_item_strcached ((struct hash_table *) &set->table, &var_key);
# endif /* CONFIG_WITH_STRCACHE2 */
- if (v)
+ if (v && (!is_parent || !v->private_var))
return v->special ? lookup_special_var (v) : v;
+
+ is_parent |= setlist->next_is_parent;
}
#else /* KMK - need for speed */
@@ -742,9 +825,7 @@ lookup_variable (const char *name, unsigned int length)
}
#endif /* VMS */
-#if !defined (KMK) || defined(VMS)
return 0;
-#endif
}
/* Lookup a variable whose name is a string starting at NAME
@@ -831,6 +912,7 @@ initialize_file_variables (struct file *file, int reading)
{
initialize_file_variables (file->double_colon, reading);
l->next = file->double_colon->variables;
+ l->next_is_parent = 0;
return;
}
@@ -841,6 +923,7 @@ initialize_file_variables (struct file *file, int reading)
initialize_file_variables (file->parent, reading);
l->next = file->parent->variables;
}
+ l->next_is_parent = 1;
/* If we're not reading makefiles and we haven't looked yet, see if
we can find pattern variables for this target. */
@@ -893,6 +976,7 @@ initialize_file_variables (struct file *file, int reading)
/* Also mark it as a per-target and copy export status. */
v->per_target = p->variable.per_target;
v->export = p->variable.export;
+ v->private_var = p->variable.private_var;
}
while ((p = lookup_pattern_var (p, file->name)) != 0);
@@ -906,7 +990,9 @@ initialize_file_variables (struct file *file, int reading)
if (file->pat_variables != 0)
{
file->pat_variables->next = l->next;
+ file->pat_variables->next_is_parent = l->next_is_parent;
l->next = file->pat_variables;
+ l->next_is_parent = 0;
}
}
@@ -941,6 +1027,7 @@ create_new_variable_set (void)
#endif
setlist->set = set;
setlist->next = current_variable_set_list;
+ setlist->next_is_parent = 0;
return setlist;
}
@@ -1023,6 +1110,7 @@ pop_variable_scope (void)
set = global_setlist.set;
global_setlist.set = setlist->set;
global_setlist.next = setlist->next;
+ global_setlist.next_is_parent = setlist->next_is_parent;
}
/* Free the one we no longer need. */
@@ -1158,7 +1246,7 @@ define_automatic_variables (void)
#endif
sprintf (buf, "%u", makelevel);
- (void) define_variable (MAKELEVEL_NAME, MAKELEVEL_LENGTH, buf, o_env, 0);
+ define_variable_cname (MAKELEVEL_NAME, buf, o_env, 0);
sprintf (buf, "%s%s%s",
version_string,
@@ -1167,30 +1255,25 @@ define_automatic_variables (void)
(remote_description == 0 || remote_description[0] == '\0')
? "" : remote_description);
#ifndef KMK
- (void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0);
+ define_variable_cname ("MAKE_VERSION", buf, o_default, 0);
#else /* KMK */
/* Define KMK_VERSION to indicate kMk. */
- (void) define_variable ("KMK_VERSION", 11, buf, o_default, 0);
+ define_variable_cname ("KMK_VERSION", buf, o_default, 0);
/* Define KBUILD_VERSION* */
sprintf (buf, "%d", KBUILD_VERSION_MAJOR);
- define_variable ("KBUILD_VERSION_MAJOR", sizeof ("KBUILD_VERSION_MAJOR") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_VERSION_MAJOR", buf, o_default, 0);
sprintf (buf, "%d", KBUILD_VERSION_MINOR);
- define_variable ("KBUILD_VERSION_MINOR", sizeof("KBUILD_VERSION_MINOR") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_VERSION_MINOR", buf, o_default, 0);
sprintf (buf, "%d", KBUILD_VERSION_PATCH);
- define_variable ("KBUILD_VERSION_PATCH", sizeof ("KBUILD_VERSION_PATCH") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_VERSION_PATCH", buf, o_default, 0);
sprintf (buf, "%d", KBUILD_SVN_REV);
- define_variable ("KBUILD_KMK_REVISION", sizeof ("KBUILD_KMK_REVISION") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_KMK_REVISION", buf, o_default, 0);
sprintf (buf, "%d.%d.%d-r%d", KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR,
KBUILD_VERSION_PATCH, KBUILD_SVN_REV);
- define_variable ("KBUILD_VERSION", sizeof ("KBUILD_VERSION") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_VERSION", buf, o_default, 0);
/* The host defaults. The BUILD_* stuff will be replaced by KBUILD_* soon. */
envvar1 = lookup_variable (STRING_SIZE_TUPLE ("KBUILD_HOST"));
@@ -1199,11 +1282,9 @@ define_automatic_variables (void)
if (envvar1 && envvar2 && strcmp (envvar1->value, envvar2->value))
error (NULL, _("KBUILD_HOST and BUILD_PLATFORM differs, using KBUILD_HOST=%s."), val);
if (!envvar1)
- define_variable ("KBUILD_HOST", sizeof ("KBUILD_HOST") - 1,
- val, o_default, 0);
+ define_variable_cname ("KBUILD_HOST", val, o_default, 0);
if (!envvar2)
- define_variable ("BUILD_PLATFORM", sizeof ("BUILD_PLATFORM") - 1,
- val, o_default, 0);
+ define_variable_cname ("BUILD_PLATFORM", val, o_default, 0);
envvar1 = lookup_variable (STRING_SIZE_TUPLE ("KBUILD_HOST_ARCH"));
envvar2 = lookup_variable (STRING_SIZE_TUPLE ("BUILD_PLATFORM_ARCH"));
@@ -1211,11 +1292,9 @@ define_automatic_variables (void)
if (envvar1 && envvar2 && strcmp (envvar1->value, envvar2->value))
error (NULL, _("KBUILD_HOST_ARCH and BUILD_PLATFORM_ARCH differs, using KBUILD_HOST_ARCH=%s."), val);
if (!envvar1)
- define_variable ("KBUILD_HOST_ARCH", sizeof ("KBUILD_HOST_ARCH") - 1,
- val, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_ARCH", val, o_default, 0);
if (!envvar2)
- define_variable ("BUILD_PLATFORM_ARCH", sizeof ("BUILD_PLATFORM_ARCH") - 1,
- val, o_default, 0);
+ define_variable_cname ("BUILD_PLATFORM_ARCH", val, o_default, 0);
envvar1 = lookup_variable (STRING_SIZE_TUPLE ("KBUILD_HOST_CPU"));
envvar2 = lookup_variable (STRING_SIZE_TUPLE ("BUILD_PLATFORM_CPU"));
@@ -1223,11 +1302,9 @@ define_automatic_variables (void)
if (envvar1 && envvar2 && strcmp (envvar1->value, envvar2->value))
error (NULL, _("KBUILD_HOST_CPU and BUILD_PLATFORM_CPU differs, using KBUILD_HOST_CPU=%s."), val);
if (!envvar1)
- define_variable ("KBUILD_HOST_CPU", sizeof ("KBUILD_HOST_CPU") - 1,
- val, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_CPU", val, o_default, 0);
if (!envvar2)
- define_variable ("BUILD_PLATFORM_CPU", sizeof ("BUILD_PLATFORM_CPU") - 1,
- val, o_default, 0);
+ define_variable_cname ("BUILD_PLATFORM_CPU", val, o_default, 0);
/* The host kernel version. */
#if defined(WINDOWS32)
@@ -1266,31 +1343,23 @@ define_automatic_variables (void)
#endif
sprintf (buf, "%lu.%lu.%lu.%lu", ulMajor, ulMinor, ulPatch, ul4th);
- define_variable ("KBUILD_HOST_VERSION", sizeof ("KBUILD_HOST_VERSION") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_VERSION", buf, o_default, 0);
sprintf (buf, "%lu", ulMajor);
- define_variable ("KBUILD_HOST_VERSION_MAJOR", sizeof ("KBUILD_HOST_VERSION_MAJOR") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_VERSION_MAJOR", buf, o_default, 0);
sprintf (buf, "%lu", ulMinor);
- define_variable ("KBUILD_HOST_VERSION_MINOR", sizeof ("KBUILD_HOST_VERSION_MINOR") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_VERSION_MINOR", buf, o_default, 0);
sprintf (buf, "%lu", ulPatch);
- define_variable ("KBUILD_HOST_VERSION_PATCH", sizeof ("KBUILD_HOST_VERSION_PATCH") - 1,
- buf, o_default, 0);
+ define_variable_cname ("KBUILD_HOST_VERSION_PATCH", buf, o_default, 0);
/* The kBuild locations. */
- define_variable ("KBUILD_PATH", sizeof ("KBUILD_PATH") - 1,
- get_kbuild_path (), o_default, 0);
- define_variable ("KBUILD_BIN_PATH", sizeof ("KBUILD_BIN_PATH") - 1,
- get_kbuild_bin_path (), o_default, 0);
+ define_variable_cname ("KBUILD_PATH", get_kbuild_path (), o_default, 0);
+ define_variable_cname ("KBUILD_BIN_PATH", get_kbuild_bin_path (), o_default, 0);
- define_variable ("PATH_KBUILD", sizeof ("PATH_KBUILD") - 1,
- get_kbuild_path (), o_default, 0);
- define_variable ("PATH_KBUILD_BIN", sizeof ("PATH_KBUILD_BIN") - 1,
- get_kbuild_bin_path (), o_default, 0);
+ define_variable_cname ("PATH_KBUILD", get_kbuild_path (), o_default, 0);
+ define_variable_cname ("PATH_KBUILD_BIN", get_kbuild_bin_path (), o_default, 0);
/* Define KMK_FEATURES to indicate various working KMK features. */
# if defined (CONFIG_WITH_RSORT) \
@@ -1319,36 +1388,36 @@ define_automatic_variables (void)
&& defined (CONFIG_WITH_STRING_FUNCTIONS) \
&& defined (CONFIG_WITH_DEFINED_FUNCTIONS) \
&& defined (KMK_HELPERS)
- (void) define_variable ("KMK_FEATURES", 12,
- "append-dash-n abspath includedep-queue install-hard-linking umask"
- " kBuild-define"
- " rsort"
- " abspathex"
- " toupper tolower"
- " defined"
- " comp-vars comp-cmds comp-cmds-ex"
- " stack"
- " math-int"
- " xargs"
- " explicit-multitarget"
- " dot-must-make"
- " prepend-assignment"
- " set-conditionals intersects"
- " date"
- " file-size"
- " expr if-expr select"
- " where"
- " which"
- " evalctx evalval evalvalctx evalcall evalcall2 eval-opt-var"
- " make-stats"
- " commands"
- " printf"
- " for while"
- " root"
- " length insert pos lastpos substr translate"
- " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one kb-exp-tmpl"
- " firstdefined lastdefined"
- , o_default, 0);
+ define_variable_cname ("KMK_FEATURES",
+ "append-dash-n abspath includedep-queue install-hard-linking umask"
+ " kBuild-define"
+ " rsort"
+ " abspathex"
+ " toupper tolower"
+ " defined"
+ " comp-vars comp-cmds comp-cmds-ex"
+ " stack"
+ " math-int"
+ " xargs"
+ " explicit-multitarget"
+ " dot-must-make"
+ " prepend-assignment"
+ " set-conditionals intersects"
+ " date"
+ " file-size"
+ " expr if-expr select"
+ " where"
+ " which"
+ " evalctx evalval evalvalctx evalcall evalcall2 eval-opt-var"
+ " make-stats"
+ " commands"
+ " printf"
+ " for while"
+ " root"
+ " length insert pos lastpos substr translate"
+ " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one kb-exp-tmpl"
+ " firstdefined lastdefined"
+ , o_default, 0);
# else /* MSC can't deal with strings mixed with #if/#endif, thus the slow way. */
# error "All features should be enabled by default!"
strcpy (buf, "append-dash-n abspath includedep-queue install-hard-linking umask"
@@ -1431,14 +1500,14 @@ define_automatic_variables (void)
# if defined (KMK_HELPERS)
strcat (buf, " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one kb-exp-tmpl");
# endif
- (void) define_variable ("KMK_FEATURES", 12, buf, o_default, 0);
+ define_variable_cname ("KMK_FEATURES", buf, o_default, 0);
# endif
#endif /* KMK */
#ifdef CONFIG_WITH_KMK_BUILTIN
/* The supported kMk Builtin commands. */
- (void) define_variable ("KMK_BUILTIN", 11, "append cat chmod cp cmp echo expr install kDepIDB ln md5sum mkdir mv printf rm rmdir sleep test", o_default, 0);
+ define_variable_cname ("KMK_BUILTIN", "append cat chmod cp cmp echo expr install kDepIDB ln md5sum mkdir mv printf rm rmdir sleep test", o_default, 0);
#endif
#ifdef __MSDOS__
@@ -1450,13 +1519,13 @@ define_automatic_variables (void)
struct variable *mshp = lookup_variable ("MAKESHELL", 9);
struct variable *comp = lookup_variable ("COMSPEC", 7);
- /* Make $MAKESHELL override $SHELL even if -e is in effect. */
+ /* $(MAKESHELL) overrides $(SHELL) even if -e is in effect. */
if (mshp)
(void) define_variable (shell_str, shlen,
mshp->value, o_env_override, 0);
else if (comp)
{
- /* $COMSPEC shouldn't override $SHELL. */
+ /* $(COMSPEC) shouldn't override $(SHELL). */
struct variable *shp = lookup_variable (shell_str, shlen);
if (!shp)
@@ -1515,7 +1584,7 @@ define_automatic_variables (void)
/* This won't override any definition, but it will provide one if there
isn't one there. */
- v = define_variable ("SHELL", 5, default_shell, o_default, 0);
+ v = define_variable_cname ("SHELL", default_shell, o_default, 0);
#ifdef __MSDOS__
v->export = v_export; /* Export always SHELL. */
#endif
@@ -1544,36 +1613,36 @@ define_automatic_variables (void)
#endif
/* Make sure MAKEFILES gets exported if it is set. */
- v = define_variable ("MAKEFILES", 9, "", o_default, 0);
+ v = define_variable_cname ("MAKEFILES", "", o_default, 0);
v->export = v_ifset;
/* Define the magic D and F variables in terms of
the automatic variables they are variations of. */
#ifdef VMS
- define_variable ("@D", 2, "$(dir $@)", o_automatic, 1);
- define_variable ("%D", 2, "$(dir $%)", o_automatic, 1);
- define_variable ("*D", 2, "$(dir $*)", o_automatic, 1);
- define_variable ("<D", 2, "$(dir $<)", o_automatic, 1);
- define_variable ("?D", 2, "$(dir $?)", o_automatic, 1);
- define_variable ("^D", 2, "$(dir $^)", o_automatic, 1);
- define_variable ("+D", 2, "$(dir $+)", o_automatic, 1);
+ define_variable_cname ("@D", "$(dir $@)", o_automatic, 1);
+ define_variable_cname ("%D", "$(dir $%)", o_automatic, 1);
+ define_variable_cname ("*D", "$(dir $*)", o_automatic, 1);
+ define_variable_cname ("<D", "$(dir $<)", o_automatic, 1);
+ define_variable_cname ("?D", "$(dir $?)", o_automatic, 1);
+ define_variable_cname ("^D", "$(dir $^)", o_automatic, 1);
+ define_variable_cname ("+D", "$(dir $+)", o_automatic, 1);
#else
- define_variable ("@D", 2, "$(patsubst %/,%,$(dir $@))", o_automatic, 1);
- define_variable ("%D", 2, "$(patsubst %/,%,$(dir $%))", o_automatic, 1);
- define_variable ("*D", 2, "$(patsubst %/,%,$(dir $*))", o_automatic, 1);
- define_variable ("<D", 2, "$(patsubst %/,%,$(dir $<))", o_automatic, 1);
- define_variable ("?D", 2, "$(patsubst %/,%,$(dir $?))", o_automatic, 1);
- define_variable ("^D", 2, "$(patsubst %/,%,$(dir $^))", o_automatic, 1);
- define_variable ("+D", 2, "$(patsubst %/,%,$(dir $+))", o_automatic, 1);
+ define_variable_cname ("@D", "$(patsubst %/,%,$(dir $@))", o_automatic, 1);
+ define_variable_cname ("%D", "$(patsubst %/,%,$(dir $%))", o_automatic, 1);
+ define_variable_cname ("*D", "$(patsubst %/,%,$(dir $*))", o_automatic, 1);
+ define_variable_cname ("<D", "$(patsubst %/,%,$(dir $<))", o_automatic, 1);
+ define_variable_cname ("?D", "$(patsubst %/,%,$(dir $?))", o_automatic, 1);
+ define_variable_cname ("^D", "$(patsubst %/,%,$(dir $^))", o_automatic, 1);
+ define_variable_cname ("+D", "$(patsubst %/,%,$(dir $+))", o_automatic, 1);
#endif
- define_variable ("@F", 2, "$(notdir $@)", o_automatic, 1);
- define_variable ("%F", 2, "$(notdir $%)", o_automatic, 1);
- define_variable ("*F", 2, "$(notdir $*)", o_automatic, 1);
- define_variable ("<F", 2, "$(notdir $<)", o_automatic, 1);
- define_variable ("?F", 2, "$(notdir $?)", o_automatic, 1);
- define_variable ("^F", 2, "$(notdir $^)", o_automatic, 1);
- define_variable ("+F", 2, "$(notdir $+)", o_automatic, 1);
+ define_variable_cname ("@F", "$(notdir $@)", o_automatic, 1);
+ define_variable_cname ("%F", "$(notdir $%)", o_automatic, 1);
+ define_variable_cname ("*F", "$(notdir $*)", o_automatic, 1);
+ define_variable_cname ("<F", "$(notdir $<)", o_automatic, 1);
+ define_variable_cname ("?F", "$(notdir $?)", o_automatic, 1);
+ define_variable_cname ("^F", "$(notdir $^)", o_automatic, 1);
+ define_variable_cname ("+F", "$(notdir $+)", o_automatic, 1);
#ifdef CONFIG_WITH_LAZY_DEPS_VARS
define_variable ("^", 1, "$(deps $@)", o_automatic, 1);
define_variable ("+", 1, "$(deps-all $@)", o_automatic, 1);
@@ -1741,7 +1810,7 @@ target_environment (struct file *file)
strcmp(v->name, "PATH") == 0)
convert_Path_to_windows32(value, ';');
#endif
- *result++ = xstrdup (concat (v->name, "=", value));
+ *result++ = xstrdup (concat (3, v->name, "=", value));
free (value);
}
else
@@ -1751,7 +1820,7 @@ target_environment (struct file *file)
strcmp(v->name, "PATH") == 0)
convert_Path_to_windows32(v->value, ';');
#endif
- *result++ = xstrdup (concat (v->name, "=", v->value));
+ *result++ = xstrdup (concat (3, v->name, "=", v->value));
}
}
@@ -1939,7 +2008,7 @@ do_variable_definition_2 (const struct floc *flocp,
if (value_len == ~0U)
value_len = strlen (value);
if (!free_value)
- p = alloc_value = savestring (value, value_len);
+ p = alloc_value = xstrndup (value, value_len);
else
{
assert (value == free_value);
@@ -2033,7 +2102,7 @@ do_variable_definition_2 (const struct floc *flocp,
unsigned int oldlen, vallen;
const char *val;
- char *tp;
+ char *tp = NULL;
val = value;
if (v->recursive)
@@ -2046,26 +2115,28 @@ do_variable_definition_2 (const struct floc *flocp,
when it was set; and from the expanded new value. Allocate
memory for the expansion as we may still need the rest of the
buffer if we're looking at a target-specific variable. */
- val = alloc_value = allocated_variable_expand (val);
+ val = tp = allocated_variable_expand (val);
oldlen = strlen (v->value);
vallen = strlen (val);
- tp = alloca (oldlen + 1 + vallen + 1);
+ p = alloc_value = xmalloc (oldlen + 1 + vallen + 1);
# ifdef CONFIG_WITH_PREPEND_ASSIGNMENT
if (org_flavor == f_prepend)
{
- memcpy (tp, val, vallen);
- tp[oldlen] = ' ';
- memcpy (&tp[oldlen + 1], v->value, oldlen + 1);
+ memcpy (alloc_value, val, vallen);
+ alloc_value[oldlen] = ' ';
+ memcpy (&alloc_value[oldlen + 1], v->value, oldlen + 1);
}
else
# endif /* CONFIG_WITH_PREPEND_ASSIGNMENT */
{
- memcpy (tp, v->value, oldlen);
- tp[oldlen] = ' ';
- memcpy (&tp[oldlen + 1], val, vallen + 1);
+ memcpy (alloc_value, v->value, oldlen);
+ alloc_value[oldlen] = ' ';
+ memcpy (&alloc_value[oldlen + 1], val, vallen + 1);
}
- p = tp;
+
+ if (tp)
+ free (tp);
#endif /* !CONFIG_WITH_VALUE_LENGTH */
}
}
@@ -2178,10 +2249,10 @@ do_variable_definition_2 (const struct floc *flocp,
}
else
{
- if (alloc_value)
- free (alloc_value);
+ char *tp = alloc_value;
alloc_value = allocated_variable_expand (p);
+
if (find_and_set_default_shell (alloc_value))
{
v = define_variable_in_set (varname, varname_len, p,
@@ -2197,6 +2268,9 @@ do_variable_definition_2 (const struct floc *flocp,
}
else
v = lookup_variable (varname, varname_len);
+
+ if (tp)
+ free (tp);
}
}
else
@@ -2234,80 +2308,32 @@ do_variable_definition_2 (const struct floc *flocp,
return v->special ? set_special_var (v) : v;
}
-/* Try to interpret LINE (a null-terminated string) as a variable definition.
+/* Parse P (a null-terminated string) as a variable definition.
- ORIGIN may be o_file, o_override, o_env, o_env_override,
- or o_command specifying that the variable definition comes
- from a makefile, an override directive, the environment with
- or without the -e switch, or the command line.
+ If it is not a variable definition, return NULL.
- See the comments for parse_variable_definition().
+ If it is a variable definition, return a pointer to the char after the
+ assignment token and set *FLAVOR to the type of variable assignment. */
- If LINE was recognized as a variable definition, a pointer to its `struct
- variable' is returned. If LINE is not a variable definition, NULL is
- returned. */
-
-struct variable *
-#ifndef CONFIG_WITH_VALUE_LENGTH
-parse_variable_definition (struct variable *v, char *line)
-#else
-parse_variable_definition (struct variable *v, char *line, char *eos)
-#endif
+char *
+parse_variable_definition (const char *p, enum variable_flavor *flavor)
{
- register int c;
- register char *p = line;
- register char *beg;
- register char *end;
- enum variable_flavor flavor = f_bogus;
-#ifndef CONFIG_WITH_VALUE_LENGTH
- char *name;
-#endif
+ int wspace = 0;
+
+ p = next_token (p);
while (1)
{
- c = *p++;
+ int c = *p++;
+
+ /* If we find a comment or EOS, it's not a variable definition. */
if (c == '\0' || c == '#')
- return 0;
- if (c == '=')
- {
- end = p - 1;
- flavor = f_recursive;
- break;
- }
- else if (c == ':')
- if (*p == '=')
- {
- end = p++ - 1;
- flavor = f_simple;
- break;
- }
- else
- /* A colon other than := is a rule line, not a variable defn. */
- return 0;
- else if (c == '+' && *p == '=')
- {
- end = p++ - 1;
- flavor = f_append;
- break;
- }
-#ifdef CONFIG_WITH_PREPEND_ASSIGNMENT
- else if (c == '<' && *p == '=')
- {
- end = p++ - 1;
- flavor = f_prepend;
- break;
- }
-#endif
- else if (c == '?' && *p == '=')
- {
- end = p++ - 1;
- flavor = f_conditional;
- break;
- }
- else if (c == '$')
+ return NULL;
+
+ if (c == '$')
{
- /* This might begin a variable expansion reference. Make sure we
- don't misrecognize chars inside the reference as =, := or +=. */
+ /* This begins a variable expansion reference. Make sure we don't
+ treat chars inside the reference as assignment tokens. */
char closeparen;
int count;
c = *p++;
@@ -2316,7 +2342,8 @@ parse_variable_definition (struct variable *v, char *line, char *eos)
else if (c == '{')
closeparen = '}';
else
- continue; /* Nope. */
+ /* '$$' or '$X'. Either way, nothing special to do here. */
+ continue;
/* P now points past the opening paren or brace.
Count parens or braces until it is matched. */
@@ -2331,19 +2358,99 @@ parse_variable_definition (struct variable *v, char *line, char *eos)
break;
}
}
+ continue;
}
+
+ /* If we find whitespace skip it, and remember we found it. */
+ if (isblank ((unsigned char)c))
+ {
+ wspace = 1;
+ p = next_token (p);
+ c = *p;
+ if (c == '\0')
+ return NULL;
+ ++p;
+ }
+
+
+ if (c == '=')
+ {
+ *flavor = f_recursive;
+ return (char *)p;
+ }
+
+ /* Match assignment variants (:=, +=, ?=) */
+ if (*p == '=')
+ {
+ switch (c)
+ {
+ case ':':
+ *flavor = f_simple;
+ break;
+ case '+':
+ *flavor = f_append;
+ break;
+#ifdef CONFIG_WITH_PREPEND_ASSIGNMENT
+ case '<':
+ *flavor = f_prepend;
+ break;
+#endif
+ case '?':
+ *flavor = f_conditional;
+ break;
+ default:
+ /* If we skipped whitespace, non-assignments means no var. */
+ if (wspace)
+ return NULL;
+
+ /* Might be assignment, or might be $= or #=. Check. */
+ continue;
+ }
+ return (char *)++p;
+ }
+ else if (c == ':')
+ /* A colon other than := is a rule line, not a variable defn. */
+ return NULL;
+
+ /* If we skipped whitespace, non-assignments means no var. */
+ if (wspace)
+ return NULL;
}
- v->flavor = flavor;
+
+ return (char *)p;
+}
+
+/* Try to interpret LINE (a null-terminated string) as a variable definition.
+
+ If LINE was recognized as a variable definition, a pointer to its `struct
+ variable' is returned. If LINE is not a variable definition, NULL is
+ returned. */
+
+struct variable *
+assign_variable_definition (struct variable *v, char *line IF_WITH_VALUE_LENGTH_PARAM(char *eos))
+{
+ char *beg;
+ char *end;
+ enum variable_flavor flavor;
+#ifndef CONFIG_WITH_VALUE_LENGTH
+ char *name;
+#endif
beg = next_token (line);
+ line = parse_variable_definition (beg, &flavor);
+ if (!line)
+ return NULL;
+
+ end = line - (flavor == f_recursive ? 1 : 2);
while (end > beg && isblank ((unsigned char)end[-1]))
--end;
- p = next_token (p);
- v->value = p;
+ line = next_token (line);
+ v->value = line;
+ v->flavor = flavor;
#ifdef CONFIG_WITH_VALUE_LENGTH
v->value_alloc_len = ~(unsigned int)0;
- v->value_length = eos != NULL ? eos - p : -1;
- assert (eos == NULL || strchr (p, '\0') == eos);
+ v->value_length = eos != NULL ? eos - line : -1;
+ assert (eos == NULL || strchr (line, '\0') == eos);
# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
v->rdonly_val = 0;
# endif
@@ -2372,20 +2479,16 @@ parse_variable_definition (struct variable *v, char *line, char *eos)
from a makefile, an override directive, the environment with
or without the -e switch, or the command line.
- See the comments for parse_variable_definition().
+ See the comments for assign_variable_definition().
If LINE was recognized as a variable definition, a pointer to its `struct
variable' is returned. If LINE is not a variable definition, NULL is
returned. */
struct variable *
-#ifndef CONFIG_WITH_VALUE_LENGTH
-try_variable_definition (const struct floc *flocp, char *line,
+try_variable_definition (const struct floc *flocp, char *line
+ IF_WITH_VALUE_LENGTH_PARAM(char *eos),
enum variable_origin origin, int target_var)
-#else
-try_variable_definition (const struct floc *flocp, char *line, char *eos,
- enum variable_origin origin, int target_var)
-#endif
{
struct variable v;
struct variable *vp;
@@ -2396,13 +2499,13 @@ try_variable_definition (const struct floc *flocp, char *line, char *eos,
v.fileinfo.filenm = 0;
#ifndef CONFIG_WITH_VALUE_LENGTH
- if (!parse_variable_definition (&v, line))
+ if (!assign_variable_definition (&v, line))
return 0;
vp = do_variable_definition (flocp, v.name, v.value,
origin, v.flavor, target_var);
#else
- if (!parse_variable_definition (&v, line, eos))
+ if (!assign_variable_definition (&v, line, eos))
return 0;
vp = do_variable_definition_2 (flocp, v.name, v.value, v.value_length,
@@ -2468,6 +2571,8 @@ print_variable (const void *item, void *arg)
}
fputs ("# ", stdout);
fputs (origin, stdout);
+ if (v->private_var)
+ fputs (" private", stdout);
if (v->fileinfo.filenm)
printf (_(" (from `%s', line %lu)"),
v->fileinfo.filenm, v->fileinfo.lineno);
@@ -2496,7 +2601,7 @@ print_variable (const void *item, void *arg)
printf ("define %s\n%s\nendef\n", v->name, v->value);
else
{
- register char *p;
+ char *p;
printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":");
@@ -2642,7 +2747,7 @@ sync_Path_environment (void)
* Create something WINDOWS32 world can grok
*/
convert_Path_to_windows32 (path, ';');
- environ_path = xstrdup (concat ("PATH", "=", path));
+ environ_path = xstrdup (concat (3, "PATH", "=", path));
putenv (environ_path);
free (path);
}