]> git.ipfire.org Git - thirdparty/make.git/commitdiff
- Fix bug #1405: allow multiple pattern-specific variables to match a target.
authorPaul Smith <psmith@gnu.org>
Fri, 2 May 2003 01:44:59 +0000 (01:44 +0000)
committerPaul Smith <psmith@gnu.org>
Fri, 2 May 2003 01:44:59 +0000 (01:44 +0000)
- Fix some uncleanliness about the implementation of patterns-specific vars.
- Some enhancements to the OS/2 port.

24 files changed:
ChangeLog
Makefile.am
NEWS
README.OS2.template [new file with mode: 0644]
README.cvs
build.template
config/ChangeLog
config/dospaths.m4 [new file with mode: 0644]
configure.in
default.c
dir.c
doc/make.texi
function.c
implicit.c
job.c
maintMakefile
read.c
rule.c
rule.h
tests/ChangeLog
tests/run_make_tests.pl
tests/scripts/features/patspecific_vars
variable.c
variable.h

index cce4014b2f65bb83dd49f6f9a63c77988e274abd..b5db571558bfa72160ad9a91e72a5d56cc7fee91 100644 (file)
--- 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
index fea1f4d2ec118ac18b210f95f2c0005e89983773..06d2df179f6fe79b965f7d7920df08eef993b332 100644 (file)
@@ -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 6c1161258ab40abf655f1a215a708692a36b050d..a93fc4e1e67a6e9d8fe5ab1208790e5f8aa76864 100644 (file)
--- 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.
 \f
-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.
 
 \f
 Version 3.80
diff --git a/README.OS2.template b/README.OS2.template
new file mode 100644 (file)
index 0000000..eff2c0b
--- /dev/null
@@ -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).
index 9cf91b714101d2a1f54ec061f1eb2938d1773b43..8fa4feb777fd31c04d868ef991e1b42d689d4ecc 100644 (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
index 1cf7cd856053c3142bd38f269275ec5184ff40da..894140e2a5c9e24d7fda906327cf28bbe5ea841d 100644 (file)
@@ -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}
index 9755ae99f9008e6b136573fdf9c8bd1bc1751931..319217753dab3e1fe4e0ccc4afd84bef62caa604 100644 (file)
@@ -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 (file)
index 0000000..3cadbbf
--- /dev/null
@@ -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
+  ])
index c2f065e4ea74d82310f79b98f5eac91fda76d469..ef44f90485e33e250830d969a0550880f59ceb81 100644 (file)
@@ -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
index d262a309abbcd77c892d324ab068667a395c0751..b07f1527bd212f82ea58f7eaa943538886b4229c 100644 (file)
--- 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 1de62e5c2929d2f88f660ad8c67997efdd5d2850..8050a36cbd2e838631b4e65b1fe5fe90b2d62607 100644 (file)
--- 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, '/');
index 1f491ad9992f5a0016b4c442fcc4687420aff8ac..1470adb0348689c65a381dd6bd3ad20e3432116e 100644 (file)
@@ -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:
 
index 08a4d569181bbf94eb68931f21226ab557f57860..d05a5bb612928b0177076e9f2a5f7264968e6981 100644 (file)
@@ -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;
 }
index 0908cbd75f2eb6ddf5333954b61f25b92f6c47fc..944d57a970782bcec82f14bc78277e8bcea824e2 100644 (file)
@@ -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 b0832146f5d48c2338ddc2b3852be704167571af..1ee444a5cdb55ebb887f8e861fecfd8392556bc7 100644 (file)
--- 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;
index 1bf49f00c1faf4b399229304f3ff689b8fb0346b..1c934636d4af75490e6883637d552cdb2eed9c57 100644 (file)
@@ -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 40ff3d6bc8e2c7d8ed8018fc7e3961f01aacbff3..d79895e1687538695246b2455881b1f2ed907e16 100644 (file)
--- 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;
 }
 \f
 /* Record a description line for files FILENAMES,
diff --git a/rule.c b/rule.c
index 1d4a089cfe7b0fe5b2130e5b0f6e08d56f2a9c57..77451cc702b7f2d90d57d242480e7324cf1ed692 100644 (file)
--- 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;
 }
 \f
-/* 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;
-}
-\f
-/* 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;
-}
-\f
 /* 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 30cc54492498df18632f912dcedca170889d4526..576be9e3b6b60f695a639729a8a184de1b1b7ca4 100644 (file)
--- 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,
index b4ba23ecb37bfa9ed5895986597584544903cbbd..3880e8a93a3f11387b1cc196407c6eab08d51343 100644 (file)
@@ -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
index 0ada574ffa91f7335e686f6dc5a01f93e1d31a2f..4389d4349f26fe182eecc65abb7501c62712eedc 100755 (executable)
@@ -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.
index 7feb68769a48613e13880580363550f3e84ff5de..9ace5c4130fcc168a81fba7a2750cf68023ff8eb 100644 (file)
@@ -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;
index 723c9504a8a33d1c561883422a39126863ca367c..d74672b3ac3105572885cf7ba51eb2f45043f6ca 100644 (file)
@@ -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;
+}
+\f
 /* 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());
 }
 \f
-/* 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;
+}
+\f
+/* 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;
 }
 \f
 /* 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);
+  }
 }
 
 
index 5ce1944a5eceefa3ed7e76527852a3b0aecaebb2..613278a3c502861ee56ea4af09167d09607c7776 100644 (file)
@@ -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"