Add support for broken SA_RESTART on PTX.

Fix bug #103: allow ifdef, export, and unexport to expand their arguments.
This commit is contained in:
Paul Smith 2002-09-10 07:27:28 +00:00
parent 9b41488ad1
commit 7ea029a07c
9 changed files with 345 additions and 7 deletions

View file

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

View 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.])

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

14
make.h
View file

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

35
misc.c
View file

@ -856,3 +856,38 @@ get_path_max ()
return value;
}
#endif
#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 */

43
read.c
View file

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

View 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

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

View file

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