Add support for broken SA_RESTART on PTX.
authorPaul Smith <psmith@gnu.org>
Tue, 10 Sep 2002 07:27:28 +0000 (07:27 +0000)
committerPaul Smith <psmith@gnu.org>
Tue, 10 Sep 2002 07:27:28 +0000 (07:27 +0000)
Fix bug #103: allow ifdef, export, and unexport to expand their arguments.

ChangeLog
configure.in
doc/make.texi
make.h
misc.c
read.c
tests/ChangeLog
tests/scripts/features/conditionals
tests/scripts/features/export [new file with mode: 0644]

index d600686..4891382 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,29 @@
+2002-09-10  Paul D. Smith  <psmith@gnu.org>
+
+       * read.c (eval): Expand variable lists given to export and
+       unexport, so that "export $(LIST_OF_VARIABLES)" (etc.) works.
+       (conditional_line): Ditto for "ifdef".  Fixes bug #103.
+
+       * doc/make.texi (Variables/Recursion): Document this.
+       (Conditional Syntax): And here.
+
 2002-09-09  Paul D. Smith  <psmith@gnu.org>
 
        * configure.in: Check for memmove().
 
+2002-09-07  Paul D. Smith  <psmith@gnu.org>
+
+       * configure.in (HAVE_BROKEN_RESTART): Define this on PTX systems;
+       Michael Sterrett <msterret@coat.com> reports that while it has
+       SA_RESTART, it does not work properly.
+
+       * misc.c (atomic_stat): If HAVE_BROKEN_RESTART, create a function
+       that invokes stat() and loops to do it again if it returns EINTR.
+       (atomic_readdir): Ditto, with readdir().
+
+       * make.h (stat, readdir): If HAVE_BROKEN_RESTART, alias stat()
+       and readdir() to atomic_stat() and atomic_readdir().
+
 2002-09-04  Paul D. Smith  <psmith@gnu.org>
 
        * implicit.c (pattern_search): Daniel <barkalow@reputation.com>
index 5abbad5..c5c8026 100644 (file)
@@ -291,6 +291,21 @@ make_cv_sys_gnu_glob=no])])
 # Tell automake about this, so it can build the right .c files.
 AM_CONDITIONAL(USE_LOCAL_GLOB, test "$make_cv_sys_gnu_glob" = no)
 
