Fix Debian bug #144306: pass target-specific variables into the environment

properly.

Fix configure: allow cross-compilation; fix getloadavg (still needs _lots_
of work!)

Let $(call ...) functions to be self-referencing.  Lets us do transitive
closures, for example.
This commit is contained in:
Paul Smith 2002-05-10 03:15:07 +00:00
parent 5dedf7be63
commit 9052b52dfc
16 changed files with 320 additions and 174 deletions

View file

@ -1,3 +1,58 @@
2002-05-09 Paul D. Smith <psmith@gnu.org>
* file.c (file_timestamp_now): Use K&R function declaration.
* getloadavg.c (getloadavg): Merge setlocale() fix from sh-utils
getloadavg.c. Autoconf thinks QNX is SVR4-like, but it isn't, so
#undef it. Remove predefined setup of NLIST_STRUCT. Decide
whether to include nlist.h based on HAVE_NLIST_H. Change obsolete
NLIST_NAME_UNION to new HAVE_STRUCT_NLIST_N_UN_N_NAME.
* configure.in (NLIST_STRUCT): Define this if we have nlist.h and
nlist.n_name is a pointer rather than an array.
* acinclude.m4 (make_FUNC_SETVBUF_REVERSED): Grab the latest
version of AC_FUNC_SETVBUF_REVERSED from autoconf CVS.
* configure.in: Use it instead of the old version.
* main.c (main): Prefer setvbuf() to setlinebuf().
2002-05-08 Paul D. Smith <psmith@gnu.org>
* Makefile.am (make_LDADD): Add GETLOADAVG_LIBS.
(loadavg_LDADD): Ditto.
2002-04-29 Paul D. Smith <psmith@gnu.org>
* expand.c (recursively_expand_for_file): Rename
recursively_expand() to recursively_expand_for_file() and provide
an extra argument, struct file. If the argument is provided, set
the variable scope to that of the file before expanding.
* variable.h (recursively_expand): Make this a macro that invokes
recursively_expand_for_file() with a NULL file pointer.
* variable.c (target_environment): Call the renamed function and
provide the current file context.
Fixes Debian bug #144306.
2002-04-28 Paul D. Smith <psmith@gnu.org>
Allow $(call ...) user-defined variables to be self-referencing
without throwing an error. Allows implementation of transitive
closures, among other possibly useful things.
Requested by: Philip Guenther <guenther@sendmail.com>
* variable.h (struct variable): Add a new field: exp_count, and
new macros to hold its size and maximum value.
(warn_undefined): Make this a macro.
* variable.c (define_variable_in_set): Initialize it.
* expand.c (recursively_expand): If we detect recursive expansion
of a variable, check the exp_count field. If it's greater than 0
allow the recursion and decrement the count.
(warn_undefined): Remove this (now a macro in variable.h).
* function.c (func_call): Before we expand the user-defined
function, modify its exp_count field to contain the maximum
number of recursive calls we'll allow. After the call, reset it
to 0.
2002-04-21 Paul D. Smith <psmith@gnu.org>
Modified to use latest autoconf (2.53), automake (1.6.1), and

View file

@ -23,7 +23,7 @@ EXTRA_make_SOURCES = remote-stub.c remote-cstms.c
noinst_HEADERS = commands.h dep.h filedef.h job.h make.h rule.h variable.h \
debug.h getopt.h gettext.h
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB)
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@
man_MANS = make.1
info_TEXINFOS = make.texinfo
@ -117,6 +117,7 @@ check-loadavg: loadavg
noinst_PROGRAMS = loadavg
loadavg_SOURCES = getloadavg.c
loadavg_CFLAGS = -DTEST
loadavg_LDADD = @GETLOADAVG_LIBS@
# > check-regression
#

View file

