* Fix PR/1407.

* Keep filename/lineno information for variables, for debugging.
This commit is contained in:
Paul Smith 2000-02-05 07:37:40 +00:00
parent 95a09e94f7
commit 9b0a3d91ea
11 changed files with 159 additions and 91 deletions

View file

@ -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
View file

@ -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.

View file

@ -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);

View file

@ -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;
}

View file

@ -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
View file

@ -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. */

2
rule.c
View file

@ -607,7 +607,7 @@ 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. */

View file

@ -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

View file

@ -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;

View file

@ -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'? */

View file

@ -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;