+# PTX systems have a broken implementation of SA_RESTART.  I know of
+# no way to test for this behavior, so I'll just test for PTX
+
+case "$host" in
+  i386-sequent-sysv4)
+    AC_DEFINE(HAVE_BROKEN_RESTART, 1, [This system has SA_RESTART, but it doesn't work properly.])
+    echo ""
+    echo "WARNING: The SA_RESTART sigaction() flag does not work on PTX."
+    echo "         This causes 'make -j' to fail at random times."
+    echo "         I am installing a workaround, which is mostly but not 100%"
+    echo "         effective.  If you see random failures during 'make -j'"
+    echo "         you should either contact the bug list, or not use -j."
+    echo "" ;;
+esac
+
 # Let the makefile know what our build host is
 
 AC_DEFINE_UNQUOTED(MAKE_HOST,"$host",[Build host information.])
index 4ef1107..2389ca0 100644 (file)
@@ -3747,6 +3747,10 @@ unexport @var{variable} @dots{}
 @end example
 
 @noindent
+In both of these forms, the arguments to @code{export} and
+@code{unexport} are expanded, and so could be variables or functions
+which expand to a (list of) variable names to be (un)exported.
+
 As a convenience, you can define a variable and export it at the same
 time by doing:
 
@@ -5434,7 +5438,9 @@ effective; otherwise, the @var{text-if-false}, if any, is effective.
 If the variable @var{variable-name} has a non-empty value, the
 @var{text-if-true} is effective; otherwise, the @var{text-if-false},
 if any, is effective.  Variables that have never been defined have an
-empty value.
+empty value.  The variable @var{variable-name} is itself expanded, so
+it could be a variable or function that expands to the name of a
+variable.
 
 Note that @code{ifdef} only tests whether a variable has a value.  It
 does not expand the variable to see if that value is nonempty.
diff --git a/make.h b/make.h
index 32f233f..2e354c9 100644 (file)
--- a/make.h
+++ b/make.h
@@ -537,3 +537,17 @@ extern int handling_fatal_signal;
 #ifdef HAVE_DMALLOC_H
 #include <dmalloc.h>
 #endif
+
+
+/* If we have broken SA_RESTART support, then wrap stat() and readdir() with
+   versions that handle EINTR.  Note that there are still plenty of system
+   calls that can fail with EINTR but this, reportedly, gets the vast
+   majority of failure cases.  If you still experience failures you'll need
+   to either get a system where SA_RESTART works, or you need to avoid -j.  */
+
+#ifdef HAVE_BROKEN_RESTART
+
+#define stat(_f,_b)     atomic_stat ((_f), (_b))
+#define readdir(_d)     atomic_readdir (_d)
+
+#endif
diff --git a/misc.c b/misc.c
index 6e2b570..669dabc 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -856,3 +856,38 @@ get_path_max ()
   return value;
 }
 #endif
+\f
+
+#ifdef HAVE_BROKEN_RESTART
+
+#undef stat
+#undef readdir
+
+int
+atomic_stat(file, buf)
+     const char *file;
+     struct stat *buf;
+{
+  int r;
+
+  while ((r = stat (file, buf)) < 0)
+    if (errno != EINTR)
+      break;
+
+  return r;
+}
+
+struct dirent *
+atomic_readdir(dir)
+     DIR *file;
+{
+  struct dirent *r;
+
+  while ((r = readdir (file, buf)) == NULL)
+    if (errno != EINTR)
+      break;
+
+  return r;
+}
+
+#endif  /* HAVE_BROKEN_RESTART */
diff --git a/read.c b/read.c
index 7dee3e3..dd930f7 100644 (file)
--- a/read.c
+++ b/read.c
@@ -593,7 +593,7 @@ eval (ebuf, set_default)
              || word1eq ("ifeq") || word1eq ("ifneq")
              || word1eq ("else") || word1eq ("endif")))
        {
-         int i = conditional_line (p, fstart);
+         int i = conditional_line (p, fstart);
          if (i < 0)
            fatal (fstart, _("invalid syntax in conditional"));
 
@@ -686,11 +686,21 @@ eval (ebuf, set_default)
                   for (p = find_next_token (&p2, &len); p != 0;
                        p = find_next_token (&p2, &len))
                     {
-                      v = lookup_variable (p, len);
+                      char *var;
+                      int l;
+
+                      /* Expand the thing we're looking up, so we can use
+                         indirect and constructed variable names.  */
+                      p[len] = '\0';
+                      var = allocated_variable_expand (p);
+                      l = strlen (var);
+
+                      v = lookup_variable (var, l);
                       if (v == 0)
-                        v = define_variable_loc (p, len, "", o_file, 0,
+                        v = define_variable_loc (var, l, "", o_file, 0,
                                                  fstart);
                       v->export = v_export;
+                      free (var);
                     }
                 }
             }
@@ -708,10 +718,22 @@ eval (ebuf, set_default)
               for (p = find_next_token (&p2, &len); p != 0;
                    p = find_next_token (&p2, &len))
                 {
-                  v = lookup_variable (p, len);
+                  char *var;
+                  int l;
+
+                  /* Expand the thing we're looking up, so we can use
+                     indirect and constructed variable names.  */
+                  p[len] = '\0';
+                  var = allocated_variable_expand (p);
+                  l = strlen (var);
+
+                  v = lookup_variable (var, l);
                   if (v == 0)
-                    v = define_variable_loc (p, len, "", o_file, 0, fstart);
+                    v = define_variable_loc (var, l, "", o_file, 0, fstart);
+
                   v->export = v_noexport;
+
+                  free (var);
                 }
             }
           goto rule_complete;
