mirror of
https://github.com/mirror/make.git
synced 2024-12-27 13:20:34 +08:00
* Fix PR/1407.
* Keep filename/lineno information for variables, for debugging.
This commit is contained in:
parent
95a09e94f7
commit
9b0a3d91ea
29
ChangeLog
29
ChangeLog
@ -1,3 +1,32 @@
|
||||
2000-02-04 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* variable.c (print_variable): Write out filename/linenumber
|
||||
information for the variable definition if present.
|
||||
(define_variable_in_set): Store filename information if provided.
|
||||
(define_variable, define_variable_for_file): Removed.
|
||||
(try_variable_definition): Use define_variable_loc() to keep
|
||||
variable definition location information.
|
||||
* read.c (read_makefile): Keep variable definition location info.
|
||||
(do_define): Ditto.
|
||||
(record_target_var): Ditto.
|
||||
* variable.h (define_variable_in_set): New fileinfo argument.
|
||||
(define_variable, define_variable_loc, define_variable_for_file):
|
||||
Declare new macros.
|
||||
|
||||
Fix PR/1407:
|
||||
|
||||
* filedef.h (struct file): Rename patvar to pat_variables and make
|
||||
it just a variable_set_list; we need our own copy of the pattern
|
||||
variable's variable set list here to avoid overwriting the global
|
||||
one.
|
||||
* variable.c (initialize_file_variables): Move the instantiation
|
||||
of the pat_variables pointer here. Only do the search after we're
|
||||
done reading the makefiles so we don't search too early. If
|
||||
there's a pat_variables value, set up the variables next ptr.
|
||||
* expand.c (variable_expand_for_file): Remove the setup of the
|
||||
pat_variables info; it's done earlier now to ensure the parent's
|
||||
pattern variables are set up correctly as well.
|
||||
|
||||
2000-01-25 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Change gettext support to use the simplified version in libit 0.7.
|
||||
|
17
NEWS
17
NEWS
@ -23,8 +23,8 @@ Version 3.79
|
||||
be used within make build scripts. However, using them there is not
|
||||
proper behavior: they are meant to be passed to subshells via the
|
||||
environment. Unfortunately the values were not quoted properly to be
|
||||
passed through the environment. This meant that some invocations of
|
||||
make didn't properly pass values to submakes.
|
||||
passed through the environment. This meant that make didn't properly
|
||||
pass some types of command line values to submakes.
|
||||
|
||||
With this version we change that behavior: now these variables are
|
||||
quoted properly for passing through the environment, which is the
|
||||
@ -32,9 +32,9 @@ Version 3.79
|
||||
explicitly within a make rule you may need to re-examine your use for
|
||||
correctness given this change.
|
||||
|
||||
* A new psuedo-target, .NOTPARALLEL, is defined. If set the current
|
||||
makefile is always run serially regardless of the value of -j. Any
|
||||
submakes will still be run in parallel if -j was specified.
|
||||
* A new psuedo-target .NOTPARALLEL is available. If defined, the
|
||||
current makefile is run serially regardless of the value of -j.
|
||||
However, submakes are still eligible for parallel execution.
|
||||
|
||||
* The $(call ...) function doesn't expand its arguments automatically
|
||||
anymore. This allows you to put builtin functions like "if" and
|
||||
@ -48,8 +48,11 @@ Version 3.79
|
||||
"normal" targets (not makefiles) were deemed out of date and in need
|
||||
of being rebuilt.
|
||||
|
||||
Note that the -d option behaves as before: all debugging information
|
||||
is generated.
|
||||
Note that the -d option behaves as before: it takes no arguments and
|
||||
all debugging information is generated.
|
||||
|
||||
* The `-p' (print database) output now includes filename and linenumber
|
||||
information for variable definitions, to help debugging.
|
||||
|
||||
* Hartmut Becker provided many updates for the VMS port of GNU make.
|
||||
See the readme.vms file for more details.
|
||||
|
@ -108,7 +108,7 @@ set_file_variables (file)
|
||||
less = at;
|
||||
|
||||
#define DEFINE_VARIABLE(name, len, value) \
|
||||
(void) define_variable_for_file (name, len, value, o_automatic, 0, file)
|
||||
(void) define_variable_for_file (name,len,value,o_automatic,0,file)
|
||||
|
||||
/* Define the variables. */
|
||||
|
||||
@ -354,7 +354,7 @@ execute_file_commands (file)
|
||||
|
||||
/* First set the automatic variables according to this file. */
|
||||
|
||||
initialize_file_variables (file);
|
||||
initialize_file_variables (file, 0);
|
||||
|
||||
set_file_variables (file);
|
||||
|
||||
|
15
expand.c
15
expand.c
@ -445,7 +445,7 @@ variable_expand_for_file (line, file)
|
||||
register struct file *file;
|
||||
{
|
||||
char *result;
|
||||
struct variable_set_list *save, *fnext;
|
||||
struct variable_set_list *save;
|
||||
|
||||
if (file == 0)
|
||||
return variable_expand (line);
|
||||
@ -456,22 +456,9 @@ variable_expand_for_file (line, file)
|
||||
reading_file = &file->cmds->fileinfo;
|
||||
else
|
||||
reading_file = 0;
|
||||
fnext = file->variables->next;
|
||||
/* See if there's a pattern-specific variable struct for this target. */
|
||||
if (!file->pat_searched)
|
||||
{
|
||||
file->patvar = lookup_pattern_var(file->name);
|
||||
file->pat_searched = 1;
|
||||
}
|
||||
if (file->patvar != 0)
|
||||
{
|
||||
file->patvar->vars->next = fnext;
|
||||
file->variables->next = file->patvar->vars;
|
||||
}
|
||||
result = variable_expand (line);
|
||||
current_variable_set_list = save;
|
||||
reading_file = 0;
|
||||
file->variables->next = fnext;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ struct file
|
||||
/* List of variable sets used for this file. */
|
||||
struct variable_set_list *variables;
|
||||
|
||||
/* Pattern-specific variable reference for this target, or null if there
|
||||
isn't one. Also see the pat_searched flag, below. */
|
||||
struct variable_set_list *pat_variables;
|
||||
|
||||
/* Immediate dependent that caused this target to be remade,
|
||||
or nil if there isn't one. */
|
||||
struct file *parent;
|
||||
@ -56,10 +60,6 @@ struct file
|
||||
the same file. Otherwise this is null. */
|
||||
struct file *double_colon;
|
||||
|
||||
/* Pattern-specific variable reference for this target, or null if there
|
||||
isn't one. Also see the pat_searched flag, below. */
|
||||
struct pattern_var *patvar;
|
||||
|
||||
short int update_status; /* Status of the last attempt to update,
|
||||
or -1 if none has been made. */
|
||||
|
||||
|
11
read.c
11
read.c
@ -609,7 +609,7 @@ read_makefile (filename, flags)
|
||||
{
|
||||
v = lookup_variable (p, len);
|
||||
if (v == 0)
|
||||
v = define_variable (p, len, "", o_file, 0);
|
||||
v = define_variable_loc (p, len, "", o_file, 0, &fileinfo);
|
||||
v->export = v_export;
|
||||
}
|
||||
}
|
||||
@ -626,7 +626,7 @@ read_makefile (filename, flags)
|
||||
{
|
||||
v = lookup_variable (p, len);
|
||||
if (v == 0)
|
||||
v = define_variable (p, len, "", o_file, 0);
|
||||
v = define_variable_loc (p, len, "", o_file, 0, &fileinfo);
|
||||
v->export = v_noexport;
|
||||
}
|
||||
}
|
||||
@ -1116,7 +1116,8 @@ do_define (name, namelen, origin, infile, flocp)
|
||||
definition[0] = '\0';
|
||||
else
|
||||
definition[idx - 1] = '\0';
|
||||
(void) define_variable (var, strlen (var), definition, origin, 1);
|
||||
(void) define_variable_loc (var, strlen (var), definition, origin,
|
||||
1, flocp);
|
||||
free (definition);
|
||||
freebuffer (&lb);
|
||||
return;
|
||||
@ -1454,7 +1455,7 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
|
||||
|
||||
/* Get a file reference for this file, and initialize it. */
|
||||
f = enter_file (name);
|
||||
initialize_file_variables (f);
|
||||
initialize_file_variables (f, 1);
|
||||
vlist = f->variables;
|
||||
fname = f->name;
|
||||
}
|
||||
@ -1477,7 +1478,7 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
|
||||
gv = lookup_variable (v->name, len);
|
||||
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
|
||||
define_variable_in_set (v->name, len, gv->value, gv->origin,
|
||||
gv->recursive, vlist->set);
|
||||
gv->recursive, vlist->set, flocp);
|
||||
}
|
||||
|
||||
/* Free name if not needed further. */
|
||||
|
4
rule.c
4
rule.c
@ -607,12 +607,12 @@ lookup_pattern_var (target)
|
||||
continue;
|
||||
|
||||
/* Compare the text in the pattern after the stem, if any.
|
||||
We could test simply use streq, but this way we compare the
|
||||
We could test simply using streq, but this way we compare the
|
||||
first two characters immediately. This saves time in the very
|
||||
common case where the first character matches because it is a
|
||||
period. */
|
||||
if (*p->suffix == stem[stemlen]
|
||||
&& (*p->suffix == '\0'|| streq (&p->suffix[1], &stem[stemlen+1])))
|
||||
&& (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1])))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2000-02-04 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/patspecific_vars: Add a test for PR/1407.
|
||||
|
||||
2000-01-23 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/include: Remove a check; the fix caused more
|
||||
|
@ -19,6 +19,8 @@ t%.x: BAR = four
|
||||
%.x: override BAZ = three
|
||||
one.x: override FOO = one
|
||||
one.x two.x three.x: ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
four.x: baz ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
baz: ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
EOF
|
||||
|
||||
close(MAKEFILE);
|
||||
@ -37,4 +39,11 @@ $answer = "one two three\nfoo four baz\nfoo bar three\n";
|
||||
$answer = "one two three\nfoo four five\nfoo bar three\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
|
||||
# TEST #3 -- make sure patterns are inherited properly
|
||||
|
||||
&run_make_with_options($makefile, "four.x", &get_logfile);
|
||||
$answer = "foo two three\nfoo two three\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
1;
|
||||
|
117
variable.c
117
variable.c
@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
#include "rule.h"
|
||||
#ifdef WINDOWS32
|
||||
#include "pathstuff.h"
|
||||
#endif
|
||||
@ -58,13 +59,14 @@ static struct variable *lookup_variable_in_set PARAMS ((char *name,
|
||||
that it should be recursively re-expanded. */
|
||||
|
||||
struct variable *
|
||||
define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
define_variable_in_set (name, length, value, origin, recursive, set, flocp)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
struct variable_set *set;
|
||||
const struct floc *flocp;
|
||||
{
|
||||
register unsigned int i;
|
||||
register unsigned int hashval;
|
||||
@ -99,6 +101,10 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = xstrdup (value);
|
||||
if (flocp != 0)
|
||||
v->fileinfo = *flocp;
|
||||
else
|
||||
v->fileinfo.filenm = 0;
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
}
|
||||
@ -110,6 +116,10 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
v = (struct variable *) xmalloc (sizeof (struct variable));
|
||||
v->name = savestring (name, length);
|
||||
v->value = xstrdup (value);
|
||||
if (flocp != 0)
|
||||
v->fileinfo = *flocp;
|
||||
else
|
||||
v->fileinfo.filenm = 0;
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
v->expanding = 0;
|
||||
@ -120,35 +130,6 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
set->table[hashval] = v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Define a variable in the current variable set. */
|
||||
|
||||
struct variable *
|
||||
define_variable (name, length, value, origin, recursive)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
{
|
||||
return define_variable_in_set (name, length, value, origin, recursive,
|
||||
current_variable_set_list->set);
|
||||
}
|
||||
|
||||
/* Define a variable in FILE's variable set. */
|
||||
|
||||
struct variable *
|
||||
define_variable_for_file (name, length, value, origin, recursive, file)
|
||||
char *name;
|
||||
unsigned int length;
|
||||
char *value;
|
||||
enum variable_origin origin;
|
||||
int recursive;
|
||||
struct file *file;
|
||||
{
|
||||
return define_variable_in_set (name, length, value, origin, recursive,
|
||||
file->variables->set);
|
||||
}
|
||||
|
||||
/* Lookup a variable whose name is a string starting at NAME
|
||||
and with LENGTH chars. NAME need not be null-terminated.
|
||||
@ -272,13 +253,17 @@ lookup_variable_in_set (name, length, set)
|
||||
|
||||
/* Initialize FILE's variable set list. If FILE already has a variable set
|
||||
list, the topmost variable set is left intact, but the the rest of the
|
||||
chain is replaced with FILE->parent's setlist. */
|
||||
chain is replaced with FILE->parent's setlist. If we're READing a
|
||||
makefile, don't do the pattern variable search now, since the pattern
|
||||
variable might not have been defined yet. */
|
||||
|
||||
void
|
||||
initialize_file_variables (file)
|
||||
initialize_file_variables (file, reading)
|
||||
struct file *file;
|
||||
int reading;
|
||||
{
|
||||
register struct variable_set_list *l = file->variables;
|
||||
|
||||
if (l == 0)
|
||||
{
|
||||
l = (struct variable_set_list *)
|
||||
@ -296,9 +281,35 @@ initialize_file_variables (file)
|
||||
l->next = &global_setlist;
|
||||
else
|
||||
{
|
||||
initialize_file_variables (file->parent);
|
||||
initialize_file_variables (file->parent, reading);
|
||||
l->next = file->parent->variables;
|
||||
}
|
||||
|
||||
/* If we're not reading makefiles and we haven't looked yet, see if
|
||||
we can find a pattern variable. */
|
||||
|
||||
if (!reading && !file->pat_searched)
|
||||
{
|
||||
struct pattern_var *p = lookup_pattern_var (file->name);
|
||||
|
||||
file->pat_searched = 1;
|
||||
if (p != 0)
|
||||
{
|
||||
/* If we found one, insert it between the current target's
|
||||
variables and the next set, whatever it is. */
|
||||
file->pat_variables = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
file->pat_variables->set = p->vars->set;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a pattern variable match, set it up. */
|
||||
|
||||
if (file->pat_variables != 0)
|
||||
{
|
||||
file->pat_variables->next = l->next;
|
||||
l->next = file->pat_variables;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the top set off the current variable set list,
|
||||
@ -947,8 +958,9 @@ try_variable_definition (flocp, line, origin, target_var)
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
shellpath, origin, flavor == f_recursive);
|
||||
v = define_variable_loc (expanded_name, strlen (expanded_name),
|
||||
shellpath, origin, flavor == f_recursive,
|
||||
flocp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -987,8 +999,9 @@ try_variable_definition (flocp, line, origin, target_var)
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
shellpath, origin, flavor == f_recursive);
|
||||
v = define_variable_loc (expanded_name, strlen (expanded_name),
|
||||
shellpath, origin,
|
||||
flavor == f_recursive, flocp);
|
||||
}
|
||||
else
|
||||
v = lookup_variable (expanded_name, strlen (expanded_name));
|
||||
@ -1009,15 +1022,16 @@ try_variable_definition (flocp, line, origin, target_var)
|
||||
* set new value for SHELL variable.
|
||||
*/
|
||||
if (find_and_set_default_shell(value)) {
|
||||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
default_shell, origin, flavor == f_recursive);
|
||||
v = define_variable_loc (expanded_name, strlen (expanded_name),
|
||||
default_shell, origin, flavor == f_recursive,
|
||||
flocp);
|
||||
no_default_sh_exe = 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
||||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
value, origin, flavor == f_recursive);
|
||||
v = define_variable_loc (expanded_name, strlen (expanded_name), value,
|
||||
origin, flavor == f_recursive, flocp);
|
||||
|
||||
v->append = append;
|
||||
|
||||
@ -1040,32 +1054,35 @@ print_variable (v, prefix)
|
||||
switch (v->origin)
|
||||
{
|
||||
case o_default:
|
||||
origin = "default";
|
||||
origin = _("default");
|
||||
break;
|
||||
case o_env:
|
||||
origin = "environment";
|
||||
origin = _("environment");
|
||||
break;
|
||||
case o_file:
|
||||
origin = "makefile";
|
||||
origin = _("makefile");
|
||||
break;
|
||||
case o_env_override:
|
||||
origin = "environment under -e";
|
||||
origin = _("environment under -e");
|
||||
break;
|
||||
case o_command:
|
||||
origin = "command line";
|
||||
origin = _("command line");
|
||||
break;
|
||||
case o_override:
|
||||
origin = "`override' directive";
|
||||
origin = _("`override' directive");
|
||||
break;
|
||||
case o_automatic:
|
||||
origin = "automatic";
|
||||
origin = _("automatic");
|
||||
break;
|
||||
case o_invalid:
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
printf ("# %s\n", origin);
|
||||
|
||||
fputs ("# ", stdout);
|
||||
fputs (origin, stdout);
|
||||
if (v->fileinfo.filenm)
|
||||
printf (" (from `%s', line %lu)", v->fileinfo.filenm, v->fileinfo.lineno);
|
||||
putchar ('\n');
|
||||
fputs (prefix, stdout);
|
||||
|
||||
/* Is this a `define'? */
|
||||
|
32
variable.h
32
variable.h
@ -40,6 +40,7 @@ struct variable
|
||||
struct variable *next; /* Link in the chain. */
|
||||
char *name; /* Variable name. */
|
||||
char *value; /* Variable value. */
|
||||
struct floc fileinfo; /* Where the variable was defined. */
|
||||
enum variable_origin
|
||||
origin ENUM_BITFIELD (3); /* Variable origin. */
|
||||
unsigned int recursive:1; /* Gets recursively re-evaluated. */
|
||||
@ -101,19 +102,36 @@ extern struct variable_set_list *create_new_variable_set PARAMS ((void));
|
||||
extern struct variable_set_list *push_new_variable_scope PARAMS ((void));
|
||||
extern void pop_variable_scope PARAMS ((void));
|
||||
extern void define_automatic_variables PARAMS ((void));
|
||||
extern void initialize_file_variables PARAMS ((struct file *file));
|
||||
extern void initialize_file_variables PARAMS ((struct file *file, int read));
|
||||
extern void print_file_variables PARAMS ((struct file *file));
|
||||
extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix));
|
||||
extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
|
||||
extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin, int target_var));
|
||||
|
||||
extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length));
|
||||
extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value,
|
||||
enum variable_origin origin, int recursive));
|
||||
extern struct variable *define_variable_in_set PARAMS ((char *name, unsigned int length,
|
||||
char *value, enum variable_origin origin, int recursive, struct variable_set *set));
|
||||
extern struct variable *define_variable_for_file PARAMS ((char *name, unsigned int length,
|
||||
char *value, enum variable_origin origin, int recursive, struct file *file));
|
||||
|
||||
extern struct variable *define_variable_in_set
|
||||
PARAMS ((char *name, unsigned int length, char *value,
|
||||
enum variable_origin origin, int recursive,
|
||||
struct variable_set *set, const struct floc *flocp));
|
||||
|
||||
/* Define a variable in the current variable set. */
|
||||
|
||||
#define define_variable(n,l,v,o,r) \
|
||||
define_variable_in_set((n),(l),(v),(o),(r),\
|
||||
current_variable_set_list->set,NILF)
|
||||
|
||||
/* Define a variable with a location in the current variable set. */
|
||||
|
||||
#define define_variable_loc(n,l,v,o,r,f) \
|
||||
define_variable_in_set((n),(l),(v),(o),(r),\
|
||||
current_variable_set_list->set,(f))
|
||||
|
||||
/* Define a variable in FILE's variable set. */
|
||||
|
||||
#define define_variable_for_file(n,l,v,o,r,f) \
|
||||
define_variable_in_set((n),(l),(v),(o),(r),(f)->variables->set,NILF)
|
||||
|
||||
extern char **target_environment PARAMS ((struct file *file));
|
||||
|
||||
extern int export_all_variables;
|
||||
|
Loading…
Reference in New Issue
Block a user