@ -53,7 +53,13 @@ and you can just run "autoreconf" and have it DTRT.
Generate the proper aclocal.m4 file.
3) $ automake --add-missing
3) $ autoheader
Generate a "config.h.in" file from the contents of configure.in,
etc.
4) $ automake --add-missing
Add (symlink) missing files into the distribution, and generate
Makefile.in's from Makefile.am's.
@ -67,17 +73,11 @@ and you can just run "autoreconf" and have it DTRT.
Makefile.am:xxx: automatically discovered file `getloadavg.c' should not be explicitly mentioned
4) $ autoconf
5) $ autoconf
Generate a "configure" script from configure.in and acinclude.m4.
5) $ autoheader
Generate a "config.h.in" file from the contents of configure.in,
etc.
At this point you have successfully brought your CVS copy of the GNU
make source directory up to the point where it can be treated
more-or-less like the official package you would get from ftp.gnu.org.
@ -134,9 +134,9 @@ mv config/Makefile.am~ config/Makefile.am
mv Makefile.am~ Makefile.am
mv configure.in~ configure.in
aclocal -I config
autoheader
automake --add-missing
autoconf
autoheader
./configure
make
make check

View file

@ -111,3 +111,54 @@ AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC,
fi
]
)
dnl ---------------------------------------------------------------------------
dnl This will be in the next version of autoconf; take this out then!
# make_FUNC_SETVBUF_REVERSED
# ------------------------
AC_DEFUN([make_FUNC_SETVBUF_REVERSED],
[AC_REQUIRE([AC_C_PROTOTYPES])dnl
AC_CACHE_CHECK(whether setvbuf arguments are reversed,
ac_cv_func_setvbuf_reversed,
[ac_cv_func_setvbuf_reversed=no
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdio.h>
# if PROTOTYPES
int (setvbuf) (FILE *, int, char *, size_t);
# endif]],
[[char buf; return setvbuf (stdout, _IOLBF, &buf, 1);]])],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdio.h>
# if PROTOTYPES
int (setvbuf) (FILE *, int, char *, size_t);
# endif]],
[[char buf; return setvbuf (stdout, &buf, _IOLBF, 1);]])],
[# It compiles and links either way, so it must not be declared
# with a prototype and most likely this is a K&R C compiler.
# Try running it.
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdio.h>]],
[[/* This call has the arguments reversed.
A reversed system may check and see that the address of buf
is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */
char buf;
if (setvbuf (stdout, _IOLBF, &buf, 1) != 0)
exit (1);
putchar ('\r');
exit (0); /* Non-reversed systems SEGV here. */]])],
ac_cv_func_setvbuf_reversed=yes,
rm -f core core.* *.core,
[[: # Assume setvbuf is not reversed when cross-compiling.]])]
ac_cv_func_setvbuf_reversed=yes)])])
if test $ac_cv_func_setvbuf_reversed = yes; then
AC_DEFINE(SETVBUF_REVERSED, 1,
[Define to 1 if the `setvbuf' function takes the buffering type as
its second argument and the buffer pointer as the third, as on
System V before release 3.])
fi
])# make_FUNC_SETVBUF_REVERSED

View file

