mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-12-27 06:27:51 +00:00
Fix eval bugs 1516 and 1517.
This commit is contained in:
parent
bd108cf45c
commit
d696707cb5
7 changed files with 130 additions and 17 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,5 +1,24 @@
|
|||
2002-10-25 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* expand.c (install_variable_buffer): New function. Install a new
|
||||
variable_buffer context and return the previous one.
|
||||
(restore_variable_buffer): New function. Free the current
|
||||
variable_buffer context and put a previously saved one back.
|
||||
* variable.h: Prototypes for {install,restore}_variable_buffer.
|
||||
* function.c (func_eval): Push a new variable_buffer context
|
||||
before we eval, then restore the old one when we're done.
|
||||
Fixes Bug #1517.
|
||||
|
||||
* read.c (install_conditionals): New function. Install a new
|
||||
conditional context and return the previous one.
|
||||
(restore_conditionals): New function. Free the current
|
||||
conditional context and put a previously saved one back.
|
||||
(eval): Use the {install,restore}_conditionals for "include"
|
||||
handling.
|
||||
(eval_buffer): Use {install,restore}_conditionals to preserve the
|
||||
present conditional state before we evaluate the buffer.
|
||||
Fixes Bug #1516.
|
||||
|
||||
* doc/make.texi (Quick Reference): Add references to $(eval ...)
|
||||
and $(value ...).
|
||||
(Recursion): Add a variable index entry for CURDIR.
|
||||
|
|
25
expand.c
25
expand.c
|
@ -545,3 +545,28 @@ allocated_variable_expand_for_file (char *line, struct file *file)
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Install a new variable_buffer context, returning the current one for
|
||||
safe-keeping. */
|
||||
|
||||
void
|
||||
install_variable_buffer (char **bufp, unsigned int *lenp)
|
||||
{
|
||||
*bufp = variable_buffer;
|
||||
*lenp = variable_buffer_length;
|
||||
|
||||
variable_buffer = 0;
|
||||
initialize_variable_output ();
|
||||
}
|
||||
|
||||
/* Restore a previously-saved variable_buffer setting (free the current one).
|
||||
*/
|
||||
|
||||
void
|
||||
restore_variable_buffer (char *buf, unsigned int len)
|
||||
{
|
||||
free (variable_buffer);
|
||||
|
||||
variable_buffer = buf;
|
||||
variable_buffer_length = len;
|
||||
}
|
||||
|
|
10
function.c
10
function.c
|
@ -1196,8 +1196,18 @@ func_wildcard (char *o, char **argv, const char *funcname)
|
|||
static char *
|
||||
func_eval (char *o, char **argv, const char *funcname)
|
||||
{
|
||||
char *buf;
|
||||
unsigned int len;
|
||||
|
||||
/* 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);
|
||||
|
||||
eval_buffer (argv[0]);
|
||||
|
||||
restore_variable_buffer (buf, len);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
|
55
read.c
55
read.c
|
@ -272,6 +272,34 @@ read_all_makefiles (char **makefiles)
|
|||
return read_makefiles;
|
||||
}
|
||||
|
||||
/* Install a new conditional and return the previous one. */
|
||||
|
||||
static struct conditionals *
|
||||
install_conditionals (struct conditionals *new)
|
||||
{
|
||||
struct conditionals *save = conditionals;
|
||||
|
||||
bzero ((char *) new, sizeof (*new));
|
||||
conditionals = new;
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
/* Free the current conditionals and reinstate a saved one. */
|
||||
|
||||
static void
|
||||
restore_conditionals (struct conditionals *saved)
|
||||
{
|
||||
/* Free any space allocated by conditional_line. */
|
||||
if (conditionals->ignoring)
|
||||
free (conditionals->ignoring);
|
||||
if (conditionals->seen_else)
|
||||
free (conditionals->seen_else);
|
||||
|
||||
/* Restore state. */
|
||||
conditionals = saved;
|
||||
}
|
||||
|
||||
static int
|
||||
eval_makefile (char *filename, int flags)
|
||||
{
|
||||
|
@ -388,6 +416,8 @@ int
|
|||
eval_buffer (char *buffer)
|
||||
{
|
||||
struct ebuffer ebuf;
|
||||
struct conditionals *saved;
|
||||
struct conditionals new;
|
||||
const struct floc *curfile;
|
||||
int r;
|
||||
|
||||
|
@ -402,8 +432,12 @@ eval_buffer (char *buffer)
|
|||
curfile = reading_file;
|
||||
reading_file = &ebuf.floc;
|
||||
|
||||
saved = install_conditionals (&new);
|
||||
|
||||
r = eval (&ebuf, 1);
|
||||
|
||||
restore_conditionals (saved);
|
||||
|
||||
reading_file = curfile;
|
||||
|
||||
return r;
|
||||
|
@ -412,13 +446,8 @@ eval_buffer (char *buffer)
|
|||
|
||||
/* Read file FILENAME as a makefile and add its contents to the data base.
|
||||
|
||||
SET_DEFAULT is true if we are allowed to set the default goal.
|
||||
SET_DEFAULT is true if we are allowed to set the default goal. */
|
||||
|
||||
FILENAME is added to the `read_makefiles' chain.
|
||||
|
||||
Returns 0 if a file was not found or not read.
|
||||
Returns 1 if FILENAME was found and read.
|
||||
Returns 2 if FILENAME was read, and we kept a reference (don't free it). */
|
||||
|
||||
static int
|
||||
eval (struct ebuffer *ebuf, int set_default)
|
||||
|
@ -782,9 +811,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
|||
|
||||
/* Save the state of conditionals and start
|
||||
the included makefile with a clean slate. */
|
||||
save = conditionals;
|
||||
bzero ((char *) &new_conditionals, sizeof new_conditionals);
|
||||
conditionals = &new_conditionals;
|
||||
save = install_conditionals (&new_conditionals);
|
||||
|
||||
/* Record the rules that are waiting so they will determine
|
||||
the default goal before those in the included makefile. */
|
||||
|
@ -810,14 +837,8 @@ eval (struct ebuffer *ebuf, int set_default)
|
|||
}
|
||||
}
|
||||
|
||||
/* Free any space allocated by conditional_line. */
|
||||
if (conditionals->ignoring)
|
||||
free (conditionals->ignoring);
|
||||
if (conditionals->seen_else)
|
||||
free (conditionals->seen_else);
|
||||
|
||||
/* Restore state. */
|
||||
conditionals = save;
|
||||
/* Restore conditional state. */
|
||||
restore_conditionals (save);
|
||||
|
||||
goto rule_complete;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2002-10-25 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/functions/eval: Test using $(eval ...) inside
|
||||
conditionals (Bug #1516).
|
||||
|
||||
2002-10-13 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/targetvars: Add a test for exporting
|
||||
|
|
|
@ -57,4 +57,35 @@ $answer = "A = A B = B\n";
|
|||
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
# Test to make sure eval'ing inside conditionals works properly
|
||||
|
||||
$makefile3 = &get_tmpfile;
|
||||
|
||||
open(MAKEFILE,"> $makefile3");
|
||||
|
||||
print MAKEFILE <<'EOF';
|
||||
FOO = foo
|
||||
|
||||
all:: ; @echo it
|
||||
|
||||
define Y
|
||||
all:: ; @echo worked
|
||||
endef
|
||||
|
||||
ifdef BAR
|
||||
$(eval $(Y))
|
||||
endif
|
||||
|
||||
EOF
|
||||
|
||||
close(MAKEFILE);
|
||||
|
||||
&run_make_with_options($makefile3, "", &get_logfile);
|
||||
$answer = "it\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
&run_make_with_options($makefile3, "BAR=1", &get_logfile);
|
||||
$answer = "it\nworked\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
1;
|
||||
|
|
|
@ -107,6 +107,8 @@ extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file
|
|||
extern char *expand_argument PARAMS ((char *str, char *end));
|
||||
extern char *variable_expand_string PARAMS ((char *line, char *string,
|
||||
long length));
|
||||
extern void install_variable_buffer PARAMS ((char **bufp, unsigned int *lenp));
|
||||
extern void restore_variable_buffer PARAMS ((char *buf, unsigned int len));
|
||||
|
||||
/* function.c */
|
||||
extern int handle_function PARAMS ((char **op, char **stringp));
|
||||
|
|
Loading…
Reference in a new issue