summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog57
-rw-r--r--Makefile.am10
-rw-r--r--NEWS21
-rw-r--r--README.OS2.template159
-rw-r--r--README.cvs3
-rw-r--r--build.template17
-rw-r--r--config/ChangeLog5
-rw-r--r--config/dospaths.m421
-rw-r--r--configure.in9
-rw-r--r--default.c4
-rw-r--r--dir.c6
-rw-r--r--doc/make.texi17
-rw-r--r--function.c4
-rw-r--r--implicit.c2
-rw-r--r--job.c13
-rw-r--r--maintMakefile6
-rw-r--r--read.c36
-rw-r--r--rule.c100
-rw-r--r--rule.h11
-rw-r--r--tests/ChangeLog11
-rwxr-xr-xtests/run_make_tests.pl6
-rw-r--r--tests/scripts/features/patspecific_vars35
-rw-r--r--variable.c175
-rw-r--r--variable.h28
24 files changed, 551 insertions, 205 deletions
diff --git a/ChangeLog b/ChangeLog
index cce4014..b5db571 100644
--- a/ChangeLog
+++ b/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
diff --git a/Makefile.am b/Makefile.am
index fea1f4d..06d2df1 100644
--- a/Makefile.am
+++ b/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
diff --git a/NEWS b/NEWS
index 6c11612..a93fc4e 100644
--- a/NEWS
+++ b/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
diff --git a/README.OS2.template b/README.OS2.template
new file mode 100644
index 0000000..eff2c0b
--- /dev/null
+++ b/README.OS2.template
@@ -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).
diff --git a/README.cvs b/README.cvs
index 9cf91b7..8fa4feb 100644
--- a/README.cvs
+++ b/README.cvs
@@ -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
diff --git a/build.template b/build.template
index 1cf7cd8..894140e 100644
--- a/build.template
+++ b/build.template
@@ -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}
diff --git a/config/ChangeLog b/config/ChangeLog
index 9755ae9..3192177 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -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.
diff --git a/config/dospaths.m4 b/config/dospaths.m4
new file mode 100644
index 0000000..3cadbbf
--- /dev/null
+++ b/config/dospaths.m4
@@ -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
+ ])
diff --git a/configure.in b/configure.in
index c2f065e..ef44f90 100644
--- a/configure.in
+++ b/configure.in
@@ -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
diff --git a/default.c b/default.c
index d262a30..b07f152 100644
--- a/default.c
+++ b/default.c
@@ -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). */
diff --git a/dir.c b/dir.c
index 1de62e5..8050a36 100644
--- a/dir.c
+++ b/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, '/');
diff --git a/doc/make.texi b/doc/make.texi
index 1f491ad..1470adb 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -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:
diff --git a/function.c b/function.c
index 08a4d56..d05a5bb 100644
--- a/function.c
+++ b/function.c
@@ -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;
}
diff --git a/implicit.c b/implicit.c
index 0908cbd..944d57a 100644
--- a/implicit.c
+++ b/implicit.c
@@ -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,
diff --git a/job.c b/job.c
index b083214..1ee444a 100644
--- a/job.c
+++ b/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;
diff --git a/maintMakefile b/maintMakefile
index 1bf49f0..1c93463 100644
--- a/maintMakefile
+++ b/maintMakefile
@@ -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 $@
diff --git a/read.c b/read.c
index 40ff3d6..d79895e 100644
--- a/read.c
+++ b/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,
diff --git a/rule.c b/rule.c
index 1d4a089..77451cc 100644
--- a/rule.c
+++ b/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);
- }
- }
}
diff --git a/rule.h b/rule.h
index 30cc544..576be9e 100644
--- a/rule.h
+++ b/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,
diff --git a/tests/ChangeLog b/tests/ChangeLog
index b4ba23e..3880e8a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index 0ada574..4389d43 100755
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -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.
diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars
index 7feb687..9ace5c4 100644
--- a/tests/scripts/features/patspecific_vars
+++ b/tests/scripts/features/patspecific_vars
@@ -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;
diff --git a/variable.c b/variable.c
index 723c950..d74672b 100644
--- a/variable.c
+++ b/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,27 +1211,60 @@ 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 (v->name[0] == '\0')
+ fatal (&v->fileinfo, _("empty variable name"));
+
+ return v;
+}
+
+/* Try to interpret LINE (a null-terminated string) as a variable definition.
- if (expanded_name[0] == '\0')
- fatal (flocp, _("empty variable name"));
+ 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.
- v = do_variable_definition (flocp, expanded_name, p,
- origin, flavor, target_var);
+ See the comments for parse_variable_definition().
- free (expanded_name);
+ 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. */
- return v;
+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. */
@@ -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);
+ }
}
diff --git a/variable.h b/variable.h
index 5ce1944..613278a 100644
--- a/variable.h
+++ b/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"