@@ -1410,15 +1432,24 @@ conditional_line (line, flocp)
   if (cmdname[notdef ? 3 : 2] == 'd')
     {
       /* "Ifdef" or "ifndef".  */
+      char *var;
       struct variable *v;
       register char *p = end_of_token (line);
       i = p - line;
       p = next_token (p);
       if (*p != '\0')
        return -1;
-      v = lookup_variable (line, i);
+
+      /* Expand the thing we're looking up, so we can use indirect and
+         constructed variable names.  */
+      line[i] = '\0';
+      var = allocated_variable_expand (line);
+
+      v = lookup_variable (var, strlen (var));
       conditionals->ignoring[conditionals->if_cmds - 1]
        = (v != 0 && *v->value != '\0') == notdef;
+
+      free (var);
     }
   else
     {
index 7336bd3..64a8322 100644 (file)
@@ -1,3 +1,11 @@
+2002-09-10  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/features/export: Created.  Add tests for export/unexport
+       capabilities, including exporting/unexporting expanded variables.
+
+       * scripts/features/conditionals: Add a test for expanded variables
+       in ifdef conditionals.
+
 2002-09-04  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/features/reinvoke: Change touch/sleep combos to utouch
index 3557fb5..ab3d9d5 100644 (file)
@@ -63,5 +63,39 @@ arg4 is defined
 
 &compare_output($answer,&get_logfile(1));
 
+
+# Test expansion of variables inside ifdef.
+
+$makefile2 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile2");
+
+print MAKEFILE <<'EOF';
+
+foo = 1
+
+FOO = foo
+F = f
+
+DEF = no
+DEF2 = no
+
+ifdef $(FOO)
+DEF = yes
+endif
+
+ifdef $(F)oo
+DEF2 = yes
+endif
+
+all:; @echo DEF=$(DEF) DEF2=$(DEF2)
+
+EOF
+
+&run_make_with_options($makefile2,"",&get_logfile,0);
+$answer = "DEF=yes DEF2=yes\n";
+&compare_output($answer,&get_logfile(1));
+
+
 # This tells the test driver that the perl test script executed properly.
 1;
diff --git a/tests/scripts/features/export b/tests/scripts/features/export
new file mode 100644 (file)
index 0000000..09aeac2
--- /dev/null
@@ -0,0 +1,173 @@
+#                                                                    -*-perl-*-
+$description = "Check GNU make export/unexport commands.";
+
+$details = "";
+
+# The test driver cleans out our environment for us so we don't have to worry
+# about that here.
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE <<'EOMAKE';
+
+FOO = foo
+BAR = bar
+BOZ = boz
+
+export BAZ = baz
+export BOZ
+
+BITZ = bitz
+BOTZ = botz
+
+export BITZ BOTZ
+unexport BOTZ
+
+
+ifdef EXPORT_ALL
+export
+endif
+
+ifdef UNEXPORT_ALL
+unexport
+endif
+
+ifdef EXPORT_ALL_PSEUDO
+.EXPORT_ALL_VARIABLES:
+endif
+
+all:
+       @echo "FOO=$(FOO) BAR=$(BAR) BAZ=$(BAZ) BOZ=$(BOZ) BITZ=$(BITZ) BOTZ=$(BOTZ)"
+       @echo "FOO=$$FOO BAR=$$BAR BAZ=$$BAZ BOZ=$$BOZ BITZ=$$BITZ BOTZ=$$BOTZ"
+
+EOMAKE
+
+close(MAKEFILE);
+
+# TEST 0: basics
+
+&run_make_with_options($makefile,"",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+# TEST 1: make sure vars inherited from the parent are exported
+
+$ENV{FOO} = 1;
+
+&run_make_with_options($makefile,"",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+delete $ENV{FOO};
+
+# TEST 2: global export.  Explicit unexport takes precedence.
+
+&run_make_with_options($makefile,"EXPORT_ALL=1",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+# TEST 3: global unexport.  Explicit export takes precedence.
+
+&run_make_with_options($makefile,"UNEXPORT_ALL=1",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+# TEST 4: both: in the above makefile the unexport comes last so that rules.
+
+&run_make_with_options($makefile,"EXPORT_ALL=1 UNEXPORT_ALL=1",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+# TEST 5: test the pseudo target.
+
+&run_make_with_options($makefile,"EXPORT_ALL_PSEUDO=1",&get_logfile,0);
+
+$answer = "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n";
+
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST 6: Test the expansion of variables inside export
+
+$makefile2 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile2");
+
+print MAKEFILE <<'EOF';
+
+foo = f-ok
+bar = b-ok
+
+FOO = foo
+F = f
+
+BAR = bar
+B = b
+
+export $(FOO)
+export $(B)ar
+
+all:
+       @echo foo=$(foo) bar=$(bar)
+       @echo foo=$$foo bar=$$bar
+
+EOF
+
+&run_make_with_options($makefile2,"",&get_logfile,0);
+$answer = "foo=f-ok bar=b-ok\nfoo=f-ok bar=b-ok\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST 7: Test the expansion of variables inside unexport
+
+$makefile3 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile3");
+
+print MAKEFILE <<'EOF';
+
+foo = f-ok
+bar = b-ok
+
+FOO = foo
+F = f
+
+BAR = bar
+B = b
+
+export foo bar
+
+unexport $(FOO)
+unexport $(B)ar
+
+all:
+       @echo foo=$(foo) bar=$(bar)
+       @echo foo=$$foo bar=$$bar
+
+EOF
+
+&run_make_with_options($makefile3,"",&get_logfile,0);
+$answer = "foo=f-ok bar=b-ok\nfoo= bar=\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# This tells the test driver that the perl test script executed properly.
+1;