mirror of
https://github.com/mirror/make.git
synced 2025-01-27 04:40:33 +08:00
- Fix bug #1405: allow multiple pattern-specific variables to match a target.
- Fix some uncleanliness about the implementation of patterns-specific vars. - Some enhancements to the OS/2 port.
This commit is contained in:
parent
652234e967
commit
1a5beef51f
57
ChangeLog
57
ChangeLog
@ -1,3 +1,60 @@
|
||||
2003-04-30 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* build.template: Make some changes to maybe allow this script to
|
||||
work on DOS/Windows/OS2 systems. Suggested by Andreas Buening.
|
||||
|
||||
* README.OS2.template: New file for OS/2 support. Original
|
||||
contributed by Andreas Buening.
|
||||
* configure.in: Invoke new pds_AC_DOS_PATHS macro to test for
|
||||
DOS-style paths.
|
||||
|
||||
2003-04-19 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Fix bug #1405: allow a target to match multiple pattern-specific
|
||||
variables.
|
||||
|
||||
* rule.c (create_pattern_var, lookup_pattern_var): Move these to
|
||||
variable.c, where they've always belonged.
|
||||
* rule.h: Move the prototypes and struct pattern_var as well.
|
||||
* variable.c (initialize_file_variables): Invoke
|
||||
lookup_pattern_var() in a loop, until no more matches are found.
|
||||
If a match is found, create a new variable set for the target's
|
||||
pattern variables. Then merge the contents of each matching
|
||||
pattern variable set into the target's pattern variable set.
|
||||
(lookup_pattern_var): Change this function to be usable
|
||||
in a loop. It takes a starting position: if NULL, start at the
|
||||
beginning; if non-NULL, start with the pattern variable after that
|
||||
position, and return the next matching pattern.
|
||||
(create_pattern_var): Create a unique instance of
|
||||
pattern-specific variables for every definition in the makefile.
|
||||
Don't combine the same pattern together. This allows us to
|
||||
process the variable handling properly even when the same pattern
|
||||
is used multiple times.
|
||||
(parse_variable_definition): New function: break out the parsing
|
||||
of a variable definition line from try_variable_definition.
|
||||
(try_variable_definition): Call parse_variable_definition to
|
||||
parse.
|
||||
(print_variable_data_base): Print out pattern-specific variables.
|
||||
* variable.h (struct variable): Remember when a variable is
|
||||
conditional. Also remember its flavor.
|
||||
(struct pattern_var): Instead of keeping a variable set, we just
|
||||
keep a single variable for each pattern.
|
||||
* read.c (record_target_var): Each pattern variable contains only a
|
||||
single variable, not a set, so create it properly.
|
||||
* doc/make.texi (Pattern-specific): Document the new behavior.
|
||||
|
||||
2003-04-17 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* dir.c (file_exists_p) [VMS]: Patch provided with Bug #3018 by
|
||||
Jean-Pierre Portier <portierjp2@free.fr>. I don't understand the
|
||||
file/directory naming rules for VMS so I can't tell whether this
|
||||
is correct or not.
|
||||
|
||||
2003-04-09 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* configure.in (HAVE_DOS_PATHS): Define this on systems that need
|
||||
DOS-style pathnames: backslash separators and drive specifiers.
|
||||
|
||||
2003-03-28 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* file.c (snap_deps): If .SECONDARY with no targets is given, set
|
||||
|
10
Makefile.am
10
Makefile.am
@ -38,12 +38,12 @@ AM_CPPFLAGS = $(GLOBINC)
|
||||
# because often that directory isn't built on the systems used by the
|
||||
# maintainers.
|
||||
|
||||
EXTRA_DIST = README build.sh.in $(man_MANS)\
|
||||
README.customs\
|
||||
SCOPTIONS SMakefile\
|
||||
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h\
|
||||
EXTRA_DIST = README build.sh.in $(man_MANS) \
|
||||
README.customs README.OS2 \
|
||||
SCOPTIONS SMakefile \
|
||||
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
|
||||
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
|
||||
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat\
|
||||
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
|
||||
readme.vms makefile.vms makefile.com config.h-vms \
|
||||
vmsdir.h vmsfunctions.c vmsify.c
|
||||
|
||||
|
21
NEWS
21
NEWS
@ -1,8 +1,8 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
03 October 2002
|
||||
17 April 2003
|
||||
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002,2003 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
All changes mentioned here are more fully described in the GNU make
|
||||
@ -12,7 +12,22 @@ Please send GNU make bug reports to <bug-make@gnu.org>.
|
||||
See the README file and the GNU make manual for details on sending bug
|
||||
reports.
|
||||
|
||||
Version 3.81a1
|
||||
Version 3.81a2
|
||||
|
||||
* GNU make is ported to OS/2.
|
||||
Port provided by Andreas Buening <andreas.buening@nexgo.de>.
|
||||
|
||||
* All pattern-specific variables that match a given target are now used
|
||||
(previously only the first match was used).
|
||||
|
||||
* Target-specific variables can be marked as exportable using the
|
||||
"export" keyword.
|
||||
|
||||
* In a recursive $(call ...) context, any extra arguments from the outer
|
||||
call are now masked in the context of the inner call.
|
||||
|
||||
* Enhancements for POSIX compatibility:
|
||||
- Only touch targets (under -t) if they have at least one command.
|
||||
|
||||
|
||||
Version 3.80
|
||||
|
159
README.OS2.template
Normal file
159
README.OS2.template
Normal file
@ -0,0 +1,159 @@
|
||||
Port of GNU make to OS/2.
|
||||
|
||||
Features of GNU make that do not work under OS/2:
|
||||
- remote job execution
|
||||
- dynamic load balancing
|
||||
|
||||
|
||||
Special features of the OS/2 version:
|
||||
|
||||
Due to the fact that some people might want to use sh syntax in
|
||||
Makefiles while others might want to use OS/2's native shell cmd.exe,
|
||||
GNU make supports both shell types. The following list defines the order
|
||||
that is used to determine the shell:
|
||||
|
||||
1. The shell specified by the environment variable MAKESHELL.
|
||||
2. The shell specified by the SHELL variable within a Makefile. As on
|
||||
Unix, SHELL is NOT taken from the environment.
|
||||
3. The shell specified by the COMSPEC environment variable.
|
||||
4. The shell specified by the OS2_SHELL environment variable.
|
||||
5. If none of the above is defined /bin/sh is used as default. This
|
||||
happens e.g. in the make testsuite.
|
||||
|
||||
Note: - Points 3 and 4 can be turned off at compile time by adding
|
||||
-DNO_CMD_DEFAULT to the CPPFLAGS.
|
||||
- DOS support is not tested for EMX and therefore might not work.
|
||||
- The UNIXROOT environment variable is supported to find /bin/sh
|
||||
if it is not on the current drive.
|
||||
|
||||
|
||||
COMPILATION OF GNU MAKE FOR OS/2:
|
||||
|
||||
I. ***** SPECIAL OPTIONS *****
|
||||
|
||||
- At compile time you can turn off that cmd is used as default shell
|
||||
(but only /bin/sh). Simply set CPPFLAGS="-DNO_CMD_DEFAULT" and make
|
||||
will not use cmd unless you cause it to do so by setting MAKESHELL to
|
||||
cmd or by specifying SHELL=cmd in your Makefile.
|
||||
|
||||
- At compile time you can set CPPFLAGS="-DNO_CHDIR2" to turn off that
|
||||
GNU make prints drive letters. This is necessary if you want to run
|
||||
the testsuite.
|
||||
|
||||
|
||||
II. ***** REQUIREMENTS FOR THE COMPILATION *****
|
||||
|
||||
A standard Unix like build environment:
|
||||
|
||||
- sh compatible shell (ksh, bash, ash, but tested only with pdksh 5.2.14
|
||||
(release 2)
|
||||
If you use pdksh it is recommended to update to 5.2.14 release 2. Older
|
||||
versions may not work! You can get this version at
|
||||
http://www.math.ohio-state.edu/~ilya/software/os2/pdksh-5.2.14-bin-2.zip
|
||||
- GNU file utilities (make sure that install.exe from the file utilities
|
||||
is in front of your PATH before X:\OS2\INSTALL\INSTALL.EXE. I recommend
|
||||
also to change the filename to ginstall.exe instead of install.exe
|
||||
to avoid confusion with X:\OS2\INSTALL\INSTALL.EXE)
|
||||
- GNU shell utilities
|
||||
- GNU text utilities
|
||||
- gawk
|
||||
- grep
|
||||
- sed
|
||||
- GNU make 3.79.1 (special OS/2 patched version)
|
||||
- perl 5.005 or higher
|
||||
- GNU texinfo (you can use 3.1 (gnuinfo.zip), but I recommend 4.0)
|
||||
|
||||
If you want to recreate the configuration files (developers only!)
|
||||
you need also: GNU m4 1.4, autoconf 2.57, automake 1.7.2 (or compatible)
|
||||
|
||||
|
||||
III. ***** COMPILATION AND INSTALLATION *****
|
||||
|
||||
a) ** Developers only - Everyone else should skip this section **
|
||||
To recreate the configuration files use:
|
||||
|
||||
export EMXSHELL=ksh
|
||||
aclocal -I config
|
||||
automake
|
||||
autoconf
|
||||
autoheader
|
||||
|
||||
|
||||
b) Installation into x:/usr
|
||||
|
||||
Note: Although it is possible to compile make using "./configure",
|
||||
"make", "make install" this is not recommended. In particular,
|
||||
you must ALWAYS use LDFLAGS="-Zstack 0x8000" because the default
|
||||
stack size is far to small and make will not work properly!
|
||||
|
||||
Recommended environment variables and installation options:
|
||||
|
||||
export ac_executable_extensions=".exe"
|
||||
export CPPFLAGS="-D__ST_MT_ERRNO__"
|
||||
export CFLAGS="-O2 -Zomf -Zmt"
|
||||
export LDFLAGS="-Zcrtdll -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x8000"
|
||||
export RANLIB="echo"
|
||||
./configure --prefix=x:/usr --infodir=x:/usr/share/info --mandir=x:/usr/share/man --without-included-gettext
|
||||
make AR=emxomfar
|
||||
make install
|
||||
|
||||
Note: If you use gcc 2.9.x or higher I recommend to set also LIBS="-lgcc"
|
||||
|
||||
Note: You can add -DNO_CMD_DEFAULT and -DNO_CHDIR2 to CPPFLAGS.
|
||||
See section I. for details.
|
||||
|
||||
|
||||
IV. ***** NLS support *****
|
||||
|
||||
GNU make has NLS (National Language Support), with the following
|
||||
caveats:
|
||||
|
||||
a) It will only work with GNU gettext, and
|
||||
b) GNU gettext support is not included in the GNU make package.
|
||||
|
||||
Therefore, if you wish to enable the internationalization features of
|
||||
GNU make you must install GNU gettext on your system before configuring
|
||||
GNU make.
|
||||
|
||||
You can choose the languages to be installed. To install support for
|
||||
English, German and French only enter:
|
||||
|
||||
export LINGUAS="en de fr"
|
||||
|
||||
If you don't specify LINGUAS all languages are installed.
|
||||
|
||||
If you don't want NLS support (English only) use the option
|
||||
--disable-nls for the configure script. Note if GNU gettext is not
|
||||
installed then NLS will not be enabled regardless of this flag.
|
||||
|
||||
|
||||
V. ***** Running the make test suite *****
|
||||
|
||||
To run the included make test suite you have to set
|
||||
|
||||
CPPFLAGS="-D__ST_MT_ERRNO__ -DNO_CMD_DEFAULT -DNO_CHDIR2"
|
||||
|
||||
before you compile make. This is due to some restrictions of the
|
||||
testsuite itself. -DNO_CMD_DEFAULT causes make to use /bin/sh as default
|
||||
shell in every case. Normally you could simply set MAKESHELL="/bin/sh"
|
||||
to do this but the testsuite ignores the environment. -DNO_CHDIR2 causes
|
||||
make not to use drive letters for directory names (i.e. _chdir2() and
|
||||
_getcwd2() are NOT used). The testsuite interpretes the whole output of
|
||||
make, especially statements like make[1]: Entering directory
|
||||
`C:/somewhere/make-3.79.1/tests' where the testsuite does not expect the
|
||||
drive letter. This would be interpreted as an error even if there is
|
||||
none.
|
||||
|
||||
To run the testsuite do the following:
|
||||
|
||||
export CPPFLAGS="-D__ST_MT_ERRNO__ -DNO_CMD_DEFAULT -DNO_CHDIR2"
|
||||
export CFLAGS="-Zomf -O2 -s -Zmt"
|
||||
export LDFLAGS="-Zcrtdll -Zmt -s -Zlinker /exepack:2 -Zlinker /pm:vio -Zstack 0x8000"
|
||||
export RANLIB="echo"
|
||||
./configure --prefix=x:/usr --disable-nls
|
||||
make AR=emxomfar
|
||||
make checks
|
||||
|
||||
All tests should work fine with the exception of "default_names" which
|
||||
is because OS/2 file systems are not case sensitive ("makefile" and
|
||||
"Makefile" specify the same file).
|
@ -48,6 +48,9 @@ to the point where you can run "make".
|
||||
Use wget to retrieve various other files that GNU make relies on,
|
||||
but does not keep in its own source tree.
|
||||
|
||||
NB: You may need GNU make to correctly perform this step; if you use
|
||||
a platform-local make you may get problems with missing files in doc/.
|
||||
|
||||
|
||||
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
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Shell script to build GNU Make in the absence of any `make' program.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1993, 1994, 1997, 2003 Free Software Foundation, Inc.
|
||||
# This file is part of GNU Make.
|
||||
#
|
||||
# GNU Make is free software; you can redistribute it and/or modify
|
||||
@ -29,9 +29,12 @@ CPPFLAGS='@CPPFLAGS@'
|
||||
LDFLAGS='@LDFLAGS@'
|
||||
ALLOCA='@ALLOCA@'
|
||||
LOADLIBES='@LIBS@'
|
||||
extras='@LIBOBJS@'
|
||||
eval extras=\'@LIBOBJS@\'
|
||||
REMOTE='@REMOTE@'
|
||||
GLOBLIB='@GLOBLIB@'
|
||||
PATH_SEPARATOR='@PATH_SEPARATOR@'
|
||||
OBJEXT='@OBJEXT@'
|
||||
EXEEXT='@EXEEXT@'
|
||||
|
||||
# Common prefix for machine-independent installed files.
|
||||
prefix='@prefix@'
|
||||
@ -43,7 +46,7 @@ libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
localedir=${prefix}/share/locale
|
||||
aliaspath=${localedir}:.
|
||||
aliaspath=${localedir}${PATH_SEPARATOR}.
|
||||
|
||||
defines="-DALIASPATH=\"${aliaspath}\" -DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@'
|
||||
|
||||
@ -51,7 +54,7 @@ defines="-DALIASPATH=\"${aliaspath}\" -DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${
|
||||
set -e
|
||||
|
||||
# These are all the objects we need to link together.
|
||||
objs="%objs% remote-${REMOTE}.o ${extras} ${ALLOCA}"
|
||||
objs="%objs% remote-${REMOTE}.${OBJEXT} ${extras} ${ALLOCA}"
|
||||
|
||||
if [ x"$GLOBLIB" != x ]; then
|
||||
objs="$objs %globobjs%"
|
||||
@ -59,7 +62,7 @@ if [ x"$GLOBLIB" != x ]; then
|
||||
fi
|
||||
|
||||
# Compile the source files into those objects.
|
||||
for file in `echo ${objs} | sed 's/\.o/.c/g'`; do
|
||||
for file in `echo ${objs} | sed 's/\.'${OBJEXT}'/.c/g'`; do
|
||||
echo compiling ${file}...
|
||||
$CC $defines $CPPFLAGS $CFLAGS \
|
||||
-c -I. -I${srcdir} ${globinc} ${srcdir}/$file
|
||||
@ -75,6 +78,6 @@ done
|
||||
|
||||
# Link all the objects together.
|
||||
echo linking make...
|
||||
$CC $LDFLAGS $objs $LOADLIBES -o make.new
|
||||
$CC $LDFLAGS $objs $LOADLIBES -o makenew${EXEEXT}
|
||||
echo done
|
||||
mv -f make.new make
|
||||
mv -f makenew${EXEEXT} make${EXEEXT}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-04-30 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* dospaths.m4: New macro to test for DOS-style pathnames, based on
|
||||
coreutils 5.0 "dos.m4" by Jim Meyering.
|
||||
|
||||
2002-04-21 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* codeset.m4: New file, from gettext-0.11.1.
|
||||
|
21
config/dospaths.m4
Normal file
21
config/dospaths.m4
Normal file
@ -0,0 +1,21 @@
|
||||
# Test if the system uses DOS-style pathnames (drive specs and backslashes)
|
||||
# By Paul Smith <psmith@gnu.org>. Based on dos.m4 by Jim Meyering.
|
||||
|
||||
AC_DEFUN([pds_AC_DOS_PATHS],
|
||||
[
|
||||
AC_CACHE_CHECK([whether system uses MSDOS-style paths], [ac_cv_dos_paths],
|
||||
[
|
||||
AC_COMPILE_IFELSE([
|
||||
#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __EMX__
|
||||
neither MSDOS nor Windows nor OS2
|
||||
#endif
|
||||
],
|
||||
[ac_cv_dos_paths=yes],
|
||||
[ac_cv_dos_paths=no])
|
||||
])
|
||||
|
||||
if test x"$ac_cv_dos_paths" = xyes; then
|
||||
AC_DEFINE_UNQUOTED([HAVE_DOS_PATHS], 1,
|
||||
[Define if the system uses DOS-style pathnames.])
|
||||
fi
|
||||
])
|
@ -103,6 +103,8 @@ if test "$make_cv_file_timestamp_hi_res" = yes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for DOS-style pathnames.
|
||||
pds_AC_DOS_PATHS
|
||||
|
||||
# See if we have a standard version of gettimeofday(). Since actual
|
||||
# implementations can differ, just make sure we have the most common
|
||||
@ -192,6 +194,13 @@ fi
|
||||
AC_MSG_RESULT($make_cv_union_wait)
|
||||
|
||||
|
||||
# If we're building on Windows/DOS/OS/2, add some support for DOS drive specs.
|
||||
if test "$PATH_SEPARATOR" = ';'; then
|
||||
AC_DEFINE(HAVE_DOS_PATHS, 1,
|
||||
[Define this if your system requires backslashes or drive specs in pathnames.])
|
||||
fi
|
||||
|
||||
|
||||
# See if the user wants to use pmake's "customs" distributed build capability
|
||||
|
||||
AC_SUBST(REMOTE) REMOTE=stub
|
||||
|
@ -18,12 +18,12 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "filedef.h"
|
||||
#include "variable.h"
|
||||
#include "rule.h"
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#include "variable.h"
|
||||
|
||||
/* Define GCC_IS_NATIVE if gcc is the native development environment on
|
||||
your system (gcc/bison/flex vs cc/yacc/lex). */
|
||||
|
6
dir.c
6
dir.c
@ -590,7 +590,8 @@ dir_contents_file_exists_p (struct directory_contents *dir, char *filename)
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
_fnlwr(filename); /* lower case for FAT drives */
|
||||
if (filename != 0)
|
||||
_fnlwr (filename); /* lower case for FAT drives */
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
@ -736,8 +737,7 @@ file_exists_p (char *name)
|
||||
dirend = strrchr (name, ']');
|
||||
if (dirend == 0)
|
||||
dirend = strrchr (name, ':');
|
||||
dirend++;
|
||||
if (dirend == (char *)1)
|
||||
if (dirend == (char *)0)
|
||||
return dir_file_exists_p ("[]", name);
|
||||
#else /* !VMS */
|
||||
dirend = strrchr (name, '/');
|
||||
|
@ -5245,13 +5245,16 @@ command scripts that create @file{prog.o}, @file{foo.o}, and
|
||||
@cindex pattern-specific variables
|
||||
@cindex variables, pattern-specific
|
||||
|
||||
In addition to target-specific variable values (@pxref{Target-specific,
|
||||
,Target-specific Variable Values}), GNU @code{make} supports
|
||||
pattern-specific variable values. In this form, a variable is defined
|
||||
for any target that matches the pattern specified. Variables defined in
|
||||
this way are searched after any target-specific variables defined
|
||||
explicitly for that target, and before target-specific variables defined
|
||||
for the parent target.
|
||||
In addition to target-specific variable values
|
||||
(@pxref{Target-specific, ,Target-specific Variable Values}), GNU
|
||||
@code{make} supports pattern-specific variable values. In this form,
|
||||
the variable is defined for any target that matches the pattern
|
||||
specified. If a target matches more than one pattern, all the
|
||||
matching pattern-specific variables are interpreted in the order in
|
||||
which they were defined in the makefile, and collected together into
|
||||
one set. Variables defined in this way are searched after any
|
||||
target-specific variables defined explicitly for that target, and
|
||||
before target-specific variables defined for the parent target.
|
||||
|
||||
Set a pattern-specific variable value like this:
|
||||
|
||||
|
@ -681,9 +681,9 @@ func_words (char *o, char **argv, const char *funcname)
|
||||
static char *
|
||||
strip_whitespace (const char **begpp, const char **endpp)
|
||||
{
|
||||
while (isspace ((unsigned char)**begpp) && *begpp <= *endpp)
|
||||
while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
|
||||
(*begpp) ++;
|
||||
while (isspace ((unsigned char)**endpp) && *endpp >= *begpp)
|
||||
while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
|
||||
(*endpp) --;
|
||||
return (char *)*begpp;
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "make.h"
|
||||
#include "filedef.h"
|
||||
#include "rule.h"
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int pattern_search PARAMS ((struct file *file, int archive, unsigned int depth,
|
||||
|
13
job.c
13
job.c
@ -104,7 +104,7 @@ static int amiga_batch_file;
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#ifdef __EMX__
|
||||
# include <sys/file.h>
|
||||
# include <process.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT)
|
||||
@ -2507,9 +2507,9 @@ exec_command (char **argv, char **envp)
|
||||
|
||||
# ifdef __EMX__
|
||||
/* Do not use $SHELL from the environment */
|
||||
shell = lookup_variable ("SHELL", 5);
|
||||
if (shell)
|
||||
shell = shell->value;
|
||||
struct variable *p = lookup_variable ("SHELL", 5);
|
||||
if (p)
|
||||
shell = p->value;
|
||||
else
|
||||
shell = 0;
|
||||
# else
|
||||
@ -2756,11 +2756,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
DB (DB_BASIC, (_("$SHELL changed (was `%s', now `%s')\n"),
|
||||
default_shell, shell));
|
||||
unixy_shell = _is_unixy_shell (shell);
|
||||
default_shell = shell;
|
||||
/* we must allocate a copy of shell: construct_command_argv() will free
|
||||
* shell after this function returns. */
|
||||
default_shell = xmalloc (strlen (shell) + 1);
|
||||
strcpy (default_shell, shell);
|
||||
default_shell = xstrdup (shell);
|
||||
}
|
||||
if (unixy_shell)
|
||||
{
|
||||
@ -2778,6 +2776,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
sh_cmds = sh_cmds_os2;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#else /* !__MSDOS__ */
|
||||
else if (strcmp (shell, default_shell))
|
||||
goto slow;
|
||||
|
@ -8,7 +8,7 @@
|
||||
globsrc := $(wildcard glob/*.c)
|
||||
globhdr := $(wildcard glob/*.h)
|
||||
|
||||
TEMPLATES = README README.DOS README.W32 \
|
||||
TEMPLATES = README README.DOS README.W32 README.OS2 \
|
||||
config.ami configh.dos config.h.W32 config.h-vms
|
||||
MTEMPLATES = Makefile.DOS SMakefile
|
||||
|
||||
@ -54,8 +54,8 @@ NMakefile: NMakefile.template .dep_segment Makefile
|
||||
#
|
||||
build.sh.in: build.template Makefile
|
||||
rm -f $@
|
||||
sed -e 's@%objs%@$(filter-out remote-%,$(make_OBJECTS)@g' \
|
||||
-e 's@%globobjs%@$(patsubst %.c,%.o,$(globsrc)))@g' \
|
||||
sed -e 's@%objs%@$(patsubst %.o,%.$${OBJEXT},$(filter-out remote-%,$(make_OBJECTS)))@g' \
|
||||
-e 's@%globobjs%@$(patsubst %.c,%.$${OBJEXT},$(globsrc)))@g' \
|
||||
$< > $@
|
||||
chmod a-w+x $@
|
||||
|
||||
|
36
read.c
36
read.c
@ -1667,9 +1667,9 @@ record_target_var (struct nameseq *filenames, char *defn, int two_colon,
|
||||
{
|
||||
struct variable *v;
|
||||
register char *name = filenames->name;
|
||||
struct variable_set_list *vlist;
|
||||
char *fname;
|
||||
char *percent;
|
||||
struct pattern_var *p;
|
||||
|
||||
nextf = filenames->next;
|
||||
free ((char *) filenames);
|
||||
@ -1679,11 +1679,13 @@ record_target_var (struct nameseq *filenames, char *defn, int two_colon,
|
||||
percent = find_percent (name);
|
||||
if (percent)
|
||||
{
|
||||
struct pattern_var *p;
|
||||
|
||||
/* Get a reference for this pattern-specific variable struct. */
|
||||
p = create_pattern_var(name, percent);
|
||||
vlist = p->vars;
|
||||
p = create_pattern_var (name, percent);
|
||||
p->variable.fileinfo = *flocp;
|
||||
v = parse_variable_definition (&p->variable, defn);
|
||||
v->value = xstrdup (v->value);
|
||||
if (!v)
|
||||
error (flocp, _("Malformed pattern-specific variable definition"));
|
||||
fname = p->target;
|
||||
}
|
||||
else
|
||||
@ -1701,15 +1703,17 @@ record_target_var (struct nameseq *filenames, char *defn, int two_colon,
|
||||
f = f->double_colon;
|
||||
|
||||
initialize_file_variables (f, 1);
|
||||
vlist = f->variables;
|
||||
fname = f->name;
|
||||
|
||||
current_variable_set_list = f->variables;
|
||||
v = try_variable_definition (flocp, defn, origin, 1);
|
||||
if (!v)
|
||||
error (flocp, _("Malformed target-specific variable definition"));
|
||||
current_variable_set_list = global;
|
||||
}
|
||||
|
||||
/* Make the new variable context current and define the variable. */
|
||||
current_variable_set_list = vlist;
|
||||
v = try_variable_definition (flocp, defn, origin, 1);
|
||||
if (!v)
|
||||
error (flocp, _("Malformed per-target variable definition"));
|
||||
/* Set up the variable to be *-specific. */
|
||||
v->origin = origin;
|
||||
v->per_target = 1;
|
||||
if (exported)
|
||||
v->export = v_export;
|
||||
@ -1721,12 +1725,14 @@ record_target_var (struct nameseq *filenames, char *defn, int two_colon,
|
||||
struct variable *gv;
|
||||
int len = strlen(v->name);
|
||||
|
||||
current_variable_set_list = global;
|
||||
gv = lookup_variable (v->name, len);
|
||||
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
|
||||
{
|
||||
v = define_variable_in_set (v->name, len, gv->value, gv->origin,
|
||||
gv->recursive, vlist->set, flocp);
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = xstrdup (gv->value);
|
||||
v->origin = gv->origin;
|
||||
v->recursive = gv->recursive;
|
||||
v->append = 0;
|
||||
}
|
||||
}
|
||||
@ -1735,8 +1741,6 @@ record_target_var (struct nameseq *filenames, char *defn, int two_colon,
|
||||
if (name != fname && (name < fname || name > fname + strlen (fname)))
|
||||
free (name);
|
||||
}
|
||||
|
||||
current_variable_set_list = global;
|
||||
}
|
||||
|
||||
/* Record a description line for files FILENAMES,
|
||||
|
100
rule.c
100
rule.c
@ -51,14 +51,6 @@ unsigned int max_pattern_deps;
|
||||
|
||||
unsigned int max_pattern_dep_length;
|
||||
|
||||
/* Chain of all pattern-specific variables. */
|
||||
|
||||
static struct pattern_var *pattern_vars;
|
||||
|
||||
/* Pointer to last struct in the chain, so we can add onto the end. */
|
||||
|
||||
static struct pattern_var *last_pattern_var;
|
||||
|
||||
/* Pointer to structure for the file .SUFFIXES
|
||||
whose dependencies are the suffixes to be searched. */
|
||||
|
||||
@ -537,76 +529,6 @@ create_pattern_rule (char **targets, char **target_percents,
|
||||
r->terminal = terminal;
|
||||
}
|
||||
|
||||
/* Create a new pattern-specific variable struct. */
|
||||
|
||||
struct pattern_var *
|
||||
create_pattern_var (char *target, char *suffix)
|
||||
{
|
||||
register struct pattern_var *p = 0;
|
||||
unsigned int len = strlen(target);
|
||||
|
||||
/* Look to see if this pattern already exists in the list. */
|
||||
for (p = pattern_vars; p != NULL; p = p->next)
|
||||
if (p->len == len && !strcmp(p->target, target))
|
||||
break;
|
||||
|
||||
if (p == 0)
|
||||
{
|
||||
p = (struct pattern_var *) xmalloc (sizeof (struct pattern_var));
|
||||
if (last_pattern_var != 0)
|
||||
last_pattern_var->next = p;
|
||||
else
|
||||
pattern_vars = p;
|
||||
last_pattern_var = p;
|
||||
p->next = 0;
|
||||
p->target = target;
|
||||
p->len = len;
|
||||
p->suffix = suffix + 1;
|
||||
p->vars = create_new_variable_set();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Look up a target in the pattern-specific variable list. */
|
||||
|
||||
struct pattern_var *
|
||||
lookup_pattern_var (char *target)
|
||||
{
|
||||
struct pattern_var *p;
|
||||
unsigned int targlen = strlen(target);
|
||||
|
||||
for (p = pattern_vars; p != 0; p = p->next)
|
||||
{
|
||||
char *stem;
|
||||
unsigned int stemlen;
|
||||
|
||||
if (p->len > targlen)
|
||||
/* It can't possibly match. */
|
||||
continue;
|
||||
|
||||
/* From the lengths of the filename and the pattern parts,
|
||||
find the stem: the part of the filename that matches the %. */
|
||||
stem = target + (p->suffix - p->target - 1);
|
||||
stemlen = targlen - p->len + 1;
|
||||
|
||||
/* Compare the text in the pattern before the stem, if any. */
|
||||
if (stem > target && !strneq (p->target, target, stem - target))
|
||||
continue;
|
||||
|
||||
/* Compare the text in the pattern after the stem, if any.
|
||||
We could test simply using streq, but this way we compare the
|
||||
first two characters immediately. This saves time in the very
|
||||
common case where the first character matches because it is a
|
||||
period. */
|
||||
if (*p->suffix == stem[stemlen]
|
||||
&& (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1])))
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print the data base of rules. */
|
||||
|
||||
static void /* Useful to call from gdb. */
|
||||
@ -678,26 +600,4 @@ print_rule_data_base (void)
|
||||
fatal (NILF, _("BUG: num_pattern_rules wrong! %u != %u"),
|
||||
num_pattern_rules, rules);
|
||||
}
|
||||
|
||||
puts (_("\n# Pattern-specific variable values"));
|
||||
|
||||
{
|
||||
struct pattern_var *p;
|
||||
|
||||
rules = 0;
|
||||
for (p = pattern_vars; p != 0; p = p->next)
|
||||
{
|
||||
++rules;
|
||||
|
||||
printf ("\n%s :\n", p->target);
|
||||
print_variable_set (p->vars->set, "# ");
|
||||
}
|
||||
|
||||
if (rules == 0)
|
||||
puts (_("\n# No pattern-specific variable values."));
|
||||
else
|
||||
{
|
||||
printf (_("\n# %u pattern-specific variable values"), rules);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
rule.h
11
rule.h
@ -31,15 +31,6 @@ struct rule
|
||||
char in_use; /* If in use by a parent pattern_search. */
|
||||
};
|
||||
|
||||
struct pattern_var
|
||||
{
|
||||
struct pattern_var *next;
|
||||
char *target;
|
||||
unsigned int len;
|
||||
char *suffix;
|
||||
struct variable_set_list *vars;
|
||||
};
|
||||
|
||||
/* For calling install_pattern_rule. */
|
||||
struct pspec
|
||||
{
|
||||
@ -61,8 +52,6 @@ extern unsigned int maxsuffix;
|
||||
|
||||
extern void install_pattern_rule PARAMS ((struct pspec *p, int terminal));
|
||||
extern int new_pattern_rule PARAMS ((struct rule *rule, int override));
|
||||
extern struct pattern_var *create_pattern_var PARAMS ((char *target, char *suffix));
|
||||
extern struct pattern_var *lookup_pattern_var PARAMS ((char *target));
|
||||
extern void count_implicit_rule_limits PARAMS ((void));
|
||||
extern void convert_to_pattern PARAMS ((void));
|
||||
extern void create_pattern_rule PARAMS ((char **targets,
|
||||
|
@ -1,3 +1,14 @@
|
||||
2003-04-19 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/patspecific_vars: Test multiple patterns
|
||||
matching the same target--Bug #1405.
|
||||
|
||||
2003-04-09 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* run_make_tests.pl (set_more_defaults): A new $port_type of
|
||||
'OS/2' for (surprise!) OS/2. Also choose a wait time of 2 seconds
|
||||
for OS/2.
|
||||
|
||||
2003-03-28 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/targets/SECONDARY: Test the "global" .SECONDARY (with
|
||||
|
@ -169,6 +169,10 @@ sub set_more_defaults
|
||||
elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) {
|
||||
$port_type = 'DOS';
|
||||
}
|
||||
# Check for OS/2
|
||||
elsif ($osname =~ m%OS/2%) {
|
||||
$port_type = 'OS/2';
|
||||
}
|
||||
# Everything else, right now, is UNIX. Note that we should integrate
|
||||
# the VOS support into this as well and get rid of $vos; we'll do
|
||||
# that next time.
|
||||
@ -180,7 +184,7 @@ sub set_more_defaults
|
||||
# timestamps with second granularity (!!). Change the sleep time
|
||||
# needed to force a file to be considered "old".
|
||||
#
|
||||
$wtime = $port_type eq 'UNIX' ? 1 : 4;
|
||||
$wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
|
||||
|
||||
# Find the full pathname of Make. For DOS systems this is more
|
||||
# complicated, so we ask make itself.
|
||||
|
@ -13,14 +13,22 @@ all: one.x two.x three.x
|
||||
FOO = foo
|
||||
BAR = bar
|
||||
BAZ = baz
|
||||
thr% : override BAZ = three
|
||||
t%.x: BAR = four
|
||||
%.x: BAR = two
|
||||
%.x: override BAZ = three
|
||||
one.x: override FOO = one
|
||||
one.x two.x three.x: ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
four.x: baz ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
baz: ; @echo $(FOO) $(BAR) $(BAZ)
|
||||
%.x: BAR = two
|
||||
t%.x: BAR = four
|
||||
thr% : override BAZ = three
|
||||
one.x two.x three.x: ; @echo $@: $(FOO) $(BAR) $(BAZ)
|
||||
four.x: baz ; @echo $@: $(FOO) $(BAR) $(BAZ)
|
||||
baz: ; @echo $@: $(FOO) $(BAR) $(BAZ)
|
||||
|
||||
# test matching multiple patterns
|
||||
a%: AAA = aaa
|
||||
%b: BBB = ccc
|
||||
a%: BBB += ddd
|
||||
%b: AAA ?= xxx
|
||||
%b: AAA += bbb
|
||||
.PHONY: ab
|
||||
ab: ; @echo $(AAA); echo $(BBB)
|
||||
EOF
|
||||
|
||||
close(MAKEFILE);
|
||||
@ -29,21 +37,28 @@ close(MAKEFILE);
|
||||
# TEST #1 -- basics
|
||||
|
||||
&run_make_with_options($makefile, "", &get_logfile);
|
||||
$answer = "one two three\nfoo four baz\nfoo bar three\n";
|
||||
$answer = "one.x: one two baz\ntwo.x: foo four baz\nthree.x: foo four three\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
|
||||
# TEST #2 -- try the override feature
|
||||
|
||||
&run_make_with_options($makefile, "BAZ=five", &get_logfile);
|
||||
$answer = "one two three\nfoo four five\nfoo bar three\n";
|
||||
$answer = "one.x: one two five\ntwo.x: foo four five\nthree.x: foo four three\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
|
||||
# TEST #3 -- make sure patterns are inherited properly
|
||||
|
||||
&run_make_with_options($makefile, "four.x", &get_logfile);
|
||||
$answer = "foo two three\nfoo two three\n";
|
||||
$answer = "baz: foo two baz\nfour.x: foo two baz\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
|
||||
# TEST #4 -- test multiple patterns matching the same target
|
||||
|
||||
&run_make_with_options($makefile, "ab", &get_logfile);
|
||||
$answer = "aaa bbb\nccc ddd\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
1;
|
||||
|
177
variable.c
177
variable.c
@ -30,6 +30,75 @@ Boston, MA 02111-1307, USA. */
|
||||
#endif
|
||||
#include "hash.h"
|
||||
|
||||
/* Chain of all pattern-specific variables. */
|
||||
|
||||
static struct pattern_var *pattern_vars;
|
||||
|
||||
/* Pointer to last struct in the chain, so we can add onto the end. */
|
||||
|
||||
static struct pattern_var *last_pattern_var;
|
||||
|
||||
/* Create a new pattern-specific variable struct. */
|
||||
|
||||
struct pattern_var *
|
||||
create_pattern_var (char *target, char *suffix)
|
||||
{
|
||||
register struct pattern_var *p
|
||||
= (struct pattern_var *) xmalloc (sizeof (struct pattern_var));
|
||||
|
||||
if (last_pattern_var != 0)
|
||||
last_pattern_var->next = p;
|
||||
else
|
||||
pattern_vars = p;
|
||||
last_pattern_var = p;
|
||||
p->next = 0;
|
||||
|
||||
p->target = target;
|
||||
p->len = strlen (target);
|
||||
p->suffix = suffix + 1;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Look up a target in the pattern-specific variable list. */
|
||||
|
||||
static struct pattern_var *
|
||||
lookup_pattern_var (struct pattern_var *start, char *target)
|
||||
{
|
||||
struct pattern_var *p;
|
||||
unsigned int targlen = strlen(target);
|
||||
|
||||
for (p = start ? start->next : pattern_vars; p != 0; p = p->next)
|
||||
{
|
||||
char *stem;
|
||||
unsigned int stemlen;
|
||||
|
||||
if (p->len > targlen)
|
||||
/* It can't possibly match. */
|
||||
continue;
|
||||
|
||||
/* From the lengths of the filename and the pattern parts,
|
||||
find the stem: the part of the filename that matches the %. */
|
||||
stem = target + (p->suffix - p->target - 1);
|
||||
stemlen = targlen - p->len + 1;
|
||||
|
||||
/* Compare the text in the pattern before the stem, if any. */
|
||||
if (stem > target && !strneq (p->target, target, stem - target))
|
||||
continue;
|
||||
|
||||
/* Compare the text in the pattern after the stem, if any.
|
||||
We could test simply using streq, but this way we compare the
|
||||
first two characters immediately. This saves time in the very
|
||||
common case where the first character matches because it is a
|
||||
period. */
|
||||
if (*p->suffix == stem[stemlen]
|
||||
&& (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1])))
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Hash table of all global variable definitions. */
|
||||
|
||||
static unsigned long
|
||||
@ -147,6 +216,7 @@ define_variable_in_set (const char *name, unsigned int length,
|
||||
v->fileinfo.filenm = 0;
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
v->special = 0;
|
||||
v->expanding = 0;
|
||||
v->exp_count = 0;
|
||||
v->per_target = 0;
|
||||
@ -405,21 +475,33 @@ initialize_file_variables (struct file *file, int reading)
|
||||
}
|
||||
|
||||
/* If we're not reading makefiles and we haven't looked yet, see if
|
||||
we can find a pattern variable. */
|
||||
we can find pattern variables for this target. */
|
||||
|
||||
if (!reading && !file->pat_searched)
|
||||
{
|
||||
struct pattern_var *p = lookup_pattern_var (file->name);
|
||||
struct pattern_var *p;
|
||||
|
||||
file->pat_searched = 1;
|
||||
p = lookup_pattern_var (0, file->name);
|
||||
if (p != 0)
|
||||
{
|
||||
/* If we found one, insert it between the current target's
|
||||
variables and the next set, whatever it is. */
|
||||
file->pat_variables = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
file->pat_variables->set = p->vars->set;
|
||||
struct variable_set_list *global = current_variable_set_list;
|
||||
|
||||
/* We found at least one. Set up a new variable set to accumulate
|
||||
all the pattern variables that match this target. */
|
||||
|
||||
file->pat_variables = create_new_variable_set ();
|
||||
current_variable_set_list = file->pat_variables;
|
||||
|
||||
do
|
||||
/* We found one, so insert it into the set. */
|
||||
do_variable_definition (&p->variable.fileinfo, p->variable.name,
|
||||
p->variable.value, p->variable.origin,
|
||||
p->variable.flavor, 1);
|
||||
while ((p = lookup_pattern_var (p, file->name)) != 0);
|
||||
|
||||
current_variable_set_list = global;
|
||||
}
|
||||
file->pat_searched = 1;
|
||||
}
|
||||
|
||||
/* If we have a pattern variable match, set it up. */
|
||||
@ -483,7 +565,7 @@ push_new_variable_scope (void)
|
||||
return (current_variable_set_list = create_new_variable_set());
|
||||
}
|
||||
|
||||
/* Merge SET1 into SET0, freeing unused storage in SET1. */
|
||||
/* Merge FROM_SET into TO_SET, freeing unused storage in FROM_SET. */
|
||||
|
||||
static void
|
||||
merge_variable_sets (struct variable_set *to_set,
|
||||
@ -834,6 +916,7 @@ do_variable_definition (const struct floc *flocp, const char *varname,
|
||||
char *p, *alloc_value = NULL;
|
||||
struct variable *v;
|
||||
int append = 0;
|
||||
int conditional = 0;
|
||||
|
||||
/* Calculate the variable's new value in VALUE. */
|
||||
|
||||
@ -857,6 +940,7 @@ do_variable_definition (const struct floc *flocp, const char *varname,
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
conditional = 1;
|
||||
flavor = f_recursive;
|
||||
/* FALLTHROUGH */
|
||||
case f_recursive:
|
||||
@ -1034,6 +1118,7 @@ do_variable_definition (const struct floc *flocp, const char *varname,
|
||||
? current_variable_set_list->set : NULL),
|
||||
flocp);
|
||||
v->append = append;
|
||||
v->conditional = conditional;
|
||||
|
||||
if (alloc_value)
|
||||
free (alloc_value);
|
||||
@ -1055,16 +1140,14 @@ do_variable_definition (const struct floc *flocp, const char *varname,
|
||||
returned. */
|
||||
|
||||
struct variable *
|
||||
try_variable_definition (const struct floc *flocp, char *line,
|
||||
enum variable_origin origin, int target_var)
|
||||
parse_variable_definition (struct variable *v, char *line)
|
||||
{
|
||||
register int c;
|
||||
register char *p = line;
|
||||
register char *beg;
|
||||
register char *end;
|
||||
enum variable_flavor flavor = f_bogus;
|
||||
char *name, *expanded_name;
|
||||
struct variable *v;
|
||||
char *name;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -1128,29 +1211,62 @@ try_variable_definition (const struct floc *flocp, char *line,
|
||||
}
|
||||
}
|
||||
}
|
||||
v->flavor = flavor;
|
||||
|
||||
beg = next_token (line);
|
||||
while (end > beg && isblank ((unsigned char)end[-1]))
|
||||
--end;
|
||||
p = next_token (p);
|
||||
v->value = p;
|
||||
|
||||
/* Expand the name, so "$(foo)bar = baz" works. */
|
||||
name = (char *) alloca (end - beg + 1);
|
||||
bcopy (beg, name, end - beg);
|
||||
name[end - beg] = '\0';
|
||||
expanded_name = allocated_variable_expand (name);
|
||||
v->name = allocated_variable_expand (name);
|
||||
|
||||
if (expanded_name[0] == '\0')
|
||||
fatal (flocp, _("empty variable name"));
|
||||
|
||||
v = do_variable_definition (flocp, expanded_name, p,
|
||||
origin, flavor, target_var);
|
||||
|
||||
free (expanded_name);
|
||||
if (v->name[0] == '\0')
|
||||
fatal (&v->fileinfo, _("empty variable name"));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Try to interpret LINE (a null-terminated string) as a variable definition.
|
||||
|
||||
ORIGIN may be o_file, o_override, o_env, o_env_override,
|
||||
or o_command specifying that the variable definition comes
|
||||
from a makefile, an override directive, the environment with
|
||||
or without the -e switch, or the command line.
|
||||
|
||||
See the comments for parse_variable_definition().
|
||||
|
||||
If LINE was recognized as a variable definition, a pointer to its `struct
|
||||
variable' is returned. If LINE is not a variable definition, NULL is
|
||||
returned. */
|
||||
|
||||
struct variable *
|
||||
try_variable_definition (const struct floc *flocp, char *line,
|
||||
enum variable_origin origin, int target_var)
|
||||
{
|
||||
struct variable v;
|
||||
struct variable *vp;
|
||||
|
||||
if (flocp != 0)
|
||||
v.fileinfo = *flocp;
|
||||
else
|
||||
v.fileinfo.filenm = 0;
|
||||
|
||||
if (!parse_variable_definition (&v, line))
|
||||
return 0;
|
||||
|
||||
vp = do_variable_definition (flocp, v.name, v.value,
|
||||
origin, v.flavor, target_var);
|
||||
|
||||
free (v.name);
|
||||
|
||||
return vp;
|
||||
}
|
||||
|
||||
/* Print information for variable V, prefixing it with PREFIX. */
|
||||
|
||||
static void
|
||||
@ -1246,6 +1362,25 @@ print_variable_data_base (void)
|
||||
puts (_("\n# Variables\n"));
|
||||
|
||||
print_variable_set (&global_variable_set, "");
|
||||
|
||||
puts (_("\n# Pattern-specific Variable Values"));
|
||||
|
||||
{
|
||||
struct pattern_var *p;
|
||||
int rules = 0;
|
||||
|
||||
for (p = pattern_vars; p != 0; p = p->next)
|
||||
{
|
||||
++rules;
|
||||
printf ("\n%s :\n", p->target);
|
||||
print_variable (&p->variable, "# ");
|
||||
}
|
||||
|
||||
if (rules == 0)
|
||||
puts (_("\n# No pattern-specific variable values."));
|
||||
else
|
||||
printf (_("\n# %u pattern-specific variable values"), rules);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
28
variable.h
28
variable.h
@ -47,7 +47,6 @@ enum variable_flavor
|
||||
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
|
||||
@ -57,20 +56,21 @@ struct variable
|
||||
char *value; /* Variable value. */
|
||||
struct floc fileinfo; /* Where the variable was defined. */
|
||||
unsigned int recursive:1; /* Gets recursively re-evaluated. */
|
||||
unsigned int per_target:1; /* Nonzero if a target-specific variable. */
|
||||
unsigned int append:1; /* Nonzero if an appending target-specific
|
||||
variable. */
|
||||
unsigned int conditional:1; /* Nonzero if set with a ?=. */
|
||||
unsigned int per_target:1; /* Nonzero if a target-specific variable. */
|
||||
unsigned int special:1; /* Nonzero if this is a special variable. */
|
||||
unsigned int exportable:1; /* Nonzero if the variable _could_ be
|
||||
exported. */
|
||||
unsigned int expanding:1; /* Nonzero if currently being expanded. */
|
||||
unsigned int exp_count:EXP_COUNT_BITS;
|
||||
/* If >1, allow this many self-referential
|
||||
expansions. */
|
||||
|
||||
enum variable_flavor
|
||||
flavor ENUM_BITFIELD (3); /* Variable flavor. */
|
||||
enum variable_origin
|
||||
origin ENUM_BITFIELD (3); /* Variable origin. */
|
||||
|
||||
unsigned int exportable:1; /* Nonzero if the variable _could_ be
|
||||
exported. */
|
||||
enum variable_export
|
||||
{
|
||||
v_export, /* Export this variable. */
|
||||
@ -95,6 +95,17 @@ struct variable_set_list
|
||||
struct variable_set *set; /* Variable set. */
|
||||
};
|
||||
|
||||
/* Structure used for pattern-specific variables. */
|
||||
|
||||
struct pattern_var
|
||||
{
|
||||
struct pattern_var *next;
|
||||
char *target;
|
||||
unsigned int len;
|
||||
char *suffix;
|
||||
struct variable variable;
|
||||
};
|
||||
|
||||
extern char *variable_buffer;
|
||||
extern struct variable_set_list *current_variable_set_list;
|
||||
|
||||
@ -131,8 +142,9 @@ extern void define_automatic_variables PARAMS ((void));
|
||||
extern void initialize_file_variables PARAMS ((struct file *file, int read));
|
||||
extern void print_file_variables PARAMS ((struct file *file));
|
||||
extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix));
|
||||
extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
|
||||
extern void merge_variable_set_lists PARAMS ((struct variable_set_list **to_list, struct variable_set_list *from_list));
|
||||
extern struct variable *do_variable_definition PARAMS ((const struct floc *flocp, const char *name, char *value, enum variable_origin origin, enum variable_flavor flavor, int target_var));
|
||||
extern struct variable *parse_variable_definition PARAMS ((struct variable *v, char *line));
|
||||
extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin, int target_var));
|
||||
extern void init_hash_global_variable_set PARAMS ((void));
|
||||
extern void hash_init_function_table PARAMS ((void));
|
||||
@ -179,6 +191,8 @@ extern struct variable *define_variable_in_set
|
||||
|
||||
extern char **target_environment PARAMS ((struct file *file));
|
||||
|
||||
extern struct pattern_var *create_pattern_var PARAMS ((char *target, char *suffix));
|
||||
|
||||
extern int export_all_variables;
|
||||
|
||||
#define MAKELEVEL_NAME "MAKELEVEL"
|
||||
|
Loading…
Reference in New Issue
Block a user