]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Fix eval bugs 1516 and 1517.
authorPaul Smith <psmith@gnu.org>
Fri, 25 Oct 2002 22:01:47 +0000 (22:01 +0000)
committerPaul Smith <psmith@gnu.org>
Fri, 25 Oct 2002 22:01:47 +0000 (22:01 +0000)
ChangeLog
expand.c
function.c
read.c
tests/ChangeLog
tests/scripts/functions/eval
variable.h

index 409db2b972962a99aa312830734b450398474bf9..1f4c0586233c406dac9c858ab314c2da44d116cc 100644 (file)
--- a/ChangeLog
+++ b/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.
index 5c2c3e2efc19c5f9fd61036189d8548258bc20d9..ac4ccda505002da6517a99e08fa79b1ceebba9c1 100644 (file)
--- a/expand.c
+++ b/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;
+}
index 3282cdfc0537715ecff1995e3b500bfb73a7d0f0..5a27406b8d3746f5fe59a56f25f676e7e175b8af 100644 (file)
@@ -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;
 }
 
diff --git a/read.c b/read.c
index 4fb811a40cd5436dcdaa19a32dd4233d2a5146d0..3e0157202e4fb16fee40e1280fb0b5337a03cab2 100644 (file)
--- a/read.c
+++ b/read.c
@@ -272,6 +272,34 @@ read_all_makefiles (char **makefiles)
   return read_makefiles;
 }
 \f
+/* 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;
+}
+\f
 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)
 \f
 /* 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.
-
-   FILENAME is added to the `read_makefiles' chain.
+   SET_DEFAULT is true if we are allowed to set the default goal.  */
 
-   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;
        }
index 3c62080f3c939612c1f585c2c68cb5df50b4d873..e91ccc9bd5fd9d70bb1cbc7c40a16b66c685c7bb 100644 (file)
@@ -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
index 0d5e3b8339671a88cb046b955b83f208b8eddc29..174767d772c740263ca9a5dd31128002ed5325bc 100644 (file)
@@ -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;
index d9cd7f7c7d200224b9bf4e498c759b8d9e9e368b..f96bd6254d4f1edb55b9f6a5ad2d8c2ac65980b9 100644 (file)
@@ -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));