@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(GNU make,3.79.2rc1,bug-make@gnu.org)
AC_INIT(GNU make,3.79.2a1,bug-make@gnu.org)
AC_PREREQ(2.53)
@ -47,8 +47,8 @@ AC_HEADER_STDC
AC_HEADER_DIRENT
AC_HEADER_STAT
AC_HEADER_TIME
AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/param.h fcntl.h string.h \
memory.h sys/time.h sys/timeb.h)
AC_CHECK_HEADERS(stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
memory.h sys/param.h sys/time.h sys/timeb.h)
AM_PROG_CC_C_O
AM_PROG_CC_STDC
@ -70,7 +70,7 @@ AC_STRUCT_ST_MTIM_NSEC
AC_MSG_CHECKING([whether to use high resolution file timestamps])
AC_CACHE_VAL(make_cv_file_timestamp_hi_res, [
make_cv_file_timestamp_hi_res=no
if test $ac_cv_struct_st_mtim_nsec != no; then
if test "$ac_cv_struct_st_mtim_nsec" != no; then
AC_TRY_COMPILE([
# if HAVE_INTTYPES_H
# include <inttypes.h>
@ -79,7 +79,7 @@ AC_CACHE_VAL(make_cv_file_timestamp_hi_res, [
make_cv_file_timestamp_hi_res=yes)
fi])
AC_MSG_RESULT($make_cv_file_timestamp_hi_res)
if test $make_cv_file_timestamp_hi_res = yes; then
if test "$make_cv_file_timestamp_hi_res" = yes; then
val=1
else
val=0
@ -87,7 +87,7 @@ fi
AC_DEFINE_UNQUOTED(FILE_TIMESTAMP_HI_RES, $val,
[Use high resolution file timestamps if nonzero.])
if test $make_cv_file_timestamp_hi_res = yes; then
if test "$make_cv_file_timestamp_hi_res" = yes; then
# Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
# Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
AC_SEARCH_LIBS(clock_gettime, [rt posix4])
@ -113,24 +113,44 @@ AC_CACHE_CHECK([for standard gettimeofday], ac_cv_func_gettimeofday,
ac_cv_func_gettimeofday=yes,
ac_cv_func_gettimeofday=no,
ac_cv_func_gettimeofday="no (cross-compiling)")])
if test $ac_cv_func_gettimeofday = yes; then
if test "$ac_cv_func_gettimeofday" = yes; then
AC_DEFINE(HAVE_GETTIMEOFDAY, 1,
[Define if you have a standard gettimeofday function])
fi
AC_CHECK_FUNCS( memcpy strchr strdup mkstemp mktemp fdopen \
bsd_signal dup2 getcwd sigsetmask sigaction getgroups \
setlinebuf seteuid setegid setreuid setregid pipe \
seteuid setegid setlinebuf setreuid setregid setvbuf pipe \
strerror strsignal)
make_FUNC_SETVBUF_REVERSED
# strcoll() is used by the GNU glob library
AC_FUNC_STRCOLL
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_FUNC_VPRINTF
AC_FUNC_STRCOLL
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_SETVBUF_REVERSED
AC_FUNC_GETLOADAVG
# AC_FUNC_GETLOADAVG is documented to set the NLIST_STRUCT value, but it
# doesn't. So, we will.
if test "$ac_cv_header_nlist_h" = yes; then
AC_TRY_COMPILE([#include <nlist.h>],
[struct nlist nl;
nl.n_name = "string";
return 0;],
make_cv_nlist_struct=yes,
make_cv_nlist_struct=no)
if test "$make_cv_nlist_struct" = yes; then
AC_DEFINE(NLIST_STRUCT, 1,
[Define if struct nlist.n_name is a pointer rather than an array.])
fi
fi
AC_DECL_SYS_SIGLIST
# Check out the wait reality.
@ -168,7 +188,7 @@ AC_MSG_RESULT($make_cv_union_wait)
use_customs=false
AC_ARG_WITH(customs,
AC_HELP_STRING([--with-customs=DIR],
[Enable remote jobs via Customs--see README.customs]),
[enable remote jobs via Customs--see README.customs]),
[case $withval in
n|no) : ;;
*) make_cppflags="$CPPFLAGS"
@ -186,13 +206,13 @@ AC_ARG_WITH(customs,
;;
esac])
# Tell automake about this, so it can include the right .c files.
AM_CONDITIONAL(USE_CUSTOMS, test $use_customs = true)
AM_CONDITIONAL(USE_CUSTOMS, test "$use_customs" = true)
# See if we can handle the job server feature, and if the user wants it.
AC_ARG_ENABLE(job-server,
AC_HELP_STRING([--disable-job-server],
[Disallow recursive make communication during -jN]),
[disallow recursive make communication during -jN]),
[make_cv_job_server="$enableval" user_job_server="$enableval"],
[make_cv_job_server="yes"])
@ -268,7 +288,7 @@ AC_SUBST(GLOBINC) GLOBINC='-I$(srcdir)/glob'
AC_SUBST(GLOBLIB) GLOBLIB=glob/libglob.a
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)
AM_CONDITIONAL(USE_LOCAL_GLOB, test "$make_cv_sys_gnu_glob" = no)
# Let the makefile know what our build host is

View file

