Submitted By: Jim Gifford (patches at jg555 dot com)
Date: 2003-09-12
Initial Package Version: 3.80
Origin: http://savannah.gnu.org/bugs/?func=detailbug&bug_id=1516&group_id=71
Description: Using $(eval ...) inside a conditional (that is parsed)
	     will cause an error like this: 
	     Makefile:10: *** missing `endif'. Stop

diff -Naur make-3.80.orig/read.c make-3.80/read.c
--- make-3.80.orig/read.c	2002-10-04 02:13:42.000000000 +0000
+++ make-3.80/read.c	2003-09-12 06:06:22.000000000 +0000
@@ -272,6 +272,34 @@
   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 (filename, flags)
      char *filename;
@@ -391,6 +419,8 @@
      char *buffer;
 {
   struct ebuffer ebuf;
+  struct conditionals *saved;
+  struct conditionals new;
   const struct floc *curfile;
   int r;
 
@@ -405,8 +435,12 @@
   curfile = reading_file;
   reading_file = &ebuf.floc;
 
+  saved = install_conditionals (&new);
+
   r = eval (&ebuf, 1);
 
+  restore_conditionals (saved);
+
   reading_file = curfile;
 
   return r;
@@ -415,13 +449,8 @@
 
 /* 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 (ebuf, set_default)
@@ -787,9 +816,7 @@
 
 	  /* 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.  */
@@ -815,14 +842,8 @@
                 }
 	    }
 
-	  /* 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;
 	}
diff -Naur make-3.80.orig/tests/scripts/functions/eval make-3.80/tests/scripts/functions/eval
--- make-3.80.orig/tests/scripts/functions/eval	2002-07-08 02:26:48.000000000 +0000
+++ make-3.80/tests/scripts/functions/eval	2003-09-12 06:06:22.000000000 +0000
@@ -57,4 +57,35 @@
 
 &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;