@ -95,16 +95,28 @@ initialize_variable_output ()
static char *allocated_variable_append PARAMS ((const struct variable *v));
char *
recursively_expand (v)
register struct variable *v;
recursively_expand_for_file (v, file)
struct variable *v;
struct file *file;
{
char *value;
struct variable_set_list *save;
if (v->expanding)
/* Expanding V causes infinite recursion. Lose. */
fatal (reading_file,
_("Recursive variable `%s' references itself (eventually)"),
v->name);
{
if (!v->exp_count)
/* Expanding V causes infinite recursion. Lose. */
fatal (reading_file,
_("Recursive variable `%s' references itself (eventually)"),
v->name);
--v->exp_count;
}
if (file)
{
save = current_variable_set_list;
current_variable_set_list = file->variables;
}
v->expanding = 1;
if (v->append)
@ -113,24 +125,12 @@ recursively_expand (v)
value = allocated_variable_expand (v->value);
v->expanding = 0;
if (file)
current_variable_set_list = save;
return value;
}
/* Warn that NAME is an undefined variable. */
#ifdef __GNUC__
__inline
#endif
static void
warn_undefined (name, length)
char *name;
unsigned int length;
{
if (warn_undefined_variables_flag)
error (reading_file,
_("warning: undefined variable `%.*s'"), (int)length, name);
}
/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
#ifdef __GNUC__
@ -280,7 +280,7 @@ variable_expand_string (line, string, length)
Is the resultant text a substitution reference? */
colon = lindex (beg, end, ':');
if (colon != 0)
if (colon)
{
/* This looks like a substitution reference: $(FOO:A=B). */
char *subst_beg, *subst_end, *replace_beg, *replace_end;

3
file.c
View file

@ -594,7 +594,8 @@ file_timestamp_cons (fname, s, ns)
/* Return the current time as a file timestamp, setting *RESOLUTION to
its resolution. */
FILE_TIMESTAMP
file_timestamp_now (int *resolution)
file_timestamp_now (resolution)
int *resolution;
{
int r;
time_t s;

View file

@ -991,7 +991,7 @@ func_error (o, argv, funcname)
for (len=0, argvp=argv; *argvp != 0; ++argvp)
len += strlen (*argvp) + 2;
p = msg = alloca (len + 1);
p = msg = (char *) alloca (len + 1);
for (argvp=argv; argvp[1] != 0; ++argvp)
{
@ -1822,10 +1822,11 @@ func_call (o, argv, funcname)
{
char *fname;
char *cp;
int flen;
char *body;
int flen;
int i;
const struct function_table_entry *entry_p;
struct variable *v;
/* There is no way to define a variable with a space in the name, so strip
leading and trailing whitespace as a favor to the user. */
@ -1856,11 +1857,18 @@ func_call (o, argv, funcname)
}
/* Not a builtin, so the first argument is the name of a variable to be
expanded and interpreted as a function. Create the variable
reference. */
expanded and interpreted as a function. Find it. */
flen = strlen (fname);
body = alloca (flen + 4);
v = lookup_variable (fname, flen);
if (v == 0)
warn_undefined (fname, flen);
if (v == 0 || *v->value == '\0')
return o;
body = (char *) alloca (flen + 4);
body[0] = '$';
body[1] = '(';
memcpy (body + 2, fname, flen);
@ -1882,8 +1890,12 @@ func_call (o, argv, funcname)
/* Expand the body in the context of the arguments, adding the result to
the variable buffer. */
v->exp_count = EXP_COUNT_MAX;
o = variable_expand_string (o, body, flen+3);
v->exp_count = 0;
pop_variable_scope ();
return o + strlen (o);

View file

@ -40,7 +40,7 @@
NLIST_STRUCT Include nlist.h, not a.out.h, and
the nlist n_name element is a pointer,
not an array.
NLIST_NAME_UNION struct nlist has an n_un member, not n_name.
HAVE_STRUCT_NLIST_N_UN_N_NAME struct nlist has an n_un member, not n_name.
LINUX_LDAV_FILE [__linux__]: File containing load averages.
Specific system predefines this file uses, aside from setting
@ -99,6 +99,13 @@
extern int errno;
#endif
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#if !HAVE_SETLOCALE
# define setlocale(Category, Locale) /* empty */
#endif
#ifndef HAVE_GETLOADAVG
@ -192,6 +199,10 @@ extern int errno;
# define tek4300 /* Define by emacs, but not by other users. */
# endif
/* AC_FUNC_GETLOADAVG thinks QNX is SVR4, but it isn't. */
# if defined(__QNX__)
# undef SVR4
# endif
/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
# ifndef LOAD_AVE_TYPE
@ -309,67 +320,6 @@ extern int errno;
# define LDAV_CVT(n) (((double) (n)) / FSCALE)
# endif
/* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */
# ifndef NLIST_STRUCT
# ifdef MORE_BSD
# define NLIST_STRUCT
# endif
# ifdef sun
# define NLIST_STRUCT
# endif
# ifdef decstation
# define NLIST_STRUCT
# endif
# ifdef hpux
# define NLIST_STRUCT
# endif
# if defined (_SEQUENT_) || defined (sequent)
# define NLIST_STRUCT
# endif
# ifdef sgi
# define NLIST_STRUCT
# endif
# ifdef SVR4
# define NLIST_STRUCT
# endif
# ifdef sony_news
# define NLIST_STRUCT
# endif
# ifdef OSF_ALPHA
# define NLIST_STRUCT
# endif
# if defined (ardent) && defined (titan)
# define NLIST_STRUCT
# endif
# ifdef tek4300
# define NLIST_STRUCT
# endif
# ifdef butterfly
# define NLIST_STRUCT
# endif
# if defined(alliant) && defined(i860) /* Alliant FX/2800 */
# define NLIST_STRUCT
# endif
# ifdef _AIX
# define NLIST_STRUCT
# endif
# endif /* defined (NLIST_STRUCT) */
# if defined(sgi) || (defined(mips) && !defined(BSD))
# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
@ -413,11 +363,11 @@ extern int errno;
# ifndef VMS
# ifndef __linux__
# ifndef NLIST_STRUCT
# include <a.out.h>
# else /* NLIST_STRUCT */
# ifdef HAVE_NLIST_H
# include <nlist.h>
# endif /* NLIST_STRUCT */
# else
# include <a.out.h>
# endif
# ifdef SUNOS_5
# include <fcntl.h>
@ -646,8 +596,11 @@ getloadavg (loadavg, nelem)
if (count <= 0)
return -1;
/* The following sscanf must use the C locale. */
setlocale (LC_NUMERIC, "C");
count = sscanf (ldavgbuf, "%lf %lf %lf",
&load_ave[0], &load_ave[1], &load_ave[2]);
setlocale (LC_NUMERIC, "");
if (count < 1)
return -1;
@ -923,13 +876,13 @@ getloadavg (loadavg, nelem)
strcpy (nl[0].n_name, LDAV_SYMBOL);
strcpy (nl[1].n_name, "");
# else /* NLIST_STRUCT */
# ifdef NLIST_NAME_UNION
# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
nl[0].n_un.n_name = LDAV_SYMBOL;
nl[1].n_un.n_name = 0;
# else /* not NLIST_NAME_UNION */
# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
nl[0].n_name = LDAV_SYMBOL;
nl[1].n_name = 0;
# endif /* not NLIST_NAME_UNION */
# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
# endif /* NLIST_STRUCT */
# ifndef SUNOS_5

24
main.c
View file

@ -443,19 +443,21 @@ int clock_skew_detected;
#ifdef POSIX
sigset_t fatal_signal_set;
#else
#ifdef HAVE_SIGSETMASK
# ifdef HAVE_SIGSETMASK
int fatal_signal_mask;
#endif
# endif
#endif
#if !defined HAVE_BSD_SIGNAL && !defined bsd_signal
# if !defined HAVE_SIGACTION
# define bsd_signal signal
# else
static RETSIGTYPE
(*bsd_signal) PARAMS ((int)) (sig, func)
typedef RETSIGTYPE (*bsd_signal_ret_t) ();
static bsd_signal_ret_t
bsd_signal (sig, func)
int sig;
RETSIGTYPE (*func) PARAMS ((int));
bsd_signal_ret_t func;
{
struct sigaction act, oact;
act.sa_handler = func;
@ -902,15 +904,15 @@ int main (int argc, char ** argv)
/* Make sure stdout is line-buffered. */
#ifdef HAVE_SETLINEBUF
setlinebuf (stdout);
#else
#ifndef SETVBUF_REVERSED
#ifdef HAVE_SETVBUF
# ifdef SETVBUF_REVERSED
setvbuf (stdout, (char *) 0, _IOLBF, BUFSIZ);
#else /* setvbuf not reversed. */
# else /* setvbuf not reversed. */
/* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
#endif /* setvbuf reversed. */
# endif /* setvbuf reversed. */
#elif HAVE_SETLINEBUF
setlinebuf (stdout);
#endif /* setlinebuf missing. */
/* Figure out where this program lives. */

71
make.h
View file

@ -17,11 +17,6 @@ along with GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because make.h was found in $srcdir). */
@ -29,6 +24,21 @@ Boston, MA 02111-1307, USA. */
#undef HAVE_CONFIG_H
#define HAVE_CONFIG_H 1
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
/* Use prototypes if available. */
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
@ -44,14 +54,6 @@ Boston, MA 02111-1307, USA. */
#define _GNU_SOURCE 1
/* Always use gettext.h */
#include "gettext.h"
#define _(_s) gettext (_s)
#define S_(_1,_2,_n) ngettext (_1,_2,_n)
#define N_(_s) gettext_noop (_s)
#ifdef CRAY
/* This must happen before #include <signal.h> so
@ -233,6 +235,14 @@ extern void exit PARAMS ((int)) __attribute__ ((noreturn));
#endif /* Standard headers. */
/* These should be in stdlib.h. Make sure we have them. */
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 0
#endif
#ifdef ANSI_STRING
# ifndef bcmp
@ -272,19 +282,6 @@ extern void bcopy PARAMS ((const char *b1, char *b2, int));
extern char *strerror PARAMS ((int errnum));
#endif
#ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
#else /* Not GCC. */
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else /* Not HAVE_ALLOCA_H. */
# ifndef _AIX
extern char *alloca ();
# endif /* Not AIX. */
# endif /* HAVE_ALLOCA_H. */
#endif /* GCC. */
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
@ -344,6 +341,22 @@ extern int strcmpi (const char *,const char *);
# define ENUM_BITFIELD(bits)
#endif
/* Handle gettext and locales. */
#if HAVE_LOCALE_H
# include <locale.h>
#else
# define setlocale(category, locale)
#endif
#include <gettext.h>
#define _(msgid) gettext (msgid)
#define N_(msgid) gettext_noop (msgid)
#define S_(msg1,msg2,num) ngettext (msg1,msg2,num)
/* Handle other OSs. */
#if defined(__MSDOS__) || defined(WINDOWS32)
# define PATH_SEPARATOR_CHAR ';'
#else
@ -398,10 +411,10 @@ extern void fatal ();
extern void die PARAMS ((int)) __attribute__ ((noreturn));
extern void log_working_directory PARAMS ((int));
extern void pfatal_with_name PARAMS ((char *)) __attribute__ ((noreturn));
extern void perror_with_name PARAMS ((char *, char *));
extern void pfatal_with_name PARAMS ((const char *)) __attribute__ ((noreturn));
extern void perror_with_name PARAMS ((const char *, const char *));
extern char *savestring PARAMS ((const char *, unsigned int));
extern char *concat PARAMS ((char *, char *, char *));
extern char *concat PARAMS ((const char *, const char *, const char *));
extern char *xmalloc PARAMS ((unsigned int));
extern char *xrealloc PARAMS ((char *, unsigned int));
extern char *xstrdup PARAMS ((const char *));

14
misc.c
View file

@ -173,7 +173,7 @@ remove_comments (line)
void
print_spaces (n)
register unsigned int n;
unsigned int n;
{
while (n-- > 0)
putchar (' ');
@ -185,10 +185,10 @@ print_spaces (n)
char *
concat (s1, s2, s3)
register char *s1, *s2, *s3;
const char *s1, *s2, *s3;
{
register unsigned int len1, len2, len3;
register char *result;
unsigned int len1, len2, len3;
char *result;
len1 = *s1 != '\0' ? strlen (s1) : 0;
len2 = *s2 != '\0' ? strlen (s2) : 0;
@ -314,7 +314,7 @@ fatal (flocp, fmt, va_alist)
#undef strerror
char *
const char *
strerror (errnum)
int errnum;
{
@ -336,7 +336,7 @@ strerror (errnum)
void
perror_with_name (str, name)
char *str, *name;
const char *str, *name;
{
error (NILF, "%s%s: %s", str, name, strerror (errno));
}
@ -345,7 +345,7 @@ perror_with_name (str, name)
void
pfatal_with_name (name)
char *name;
const char *name;
{
fatal (NILF, "%s: %s", name, strerror (errno));

View file

@ -1,3 +1,8 @@
2002-04-28 Paul D. Smith <psmith@gnu.org>
* scripts/functions/call: New test: transitive closure
implementation using $(call ...) to test variable recursion.
2002-04-21 Paul D. Smith <psmith@gnu.org>
* test_driver.pl (compare_dir_tree): Ignore CVS and RCS

View file

@ -31,6 +31,15 @@ my-if = $(if $(1),$(2),$(3))
one = $(1) $(2) $(3)
two = $(call one,$(1),foo,$(2))
# Test recursion on the user-defined function. As a special case make
# won't error due to this.
# Implement transitive closure using $(call ...)
#
DEP_foo = bar baz quux
DEP_baz = quux blarp
rest = $(wordlist 2,$(words ${1}),${1})
tclose = $(if $1,$(firstword $1) \
$(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1))))
all: ; @echo '$(call reverse,bar,foo)'; \
echo '$(call map,origin,MAKE reverse map)'; \
@ -38,7 +47,10 @@ all: ; @echo '$(call reverse,bar,foo)'; \
echo '$(call my-foreach)'; \
echo '$(call my-foreach,a,,,)'; \
echo '$(call my-if,a,b,c)'; \
echo '$(call two,bar,baz)'
echo '$(call two,bar,baz)'; \
echo '$(call tclose,foo)'
EOMAKE
@ -53,7 +65,7 @@ EOMAKE
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
$answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\n";
$answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n";
&compare_output($answer, &get_logfile(1));

View file

@ -120,6 +120,7 @@ define_variable_in_set (name, length, value, origin, recursive, set, flocp)
v->origin = origin;
v->recursive = recursive;
v->expanding = 0;
v->exp_count = 0;
v->per_target = 0;
v->append = 0;
v->export = v_default;
@ -711,7 +712,7 @@ target_environment (file)
if (v->recursive
&& v->origin != o_env && v->origin != o_env_override)
{
char *value = recursively_expand (v);
char *value = recursively_expand_for_file (v, file);
#ifdef WINDOWS32
if (strcmp(v->name, "Path") == 0 ||
strcmp(v->name, "PATH") == 0)

View file

@ -35,19 +35,28 @@ enum variable_origin
Each bucket of the hash table is a chain of these,
chained through `next'. */
#define EXP_COUNT_BITS 15 /* This gets all the bitfields into 32 bits */
#define EXP_COUNT_MAX ((1<<EXP_COUNT_BITS)-1)
struct variable
{
struct variable *next; /* Link in the chain. */
char *name; /* Variable name. */
char *value; /* Variable value. */
struct floc fileinfo; /* Where the variable was defined. */
enum variable_origin
origin ENUM_BITFIELD (3); /* Variable origin. */
unsigned int recursive:1; /* Gets recursively re-evaluated. */
unsigned int expanding:1; /* Nonzero if currently being expanded. */
unsigned int exp_count:EXP_COUNT_BITS;
/* If >1, allow this many self-referential
expansions */
unsigned int per_target:1; /* Nonzero if a target-specific variable. */
unsigned int append:1; /* Nonzero if an appending target-specific
variable. */
enum variable_origin
origin ENUM_BITFIELD (3); /* Variable origin. */
enum variable_export
{
v_export, /* Export this variable. */
@ -95,7 +104,9 @@ extern char *patsubst_expand PARAMS ((char *o, char *text, char *pattern, char *
char *pattern_percent, char *replace_percent));
/* expand.c */
extern char *recursively_expand PARAMS ((struct variable *v));
extern char *recursively_expand_for_file PARAMS ((struct variable *v,
struct file *file));
#define recursively_expand(v) recursively_expand_for_file (v, NULL)
/* variable.c */
extern struct variable_set_list *create_new_variable_set PARAMS ((void));
@ -135,6 +146,15 @@ extern struct variable *define_variable_in_set
#define define_variable_for_file(n,l,v,o,r,f) \
define_variable_in_set((n),(l),(v),(o),(r),(f)->variables->set,NILF)
/* Warn that NAME is an undefined variable. */
#define warn_undefined(n,l) do{\
if (warn_undefined_variables_flag) \
error (reading_file, \
_("warning: undefined variable `%.*s'"), \
(int)(l), (n)); \
}while(0)
extern char **target_environment PARAMS ((struct file *file));
extern int export_all_variables;