~MAKE-3_78_1HB.BCKMAKE-3_78_1HB.BCK:BACKUP/LOG/INTER [.MAKE-3_78_1HB...] MAKE-3_78_1HB.BCK/SAV BECKER @ FJV7.1 _ALFAM7::  _ALFAM7$DKA100: V6.2 ~ v*[MAKE-3_78_1HB]ACCONFIG.H;1+,`./@ 4-`0123KPWO567cR m89G@HJ/* Name of this package (needed by automake) */ #undef PACKAGE /* Version of this package (needed by automake) */ #undef VERSION /* Define to the name of the SCCS `get' command. */ #undef SCCS_GET /* Define this if the SCCS `get' command understands the `-G' option. */ #undef SCCS_GET_MINUS_G /* Define this to enable job server support in GNU make. */ #undef MAKE_JOBSERVER /* Define to be the nanoseconds member of struct stat's st_mtim, if it exists. */ #undef ST_MTIM_NSEC /* Define this if the C library defines the variable `sys_siglist'. */ #undef HAVE_SYS_SIGLIST /* Define this if the C library defines the variable `_sys_siglist'. */ #undef HAVE__SYS_SIGLIST /* Define this if you have the `union wait' type in . */ #undef HAVE_UNION_WAIT /* Define to `unsigned long' or `unsigned long long' if doesn't define. */ #undef uintmax_t /* These are for AC_FUNC_SELECT */ /* Define if the system doesn't provide fd_set. */ #undef fd_set /* Define the type of the first arg to select(). */ #undef fd_set_size_t /* Define this if select() args need to be cast away from fd_set (HP-UX). */ #undef SELECT_FD_SET_CAST #*[MAKE-3_78_1HB]ACINCLUDE.M4;1+,`. /@ 4 -`0123KPWO!567!m89G@HJdnl acinclude.m4 -- Extra macros needed for GNU make. dnl dnl Automake will incorporate this into its generated aclocal.m4. dnl --------------------------------------------------------------------------- dnl Got this from the lynx 2.8 distribution. dnl by T.E.Dickey dnl and Jim Spath dnl and Philippe De Muyter dnl dnl Created: 1997/1/28 dnl Updated: 1997/12/23 dnl --------------------------------------------------------------------------- dnl After checking for functions in the default $LIBS, make a further check dnl for the functions that are netlib-related (these aren't always in the dnl libc, etc., and have to be handled specially because there are conflicting dnl and broken implementations. dnl Common library requirements (in order): dnl -lresolv -lsocket -lnsl dnl -lnsl -lsocket dnl -lsocket dnl -lbsd AC_DEFUN([CF_NETLIBS],[ cf_test_netlibs=no AC_MSG_CHECKING(for network libraries) AC_CACHE_VAL(cf_cv_netlibs,[ AC_MSG_RESULT(working...) cf_cv_netlibs="" cf_test_netlibs=yes AC_CHECK_FUNCS(gethostname,,[ CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[ CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])]) # # FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but # I don't know the entrypoints - 97/7/22 TD AC_CHECK_LIB(inet,main,cf_cv_netlibs="-linet $cf_cv_netlibs") # if test "$ac_cv_func_lsocket" != no ; then AC_CHECK_FUNCS(socket,,[ CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[ CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])]) fi # AC_CHECK_FUNCS(gethostbyname,,[ CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)]) # AC_CHECK_FUNCS(strcasecmp,,[ CF_RECHECK_FUNC(strcasecmp,resolv,cf_cv_netlibs)]) ]) LIBS="$LIBS $cf_cv_netlibs" test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&AC_FD_MSG ])dnl dnl --------------------------------------------------------------------------- dnl Re-check on a function to see if we can pick it up by adding a library. dnl $1 = function to check dnl $2 = library to check in dnl $3 = environment to update (e.g., $LIBS) dnl $4 = what to do if this fails dnl dnl This uses 'unset' if the shell happens to support it, but leaves the dnl configuration variable set to 'unknown' if not. This is a little better dnl than the normal autoconf test, which gives misleading results if a test dnl for the function is made (e.g., with AC_CHECK_FUNC) after this macro is dnl used (autoconf does not distinguish between a null token and one that is dnl set to 'no'). AC_DEFUN([CF_RECHECK_FUNC],[ AC_CHECK_LIB($2,$1,[ CF_UPPER(cf_tr_func,$1) AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func) ac_cv_func_$1=yes $3="-l$2 [$]$3"],[ ac_cv_func_$1=unknown unset ac_cv_func_$1 2>/dev/null $4], [[$]$3]) ])dnl dnl --------------------------------------------------------------------------- dnl Make an uppercase version of a variable dnl $1=uppercase($2) AC_DEFUN([CF_UPPER], [ changequote(,)dnl $1=`echo $2 | tr '[a-z]' '[A-Z]'` changequote([,])dnl ])dnl dnl --------------------------------------------------------------------------- dnl Got this from the GNU tar 1.13.11 distribution dnl by Paul Eggert dnl --------------------------------------------------------------------------- dnl By default, many hosts won't let programs access large files; dnl one must use special compiler options to get large-file access to work. dnl For more details about this brain damage please see: dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html dnl Written by Paul Eggert . dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_FLAGS(FLAGSNAME) AC_DEFUN(AC_SYS_LARGEFILE_FLAGS, [AC_CACHE_CHECK([for $1 value to request large file support], ac_cv_sys_largefile_$1, [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || { ac_cv_sys_largefile_$1=no ifelse($1, CFLAGS, [case "$host_os" in # HP-UX 10.20 requires -D__STDC_EXT__ with gcc 2.95.1. changequote(, )dnl hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) changequote([, ])dnl if test "$GCC" = yes; then ac_cv_sys  _largefile_CFLAGS=-D__STDC_EXT__ fi ;; # IRIX 6.2 and later require cc -n32. changequote(, )dnl irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) changequote([, ])dnl if test "$GCC" != yes; then ac_cv_sys_largefile_CFLAGS=-n32 fi esac if test "$ac_cv_sys_largefile_CFLAGS" != no; then ac_save_CC="$CC" CC="$CC $ac_cv_sys_largefile_CFLAGS" AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no) CC="$ac_save_CC" fi]) }])]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_SPACE_APPEND(VAR, VAL) AC_DEFUN(AC_SYS_LARGEFILE_SPACE_APPEND, [case $2 in no) ;; ?*) case "[$]$1" in '') $1=$2 ;; *) $1=[$]$1' '$2 ;; esac ;; esac]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT) AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE, [AC_CACHE_CHECK([for $1], $2, [$2=no changequote(, )dnl $4 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D$1) $2=1 ;; -D$1=*) $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done changequote([, ])dnl ]) if test "[$]$2" != no; then AC_DEFINE_UNQUOTED([$1], [$]$2, [$3]) fi]) AC_DEFUN(AC_SYS_LARGEFILE, [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, [ --disable-largefile omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, getconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) AC_SYS_LARGEFILE_FLAGS(LDFLAGS) AC_SYS_LARGEFILE_FLAGS(LIBS) for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in no) ;; -D_FILE_OFFSET_BITS=*) ;; -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; -D_LARGE_FILES | -D_LARGE_FILES=*) ;; -D?* | -I?*) AC_SYS_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;; *) AC_SYS_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;; esac done AC_SYS_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS") AC_SYS_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS") AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, ac_cv_sys_file_offset_bits, [Number of bits in a file offset, on hosts where this is settable.], [case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_file_offset_bits=64 ;; esac]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, ac_cv_sys_largefile_source, [Define to make fseeko etc. visible, on some hosts.], [case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_largefile_source=1 ;; esac]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, ac_cv_sys_large_files, [Define for large files, on AIX-style hosts.], [case "$host_os" in # AIX 4.2 and later aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*) ac_cv_sys_large_files=1 ;; esac]) fi ]) dnl --------------------------------------------------------------------------- dnl From Paul Eggert dnl Define HAVE_INTTYPES_H if exists, dnl doesn't clash with , and declares uintmax_t. AC_DEFUN(jm_AC_HEADER_INTTYPES_H, [ if test x = y; then dnl This code is deliberately never run via ./configure. dnl FIXME: this is a gross hack to make autoheader put an entry dnl for `HAVE_INTTYPES_H' in config.h.in. AC_CHECK_FUNCS(INTTYPES_H) fi AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_inttypes_h=yes, jm_ac_cv_header_inttypes_h=no)]) if test $jm_ac_cv_header_inttypes_h = yes; then ac_kludge=HAVE_INTTYPES_H AC_DEFINE_UNQUOTED($ac_kludge) fi ]) dnl --------------------------------------------------------------------------- dnl From Paul Eggert AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC, [AC_CACHE_CHECK([for nanoseconds member of struct stat.st_mtim], ac_cv_struct_st_mtim_nsec, [ac_save_CPPFLAGS="$CPPFLAGS" ac_cv_struct_st_mtim_nsec=no # tv_nsec -- the usual case # _tv_nsec -- Solaris 2.6, if # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 # && !defined __EXTENSIONS__) # st__tim.tv_nsec -- UnixWare 2.1.2 for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" AC_TRY_COMPILE([#include #include ], [struct stat s; s.st_mtim.ST_MTIM_NSEC;], [ac_cv_struct_st_mtim_nsec=$ac_val; break]) done CPPFLAGS="$ac_save_CPPFLAGS"]) if test $ac_cv_struct_st_mtim_nsec != no; then AC_DEFINE_UNQUOTED(ST_MTIM_NSEC, $ac_cv_struct_st_mtim_nsec) fi ] ) dnl --------------------------------------------------------------------------- dnl From Paul Eggert dnl Define uintmax_t to `unsigned long' or `unsigned long long' dnl if does not exist. AC_DEFUN(jm_AC_TYPE_UINTMAX_T, [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) if test $jm_ac_cv_header_inttypes_h = no; then AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(uintmax_t, unsigned long long) else AC_DEFINE(uintmax_t, unsigned long) fi fi ]) dnl --------------------------------------------------------------------------- dnl From Steve Robbins dnl From a proposed change made on the autoconf list on 2 Feb 1999 dnl http://sourceware.cygnus.com/ml/autoconf/1999-02/msg00001.html dnl Patch for AIX 3.2 by Lars Hecking on 17 May 1999 AC_DEFUN(AC_FUNC_SELECT, [AC_CHECK_FUNCS(select) if test "$ac_cv_func_select" = yes; then AC_CHECK_HEADERS(unistd.h sys/types.h sys/time.h sys/select.h sys/socket.h) AC_MSG_CHECKING([argument types of select()]) AC_CACHE_VAL(ac_cv_type_fd_set_size_t,dnl [AC_CACHE_VAL(ac_cv_type_fd_set,dnl [for ac_cv_type_fd_set in 'fd_set' 'int' 'void'; do for ac_cv_type_fd_set_size_t in 'int' 'size_t' 'unsigned long' 'unsigned'; do for ac_type_timeval in 'struct timeval' 'const struct timeval'; do AC_TRY_COMPILE(dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif], [#ifdef __STDC__ extern select ($ac_cv_type_fd_set_size_t, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_type_timeval *); #else extern select (); $ac_cv_type_fd_set_size_t s; $ac_cv_type_fd_set *p; $ac_type_timeval *t; #endif], [ac_found=yes ; break 3],ac_found=no) done done done ])dnl AC_CACHE_VAL ])dnl AC_CACHE_VAL if test "$ac_found" = no; then AC_MSG_ERROR([can't determine argument types]) fi AC_MSG_RESULT([select($ac_cv_type_fd_set_size_t,$ac_cv_type_fd_set *,...)]) AC_DEFINE_UNQUOTED(fd_set_size_t, $ac_cv_type_fd_set_size_t) ac_cast= if test "$ac_cv_type_fd_set" != fd_set; then # Arguments 2-4 are not fd_set. Some weirdo systems use fd_set type for # FD_SET macros, but insist that you cast the argument to select. I don't # understand why that might be, but it means we cannot define fd_set. AC_EGREP_CPP(dnl changequote(<<,>>)dnl <<(^|[^a-zA-Z_0-9])fd_set[^a-zA-Z_0-9]>>dnl changequote([,]),dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include  #endif],dnl # We found fd_set type in a header, need special cast ac_cast="($ac_cv_type_fd_set *)",dnl # No fd_set type; it is safe to define it AC_DEFINE_UNQUOTED(fd_set,$ac_cv_type_fd_set)) fi AC_DEFINE_UNQUOTED(SELECT_FD_SET_CAST,$ac_cast) fi ]) # The following is taken from automake 1.4, # except that it prefers the compiler option -Ae to "-Aa -D_HPUX_SOURCE" # because only the former supports 64-bit integral types on HP-UX 10.20. ## ----------------------------------------- ## ## ANSIfy the C compiler whenever possible. ## ## From Franc,ois Pinard ## ## ----------------------------------------- ## # serial 2 # @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac AC_DEFUN(AM_PROG_CC_STDC, [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require dnl a magic option to avoid problems with ANSI preprocessor commands dnl like #elif. dnl FIXME: can't do this because then AC_AIX won't work due to a dnl circular dependency. dnl AC_BEFORE([$0], [AC_PROG_CPP]) AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) AC_CACHE_VAL(am_cv_prog_cc_stdc, [am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" AC_TRY_COMPILE( [#include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; ], [ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ], [am_cv_prog_cc_stdc="$ac_arg"; break]) done CC="$ac_save_CC" ]) if test -z "$am_cv_prog_cc_stdc"; then AC_MSG_RESULT([none needed]) else AC_MSG_RESULT($am_cv_prog_cc_stdc) fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) *[MAKE-3_78_1HB]ACLOCAL.M4;1+,`.(/@ 4('!-`0123KPWO)567(m89G@HJdnl aclocal.m4 generated automatically by aclocal 1.4 dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. dnl acinclude.m4 -- Extra macros needed for GNU make. dnl dnl Automake will incorporate this into its generated aclocal.m4. dnl --------------------------------------------------------------------------- dnl Got this from the lynx 2.8 distribution. dnl by T.E.Dickey dnl and Jim Spath dnl and Philippe De Muyter dnl dnl Created: 1997/1/28 dnl Updated: 1997/12/23 dnl --------------------------------------------------------------------------- dnl After checking for functions in the default $LIBS, make a further check dnl for the functions that are netlib-related (these aren't always in the dnl libc, etc., and have to be handled specially because there are conflicting dnl and broken implementations. dnl Common library requirements (in order): dnl -lresolv -lsocket -lnsl dnl -lnsl -lsocket dnl -lsocket dnl -lbsd AC_DEFUN([CF_NETLIBS],[ cf_test_netlibs=no AC_MSG_CHECKING(for network libraries) AC_CACHE_VAL(cf_cv_netlibs,[ AC_MSG_RESULT(working...) cf_cv_netlibs="" cf_test_netlibs=yes AC_CHECK_FUNCS(gethostname,,[ CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[ CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])]) # # FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but # I don't know the entrypoints - 97/7/22 TD AC_CHECK_LIB(inet,main,cf_cv_netlibs="-linet $cf_cv_netlibs") # if test "$ac_cv_func_lsocket" != no ; then AC_CHECK_FUNCS(socket,,[ CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[ CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])]) fi # AC_CHECK_FUNCS(gethostbyname,,[ CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)]) # AC_CHECK_FUNCS(strcasecmp,,[ CF_RECHECK_FUNC(strcasecmp,resolv,cf_cv_netlibs)]) ]) LIBS="$LIBS $cf_cv_netlibs" test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&AC_FD_MSG ])dnl dnl --------------------------------------------------------------------------- dnl Re-check on a function to see if we can pick it up by adding a library. dnl $1 = function to check dnl $2 = library to check in dnl $3 = environment to update (e.g., $LIBS) dnl $4 = what to do if this fails dnl dnl This uses 'unset' if the shell happens to support it, but leaves the dnl configuration variable set to 'unknown' if not. This is a little better dnl than the normal autoconf test, which gives misleading results if a test dnl for the function is made (e.g., with AC_CHECK_FUNC) after this macro is dnl used (autoconf does not distinguish between a null token and one that is dnl set to 'no'). AC_DEFUN([CF_RECHECK_FUNC],[ AC_CHECK_LIB($2,$1,[ CF_UPPER(cf_tr_func,$1) AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func) ac_cv_func_$1=yes $3="-l$2 [$]$3"],[ ac_cv_func_$1=unknown unset ac_cv_func_$1 2>/dev/null $4], [[$]$3]) ])dnl dnl --------------------------------------------------------------------------- dnl Make an uppercase version of a variable dnl $1=uppercase($2) AC_DEFUN([CF_UPPER], [ changequote(,)dnl $1=`echo $2 | tr '[a-z]' '[A-Z]'` changequote([,])dnl ])dnl dnl --------------------------------------------------------------------------- dnl Got this from the GNU tar 1.13.11 distribution dnl by Paul Eggert dnl --------------------------------------------------------------------------- dnl By default, many hosts won't let programs access large files; dnl one must use special compiler options to get large-file access to work. dnl For more details about this brain damage please see: dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html dnl Written by Paul Eggert . dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_FLAGS(FLAGSNAME) AC_DEFUN(AC_SYS_LARGEFILE_FLAGS, [AC_CACHE_CHECK([for $1 value to request large file support], ac_cv_sys_largefile_$1, [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || { ac_cv_sys_largefile_$1=no ifelse($1, CFLAGS, [case "$host_os" in # HP-UX 10.20 requires -D__STDC_EXT__ with gcc 2.95.1. changequote(, )dnl hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) changequote([, ])dnl if test "$GCC" = yes; then ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__ fi ;; # IRIX 6.2 and later require cc -n32. changequote(, )dnl irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) changequote([, ])dnl if test "$GCC" != yes; then ac_cv_sys_largefile_CFLAGS=-n32 fi esac if test "$ac_cv_sys_largefile_CFLAGS" != no; then ac_save_CC="$CC" CC="$CC $ac_cv_sys_largefile_CFLAGS" AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no) CC="$ac_save_CC" fi]) }])]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_SPACE_APPEND(VAR, VAL) AC_DEFUN(AC_SYS_LARGEFILE_SPACE_APPEND, [case $2 in no) ;; ?*) case "[$]$1" in '') $1=$2 ;; *) $1=[$]$1' '$2 ;; esac ;; esac]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT) AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE, [AC_CACHE_CHECK([for $1], $2, [$2=no changequote(, )dnl $4 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D$1) $2=1 ;; -D$1=*) $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done changequote([, ])dnl ]) if test "[$]$2" != no; then AC_DEFINE_UNQUOTED([$1], [$]$2, [$3]) fi]) AC_DEFUN(AC_SYS_LARGEFILE, [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, [ --disable-largefile omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, g etconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) AC_SYS_LARGEFILE_FLAGS(LDFLAGS) AC_SYS_LARGEFILE_FLAGS(LIBS) for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in no) ;; -D_FILE_OFFSET_BITS=*) ;; -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; -D_LARGE_FILES | -D_LARGE_FILES=*) ;; -D?* | -I?*) AC_SYS_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;; *) AC_SYS_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;; esac done AC_SYS_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS") AC_SYS_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS") AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, ac_cv_sys_file_offset_bits, [Number of bits in a file offset, on hosts where this is settable.], [case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_file_offset_bits=64 ;; esac]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, ac_cv_sys_largefile_source, [Define to make fseeko etc. visible, on some hosts.], [case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_largefile_source=1 ;; esac]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, ac_cv_sys_large_files, [Define for large files, on AIX-style hosts.], [case "$host_os" in # AIX 4.2 and later aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*) ac_cv_sys_large_files=1 ;; esac]) fi ]) dnl --------------------------------------------------------------------------- dnl From Paul Eggert dnl Define HAVE_INTTYPES_H if exists, dnl doesn't clash with , and declares uintmax_t. AC_DEFUN(jm_AC_HEADER_INTTYPES_H, [ if test x = y; then dnl This code is deliberately never run via ./configure. dnl FIXME: this is a gross hack to make autoheader put an entry dnl for `HAVE_INTTYPES_H' in config.h.in. AC_CHECK_FUNCS(INTTYPES_H) fi AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_inttypes_h=yes, jm_ac_cv_header_inttypes_h=no)]) if test $jm_ac_cv_header_inttypes_h = yes; then ac_kludge=HAVE_INTTYPES_H AC_DEFINE_UNQUOTED($ac_kludge) fi ]) dnl --------------------------------------------------------------------------- dnl From Paul Eggert AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC, [AC_CACHE_CHECK([for nanoseconds member of struct stat.st_mtim], ac_cv_struct_st_mtim_nsec, [ac_save_CPPFLAGS="$CPPFLAGS" ac_cv_struct_st_mtim_nsec=no # tv_nsec -- the usual case # _tv_nsec -- Solaris 2.6, if # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 # && !defined __EXTENSIONS__) # st__tim.tv_nsec -- UnixWare 2.1.2 for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" AC_TRY_COMPILE([#include #include ], [struct stat s; s.st_mtim.ST_MTIM_NSEC;], [ac_cv_struct_st_mtim_nsec=$ac_val; break]) done CPPFLAGS="$ac_save_CPPFLAGS"]) if test $ac_cv_struct_st_mtim_nsec != no; then AC_DEFINE_UNQUOTED(ST_MTIM_NSEC, $ac_cv_struct_st_mtim_nsec) fi ] ) dnl --------------------------------------------------------------------------- dnl From Paul Eggert dnl Define uintmax_t to `unsigned long' or `unsigned long long' dnl if does not exist. AC_DEFUN(jm_AC_TYPE_UINTMAX_T, [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) if test $jm_ac_cv_header_inttypes_h = no; then AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(uintmax_t, unsigned long long) else AC_DEFINE(uintmax_t, unsigned long) fi fi ]) dnl --------------------------------------------------------------------------- dnl From Steve Robbins dnl From a proposed change made on the autoconf list on 2 Feb 1999 dnl http://sourceware.cygnus.com/ml/autoconf/1999-02/msg00001.html dnl Patch for AIX 3.2 by Lars Hecking on 17 May 1999 AC_DEFUN(AC_FUNC_SELECT, [AC_CHECK_FUNCS(select) if test "$ac_cv_func_select" = yes; then AC_CHECK_HEADERS(unistd.h sys/types.h sys/time.h sys/select.h sys/socket.h) AC_MSG_CHECKING([argument types of select()]) AC_CACHE_VAL(ac_cv_type_fd_set_size_t,dnl [AC_CACHE_VAL(ac_cv_type_fd_set,dnl [for ac_cv_type_fd_set in 'fd_set' 'int' 'void'; do for ac_cv_type_fd_set_size_t in 'int' 'size_t' 'unsigned long' 'unsigned'; do for ac_type_timeval in 'struct timeval' 'const struct timeval'; do AC_TRY_COMPILE(dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif], [#ifdef __STDC__ extern select ($ac_cv_type_fd_set_size_t, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_type_timeval *); #else extern select (); $ac_cv_type_fd_set_size_t s; $ac_cv_type_fd_set *p; $ac_type_timeval *t; #endif], [ac_found=yes ; break 3],ac_found=no) done done done ])dnl AC_CACHE_VAL ])dnl AC_CACHE_VAL if test "$ac_found" = no; then AC_MSG_ERROR([can't determine argument types]) fi AC_MSG_RESULT([select($ac_cv_type_fd_set_size_t,$ac_cv_type_fd_set *,...)]) AC_DEFINE_UNQUOTED(fd_set_size_t, $ac_cv_type_fd_set_size_t) ac_cast= if test "$ac_cv_type_fd_set" != fd_set; then # Arguments 2-4 are not fd_set. Some weirdo systems use fd_set type for # FD_SET macros, but insist that you cast the argument to select. I don't # understand why that might be, but it means we cannot define fd_set. AC_EGREP_CPP(dnl changequote(<<,>>)dnl <<(^|[^a-zA-Z_0-9])fd_set[^a-zA-Z_0-9]>>dnl changequote([,]),dnl [#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif],dnl # We found fd_set type in a header, need special cast ac_cast="($ac_cv_type_fd_set *)",dnl # No fd_set type; it is safe to define it AC_DEFINE_UNQUOTED(fd_set,$ac_cv_type_fd_set)) fi AC_DEFINE_UNQUOTED(SELECT_FD_SET_CAST,$ac_cast) fi ]) # The following is taken from automake 1.4, # except that it prefers the compiler option -Ae to "-Aa -D_HPUX_SOURCE" # because only the former supports 64-bit integral types on HP-UX 10.20. # serial 2 #`~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]ACLOCAL.M4;1(=z @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac AC_DEFUN(AM_PROG_CC_STDC, [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require dnl a magic option to avoid problems with ANSI preprocessor commands dnl like #elif. dnl FIXME: can't do this because then AC_AIX won't work due to a dnl circular dependency. dnl AC_BEFORE([$0], [AC_PROG_CPP]) AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) AC_CACHE_VAL(am_cv_prog_cc_stdc, [am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" AC_TRY_COMPILE( [#include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; ], [ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ], [am_cv_prog_cc_stdc="$ac_arg"; break]) done CC="$ac_save_CC" ]) if test -z "$am_cv_prog_cc_stdc"; then AC_MSG_RESULT([none needed]) else AC_MSG_RESULT($am_cv_prog_cc_stdc) fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. # serial 1 dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] AC_SUBST(VERSION) dnl test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi ifelse([$3],, AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) AC_REQUIRE([AM_SANITY_CHECK]) AC_REQUIRE([AC_ARG_PROGRAM]) dnl FIXME This is truly gross. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_REQUIRE([AC_PROG_MAKE_SET])]) # # Check to make sure that the build environment is sane. # AC_DEFUN(AM_SANITY_CHECK, [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "[$]*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "[$]*" != "X $srcdir/configure conftestfile" \ && test "[$]*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "[$]2" = conftestfile ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi rm -f conftest* AC_MSG_RESULT(yes)]) dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl %The program must properly implement --version. AC_DEFUN(AM_MISSING_PROG, [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if ($2 --version) < /dev/null > /dev/null 2>&1; then $1=$2 AC_MSG_RESULT(found) else $1="$3/missing $2" AC_MSG_RESULT(missing) fi AC_SUBST($1)]) # Like AC_CONFIG_HEADER, but automatically create stamp file. AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. dnl This file resides in the same directory as the config header dnl that is generated. We must strip everything past the first ":", dnl and everything past the last "/". AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, <>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, <>; do case " <<$>>CONFIG_HEADERS " in *" <<$>>am_file "*<<)>> echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx ;; esac am_indx=`expr "<<$>>am_indx" + 1` done<<>>dnl>>) changequote([,]))]) *[MAKE-3_78_1HB]ALLOCA.C;1+,`./@ 4-`0123KPWO56){78m89G@HJ/* alloca.c -- allocate automatically reclaimed memory (Mostly) portable public-domain implementation -- D A Gwyn This implementation of the PWB library alloca function, which is used to allocate space off the run-time stack so that it is automatically reclaimed upon procedure exit, was inspired by discussions with J. Q. Johnson of Cornell. J.Otto Tennant contributed the Cray support. There are some preprocessor constants that can be defined when compiling for your specific system, for improved efficiency; however, the defaults should be okay. The general concept of this implementation is to keep track of all alloca-allocated blocks, and reclaim any that are found to be deeper in the stack than the current invocation. This heuristic does not reclaim storage as soon as it becomes invalid, but it will do so eventually. As a special case, alloca(0) reclaims storage without allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef emacs #include "blockinput.h" #endif /* If compiling with GCC 2, this file's not needed. */ #if !defined (__GNUC__) || __GNUC__ < 2 /* If someone has defined alloca as a macro, there must be some other way alloca is supposed to work. */ #ifndef alloca #ifdef emacs #ifdef static /* actually, only want this if static is defined as "" -- this is for usg, in which emacs must undefine static in order to make unexec workable */ #ifndef STACK_DIRECTION you lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ #endif /* static */ #endif /* emacs */ /* If your stack is a linked list of frames, you have to provide an "address metric" ADDRESS_FUNCTION macro. */ #if defined (CRAY) && defined (CRAY_STACKSEG_END) long i00afunc (); #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) #else #define ADDRESS_FUNCTION(arg) &(arg) #endif #if __STDC__ typedef void *pointer; #else typedef char *pointer; #endif #ifndef NULL #define NULL 0 #endif /* Different portions of Emacs need to call different versions of malloc. The Emacs executable needs alloca to call xmalloc, because ordinary malloc isn't protected from input signals. On the other hand, the utilities in lib-src need alloca to call malloc; some of them are very simple, and don't have an xmalloc routine. Non-Emacs programs expect this to call use xmalloc. Callers below should use malloc. */ #ifndef emacs #define malloc xmalloc #endif extern pointer malloc (); /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #ifndef STACK_DIRECTION #define STACK_DIRECTION 0 /* Direction unknown. */ #endif #if STACK_DIRECTION != 0 #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ #else /* STACK_DIRECTION == 0; need run-time code. */ static int stack_dir; /* 1 or -1 once known. */ #define STACK_DIR stack_dir static void find_stack_direction () { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ if (addr == NULL) { /* Initial entry. */ addr = ADDRESS_FUNCTION (dummy); find_stack_direction (); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION (dummy) > addr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } } #endif /* STACK_DIRECTION == 0 */ /* An "alloca header" is used to: (a) chain together all alloca'ed blocks; (b) keep track of stack depth. It is very important that sizeof(header) agree with malloc alignment chunk size. The following default should work okay. */ #ifndef ALIGN_SIZE #define ALIGN_SIZE sizeof(double) #endif typedef union hdr { char align[ALIGN_SIZE]; /* To force sizeof(header). */ struct { union hdr *next; /* For chaining headers. */ char *deep; /* For stack depth measure. */ } h; } header; static header *last_alloca_header = NULL; /* -> last alloca header. */ /* Return a pointer to at least SIZE bytes of storage, which will be automatically reclaimed upon exit from the procedure that called alloca. Originally, this space was supposed to be taken from the current stack frame of the caller, but that method cannot be made to work for some implementations of C, for example under Gould's UTX/32. */ pointer alloca (size) unsigned size; { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); #if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* Unknown growth direction. */ find_stack_direction (); #endif /* Reclaim garbage, defined as all alloca'd storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* Traverses linked list. */ #ifdef emacs BLOCK_INPUT; #endif for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((pointer) hp); /* Collect garbage. */ hp = np; /* -> next header. */ } else break; /* Rest are not deeper. */ last_alloca_header = hp; /* -> last valid storage. */ #ifdef emacs UNBLOCK_INPUT; #endif } if (size == 0) return NULL; /* No allocation required. */ /* Allocate combined header + user data storage. */ { register pointer new = malloc (sizeof (header) + size); /* Address of header. */ if (new == 0) abort(); ((header *) new)->h.next = last_alloca_header; ((header *) new)->h.deep = depth; last_alloca_header = (header *) new;  /* User storage begins just after header. */ return (pointer) ((char *) new + sizeof (header)); } } #if defined (CRAY) && defined (CRAY_STACKSEG_END) #ifdef DEBUG_I00AFUNC #include #endif #ifndef CRAY_STACK #define CRAY_STACK #ifndef CRAY2 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ struct stack_control_header { long shgrow:32; /* Number of times stack has grown. */ long shaseg:32; /* Size of increments to stack. */ long shhwm:32; /* High water mark of stack. */ long shsize:32; /* Current size of stack (all segments). */ }; /* The stack segment linkage control information occurs at the high-address end of a stack segment. (The stack grows from low addresses to high addresses.) The initial part of the stack segment linkage control information is 0200 (octal) words. This provides for register storage for the routine which overflows the stack. */ struct stack_segment_linkage { long ss[0200]; /* 0200 overflow words. */ long sssize:32; /* Number of words in this segment. */ long ssbase:32; /* Offset to stack base. */ long:32; long sspseg:32; /* Offset to linkage control of previous segment of stack. */ long:32; long sstcpt:32; /* Pointer to task common address block. */ long sscsnm; /* Private control structure number for microtasking. */ long ssusr1; /* Reserved for user. */ long ssusr2; /* Reserved for user. */ long sstpid; /* Process ID for pid based multi-tasking. */ long ssgvup; /* Pointer to multitasking thread giveup. */ long sscray[7]; /* Reserved for Cray Research. */ long ssa0; long ssa1; long ssa2; long ssa3; long ssa4; long ssa5; long ssa6; long ssa7; long sss0; long sss1; long sss2; long sss3; long sss4; long sss5; long sss6; long sss7; }; #else /* CRAY2 */ /* The following structure defines the vector of words returned by the STKSTAT library routine. */ struct stk_stat { long now; /* Current total stack size. */ long maxc; /* Amount of contiguous space which would be required to satisfy the maximum stack demand to date. */ long high_water; /* Stack high-water mark. */ long overflows; /* Number of stack overflow ($STKOFEN) calls. */ long hits; /* Number of internal buffer hits. */ long extends; /* Number of block extensions. */ long stko_mallocs; /* Block allocations by $STKOFEN. */ long underflows; /* Number of stack underflow calls ($STKRETN). */ long stko_free; /* Number of deallocations by $STKRETN. */ long stkm_free; /* Number of deallocations by $STKMRET. */ long segments; /* Current number of stack segments. */ long maxs; /* Maximum number of stack segments so far. */ long pad_size; /* Stack pad size. */ long current_address; /* Current stack segment address. */ long current_size; /* Current stack segment size. This number is actually corrupted by STKSTAT to include the fifteen word trailer area. */ long initial_address; /* Address of initial segment. */ long initial_size; /* Size of initial segment. */ }; /* The following structure describes the data structure which trails any stack segment. I think that the description in 'asdef' is out of date. I only describe the parts that I am sure about. */ struct stk_trailer { long this_address; /* Address of this block. */ long this_size; /* Size of this block (does not include this trailer). */ long unknown2; long unknown3; long link; /* Address of trailer block of previous segment. */ long unknown5; long unknown6; long unknown7; long unknown8; long unknown9; long unknown10; long unknown11; long unknown12; long unknown13; long unknown14; }; #endif /* CRAY2 */ #endif /* not CRAY_STACK */ #ifdef CRAY2 /* Determine a "stack measure" for an arbitrary ADDRESS. I doubt that "lint" will like this much. */ static long i00afunc (long *address) { struct stk_stat status; struct stk_trailer *trailer; long *block, size; long result = 0; /* We want to iterate through all of the segments. The first step is to get the stack status structure. We could do this more quickly and more directly, perhaps, by referencing the $LM00 common block, but I know that this works. */ STKSTAT (&status); /* Set up the iteration. */ trailer = (struct stk_trailer *) (status.current_address + status.current_size - 15); /* There must be at least one stack segment. Therefore it is a fatal error if "trailer" is null. */ if (trailer == 0) abort (); /* Discard segments that do not contain our argument address. */ while (trailer != 0) { block = (long *) trailer->this_address; size = trailer->this_size; if (block == 0 || size == 0) abort (); trailer = (struct stk_trailer *) trailer->link; if ((block <= address) && (address < (block + size))) break; } /* Set the result to the offset in this segment and add the sizes of all predecessor segments. */ result = address - block; if (trailer == 0) { return result; } do { if (trailer->this_size <= 0) abort (); result += trailer->this_size; trailer = (struct stk_trailer *) trailer->link; } while (trailer != 0); /* We are done. Note that if you present a bogus address (one not in any segment), you will get a different number back, formed from subtracting the address of the first block. This is probably not what you want. */ return (result); } #else /* not CRAY2 */ /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. Determine the number of the cell within the stack, given the address of the cell. The purpose of this routine is to linearize, in some sense, stack addresses for alloca. */ static long i00afunc (long address) { long stkl = 0; long size, pseg, this_segment, stack; long result = 0; struct stack_segment_linkage *ssptr; /* Register B67 contains the address of the end of the current stack segment. If you (as a subprogram) store your registers on the stack and find that you are past the contents of B67, you have overflowed the segment. B67 also points to the stack segment linkage control area, which is what we are really interested in. */ stkl = CRAY_STACKSEG_END (); ssptr = (struct stack_segment_linkage *) stkl; /* If one subtracts 'size' from the end of the segment, one has the address of the first word of the segment. If this is not the first segment, 'pseg' will be nonzero. */ pseg = ssptr->sspseg; size = ssptr->sssize; this_segment = stkl - size; /* It is possible that calling this routine itself caused a stack overflow. Discard stack segments which do not contain the target address. */ while (!(this_segment <= address && address <= stkl)) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); #endif if (pseg == 0) break; stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; this_segment = stkl - size; } result = address - this_segment; /* If you subtract pseg from the current end of the stack, you get the address of the previous stack segment's end. This seems a little convoluted to me, but I'll bet you save a cycle somewhere. */ while (pseg != 0) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o\n", pseg, size); #endif stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; result += size; } return (result); } #endif /* not CRAY2 */ #endif /* CRAY */ #endif /* no alloca */ #endif /* not GCC version 2 */ *[MAKE-3_78_1HB]AMIGA.C;1+,`./@ 4U-`0123KPWO 567iGm89G@HJ /* Running commands on Amiga Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "variable.h" #include "amiga.h" #include #include #include #include #include static const char Amiga_version[] = "$VER: Make 3.74.3 (12.05.96) \n" "Amiga Port by A. Digulla (digulla@home.lake.de)"; int MyExecute (argv) char ** argv; { char * buffer, * ptr; char ** aptr; int len = 0; int status; for (aptr=argv; *aptr; aptr++) { len += strlen (*aptr) + 4; } buffer = AllocMem (len, MEMF_ANY); if (!buffer) fatal (NILF, "MyExecute: Cannot allocate space for calling a command"); ptr = buffer; for (aptr=argv; *aptr; aptr++) { if (((*aptr)[0] == ';' && !(*aptr)[1])) { *ptr ++ = '"'; strcpy (ptr, *aptr); ptr += strlen (ptr); *ptr ++ = '"'; } else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2]) { *ptr ++ = '\n'; continue; } else { strcpy (ptr, *aptr); ptr += strlen (ptr); } *ptr ++ = ' '; *ptr = 0; } ptr[-1] = '\n'; status = SystemTags (buffer, SYS_UserShell, TRUE, TAG_END); FreeMem (buffer, len); if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) status = 20; /* Warnings don't count */ if (status == 5) status = 0; return status; } char * wildcard_expansion (wc, o) char * wc, * o; { # define PATH_SIZE 1024 struct AnchorPath * apath; if ( (apath = AllocMem (sizeof (struct AnchorPath) + PATH_SIZE, MEMF_CLEAR)) ) { apath->ap_Strlen = PATH_SIZE; if (MatchFirst (wc, apath) == 0) { do { o = variable_buffer_output (o, apath->ap_Buf, strlen (apath->ap_Buf)); o = variable_buffer_output (o, " ",1); } while (MatchNext (apath) == 0); } MatchEnd (apath); FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE); } return o; } *[MAKE-3_78_1HB]AMIGA.H;1+,`./@ 4-`0123KPWO56 7Vm89G@HJ/* Definitions for amiga specific things Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ extern int MyExecute PARAMS ((char ** argv)); extern char * wildcard_expansion PARAMS ((char * wc, char * o)); u*[MAKE-3_78_1HB]AR.C;1+,`./@ 4*-`0123KPWO56Zrv7kfm89G@HJ/* Interface to `ar' archives for GNU Make. Copyright (C) 1988,89,90,91,92,93,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #ifndef NO_ARCHIVES #include "filedef.h" #include "dep.h" #include /* Defined in arscan.c. */ extern long int ar_scan PARAMS ((char *archive, long int (*function) (), long int arg)); extern int ar_name_equal PARAMS ((char *name, char *mem, int truncated)); #ifndef VMS extern int ar_member_touch PARAMS ((char *arname, char *memname)); #endif /* Return nonzero if NAME is an archive-member reference, zero if not. An archive-member reference is a name like `lib(member)'. If a name like `lib((entry))' is used, a fatal error is signaled at the attempt to use this unsupported feature. */ int ar_name (name) char *name; { char *p = index (name, '('), *end = name + strlen (name) - 1; if (p == 0 || p == name || *end != ')') return 0; if (p[1] == '(' && end[-1] == ')') fatal (NILF, _("attempt to use unsupported feature: `%s'"), name); return 1; } /* Parse the archive-member reference NAME into the archive and member names. Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil; put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil. */ void ar_parse_name (name, arname_p, memname_p) char *name, **arname_p, **memname_p; { char *p = index (name, '('), *end = name + strlen (name) - 1; if (arname_p != 0) *arname_p = savestring (name, p - name); if (memname_p != 0) *memname_p = savestring (p + 1, end - (p + 1)); } static long int ar_member_date_1 PARAMS ((int desc, char *mem, int truncated, long int hdrpos, long int datapos, long int size, long int date, int uid, int gid, int mode, char *name)); /* Return the modtime of NAME. */ time_t ar_member_date (name) char *name; { char *arname; int arname_used = 0; char *memname; long int val; ar_parse_name (name, &arname, &memname); /* Make sure we know the modtime of the archive itself because we are likely to be called just before commands to remake a member are run, and they will change the archive itself. But we must be careful not to enter_file the archive itself if it does not exist, because pattern_search assumes that files found in the data base exist or can be made. */ { struct file *arfile; arfile = lookup_file (arname); if (arfile == 0 && file_exists_p (arname)) { arfile = enter_file (arname); arname_used = 1; } if (arfile != 0) (void) f_mtime (arfile, 0); } val = ar_scan (arname, ar_member_date_1, (long int) memname); if (!arname_used) free (arname); free (memname); return (val <= 0 ? (time_t) -1 : (time_t) val); } /* This function is called by `ar_scan' to find which member to look at. */ /* ARGSUSED */ static long int ar_member_date_1 (desc, mem, truncated, hdrpos, datapos, size, date, uid, gid, mode, name) int desc; char *mem; int truncated; long int hdrpos, datapos, size, date; int uid, gid, mode; char *name; { return ar_name_equal (name, mem, truncated) ? date : 0; } /* Set the archive-member NAME's modtime to now. */ #ifdef VMS int ar_touch (name) char *name; { error (NILF, _("touch archive member is not available on VMS")); return -1; } #else int ar_touch (name) char *name; { char *arname, *memname; int arname_used = 0; register int val; ar_parse_name (name, &arname, &memname); /* Make sure we know the modtime of the archive itself before we touch the member, since this will change the archive itself. */ { struct file *arfile; arfile = lookup_file (arname); if (arfile == 0) { arfile = enter_file (arname); arname_used = 1; } (void) f_mtime (arfile, 0); } val = 1; switch (ar_member_touch (arname, memname)) { case -1: error (NILF, _("touch: Archive `%s' does not exist"), arname); break; case -2: error (NILF, _("touch: `%s' is not a valid archive"), arname); break; case -3: perror_with_name ("touch: ", arname); break; case 1: error (NILF, _("touch: Member `%s' does not exist in `%s'"), memname, arname); break; case 0: val = 0; break; default: error (NILF, _("touch: Bad return code from ar_member_touch on `%s'"), name); } if (!arname_used) free (arname); free (memname); return val; } #endif /* !VMS */ /* State of an `ar_glob' run, passed to `ar_glob_match'. */ struct ar_glob_state { char *arname; char *pattern; unsigned int size; struct nameseq *chain; unsigned int n; }; /* This function is called by `ar_scan' to match one archive element against the pattern in STATE. */ static long int ar_glob_match (desc, mem, truncated, hdrpos, datapos, size, date, uid, gid, mode, ~MAKE-3_78_1HB.BCK``[MAKE-3_78_1HB]AR.C;1"  state) int desc; char *mem; int truncated; long int hdrpos, datapos, size, date; int uid, gid, mode; struct ar_glob_state *state; { if (fnmatch (state->pattern, mem, FNM_PATHNAME|FNM_PERIOD) == 0) { /* We have a match. Add it to the chain. */ struct nameseq *new = (struct nameseq *) xmalloc (state->size); new->name = concat (state->arname, mem, ")"); new->next = state->chain; state->chain = new; ++state->n; } return 0L; } /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ static int glob_pattern_p (pattern, quote) const char *pattern; const int quote; { register const char *p; int open = 0; for (p = pattern; *p != '\0'; ++p) switch (*p) { case '?': case '*': return 1; case '\\': if (quote) ++p; break; case '[': open = 1; break; case ']': if (open) return 1; break; } return 0; } /* Glob for MEMBER_PATTERN in archive ARNAME. Return a malloc'd chain of matching elements (or nil if none). */ struct nameseq * ar_glob (arname, member_pattern, size) char *arname, *member_pattern; unsigned int size; { struct ar_glob_state state; char **names; struct nameseq *n; unsigned int i; if (! glob_pattern_p (member_pattern, 1)) return 0; /* Scan the archive for matches. ar_glob_match will accumulate them in STATE.chain. */ i = strlen (arname); state.arname = (char *) alloca (i + 2); bcopy (arname, state.arname, i); state.arname[i] = '('; state.arname[i + 1] = '\0'; state.pattern = member_pattern; state.size = size; state.chain = 0; state.n = 0; (void) ar_scan (arname, ar_glob_match, (long int) &state); if (state.chain == 0) return 0; /* Now put the names into a vector for sorting. */ names = (char **) alloca (state.n * sizeof (char *)); i = 0; for (n = state.chain; n != 0; n = n->next) names[i++] = n->name; /* Sort them alphabetically. */ qsort ((char *) names, i, sizeof (*names), alpha_compare); /* Put them back into the chain in the sorted order. */ i = 0; for (n = state.chain; n != 0; n = n->next) n->name = names[i++]; return state.chain; } #endif /* Not NO_ARCHIVES. */ *[MAKE-3_78_1HB]ARSCAN.C;2+,md.(/@ 4_((-`0123KPWO)56G-7"xm89G@HJP/* Library function for scanning an archive file. Copyright (C) 1987,89,91,92,93,94,95,97 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #ifdef HAVE_FCNTL_H #include #else #include #endif #ifndef NO_ARCHIVES #ifdef VMS #include #include #include #include #include #if __DECC #include #include #endif #define uppercasify(str) {char *str1; for (str1 = str; *str1; str1++) *str1 = _toupper(*str1);} static void *VMS_lib_idx; static char *VMS_saved_memname; static time_t VMS_member_date; static long int (*VMS_function) (); static int VMS_get_member_info (module, rfa) struct dsc$descriptor_s *module; unsigned long *rfa; { int status, i; long int fnval; time_t val; static struct dsc$descriptor_s bufdesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; struct mhddef *mhd; char filename[128]; bufdesc.dsc$a_pointer = filename; bufdesc.dsc$w_length = sizeof (filename); status = lbr$set_module (&VMS_lib_idx, rfa, &bufdesc, &bufdesc.dsc$w_length, 0); if (! status) { error (NILF, _("lbr$set_module failed to extract module info, status = %d"), status); lbr$close (&VMS_lib_idx); return 0; } mhd = (struct mhddef *) filename; #ifdef __DECC val = decc$fix_time (&mhd->mhd$l_datim); #endif for (i = 0; i < module->dsc$w_length; i++) filename[i] = _tolower (module->dsc$a_pointer[i]); filename[i] = '\0'; VMS_member_date = (time_t) -1; fnval = (*VMS_function) (-1, filename, 0, 0, 0, 0, val, 0, 0, 0, VMS_saved_memname); if (fnval) { VMS_member_date = fnval; return 0; } else return 1; } /* Takes three arguments ARCHIVE, FUNCTION and ARG. Open the archive named ARCHIVE, find its members one by one, and for each one call FUNCTION with the following arguments: archive file descriptor for reading the data, member name, member name might be truncated flag, member header position in file, member data position in file, member data size, member date, member uid, member gid, member protection mode, ARG. NOTE: on VMS systems, only name, date, and arg are meaningful! The descriptor is poised to read the data of the member when FUNCTION is called. It does not matter how much data FUNCTION reads. If FUNCTION returns nonzero, we immediately return what FUNCTION returned. Returns -1 if archive does not exist, Returns -2 if archive has invalid format. Returns 0 if have scanned successfully. */ long int ar_scan (archive, function, arg) char *archive; long int (*function) (); long int arg; { char *p; static struct dsc$descriptor_s libdesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; unsigned long func = LBR$C_READ; unsigned long type = LBR$C_TYP_UNK; unsigned long index = 1; int status; status = lbr$ini_control (&VMS_lib_idx, &func, &type, 0); if (! status) { error (NILF, _("lbr$ini_control failed with status = %d"),status); return -2; } libdesc.dsc$a_pointer = archive; libdesc.dsc$w_length = strlen (archive); status = lbr$open (&VMS_lib_idx, &libdesc, 0, 0, 0, 0, 0); if (! status) { error (NILF, _("unable to open library `%s' to lookup member `%s'"), archive, (char *)arg); return -1; } VMS_saved_memname = (char *)arg; /* For comparison, delete .obj from arg name. */ p = rindex (VMS_saved_memname, '.'); if (p) *p = '\0'; VMS_function = function; VMS_member_date = (time_t) -1; lbr$get_index (&VMS_lib_idx, &index, VMS_get_member_info, 0); /* Undo the damage. */ if (p) *p = '.'; lbr$close (&VMS_lib_idx); return VMS_member_date > 0 ? VMS_member_date : 0; } #else /* !VMS */ /* SCO Unix's compiler defines both of these. */ #ifdef M_UNIX #undef M_XENIX #endif /* On the sun386i and in System V rel 3, ar.h defines two different archive formats depending upon whether you have defined PORTAR (normal) or PORT5AR (System V Release 1). There is no default, one or the other must be defined to have a nonzero value. */ #if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0) #undef PORTAR #ifdef M_XENIX /* According to Jim Sievert , for SCO XENIX defining PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the right one. */ #define PORTAR 0 #else #define PORTAR 1 #endif #endif /* On AIX, define these symbols to be sure to get both archive formats. AIX 4.3 introduced the "big" archive format to support 64-bit object files, so on AIX 4.3 systems we need to support both the "normal" and "big" archive formats. An archive's format is indicated in the "fl_magic" field of the "FL_HDR" structure. For a normal archive, this field will be the string defined by the AIAMAG symbol. For a "big" archive, it will be the string defined by the AIAMAGBIG symbol (at least on AIX it works this way). Note: we'll define these symbols regardless of which AIX version we're compiling on, but this is okay since we'll use the new symbols only if they're present. */ #ifdef _AIX # define __AR_SMALL__ # define __AR_BIG__ #endif #ifndef WINDOWS32 # include #else /* These should allow us to read Windows (VC++) libraries (according to Frank * Libbrecht ) */ # include # include # include # define ARMAG IMAGE_ARCHIVE_START # define SARMAG IMAGE_ARCHIVE_START_SIZE # define ar_hdr _IMAGE_ARCHIVE_MEMBER_HEADER # define ar_name Name # define ar_mode Mode # define ar_size Size # define ar_date Date # define ar_uid UserID # define ar_gid GroupID #endif /* Cray's apparently defines this. */ #ifndef AR_HDR_SIZE # define AR_HDR_SIZE (sizeof (struct ar_hdr)) #endif /* Takes three arguments ARCHIVE, FUNCTION and ARG. Open the archive named ARCHIVE, find its members one by one, and for each one call FUNCTION with the following arguments: archive file descriptor for reading the data, member name, member name might be truncated flag, member header position in file, member data position in file, member data size, member date, member uid, member gid, member protection mode, ARG. The descriptor is poised to read the data of the member when FUNCTION is called. It does not matter how much data FUNCTION reads. If FUNCTION returns nonzero, we immediately return what FUNCTION returned. Returns -1 if archive does not exist, Returns -2 if archive has invalid format. Returns 0 if have scanned successfully. */ long int ar_scan (archive, function, arg) char *archive; long int (*function) (); long int arg; { #ifdef AIAMAG FL_HDR fl_header; #ifdef AIAMAGBIG int big_archive = 0; FL_HDR_BIG fl_header_big; #endif #else int long_name = 0; #endif char *namemap = 0; register int desc = open (archive, O_RDONLY, 0); if (desc < 0) return -1; #ifdef SARMAG { char buf[SARMAG]; register int nread = read (desc, buf, SARMAG); if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG)) { (void) close (desc); return -2; } } #else #ifdef AIAMAG { register int nread = read (desc, (char *) &fl_header, FL_HSZ); if (nread != FL_HSZ) { (void) close (desc); return -2; } #ifdef AIAMAGBIG /* If this is a "big" archive, then set the flag and re-read the header into the "big" structure. */ if (!bcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG)) { big_archive = 1; /* seek back to beginning of archive */ if (lseek (desc, 0, 0) < 0) { (void) close (desc); return -2; } /* re-read the header into the "big" structure */ nread = read (desc, (char *) &fl_header_big, FL_HSZ_BIG); if (nread != FL_HSZ_BIG) { (void) close (desc); return -2; } } else #endif /* Check to make sure this is a "normal" archive. */ if (bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG)) { (void) close (desc); return -2; } } #else { #ifndef M_XENIX int buf; #else unsigned short int buf; #endif register int nread = read(desc, &buf, sizeof (buf)); if (nread != sizeof (buf) || buf != ARMAG) { (void) close (desc); return -2; } } #endif #endif /* Now find the members one by one. */ { #ifdef SARMAG register long int member_offset = SARMAG; #else #ifdef AIAMAG long int member_offset; long int last_member_offset; #ifdef AIAMAGBIG if ( big_archive ) { sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset); sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset); } else #endif { sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset); sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset); } if (member_offset == 0) { /* Empty archive. */ close (desc); return 0; } #else #ifndef M_XENIX register long int member_offset = sizeof (int); #else /* Xenix. */ register long int member_offset = sizeof (unsigned short int); #endif /* Not Xenix. */ #endif #endif while (1) { register int nread; struct ar_hdr member_header; #ifdef AIAMAGBIG struct ar_hdr_big member_header_big; #endif #ifdef AIAMAG char name[256]; int name_len; long int dateval; int uidval, gidval; long int data_offset; #else char namebuf[sizeof member_header.ar_name + 1]; char *name; int is_namemap; /* Nonzero if this entry maps long names. */ #endif long int eltsize; int eltmode; long int fnval; if (lseek (desc, member_offset, 0) < 0) { (void) close (desc); return -2; } #ifdef AIAMAG #define AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name)) #ifdef AIAMAGBIG if (big_archive) { nread = read (desc, (char *) &member_header_big, AR_MEMHDR_SZ(member_header_big) ); if (nread != AR_MEMHDR_SZ(member_header_big)) { (void) close (desc); return -2; } sscanf (member_header_big.ar_namlen, "%4d", &name_len); nread = read (desc, name, name_len); if (nread != name_len) { (void) close (desc); return -2; } name[name_len] = 0; sscanf (member_header_big.ar_date, "%12ld", &dateval); sscanf (member_header_big.ar_uid, "%12d", &uidval); sscanf (member_header_big.ar_gid, "%12d", &gidval); sscanf (member_header_big.ar_mode, "%12o", &eltmode); sscanf (member_header_big.ar_size, "%20ld", &eltsize); data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big) + name_len + 2); } else #endif { nread = read (desc, (char *) &member_header, AR_MEMHDR_SZ(member_header) ); if (nread != AR_MEMHDR_SZ(member_header)) { (void) close (desc); return -2; } sscanf (member_header.ar_namlen, "%4d", &name_len); nread = read (desc, name, name_len); if (nread != name_len) { (void) close (desc); return -2; } name[name_len] = 0; sscanf (member_header.ar_date, "%12ld", &dateval); sscanf (member_header.ar_uid, "%12d", &uidval); sscanf (member_header.ar_gid, "%12d", &gidval); sscanf (member_header.ar_mode, "%12o", &eltmode); sscanf (member_header.ar_size, "%12ld", &eltsize); data_offset = (member_offset + AR_MEMHDR_SZ(member_header) + name_len + 2); } data_offset += data_offset % 2; fnval = (*function) (desc, name, 0, member_offset, data_offset, eltsize, dateval, uidval, gidval, eltmode, arg); #else /* Not AIAMAG. */ nread = read (desc, (char *) &member_header, AR_HDR_SIZE); if (nread == 0) /* No data left means end of file; that is OK. */ break; if (nread != AR_HDR_SIZE #if defined(ARFMAG) || defined(ARFZMAG) || ( # ifdef ARFMAG bcmp (member_header.ar_fmag, ARFMAG, 2) # else 1 # endif && # ifdef ARFZMAG bcmp (member_header.ar_fmag, ARFZMAG, 2) # else 1 # endif ) #endif ) { (void) close (desc); return -2; } name = namebuf; bcopy (member_header.ar_name, name, sizeof member_header.ar_name); { register char *p = name + sizeof member_header.ar_name; do *p = '\0'; while (p > name && *--p == ' '); #ifndef AIAMAG /* If the member name is "//" or "ARFILENAMES/" this may be a list of file name mappings. The maximum file name length supported by the standard archive format is 14 characters. This member will actually always be the first or second entry in the archive, but we don't check that. */ is_namemap = (!strcmp (name, "//") || !strcmp (name, "ARFILENAMES/")); #endif /* Not AIAMAG. */ /* On some systems, there is a slash after each member name. */ if (*p == '/') *p = '\0'; #ifndef AIAMAG /* If the member name starts with a space or a slash, this is an index into the file name mappings (used by GNU ar). Otherwise if the member name looks like #1/NUMBER the real member name appears in the element data (used by 4.4BSD). */ if (! is_namemap && (name[0] == ' ' || name[0] == '/') && namemap != 0) { name = namemap + atoi (name + 1); long_name = 1; } else if (name[0] == '#' && name[1] == '1' && name[2] == '/') { int namesize = atoi (name + 3); name = (char *) alloca (namesize + 1); nread = read (desc, name, namesize); if (nread != namesize) { close (desc); return -2; } name[namesize] = '\0'; long_name = 1; } #endif /* Not AIAMAG. */ } #ifndef M_XENIX sscanf (member_header.ar_mode, "%o", &eltmode); eltsize = atol (member_header.ar_size); #else /* Xenix. */ eltmode = (unsigned short int) member_header.ar_mode; eltsize = member_header.ar_size; #endif /* Not Xenix. */ fnval = (*function) (desc, name, ! long_name, member_offset, member_offset + AR_HDR_SIZE, eltsize, #ifndef M_XENIX atol (member_header.ar_date), atoi (member_header.ar_uid), atoi (member_header.ar_gid), #else /* Xenix. */ member_header.ar_date, member_header.ar_uid, member_header.ar_gid, #endif /* Not Xenix. */ eltmode, arg); #endif /* AIAMAG. */ if (fnval) { (void) close (desc); return fnval; } #ifdef AIAMAG if (member_offset == last_member_offset) /* End of the chain. */ break; #ifdef AIAMAGBIG if (big_archive) sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset); else #endif sscanf (member_header.ar_nxtmem, "%12ld", &member_offset); if (lseek (desc, member_offset, 0) != member_offset) { (void) close (desc); return -2; } #else /* If this member maps archive names, we must read it in. The name map will always precede any members whose names must be mapped. */ if (is_namemap) { char *clear; char *limit; namemap = (char *) alloca (eltsize); nread = read (desc, namemap, eltsize); if (nread != eltsize) { (void) close (desc); return -2; } /* The names are separated by newlines. Some formats have a trailing slash. Null terminate the strings for convenience. */ limit = namemap + eltsize; for (clear = namemap; clear < limit; clear++) { if (*clear == '\n') { *clear = '\0'; if (clear[-1] == '/') clear[-1] = '\0'; } } is_namemap = 0; } member_offset += AR_HDR_SIZE + eltsize; if (member_offset % 2 != 0) member_offset++; #endif } } close (desc); return 0; } #endif /* !VMS */ /* Return nonzero iff NAME matches MEM. If TRUNCATED is nonzero, MEM may be truncated to sizeof (struct ar_hdr.ar_name) - 1. */ int ar_name_equal (name, mem, truncated) char *name, *mem; int truncated; { char *p; p = rindex (name, '/'); if (p != 0) name = p + 1; #ifndef VMS if (truncated) { #ifdef AIAMAG /* TRUNCATED should never be set on this system. */ abort (); #else struct ar_hdr hdr; #if !defined (__hpux) && !defined (cray) return strneq (name, mem, sizeof(hdr.ar_name) - 1); #else return strneq (name, mem, sizeof(hdr.ar_name) - 2); #endif /* !__hpux && !cray */ #endif /* !AIAMAG */ } #endif /* !VMS */ return !strcmp (name, mem); } #ifndef VMS /* ARGSUSED */ static long int ar_member_pos (desc, mem, truncated, hdrpos, datapos, size, date, uid, gid, mode, name) int desc; char *mem; int truncated; long int hdrpos, datapos, size, date; int uid, gid, mode; char *name; { if (!ar_name_equal (name, mem, truncated)) return 0; return hdrpos; } /* Set date of member MEMNAME in archive ARNAME to current time. Returns 0 if successful, -1 if file ARNAME does not exist, -2 if not a valid archive, -3 if other random system call error (including file read-only), 1 if valid but member MEMNAME does not exist. */ int ar_member_touch (arname, memname) char *arname, *memname; { register long int pos = ar_scan (arname, ar_member_pos, (long int) memname); register int fd; struct ar_hdr ar_hdr; register int i; struct stat statbuf; if (pos < 0) return (int) pos; if (!pos) return 1; fd = open (arname, O_RDWR, 0666); if (fd < 0) return -3; /* Read in this member's header */ if (lseek (fd, pos, 0) < 0) goto lose; if (AR_HDR_SIZE != read (fd, (char *) &ar_hdr, AR_HDR_SIZE)) goto lose; /* Write back the header, thus touching the archive file. */ if (lseek (fd, pos, 0) < 0) goto lose; if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) goto lose; /* The file's mtime is the time we we want. */ while (fstat (fd, &statbuf) < 0 && EINTR_SET) ; #if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32) /* Advance member's time to that time */ for (i = 0; i < sizeof ar_hdr.ar_date; i++) ar_hdr.ar_date[i] = ' '; sprintf (ar_hdr.ar_date, "%ld", (long int) statbuf.st_mtime); #ifdef AIAMAG ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' '; #endif #else ar_hdr.ar_date = statbuf.st_mtime; #endif /* Write back this member's header */ if (lseek (fd, pos, 0) < 0) goto lose; if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) goto lose; close (fd); return 0; lose: i = errno; close (fd); errno = i; return -3; } #endif #ifdef TEST long int describe_member (desc, name, truncated, hdrpos, datapos, size, date, uid, gid, mode) int desc; char *name; int truncated; long int hdrpos, datapos, size, date; int uid, gid, mode; { extern char *ctime (); printf (_("Member `%s'%s: %ld bytes at %ld (%ld).\n"), name, truncated ? _(" (name might be truncated)") : "", size, hdrpos, datapos); printf (_(" Date %s"), ctime (&date)); printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode); return 0; } main (argc, argv) int argc; char **argv; { ar_scan (argv[1], describe_member); return 0; } #endif /* TEST. */ #endif /* NO_ARCHIVES. */ *[MAKE-3_78_1HB]AUTHORS.;1+,`./@ 4-`0123KPWO56J 7/m89G@HJ----------------------------------- GNU make development up to version 3.75 by: Roland McGrath Development starting with GNU make 3.76 by: Paul D. Smith GNU Make User's Manual Written by: Richard M. Stallman Edited by: Roland McGrath Bob Chassell Melissa Weisshaus Paul D. Smith ----------------------------------- GNU make porting efforts: Port to VMS by: Klaus Kaempf Archive support/Bug fixes by: John W. Eaton Martin Zinser Port to Amiga by: Aaron Digulla Port to MS-DOS (DJGPP) and MS-Windows 95/NT by: DJ Delorie Rob Tulloh Eli Zaretskii ----------------------------------- Other contributors: Janet Carson Howard Chu Paul Eggert Klaus Heinz Michael Joosten Jim Kelton David Lubbren Tim Magill Han-Wen Nienhuys Andreas Schwab Carl Staelin (Princeton University) Ian Stewartson (Data Logic Limited) With suggestions/comments/bug reports from a cast of ... well ... hundreds, anyway :) *[MAKE-3_78_1HB]BUILD_SH.IN;1+,`./@ 4-`0 123KPWO 567m89G@HJ #!/bin/sh # Shell script to build GNU Make in the absence of any `make' program. # @configure_input@ # Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc. # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Make is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # See Makefile.in for comments describing these variables. srcdir='@srcdir@' CC='@CC@' CFLAGS='@CFLAGS@' CPPFLAGS='@CPPFLAGS@' LDFLAGS='@LDFLAGS@' defines='@DEFS@ -DLIBDIR="${libdir}" -DINCLUDEDIR="${includedir}"' ALLOCA='@ALLOCA@' LOADLIBES='@LIBS@' extras='@LIBOBJS@' REMOTE='@REMOTE@' GLOBLIB='@GLOBLIB@' # Common prefix for machine-independent installed files. prefix='@prefix@' # Common prefix for machine-dependent installed files. exec_prefix='@exec_prefix@' # Directory to find libraries in for `-lXXX'. libdir=${exec_prefix}/lib # Directory to search by default for included makefiles. includedir=${prefix}/include # Exit as soon as any command fails. set -e # These are all the objects we need to link together. objs="main.o commands.o job.o dir.o file.o misc.o read.o remake.o rule.o implicit.o default.o variable.o expand.o function.o vpath.o version.o ar.o arscan.o signame.o getopt.o getopt1.o remote-${REMOTE}.o ${extras} ${ALLOCA}" if [ x"$GLOBLIB" != x ]; then objs="$objs glob/fnmatch.o glob/glob.o" fi # Compile the source files into those objects. for file in `echo ${objs} | sed 's/\.o/.c/g'`; do echo compiling ${file}... $CC $defines $CPPFLAGS $CFLAGS \ -c -I. -I${srcdir} ${srcdir}/$file done # The object files were actually all put in the current directory. # Remove the source directory names from the list. srcobjs="$objs" objs= for obj in $srcobjs; do objs="$objs `basename $obj`" done # Link all the objects together. echo linking make... $CC $LDFLAGS $objs $LOADLIBES -o make.new echo done mv -f make.new make *[MAKE-3_78_1HB]BUILD_W32.BAT;1+,`. /@ 4 -`0123KPWO!56 7 ̪m89G@HJset make=gnumake cd w32\subproc echo "Creating the subproc library" %ComSpec% /c build.bat cd ..\.. del link.dbg link.rel del config.h copy config.h.W32 config.h echo off echo "Creating GNU make for Windows 95/NT" echo on if not exist .\WinDebug\nul mkdir .\WinDebug cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c echo WinDebug\variable.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c rule.c echo WinDebug\rule.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remote-stub.c echo WinDebug\remote-stub.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c commands.c echo WinDebug\commands.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c file.c echo WinDebug\file.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getloadavg.c echo WinDebug\getloadavg.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c default.c echo WinDebug\default.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c signame.c echo WinDebug\signame.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c expand.c echo WinDebug\expand.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c dir.c echo WinDebug\dir.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c main.c echo WinDebug\main.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt1.c echo WinDebug\getopt1.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /F~MAKE-3_78_1HB.BCK``[MAKE-3_78_1HB]BUILD_W32.BAT;1 MX2d.\WinDebug/%make%.pdb /c job.c echo WinDebug\job.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c echo WinDebug\read.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c echo WinDebug\version.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt.c echo WinDebug\getopt.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c arscan.c echo WinDebug\arscan.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remake.c echo WinDebug\remake.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c misc.c echo WinDebug\misc.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c ar.c echo WinDebug\ar.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c function.c echo WinDebug\function.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c vpath.c echo WinDebug\vpath.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c echo WinDebug\implicit.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c echo WinDebug\dirent.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c echo WinDebug\glob.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c echo WinDebug\fnmatch.obj >>link.dbg cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\pathstuff.c echo WinDebug\pathstuff.obj >>link.dbg echo off echo "Linking WinDebug/%make%.exe" rem link.exe kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /MACHINE:I386 /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj echo kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib >>link.dbg link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /MACHINE:I386 /OUT:.\WinDebug/%make%.exe @link.dbg if not exist .\WinDebug/%make%.exe echo "WinDebug build failed" if exist .\WinDebug/%make%.exe echo "WinDebug build succeeded!" if not exist .\WinRel\nul mkdir .\WinRel echo on cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /D TIVOLI /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c variable.c echo WinRel\variable.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c rule.c echo WinRel\rule.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remote-stub.c echo WinRel\remote-stub.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c commands.c echo WinRel\commands.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c file.c echo WinRel\file.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getloadavg.c echo WinRel\getloadavg.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c default.c echo WinRel\default.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c signame.c echo WinRel\signame.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c expand.c echo WinRel\expand.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c dir.c echo WinRel\dir.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c main.c echo WinRel\main.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt1.c echo WinRel\getopt1.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c echo WinRel\job.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c echo WinRel\read.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c echo WinRel\version.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt.c echo WinRel\getopt.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c arscan.c echo WinRel\arscan.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remake.c echo WinRel\remake.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c misc.c echo WinRel\misc.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c ar.c echo WinRel\ar.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c function.c echo WinRel\function.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c vpath.c echo WinRel\vpath.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c echo WinRel\implicit.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c echo WinRel\dirent.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c echo WinRel\glob.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c echo WinRel\fnmatch.obj >>link.rel cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\pathstuff.c echo WinRel\pathstuff.obj >>link.rel echo off echo "Linking WinRel/%make%.exe" rem link.exe kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj echo kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib >>link.rel link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe @link.rel if not exist .\WinRel/%make%.exe echo "WinRel build failed" if exist .\WinRel/%make%.exe echo "WinRel build succeeded!" echo on *[MAKE-3_78_1HB]CHANGELOG.;1+,`./@ 4-`0123KPWO56s7dm89G@HJ81999-09-23 Paul D. Smith * Version 3.78.1 released. * make.texinfo: Update version/date stamp. * main.c (main): Argh. For some reason we were closing _all_ the jobserver pipes before we re-exec'd due to changed makefiles. This means that any re-exec got a "jobserver unavailable" error :-/. I can't believe we didn't notice this before. 1999-09-22 Paul D. Smith * Version 3.78 released. * main.c (main): Only fail on multiple --jobserver-fds options if they aren't all the same. Some makefiles use things like $(MAKE) $(MFLAGS) which will cause multiple, identical copies of --jobserver-fds to show up. 1999-09-16 Paul D. Smith * main.c (define_makeflags): Zero out FLAGSTRING to avoid uninitialized memory reads when checking *p != '-' in the loop. 1999-09-15 Paul D. Smith * Version 3.77.97 released. * configure.in (MAKE_HOST): AC_SUBST this so it will go into the makefile. * Makefile.am (check-local): Print a success banner if the check succeeds. (check-regression): A bit of fine-tuning. 1999-09-15 Eli Zaretskii * README.DOS.template: Document requirements for the test suite. * Makefile.DOS.template: Updates to allow the test suite to run from "make check". * main.c (main): Handle it if argv[0] isn't an absolute path. 1999-09-13 Paul D. Smith * Version 3.77.96 released. * Makefile.am (loadavg): Use CPPFLAGS, etc. to make sure we get all the right #defines to compile. (check-regression): Look for the regression test suite in the make package itself. If we're building remotely, use symlinks to make a local copy. (dist-hook): Put the test suite into the tar file. * configure.in: Look for perl for the test suite. 1999-09-10 Paul Eggert * acinclude.m4 (AC_SYS_LARGEFILE_FLAGS): If on HP-UX 10.20 or later, and using GCC, define __STDC_EXT__; this works around a bug in GCC 2.95.1. 1999-09-08 Paul D. Smith * main.c (print_version): Ugh. GLIBC's configure tries to check make version strings and is too aggressive with their matching expressions. I've struck a deal with them to leave the version output as-is for 3.78, and they'll change their configure checks so that I can change this back in the future. 1999-09-07 Eli Zaretskii * job.c (construct_command_argv_internal) [__MSDOS__]: Add "echo" and "unset" to the list of builtin shell commands. * configh.DOS.template (MAKE_HOST): Define to "i386-pc-msdosdjgpp" which is the canonical name of the DJGPP host. 1999-09-05 Paul D. Smith * Version 3.77.95 released. * make.texinfo (Make Errors): Document some new jobserver error messages. 1999-09-04 Eli Zaretskii * make.texinfo (Make Errors): Document the hint about 8 spaces instead of a TAB. (Call Function, Quick Reference): Use @code{$(1)}, not @var. * main.c (main) [__MSDOS__]: Say "on this platform" instead of "on MS-DOS", since the MSDOS version could run on Windows. 1999-09-03 Paul D. Smith * remake.c (notice_finished_file): Always set mtime_before_update if it's not been set, not just if we ran some rules. Otherwise we may have a situation where a target's prerequisite was rebuilt but not changed, so this target's rules weren't run, then update_goal_chain() sees mtime_before_update != last_mtime and thinks that the top-level target changed when it really didn't. This can cause an infinite loop when remaking makefiles. (update_goal_chain): If we get back to the top and we don't know what the goal's last_mtime was, find it now. We need to know so we can compare it to mtime_before_update later (this is only crucial when remaking makefiles--should we only do it then?) 1999-09-02 Paul D. Smith * read.c (read_makefile): If "override" appears as the first prerequisite, look further to ensure this is really a target-specific variable definition, and not just some prerequisite named "override". 1999-09-01 Paul D. Smith * function.c (IS_PATHSEP) [WINDOWS32]: Allow backslash separators for W32 platforms. * read.c (record_files) [WINDOWS32]: Allow backslash separators for W32 platforms. * implicit.c (pattern_search) [WINDOWS32]: Allow backslash separators for W32 platforms. * configure.in (MAKE_HOST): Define it to be the canonical build host info, now that we need AC_CANONICAL_HOST anyway (for large file support). * version.c (make_host): Define a variable to MAKE_HOST so we're sure to get it from the local config.h. * main.c (print_version): Use it in the version information. * config.ami.template: Add MAKE_HOST. * configh.dos.template: Ditto. * config.h.W32.template: Ditto. * config.h-vms.template: Ditto. * main.c (main): Close the jobserver file descriptors if we need to re-exec ourselves. Also print more reasonable error if users force -jN for submakes. This may be common for a while until people use the jobserver feature. If it happens, we ignore the existing jobserver stuff and use whatever they specified on the commandline. (define_makeflags): Fixed a long-standing bug: if a long name only option comes immediately after a single letter option with no argument, then the option string is constructed incorrectly. For example, with -w and --jobserver-fds you get "-w-jobserver-fds..." instead of "-w --jobserver-fds..."; add in an extra " -". * make.texinfo (Phony Targets): Add another example of using .PHONY with subdirectories/recursive make. 1999-08-30 Paul D. Smith * README.W32.template: Renamed from README.W32 so it's autogenerated during the dist. A few minor modifications. * configure.in: Check for kstat_open before AC_FUNC_GETLOADAVG since the latter needs to know whether the former exists to give an accurate result. 1999-08-26 Rob Tulloh * NMakefile [WINDOWS32]: Now more robust. If you change a file under w32/subproc, the make.exe will be relinked. Also added some tests to make sure erase commands won't fail when executed in a pristine build environment. * w32/subproc/sub_proc.c [WINDOWS32]: Added support for HAVE_CYGWIN_SHELL. If you are using the Cygwin B20.1 release, it is now possible to have have native support for this shell without having to rely on klutzy BATCH_MODE_ONLY_SHELL. * config.h.W32 [WINDOWS32]: Added HAVE_CYGWIN_SHELL macro which users can define if they want to build make to use this shell. * README.W32 [WINDOWS32]: Added informaton about HAVE_CYGWIN_SHELL. Cleaned up text a bit to make it more current. 1999-08-26 Paul Eggert Support large files in AIX, HP-UX, and IRIX. * acinclude.m4 (AC_LFS): Remove. Superseded by AC_SYS_LARGEFILE. (AC_SYS_LARGEFILE_FLAGS, AC_SYS_LARGEFILE_SPACE_APPEND, AC_SYS_LARGEFILE_MACRO_VALUE, AC_SYS_LARGEFILE): New macros. (jm_AC_TYPE_UINTMAX_T): Check for busted compilers that can't shift or divide unsigned long long. (AM_PROG_CC_STDC): New macro; a temporary workaround of a bug in automake 1.4. * configure.in (AC_CANONICAL_HOST): Add; required by new AC_SYS_LARGEFILE. (AC_SYS_LARGEFILE): Renamed from AC_LFS. (AM_PROG_CC_STDC): Add. * config.guess, config.sub: New files, needed for AC_CANONICAL_HOST. 1999-08-25 Paul Eggert * make.h (CHAR_MAX): New macro. * main.c (struct command_switch): c is now int, so that it can store values greater than CHAR_MAX. (switches): Replace small numbers N with CHAR_MAX+N-1, to avoid problems with non-ASCII character sets. (short_option): New macro. (init_switches, print_usage, define_makeflags): Use it instead of isalnum. 1999-08-25 Paul D. Smith * Version 3.77.94 released. * main.c (main) [__MSDOS__]: If the user uses -j, warn that it's not supported and reset it. * make.h (ISDIGIT): Obtained this from the textutils distribution. * main.c (decode_switches): Use it. * function.c (is_numeric): Use it. * main.c (struct command_switch): Store the switch char in an unsigned char to shut up GCC about using it with ctype.h macros. Besides, it _is_ always unsigned. 1999-08-24 Paul D. Smith * make.texinfo: Change "dependency" to "prerequisite" and "dependencies" to "prerequisites". Various other cleanups related to the terminology change. * file.c: Change debugging and error messages to use "prerequisite" instead of "dependency". * implicit.c: Ditto. * remake.c: Ditto. * NEWS: Document it. 1999-08-23 Paul D. Smith * remake.c (update_file): Move the considered check into the double-colon rule loop, so we consider double-colon rules individually (otherwise after the first is pruned, the rest won't get run). * README.template: Minor changes. Remove the debugging features of the jobserver, so it no longer writes distinct tokens to the pipe. Thus, we don't need to store the token we get. A side effect of this is to remove a potential "unavailable token" situation: make-1 invokes make-2 with its special token and make-3 with a normal token; make-2 completes. Now we're waiting for make-3 but using 2 tokens; our special token is idle. In the new version we don't have special tokens per se, we merely decide if we already have a child or not. If we don't, we don't need a token. If we do, we have to get one to run the next child. Similar for putting tokens back: if we're cleaning up the last child, we don't put a token back. Otherwise, we do. * main.c: Add a new, internal flag --jobserver-fds instead of overloading the meaning of -j. Remove job_slots_str and add the stringlist jobserver_fds. (struct command_switch): We don't need the int_string type. (switches[]): Add a new option for --jobserver-fds and remove conditions around -j. Make the description for the former 0 so it doesn't print during "make --help". (main): Rework jobserver parsing. If we got --jobserver-fds make sure it's valid. We only get one and job_slots must be 0. If we're the toplevel make (-jN without --jobserver-fds) create the pipe and write generic tokens. Create the stringlist struct for the submakes. Clean up the stringlist where necessary. (init_switches): Remove int_string handling. (print_usage): Don't print internal flags (description ptr is 0). (decode_switches): Remove int_string handling. (define_makeflags): Remove int_string handling. * job.c: Remove my_job_token flag and all references to the child->job_token field. (free_job_token): Remove this and merge it into free_child(). (reap_children): Rework the "reaped a child" logic slightly. Don't call defunct free_job_token anymore. Always call free_child, even if we're dying. (free_child): If we're not freeing the only child, put a token back in the pipe. Then, if we're dying, don't bother to free. (new_job): If we are using the jobserver, loop checking to see if a) there are no children or b) we get a token from the pipe. * job.h (struct child): Remove the job_token field. 1999-08-20 Paul D. Smith * variable.c (try_variable_definition): Allocate for variable expansion in f_append with a simple variable: if we're looking at target-specific variables we don't want to trash the buffer. Noticed by Reiner Beninga . 1999-08-16 Eli Zaretskii * main.c (main) [__MSDOS__]: Mirror any backslashes in argv[0], to avoid problems in shell commands that use backslashes as escape characters. 1999-08-16 Paul D. Smith * Version 3.77.93 released. 1999-08-13 Paul D. Smith Another jobserver algorithm change. We conveniently forgot that the blocking bit is shared by all users of the pipe, it's not a per-process setting. Since we have many make processes all sharing the pipe we can't use the blocking bit as a signal handler flag. Instead, we'll dup the pipe's read FD and have the SIGCHLD handler close the dup'd FD. This will cause the read() to fail with EBADF the next time we invoke it, so we know we need to reap children. We then re-dup and reap. * main.c (main): Define the job_rfd variable to hold the dup'd FD. Actually dup the read side of the pipe. Don't bother setting the blocking bit on the file descriptor. * make.h: Declare the job_rfd variable. * job.c (child_handler): If the dup'd jobserver pipe is open, close it and assign -1 to job_rfd to notify the main program that we got a SIGCHLD. (start_job_command): Close the dup'd FD before exec'ing children. Since we open and close this thing so often it doesn't seem worth it to use the close-on-exec bit. (new_job): Remove code for testing/setting the blocking bit. Instead of EAGAIN, test for EBADF. If the dup'd FD has been closed, re-dup it before we reap children. * function.c (func_shell): Be a little more accurate about the length of the error string to allocate. * expand.c (variable_expand_for_file): If there's no filenm info (say, from a builtin command) then reset reading_file to 0. 1999-08-09 Paul D. Smith * maintMakefile: Use g in sed (s///g) to replace >1 variable per line. * Makefile.DOS.template [__MSDOS__]: Fix mostlyclean-aminfo to remove the right files. 1999-08-01 Eli Zaretskii * function.c (msdos_openpipe) [__MSDOS__]: *Really* return a FILE ptr. 1999-08-01 Paul D. Smith New jobserver algorithm to avoid a possible hole where we could miss SIGCHLDs and get into a deadlock. The original algorithm was suggested by Roland McGrath with a nice refinement by Paul Eggert. Many thanks as well to Tim Magill and Howard Chu, who also provided many viable ideas and critiques. We all had a fun week dreaming up interesting ways to use and abuse UNIX syscalls :). Previously we could miss a SIGCHLD if it happened after we reaped the children but before we re-entered the blocking read. If this happened to all makes and/or all children, make would never wake up. We avoid this by having the SIGCHLD handler reset the blocking bit on the jobserver pipe read FD (normally read does block in this algorithm). Now if the handler is called between the time we reap and the time we read(), and there are no tokens available, the read will merely return with EAGAIN instead of blocking. * main.c (main): Set the blocking bit explicitly here. * job.c (child_handler): If we have a jobserver pipe, set the non-blocking bit for it. (start_waiting_job): Move the token stuff back to new_job; if we do it here then we're not controlling the number of remote jobs started! (new_job): Move the check for job slots to _after_ we've created a child structure. If the read returns without getting a token, set the blocking bit then try to reap_children. * make.h (EINTR_SET): Define to test errno if EINTR is available, or 0 otherwise. Just some code cleanup. * arscan.c (ar_member_touch): Use it. * function.c (func_shell): Use it. * job.c (reap_children): Use it. * remake.c (touch_file): Use it. 1999-07-28 Paul D. Smith * make.h: Define _() and N_() macros as passthrough to initiate NLS support. * : Add _()/N_() around translatable strings. 1999-07-27 Paul D. Smith * read.c: Make sure make.h comes before other headers. 1999-07-26 Paul D. Smith * make.texinfo (Quick Reference): Update with the new features. 1999-07-25 Eli Zaretskii * remake.c [__MSDOS__]: Don't include variables.h, it's already included. * function.c (msdos_openpipe) [__MSDOS__]: Return FILE ptr. (func_shell) [__MSDOS__]: Fix the argument list. * Makefile.DOS.template: Update from Makefile.in. * README.DOS.template: Configure command fixed. * configh.dos.template: Update to provide definitions for uintmax_!t, fd_set_size_t, and HAVE_SELECT. 1999-07-24 Paul D. Smith * Version 3.77.91 released. * configure.in: Changes to the boostrapping code: if build.sh.in doesn't exist configure spits an error and generates an empty build.sh file which causes make to be confused. * maintMakefile: Don't build README early. 1999-07-23 Paul D. Smith * job.c (my_job_token): This variable controls whether we've handed our personal token to a subprocess or not. Note we could probably infer this from the value of job_slots_used, but it's clearer to just keep it separately. Job_slots_used isn't really relevant when running the job server. (free_job_token): New function: free a job token. If we don't have one, no-op. If we have the personal token, reclaim it. If we have another token, write it back to the pipe. (reap_children): Call free_job_token. (free_child): Call free_job_token. (start_job_command): Remove duplicate test for '+' in the command. If we don't appear to be running a recursive make, close the jobserver filedescriptors. (start_waiting_job): If our personal token is available, use that instead of going to the server pipe. (*): Add the token value to many debugging statements, and print the child target name in addition to the ptr hex value. Change the default "no token" value from '\0' to '-' so it looks better in the output. * main.c (main): Install the child_handler with sigaction() instead of signal() if we have it. On SysV systems, signal() uses SysV semantics which are a pain. But sigaction() always does what we want. (main): If we got job server FDs from the environment, test them to see if they're open. If not, the parent make closed them because it didn't think we were a submake. Print a warning and suggestion to use "+" on the submake invocation, and hard-set to -j1 for this instance of make. (main): Change the algorithm for assigning slots to be more robust. Previously make checked to see if it thought a subprocess was a submak~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;11%e and if so, didn't give it a token. Since make's don't consume tokens we could spawn many of makes fighting for a small number of tokens. Plus this is unreliable because submakes might not be recognized by the parent (see above) then all the tokens could be used up by unrecognized makes, and no one could run. Now every make consumes a token from its parent. However, the make can also use this token to spawn a child. If the make wants more than one, it goes to the jobserver pipe. Thus there will never be more than N makes running for -jN, and N*2 processes (N makes and their N children). Every make can always run at least one job, and we'll never deadlock. (Note the closing of the pipe for non-submakes also solves this, but this is still a better algorithm.) So! Only put N-1 tokens into the pipe, since the topmost make keeps one for itself. * configure.in: Find sigaction. Disable job server support unless the system provides it, in addition to either waitpid() or wait3(). 1999-07-22 Rob Tulloh * arscan.c (ar_member_touch) [WINDOWS32]: The ar_date field is a string on Windows, not a timestamp. 1999-07-21 Paul D. Smith * Version 3.77.90 released. * Makefile.am (AUTOMAKE_OPTIONS): Require automake 1.4. * function.c: Rearrange so we don't need to predeclare the function_table array; K&R C compilers don't like that. * acinclude.m4 (AC_FUNC_SELECT): Ouch; this requires an ANSI C compiler! Change to work with K&R compilers as well. * configure.in (AC_OUTPUT): Put build.sh back. I don't know how I thought it would work this way :-/. We'll have to think of something else. * Makefile.am: Remove rule to create build.sh. * default.c (default_suffix_rules): Rearrange the default command lines to conform to POSIX rules (put the filename argument $< _after_ the OUTPUT_OPTION, not before it). * various: Changed !strncmp() calls to strneq() macros. * misc.c (sindex): Make slightly more efficient. * dir.c (file_impossible)): Change savestring(X,strlen(X)) to xstrdup(). * implicit.c (pattern_search): Ditto. * main.c (enter_command_line_file): Ditto. (main): Ditto. * misc.c (copy_dep_chain): Ditto. * read.c (read_makefile): Ditto. (parse_file_seq): Ditto. (tilde_expand): Ditto. (multi_glob): Ditto. * rule.c (install_pattern_rule): Ditto. * variable.c (define_variable_in_set): Ditto. (define_automatic_variables): Ditto. * vpath.c (construct_vpath_list): Ditto. * misc.c (xrealloc): Some reallocs are non-standard: work around them in xrealloc by calling malloc if PTR is NULL. * main.c (main): Call xrealloc() directly instead of testing for NULL. * function.c (func_sort): Don't try to free NULL; some older, non-standard versions of free() don't like it. * configure.in (--enable-dmalloc): Install some support for using dmalloc (http://www.dmalloc.com/) with make. Use --enable-dmalloc with configure to enable it. * function.c (function_table_entry): Whoops! The function.c rewrite breaks backward compatibility: all text to a function is broken into arguments, and extras are ignored. So $(sort a,b,c) returns "a"! Etc. Ouch. Fix it by making a positive value in the REQUIRED_ARGS field mean exactly that many arguments to the function; any "extras" are considered part of the last argument as before. A negative value means at least that many, but may be more: in this case all text is broken on commas. (handle_function): Stop when we've seen REQUIRED_ARGS args, if >0. (expand_builtin_function): Compare number of args to the absolute value of REQUIRED_ARGS. 1999-07-20 Paul D. Smith * job.c (start_job_command): Ensure that the state of the target is cs_running. It might not be if we skipped all the lines due to -n (for example). * commands.c (execute_file_commands): If we discover that the command script is empty and succeed early, set cs_running so the modtime of the target is still rechecked. * rule.c (freerule): Free the dependency list for the rule. * implicit.c (pattern_search): When turning an intermediate file into a real target, keep the also_make list. Free the dep->name if we didn't use it during enter_file(). 1999-07-16 Paul D. Smith * read.c (read_makefile): Don't allocate the commands buffer until we're sure we found a makefile and won't return early (mem leak). * job.c (start_job_command): Broken #ifdef test: look for F_SETFD, not FD_SETFD. Close-on-exec isn't getting set on the bad_stdin file descriptor and it's leaking :-/. * getloadavg.c (getloadavg): Ditto. 1999-07-15 Paul D. Smith * read.c (read_makefile): Fix some potential memory stomps parsing `define' directives where no variable name is given. * function.c (func_call): Rename from func_apply. Various code cleanup and tightening. (function_table): Add "call" as a valid builtin function. * make.texinfo (Call Function): Document it. * NEWS: Announce it. 1999-07-09 Eli Zaretskii * variable.c (try_variable_definition) [__MSDOS__, WINDOWS32]: Treat "override SHELL=" the same as just "SHELL=". 1999-07-09 Paul D. Smith * job.c (start_waiting_job): Don't get a second job token if we already have one; if we're waiting on the load to go down start_waiting_job() might get called twice on the same file. * filedef.h (struct file): Add new field, mtime_before_update. When notice_finished_file runs it assigns the cached last_mtime to this field. * remake.c (update_goal_chain): Notice that a file wasn't updated by asking if it changed (g->changed) and comparing the current cached time (last_mtime) with the previous one, stored in mtime_before_update. The previous check ("did last_mtime changed during the run of update_file?") fails for parallel builds because last_mtime is set during reap_children, before update_file is run. This causes update_goal_chain to always return -1 (nothing rebuilt) when running parallel (-jN). This is OK during "normal" builds since our caller (main) treats these cases idd1entically in that case, but if when rebuilding makefiles the difference is very important, as it controls whether we re-exec or not. * file.c (file_hash_enter): Copy the mtime_before_update field. (snap_deps): Initialize mtime_before_update to -1. * main.c (main): Initialize mtime_before_update on old (-o) and new (-W) files. 1999-07-08 Paul D. Smith * main.c (switches): Define a new switch -R (or --no-builtin-variables). This option disables the defining of all the GNU make builtin variables. (main): If -R was given, force -r as well. * default.c (define_default_variables): Test the new flag. * make.h: Declare global flag. * make.texinfo (Options Summary): Document the new option. (Implicit Variables): Ditto. 1999-07-06 Paul D. Smith * make.texinfo (Options Summary): Correct examples in --print-data-base option summary (problem reported by David Morse ). * arscan.c: Add support for archives in Windows (VC++). Frank Libbrecht provided info on how to do this. * NMakefile.template (CFLAGS_any): Remove NO_ARCHIVES from the compile line. * build_w32.bat: Ditto. * remake.c (no_rule_error): Fix -include/sinclude so it doesn't give errors if you try to -include the same file twice. (updating_makefiles): New variable: we need to know this info in no_rule_error() so we know whether to print an error or not. (update_file_1): Unconditionally call no_rule_error(), don't try to play games with the dontcare flag. 1999-06-14 Paul D. Smith * make.texinfo (Remaking Makefiles): Add a description of how to prevent implicit rule searches for makefiles. * make.1: Remove statement that make continues processing when -v is given. 1999-06-14 Paul D. Smith * read.c (read_makefile): Cast -1 arguments to variable_expand_string() to long. Alexandre Sauve reports that without casts, this breaks on a NEC SUPER-UX SX-4 system (and it's wrong without a cast anyway). Of course, (a) I'd really love to start using function prototypes, and (b) there's a whole slew of issues related to int vs. long and signed vs. unsigned in the length handling of variable buffers, etc. Gross. Needs a complete mucking-out. * expand.c (variable_expand): Ditto. * acinclude.m4 (AC_FUNC_SELECT): Slight enhancement for AIX 3.2 by Lars Hecking . * read.c (get_next_mword): Allow colons to be escaped in target names: fix for regression failure. 1999-04-26 Paul D. Smith * main.c (main): Reset read_makefiles to empty after processing so we get the right error message. 1999-04-25 Paul D. Smith * make.texinfo: Updates to @dircategory and @direntry suggested by Karl Berry . 1999-04-23 Eli Zaretskii * job.c (start_job_command) [__MSDOS__]: Call unblock_sigs before turning off dos_command_running, so child's signals produce the right effect. * commands.c (fatal_error_signal) [__MSDOS__]: Use EXIT_FAILURE instead of 1. 1999-04-18 Eli Zaretskii * configh.dos.template: Update to recognize that version 2.02 of DJGPP contains sys_siglist stuff. 1999-04-14 Paul D. Smith * make.texinfo (Options/Recursion): Document the job server. (Parallel): Tweaks. 1999-04-13 Paul D. Smith Implement a new "job server" feature; the implementation was suggested by Howard Chu . * configure.in (job-server): New disable option for job server support--it's enabled by default. If it works well this will go away. * NEWS: Summarize the new feature. * acconfig.h: New definition MAKE_JOBSERVER if job server support is enabled. * config.h-vms.template: Undef MAKE_JOBSERVER for this port. * config.h.W32.template: Ditto. * config.ami.template: Ditto. * main.c (struct command_switch): Add a new type: int_string. (switches[]) Use int_string for -j if MAKE_JOBSERVER. (init_switches): Initialize the new int_string switch type. (print_usage): New function, extracted from decode_switches(). (decode_switches): Call it. Decode the new int_string switch type. (define_makeflags): Add new int_string switch data to MAKEFLAGS. (job_fds[]) Array to contain the pipe file descriptors. (main): Parse the job_slots_str option results. If necessary, create the pipe and seed it with tokens. Set the non-blocking bit for the read fd. Enable the signal handler for SIGCHLD even if we have a non-hanging wait; it's needed to interrupt the select() in job.c:start_waiting_job(). * make.h: Declare job_fds[]. * job.h (struct child): Add job_token field to store the token for this job (if any). * job.c (reap_children): When a child is fully reaped, release the token back into the pipe. (free_child): If the child to be freed still has a token, put it back. (new_job): Initialize the job_token member. (start_waiting_job): For local jobs, if we're using the pipe, get a token before we check the load, etc. We do this by performing a non-blocking read in a loop. If the read fails, no token is available. Do a select on the fd to wait for a token. We need to re-enable the signal handler for SIGCHLD even if we have a non-hanging waitpid() or wait3(), so that the signal will interrupt the select() and we can wake up to reap children. (child_handler): Re-enable the signal handler. The count is still kept although it's not needed or used unless you don't have waitpid() or wait3(). 1999-04-10 Paul D. Smith * main.c (main): Reset the considered bit on all the makefiles if something failed to update; we need to examine them again if they appear as normal targets in order to get the proper error message. 1999-04-09 Paul D. Smith Performance enhancement from Tim Magill . * remake.c (update_file): If you have large numbers of dependencies and you run in parallel, make can spend considerable time each pass through the graph looking at branches it has already seen. Since we only reap_children() when starting a pass, not in the middle, if a branch has been seen already in that pass nothing interesting can happen until the next pass. So, we toggle a bit saying whether we've seen this target in this pass or not. (update_goal_chain): Initially set the global considered toggle to 1, since all targets initialize their boolean to 0. At the end of each pass, toggle the global considered variable. * filedef.h (struct file): Per-file considered toggle bit. * file.c: New global toggle variable considered. 1999-04-05 Paul D. Smith * arscan.c (ar_scan): Added support for ARFZMAG (compressed archives?) for Digital UNIX C++. Information provided by Patrick E. Krogel . (ar_member_touch): Ditto. 1999-04-03 Paul D. Smith * remake.c (f_mtime): If: a) we found a file and b) we didn't create it and c) it's not marked as an implicit target and d) it is marked as an intermediate target, then it was so marked due to an .INTERMEDIATE special target, but it already existed in the directory. In this case, unset the intermediate flag so we won't delete it when make is done. It feels like it would be cleaner to put this check in update_file_1() but I worry it'll get missed... 1999-04-01 Paul D. Smith * job.c (construct_command_argv_internal): Use bcopy() to copy overlapping strings, rather than strcpy(). ISO C says the latter is undefined. Found this in a bug report from 1996! Ouch! 1999-03-31 Paul D. Smith * read.c (readline): Ignore carriage returns at the end of the line, to allow Windows-y CRLF line terminators. 1999-03-30 Paul D. Smith * configure.in: Don't put build.sh here, since build.sh.in doesn't exist initially. This cause autoreconf and automake to fail when run on a clean CVS checkout. Instead, we create build.sh in the Makefile (see below). * Makefile.am: Remove BUILT_SOURCES; this is no longer relevant. Put those files directly into EXTRA_DIST so they're distributed. Create a local build rule to create build.sh. Create a local maintainer-clean rule to delete all the funky maintainers files. * maintMakefile: Makefile.in depends on README, since automake fails if it doesn't exist. Also don't remove glob/Makefile.in here, as it causes problems. 1999-03-26 Paul D. Smith * configure.in: Substitute GLOBLIB if we need the link the glob/libglob.a library. * Makefile.am (make_LDADD): Use the subst variable GLOBLIB so we don't link the local libglob.a at all if we don't need it. * build.template: Don't compile glob/*.o unless we want globlib. * maintMakefile (build.sh.in): Substitute the glob/*.o files separately. 1999-03-25 Paul D. Smith * make.texinfo: Various typos and additions, pointed out by James G. Sack . 1999-03-22 Paul D. Smith * make.texinfo (Functions): Add a new section documenting the new $(error ...) and $(warning ...) functions. Also updated copyright dates. * NEWS: Updated for the new functions. * function.c (func_error): Implement the new $(error ...) and $(warning ...) functions. (function_table): Insert new functions into the table. (func_firstword): Don't call find_next_token() with argv[0] itself, since that function modifies the pointer. * function.c: Cleanups and slight changes to the new method of calling functions. 1999-03-20 Han-Wen Nienhuys * function.c: Rewrite to use one C function per make function, instead of a huge switch statement. Also allows some cleanup of multi-architecture issues, and a cleaner API which makes things like func_apply() simple. * function.c (func_apply): Initial implementation. Expand either a builtin function or a make variable in the context of some arguments, provided as $1, $2, ... $N. 1999-03-19 Eli Zaretskii 1999-03-19 Rob Tulloh * job.c (construct_command_argv_internal): Don't treat _all_ backslashes as escapes, only those which really escape a special character. This allows most normal "\" directory separators to be treated normally. 1999-03-05 Paul D. Smith * configure.in: Check for a system strdup(). * misc.c (xstrdup): Created. Suggestion by Han-Wen Nienhuys . * make.h: Prototype xstrdup(). * remake.c (library_search): Use it. * main.c (main): Use it. (find_and_set_default_shell): Use it. * job.c (construct_command_argv_internal): Use it. * dir.c (find_directory): Use it. * Makefile.am, configure.in: Use AC_SUBST_FILE to insert the maintMakefile instead of "include", to avoid automake 1.4 incompatibility. 1999-03-04 Paul D. Smith * amiga.c, amiga.h, ar.c, arscan.c, commands.c, commands.h, * default.c, dep.h, dir.c, expand.c, file.c, filedef.h, function.c, * implicit.c, job.c, job.h, main.c, make.h, misc.c, read.c, remake.c * remote-cstms.c, remote-stub.c, rule.h, variable.c, variable.h, * vpath.c, Makefile.ami, NMakefile.template, build.template, * makefile.vms: Updated FSF address in the copyright notice. * variable.c (try_variable_definition): If we see a conditional variable and we decide to set it, re-type it as recursive so it will be expanded properly later. 1999-02-22 Paul D. Smith * NEWS: Mention new .LIBPATTERNS feature. * make.texinfo (Libraries/Search): Describe the use and ramifications of the new .LIBPATTERNS variable. * remake.c (library_search): Instead of searching only for the hardcoded expansion "libX.a" for a library reference "-lX", we obtain a list of patterns from the .LIBPATTERNS variable and search those in order. * default.c: Added a new default variable .LIBPATTERNS. The default for UNIX is "lib%.so lib%.a". Amiga and DOS values are also provided. * read.c: Remove bogus HAVE_GLOB_H references; always include vanilla glob.h. 1999-02-21 Paul D. Smith * function.c (expand_function): Set value to 0 to avoid freeing it. * variable.c (pop_variable_scope): Free the value of the variable. (try_variable_definition): For simple variables, use allocated_variable_expand() to avoid stomping on the variable buffer when we still need it for other things. * arscan.c: Modified to support AIX 4.3 big archives. The changes are based on information provided by Phil Adams . 1999-02-19 Paul D. Smith * configure.in: Check to see if the GNU glob library is already installed on the system. If so, _don't_ add -I./glob to the compile line. Using the system glob code with the local headers is very bad mojo! Rewrite SCCS macros to use more autoconf facilities. * Makefile.am: Move -Iglob out of INCLUDES; it'll get added to CPPFLAGS by configure now. Automake 1.4 introduced its own "include" feature which conflicts with the maintMakefile stuff. A hack that seems to work is add a space before the include :-/. * build.template: Move -Iglob out of the compile line; it'll get added to CPPFLAGS by configure now. 1999-02-16 Glenn D. Wolf * arscan.c (ar_scan) [VMS]: Initialized VMS_member_date before calling lbr$get_index since if the archive is empty, VMS_get_member_info won't get called at all, and any leftover date will be used. This bug shows up if any member of any archive is made, followed by a dependency check on a different, empty archive. 1998-12-13 Martin Zinser * config.h-vms [VMS]: Set _POSIX_C_SOURCE. Redefine the getopt functions so we don't use the broken VMS versions. * makefile.com [VMS]: Allow debugging. * dir.c (dir_setup_glob) [VMS]: Don't extern stat() on VMS. 1998-11-30 Paul D. Smith * signame.c (init_sig): Check the sizes of signals being set up to avoid array overwrites (if the system headers have problems). 1998-11-17 Paul D. Smith * read.c (record_files): Clean up some indentation. 1998-11-08 Han-Wen Nienhuys * rule.c (print_rule_data_base): Fix arguments to fatal() call. 1998-10-13 Paul D. Smith * job.c (start_job_command): If the command list resolves to no chars at all (e.g.: "foo:;$(empty)") then command_ptr is NULL; quit early. 1998-10-12 Andreas Schwab * rule.c (print_rule_data_base): Ignore num_pattern_rules if it is zero. 1998-10-09 Paul D. Smith * read.c (read_makefile): Allow non-empty lines to expand to the empty string after variable, etc., expansion, and be ignored. 1998-09-21 Paul D. Smith * job.c (construct_command_argv_internal): Only add COMMAND.COM "@echo off" line for non-UNIXy shells. 1998-09-09 Paul D. Smith * w32/subproc/sub_proc.c: Add in missing HAVE_MKS_SHELL tests. 1998-09-04 Paul D. Smith * read.c (read_makefile): If we hit the "missing separator" error, check for the common case of 8 spaces instead of a TAB and give an extra comment to help people out. 1998-08-29 Paul Eggert * configure.in (AC_STRUCT_ST_MTIM_NSEC): Renamed from AC_STRUCT_ST_MTIM. * acinclude.m4 (AC_STRUCT_ST_MTIM_NSEC): Likewise. Port to UnixWare 2.1.2 and pedantic Solaris 2.6. * acconfig.h (ST_MTIM_NSEC): Renamed from HAVE_ST_MTIM, with a new meaning. * filedef.h (FILE_TIMESTAMP_FROM_S_AND_NS): Use new ST_MTIM_NSEC macro. 1998-08-26 Paul D. Smith * remake.c (check_dep): For any intermediate file, not just secondary ones, try implicit and default rules if no explicit rules are given. I'm not sure why this was restricted to secondary rules in the first place. 1998-08-24 Paul D. Smith * make.texinfo (Special Targets): Update documentation for .INTERMEDIATE: if used with no dependencies, then it does nothing; old docs said it marked all targets as intermediate, which it didn't... and which would be silly :). * implicit.c (pattern_search): If we find a dependency in our internal tables, make sure it's not marked intermediate before accepting it as a found_file[]. 1998-08-20 Paul D. Smith * ar.c (ar_glob): Use existing alpha_compare() with qsort. (ar_glob_alphacompare): Remove it. Modify Paul Eggert's patch so we don't abandon older systems: * configure.in: Warn the user if neither waitpid() nor wait3() is available. * job.c (WAIT_NOHANG): Don't syntax error on ancient hosts. (child_handler, dead_children): Define these if WAIT_NOHANG is not available. (reap_children): Only track the dead_children count if no WAIT_NOHANG. Otherwise, it's a boolean. * main.c (main): Add back signal handler if no WAIT_NOHANG is available; only use default signal handler if it is. 1998-08-20 Paul Eggert Install a more robust signal handling mechanism for systems which support it. * job.c (WAIT_NOHANG): Define to a syntax error if our host is truly ancient; this should never happen. (child_handler, dead_children): Remove. (reap_children): Don't try to keep separate track of how many dead children we have, as this is too bug-prone. Just ask the OS instead. (vmsHandleChildTerm): Fix typo in error message; don't mention child_handler. * main.c (main): Make sure we're not ignoring SIGCHLD/SIGCLD; do this early, before we could possibly create a subprocess. Just use the default behavior; don't have our own handler. 1998-08-18 Eli Zaretskii * read.c (read_makefile) [__MSDOS__, WINDOWS32]: Add code to recognize library archive members when dealing with drive spec mess. Discovery and initial fix by George Racz . 1998-08-18 Paul D. Smith * configure.in: Check for stdlib.h explicitly (some hosts have it but don't have STDC_HEADERS). * make.h: Use HAVE_STDLIB_H. Clean up some #defines. * config.ami: Re-compute based on new config.h.in contents. * config.h-vms: Ditto. * config.h.W32: Ditto. * configh.dos: Ditto. * dir.c (find_directory) [WINDOWS32]: Windows stat() fails if directory names end with `\' so strip it. 1998-08-17 Paul D. Smith * make.texinfo: Added copyright year to the printed copy. Removed the price from the manual. Change the top-level reference to running make to be "Invoking make" instead of "make Invocation", to comply with GNU doc standards. * make.h (__format__, __printf__): Added support for these in __attribute__ macro. (message, error, fatal): Use ... prototype form under __STDC__. Add __format__ attributes for printf-style functions. * configure.in (AC_FUNC_VPRINTF): Check for vprintf()/_doprnt(). * misc.c (message, error, fatal): Add preprocessor stuff to enable creation of variable-argument functions with appropriate prototypes, that works with ANSI, pre-ANSI, varargs.h, stdarg.h, v*printf(), _doprnt(), or none of the above. Culled from GNU fileutils and slightly modified. (makefile_error, makefile_error): Removed (merged into error() and fatal(), respectively). * amiga.c: Use them. * ar.c: Use them. * arscan.c: Use them. * commands.c: Use them. * expand.c: Use them. * file.c: Use them. * function.c: Use them. * job.c: Use them. * main.c: Use them. * misc.c: Use them. * read.c: Use them. * remake.c: Use them. * remote-cstms.c: Use them. * rule.c: Use them. * variable.c: Use them. * make.h (struct floc): New structure to store file location information. * commands.h (struct commands): Use it. * variable.c (try_variable_definition): Use it. * commands.c: Use it. * default.c: Use it. * file.c: Use it. * function.c: Use it. * misc.c: Use it. * read.c: Use it. * rule.c: Use it. 1998-08-16 Paul Eggert * filedef.h (FILE_TIMESTAMP_PRINT_LEN_BOUND): Add 10, for nanoseconds. 1998-08-16 Paul Eggert * filedef.h (FLOOR_LOG2_SECONDS_PER_YEAR): New macro. (FILE_TIMESTAMP_PRINT_LEN_BOUND): Tighten bound, and try to make it easier to understand. 1998-08-14 Paul D. Smith * read.c (read_makefile): We've already unquoted any colon chars by the time we're done reading the targets, so arrange for parse_file_seq() on the target list to not do so again. 1998-08-05 Paul D. Smith * configure.in: Added glob/configure.in data. We'll have the glob code include the regular make config.h, rather than creating its own. * getloadavg.c (main): Change return type to int. 1998-08-01 Paul Eggert * job.c (reap_children): Ignore unknown children. 1998-07-31 Paul D. Smith * make.h, filedef.h, dep.h, rule.h, commands.h, remake.c: Add prototypes for functions. Some prototypes needed to be moved in order to get #include order reasonable. 1998-07-30 Paul D. Smith * make.h: Added MIN/MAX. * filedef.h: Use them; remove FILE_TIMESTAMP_MIN. 1998-07-30 Paul Eggert Add support for sub-second timestamp resolution on hosts that support it (just Solaris 2.6, so far). * acconfig.h (HAVE_ST_MTIM, uintmax_t): New undefs. * acinclude.m4 (jm_AC_HEADER_INTTYPES_H, AC_STRUCT_ST_MTIM, jm_AC_TYPE_UINTMAX_T): New defuns. * commands.c (delete_target): Convert file timestamp to seconds before comparing to archive timestamp. Extract mod time from struct stat using FILE_TIMESTAMP_STAT_MODTIME. * configure.in (C_STRUCT_ST_MTIM, jm_AC_TYPE_UINTMAX_T): Add. (AC_CHECK_LIB, AC_CHECK_FUNCS): Add clock_gettime. * file.c (snap_deps): Use FILE_TIMESTAMP, not time_t. (file_timestamp_now, file_timestamp_sprintf): New functions. (print_file): Print file timestamps as FILE_TIMESTAMP, not time_t. * filedef.h: Include if available and if HAVE_ST_MTIM. (FILE_TIMESTAMP, FILE_TIMESTAMP_STAT_MODTIME, FILE_TIMESTAMP_MIN, FILE_TIMESTAMPS_PER_S, FILE_TIMESTAMP_FROM_S_AND_NS, FILE_TIMESTAMP_DIV, FILE_TIMESTAMP_MOD, FILE_TIMESTAMP_S, FILE_TIMESTAMP_NS, FILE_TIMESTAMP_PRINT_LEN_BOUND): New macros. (file_timestamp_now, file_timestamp_sprintf): New decls. (struct file.last_mtime, f_mtime, file_mtime_1, NEW_MTIME): time_t -> FILE_TIMESTAMP. * implicit.c (pattern_search): Likewise. * vpath.c (vpath_search, selective_vpath_search): Likewise. * main.c (main): Likewise. * remake.c (check_dep, name_mtime, library_search, f_mtime): Likewise. (f_mtime): Use file_timestamp_now instead of `time'. Print file timestamp with file_timestamp_sprintf. * vpath.c (selective_vpath_search): Extract file time stamp from struct stat with FILE_TIMESTAMP_STAT_MODTIME. 1998-07-28 Paul D. Smith * Version 3.77 released. * dosbuild.bat: Change to DOS CRLF line terminators. * make-stds.texi: Update from latest version. * make.texinfo (Options Summary): Clarify that the -r option affects only rules, not builtin variables. 1998-07-27 Paul D. Smith * make.h: Make __attribute__ resolve to empty for non-GCC _and_ for GCC pre-2.5.x. * misc.c (log_access): Print UID/GID's as unsigned long int for maximum portability. * job.c (reap_children): Print PIDs as long int for maximum portability. 1998-07-24 Eli Zaretskii * Makefile.DOS (*_INSTALL, *_UNINSTALL): Replace `true' with `:'. 1998-07-25 Paul D. Smith * Version 3.76.94 released. 1998-07-23 Paul D. Smith * config.h.W32.template: Make sure all the #defines of macros here have a value (e.g., use ``#define HAVE_STRING_H 1'' instead of just ``#define HAVE_STRING_H''. Keeps the preprocessor happy in some contexts. * make.h: Remove __attribute__((format...)) stuff; using it with un-prototyped functions causes older GCC's to fail. * Version 3.76.93 released. 1998-07-22 Paul D. Smith * file.c (print_file_data_base): Fix average calculation. 1998-07-20 Paul D. Smith * main.c (die): Postpone the chdir() until after remove_intermediates() so that intermediate targets with relative pathnames are removed properly. 1998-07-17 Paul D. Smith * filedef.h (struct file): New flag: did we print an error or not? * remake.c (no_rule_error): New function to print error messages, extraced from remake_file(). * remake.c (remake_file): Invoke the new error print function. (update_file_1): Invoke the error print function if we see that we already tried this target and it failed, but that an error wasn't printed for it. This can happen if a file is included with -include or sinclude and couldn't be built, then later is also the dependency of another target. Without this change, make just silently stops :-/. 1998-07-16 Paul D. Smith * make.texinfo: Removed "beta" version designator. Updated ISBN for the next printing. 1998-07-13 Paul Eggert * acinclude.m4: New AC_LFS macro to determine if special compiler flags are needed to allow access to large files (e.g., Solaris 2.6). * configure.in: Invoke it. 1998-07-08 Eli Zaretskii * Makefile.DO~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;1o|cS: track changes in Makefile.in. 1998-07-07 Paul D. Smith * remote-cstms.c (start_remote_job): Move gethostbyaddr() to the top so host is initialized early enough. * acinclude.m4: New file. Need some special autoconf macros to check for network libraries (-lsocket, -lnsl, etc.) when configuring Customs. * configure.in (make_try_customs): Invoke new network libs macro. 1998-07-06 Paul D. Smith * Version 3.76.92 released. * README.customs: Added to the distribution. * configure.in (make_try_customs): Rewrite to require an installed Customs library, rather than looking at the build directory. * Makefile.am (man_MANS): Install make.1. * make.1: Renamed from make.man. * make.texinfo (Bugs): New mailing list address for GNU make bug reports. 1998-07-02 Paul D. Smith * Version 3.76.91 released. * default.c: Added default rule for new-style RCS master file storage; ``% :: RCS/%''. Added default rules for DOS-style C++ files with suffix ".cpp". They use the new LINK.cpp and COMPILE.cpp macros, which are set by default to be equal to LINK.cc and COMPILE.cc. 1998-06-19 Eli Zaretskii * job.c (start_job_command): Reset execute_by_shell after an empty command was skipped. 1998-06-09 Paul D. Smith * main.c (main): Keep track of the temporary filename created when reading a makefile from stdin (-f-) and attempt to remove it as soon as we know we're not going to re-exec. If we are, add it to the exec'd make's cmd line with "-o" so the exec'd make doesn't try to rebuild it. We still have a hole: if make re-execs then the temporary file will never be removed. To fix this we'd need a brand new option that meant "really delete this". * AUTHORS, getopt.c, getopt1.c, getopt.h, main.c (print_version): Updated mailing addresses. 1998-06-08 Paul D. Smith * main.c (main): Andreas Luik points out that the check for makefile :: rules with commands but no dependencies causing a loop terminates incorrectly. * maintMakefile: Make a template for README.DOS to update version numbers. 1998-05-30 Andreas Schwab * remake.c (update_file_1): Don't free the memory for the dependency structure when dropping a circular dependency. 1998-05-30 Eli Zaretskii * dir.c (file_exists_p, file_impossible_p, file_impossible) [__MSDOS__, WINDOWS32]: Retain trailing slash in "d:/", and make dirname of "d:foo" be "d:". 1998-05-26 Andreas Schwab * read.c (read_makefile): Avoid running past EOS when scanning file name after `include'. 1998-05-26 Andreas Schwab * make.texinfo (Flavors): Correct description of conditional assignment, which is not equivalent to ifndef. (Setting): Likewise. 1998-05-24 Paul D. Smith * arscan.c (ar_name_equal): strncmp() might be implemented as a macro, so don't put preprocessor conditions inside the arguments list. 1998-05-23 Eli Zaretskii * read.c (read_makefile) [__MSDOS__, WINDOWS32]: Skip colons in drive specs when parsing targets, target-specific variables and static pattern rules. A colon can only be part of drive spec if it is after the first letter in a token. 1998-05-22 Eli Zaretskii * remake.c (f_mtime) [__MSDOS__]: Allow up to 3 sec of skew before yelling bloody murder. * dosbuild.bat: Use -DINCLUDEDIR= and -DLIBDIR= where appropriate. * read.c (parse_file_seq): Combine the special file-handling code for WINDOWS32 and __MSDOS__ into a single snippet. (get_next_mword) [__MSDOS__, WINDOWS32]: Allow a word to include a colon as part of a drive spec. * job.c (batch_mode_shell) [__MSDOS__]: Declare. 1998-05-20 Paul D. Smith * Version 3.76.90 released. 1998-05-19 Paul D. Smith * make.texinfo (Make Errors): Added a new appendix describing common errors make might generate and how to resolve them (or at least more information on what they mean). * maintMakefile (NMAKEFILES): Use the new automake 1.3 feature to create a dependency file to construct Makefile.DOS, SMakefile, and NMakefile. (.dep_segment): Generate the dependency fragment file. 1998-05-14 Paul D. Smith * make.man: Minor changes. 1998-05-13 Paul D. Smith * function.c (pattern_matches,expand_function): Change variables and types named "word" to something else, to avoid compilation problems on Cray C90 Unicos. * variable.h: Modify the function prototype. 1998-05-11 Rob Tulloh * job.c (construct_command_argv_internal) [WINDOWS32]: Turn off echo when using a batch file, and make sure the command ends in a newline. 1998-05-03 Paul D. Smith * configure.in (make_try_customs): Add some customs flags if the user configures custom support. * job.c, remote-cstms.c: Merge in changes for custom library. * remote-stub.c: Add option to stub start_remote_job_p(). 1998-05-01 Paul D. Smith * remake.c (f_mtime): Install VPATH+ handling for archives; use the hname field instead of the name field, and rehash when appropriate. 1998-04-30 Paul D. Smith * rule.c (print_rule_data_base): Print out any pattern-specific variable values into the rules database. * variable.c (print_variable_set): Make this variable extern, to be called by print_rule_data_base() for pattern-specific variables. * make.texinfo (Pattern-specific): Document pattern-specific variables. 1998-04-29 Paul D. Smith * expand.c (variable_expand_for_file): Make static; its only called internally. Look up this target in the list of pattern-specific variables and insert the variable set into the queue to be searched. * filedef.h (struct file): Add a new field to hold the previously-found pattern-specific variable reference. Add a new flag to remember whether we already searched for this file. * rule.h (struct pattern_var): New structure for storing pattern-specific variable values. Define new function prototypes. * rule.c: New variables pattern_vars and last_pattern_var for storage and handling of pattern-specific variable values. (create_pattern_var): Create a new pattern-specific variable value structure. (lookup_pattern_var): Try to match a target to one of the pattern-specific variable values. 1998-04-22 Paul D. Smith * make.texinfo (Target-specific): Document target-specific variables. 1998-04-21 Paul D. Smith * variable.c (define_variable_in_set): Made globally visible. (lookup_variable_in_set): New function: like lookup_variable but look only in a specific variable set. (target_environment): Use lookup_variable_in_set() to get the correct export rules for a target-specific variable. (create_new_variable_set): Create a new variable set, and just return it without installing it anywhere. (push_new_variable_scope): Reimplement in terms of create_new_variable_set. * read.c (record_target_var): Like record_files, but instead of files create a target-specific variable value for each of the listed targets. Invoked from read_makefile() when the target line turns out to be a target-specific variable assignment. 1998-04-19 Paul D. Smith * read.c (read_makefile): Rewrite the entire target parsing section to implement target-specific variables. In particular, we cannot expand the entire line as soon as it's read in, since we may want to evaluate parts of it with different variable contexts active. Instead, start expanding from the beginning until we find the `:' (or `::'), then determine what kind of line this is and continue appropriately. * read.c (get_next_mword): New function to parse a makefile line by "words", considering an entire variable or function as one word. Return the type read in, along with its starting position and length. (enum make_word_type): The types of words that are recognized by get_next_mword(). * variable.h (struct variable): Add a flag to specify a per-target variable. * expand.c: Make variable_buffer global. We need this during the new parsing of the makefile. (variable_expand_string): New function. Like variable_expand(), but start at a specific point in the buffer, not the beginning. (variable_expand): Rewrite to simply call variable_expand_string(). 1998-04-13 Paul D. Smith * remake.c (update_goal_chain): Allow the rebuilding makefiles step to use parallel jobs. Not sure why this was disabled: hopefully we won't find out :-/. 1998-04-11 Paul D. Smith * main.c (main): Set the CURDIR makefile variable. * make.texinfo (Recursion): Document it. 1998-03-17 Paul D. Smith * misc.c (makefile_fatal): If FILE is nil, invoke plain fatal(). * variable.c (try_variable_definition): Use new feature. 1998-03-10 Paul D. Smith * main.c (main): Don't pass included, rebuilt makefiles to re-exec'd makes with -o. Reopens a possible loop, but it caused too many problems. 1998-03-02 Paul D. Smith * variable.c (try_variable_definition): Implement ?=. * make.texinfo (Setting): Document it. 1998-02-28 Eli Zaretskii * job.c (start_job_command): Reset execute_by_shell after an empty command, like ":", has been seen. Tue Oct 07 15:00:00 1997 Phil Brooks * make.h [WINDOWS32]: make case sensitivity configurable * dir.c [WINDOWS32]: make case sensitivity configurable * README.W32: Document case sensitivity * config.ami: Share case warping code with Windows Mon Oct 6 18:48:45 CDT 1997 Rob Tulloh * w32/subproc/sub_proc.c: Added support for MKS toolkit shell (turn on HAVE_MKS_SHELL). * read.c [WINDOWS32]: Fixed a problem with multiple target rules reported by Gilbert Catipon (gcatipon@tibco.com). If multiple path tokens in a rule did not have drive letters, make would incorrectly concatenate the 2 tokens together. * main.c/variable.c [WINDOWS32]: changed SHELL detection code to follow what MSDOS did. In addition to watching for SHELL variable updates, make's main will attempt to default the value of SHELL before and after makefiles are parsed. * job.c/job.h [WINDOWS32]: The latest changes made to enable use of the GNUWIN32 shell from make could cause make to fail due to a concurrency condition between parent and child processes. Make now creates a batch file per job instead of trying to reuse the same singleton batch file. * job.c/job.h/function.c/config.h.W32 [WINDOWS32]: Renamed macro from HAVE_CYGNUS_GNUWIN32_TOOLS to BATCH_MODE_ONLY_SHELL. Reworked logic to reduce complexity. WINDOWS32 now uses the unixy_shell variable to detect Bourne-shell compatible environments. There is also a batch_mode_shell variable that determines whether not command lines should be executed via script files. A WINDOWS32 system with no sh.exe installed would have unixy_shell set to FALSE and batch_mode_shell set to TRUE. If you have a unixy shell that does not behave well when invoking things via 'sh -c xxx', you may want to turn on BATCH_MODE_ONLY_SHELL and see if things improve. * NMakefile: Added /D DEBUG to debug build flags so that unhandled exceptions could be debugged. Mon Oct 6 00:04:25 1997 Rob Tulloh * main.c [WINDOWS32]: The function define_variable() does not handle NULL. Test before calling it to set Path. * main.c [WINDOWS32]: Search Path again after makefiles have been parsed to detect sh.exe. * job.c [WINDOWS32]: Added support for Cygnus GNU WIN32 tools. To use, turn on HAVE_CYGNUS_GNUWIN32_TOOLS in config.h.W32. * config.h.W32: Added HAVE_CYGNUS_GNUWIN32_TOOLS macro. Sun Oct 5 22:43:59 1997 John W. Eaton * glob/glob.c (glob_in_dir) [VMS]: Globbing shouldn't be case-sensitive. * job.c (child_execute_job) [VMS]: Use a VMS .com file if the command contains a newline (e.g. from a define/enddef block). * vmsify.c (vmsify): Return relative pathnames wherever possible. * vmsify.c (vmsify): An input string like "../.." returns "[--]". Wed Oct 1 15:45:09 1997 Rob Tulloh * NMakefile: Changed nmake to $(MAKE). * subproc.bat: Take the make command name from the command line. If no command name was given, default to nmake. * job.c [MSDOS, WINDOWS32]: Fix memory stomp: temporary file names are now always created in heap memory. * w32/subproc/sub_proc.c: New implementation of make_command_line() which is more compatible with different Bourne shell implementations. Deleted the now obsolete fix_command_line() function. * main.c [WINDOWS32]: Any arbitrary spelling of Path can be detected. Make will ensure that the special spelling `Path' is inserted into the environment when the path variable is propagated within itself and to make's children. * main.c [WINDOWS32]: Detection of sh.exe was occurring too soon. The 2nd check for the existence of sh.exe must come after the call to read_all_makefiles(). Fri Sep 26 01:14:18 1997 * makefile.com [VMS]: Fixed definition of sys. * readme.vms: Comments on what's changed lately. Fri Sep 26 01:14:18 1997 John W. Eaton * read.c (read_all_makefiles): Allow make to find files named "MAKEFILE" with no extension on VMS. * file.c (lookup_file): Lowercase filenames on VMS. 1997-09-29 Paul D. Smith * read.c (read_makefile): Reworked target detection again; the old version had an obscure quirk. Fri Sep 19 09:20:49 1997 Paul D. Smith * Version 3.76.1 released. * Makefile.am: Add loadavg files to clean rules. * configure.in (AC_OUTPUT): Remove stamp-config; no longer needed. * Makefile.ami (distclean): Ditto. * SMakefile (distclean): Ditto. * main.c (main): Arg count should be int, not char! Major braino. Tue Sep 16 10:18:22 1997 Paul D. Smith * Version 3.76 released. Tue Sep 2 10:07:39 1997 Paul D. Smith * function.c (expand_function): When processing $(shell...) translate a CRLF (\r\n) sequence as well as a newline (\n) to a space. Also remove an ending \r\n sequence. * make.texinfo (Shell Function): Document it. Fri Aug 29 12:59:06 1997 Rob Tulloh * w32/pathstuff.c (convert_Path_to_windows32): Fix problem where paths which contain single character entries like `.' are not handled correctly. * README.W32: Document path handling issues on Windows systems. Fri Aug 29 02:01:27 1997 Paul D. Smith * Version 3.75.93. Thu Aug 28 19:39:06 1997 Rob Tulloh * job.c (exec_command) [WINDOWS32]: If exec_command() is invoked from main() to re-exec make, the call to execvp() would incorrectly return control to parent shell before the exec'ed command could run to completion. I believe this is a feature of the way that execvp() is implemented on top of WINDOWS32 APIs. To alleviate the problem, use the supplied process launch function in the sub_proc library and suspend the parent process until the child process has run. When the child exits, exit the parent make with the exit code of the child make. Thu Aug 28 17:04:47 1997 Paul D. Smith * Makefile.DOS.template (distdir): Fix a line that got wrapped in email. * Makefile.am (loadavg): Give the necessary cmdline options when linking loadavg. * configure.in: Check for pstat_getdynamic for getloadvg on HP. * job.c (start_job_command) [VMS, _AMIGA]: Don't perform empty command optimization on these systems; it doesn't make sense. Wed Aug 27 17:09:32 1997 Paul D. Smith * Version 3.75.92 Tue Aug 26 11:59:15 1997 Paul D. Smith * main.c (print_version): Add '97 to copyright years. * read.c (do_define): Check the length of the array before looking at a particular offset. * job.c (construct_command_argv_internal): Examine the last byte of the previous arg, not the byte after that. Sat Aug 23 1997 Eli Zaretskii * Makefile.DOS.template: New file (converted to Makefile.DOS in the distribution). * configure.bat: Rewrite to use Makefile.DOS instead of editing Makefile.in. Add support for building from outside of the source directory. Fail if the environment block is too small. * configh.dos: Use . * README.DOS: Update instructions. Fri Aug 22 1997 Eli Zaretskii * job.c (start_job_command) [__MSDOS__]: Don't test for "/bin/sh" literally, use value of unixy_shell instead. * filedef.h (NEW_MTIME): Use 1 less than maximum possible value if time_t is unsigned. Sat Aug 16 00:56:15 1997 John W. Eaton * vmsify.c (vmsify, case 11): After translating `..' elements, set nstate to N_OPEN if there are still more elements to process. (vmsify, case 2): After translating `foo/bar' up to the slash, set nstate to N_OPEN, not N_DOT. Fri Aug 8 15:18:09 1997 John W. Eaton * dir.c (vmsstat_dir): Leave name unmodified on exit. * make.h (PATH_SEPARATOR_CHAR): Set to comma for VMS. * vpath.c: Fix comments to refer to path separator, not colon. (selective_vpath_search): Avoid Unixy slash handling for VMS. Thu Aug 7 22:24:03 1997 John W. Eaton * ar.c [VMS]: Don't declare ar_member_touch. Delete VMS version of ar_member_date. Enable non-VMS versions of ar_member_date and ar_member_date_1 for VMS too. * arscan.c (VMS_get_member_info): New function. (ar_scan): Provide version for VMS systems. (ar_name_equal): Simply compare name and mem on VMS systems. Don't define ar_member_pos or ar_member_touch on VMS systems. * config.h-vms (pid_t, uid_t): Don't define. * remake.c: Delete declaration of vms_stat. (name_mtime): Don't call vms_stat. (f_mtime) [VMS]: Funky time value manipulation no longer necessary. * file.c (print_file): [VMS] Use ctime, not cvt_time. * make.h [VMS]: Don't define POSIX. * makefile.com (filelist): Include ar and arscan. Also include them in the link commands. Don't define NO_ARCHIVES in cc command. * makefile.vms (ARCHIVES, ARCHIVES_SRC): Uncomment. (defines): Delete NO_ARCHIVES from list. * remake.c (f_mtime): Only check to see if intermediate file is out of date if it also exists (i.e., mtime != (time_t) -1). * vmsdir.h (u_long, u_short): Skip typedefs if using DEC C. Fri Jun 20 23:02:07 1997 Rob Tulloh * w32/subproc/sub_proc.c: Get W32 sub_proc to handle shebang (#!/bin/sh) in script files correctly. Fixed a couple of memory leaks. Fixed search order in find_file() (w32/subproc/sub_proc.c) so that files with extensions are preferred over files without extensions. Added search for files with .cmd extension too. * w32/subproc/misc.c (arr2envblk): Fixed memory leak. Mon Aug 18 09:41:08 1997 Paul D. Smith * Version 3.75.91 Fri Aug 15 13:50:54 1997 Paul D. Smith * read.c (do_define): Remember to count the newline after the endef. Thu Aug 14 23:14:37 1997 Paul D. Smith * many: Rewrote builds to use Automake 1.2. * AUTHORS: New file. * maintMakefile: Contains maintainer-only make snippets. * GNUmakefile: This now only runs the initial auto* tools. * COPYING,texinfo.tex,mkinstalldirs,install-sh: Removed (obtained automatically by automake). * compatMakefile: Removed (not needed anymore). * README,build.sh.in: Removed (built from templates). * config.h.in,Makefile.in: Removed (built by tools). Wed Aug 13 02:22:08 1997 Paul D. Smith * make.texinfo: Updates for DOS/Windows information (Eli Zaretskii) * README,README.DOS: Ditto. * remake.c (update_file_1,f_mtime): Fix GPATH handling. * vpath.c (gpath_search): Ditto. * file.c (rename_file): New function: rehash, but also rename to the hashname. * filedef.h: Declare it. * variable.c (merge_variable_set_lists): Remove free() of variable set; since various files can share variable sets we don't want to free them here. Tue Aug 12 10:51:54 1997 Paul D. Smith * configure.in: Require autoconf 2.12 * make.texinfo: Replace all "cd subdir; $(MAKE)" examples with a more stylistically correct "cd subdir && $(MAKE)". * main.c: Global variable `clock_skew_detected' defined. (main): Print final warning if it's set. * make.h: Declare it. * remake.c (f_mtime): Test and set it. * job.c (start_job_command): Add special optimizations for "do-nothing" rules, containing just the shell no-op ":". This is useful for timestamp files and can make a real difference if you have a lot of them (requested by Fergus Henderson ). * configure.in,Makefile.in: Rewrote to use the new autoconf program_transform_name macro. * function.c (function_strip): Strip newlines as well as spaces and TABs. Fri Jun 6 23:41:04 1997 Rob Tulloh * remake.c (f_mtime): Datestamps on FAT-based files are rounded to even seconds when stored, so if the date check fails on WINDOWS32 systems, see if this "off-by-one" error is the problem. * General: If your TZ environment variable is not set correctly then all your timestamps will be off by hours. So, set it! Mon Apr 7 02:06:22 1997 Paul D. Smith * Version 3.75.1 * compatMakefile (objs): Define & use the $(GLOB) variable so that it's removed correctly from build.sh.in when it's built. * configure.in: On Solaris we can use the kstat_*() functions to get load averages without needing special permissions. Add a check for -lkstat to see if we have it. * getloadavg.c (getloadavg): Use HAVE_LIBKSTAT instead of SUN5 as the test to enable kstat_open(), etc. processing. Fri Apr 4 20:21:18 1997 Eli Zaretskii * : Fixes to work in the DJGPP DOS environment. Mon Mar 31 02:42:52 1997 Paul D. Smith * function.c (expand_function): Added new function $(wordlist). * make.texinfo (Filename Functions): Document $(wordlist) function. * vpath.c (build_vpath_lists): Construct the GPATH variable information in the same manner we used to construct VPATH. (gpath_search): New function to search GPATH. * make.h: Declare the new function. * remake.c (update_file_1): Call it, and keep VPATH if it's found. * make.texinfo (Search Algorithm): Document GPATH variable. Sun Mar 30 20:57:16 1997 Paul D. Smith * main.c (handle_non_switch_argument): Defined the MAKECMDGOALS variable to contain the user options passed in on the cmd line. * make.texinfo (Goals): Document MAKECMDGOALS variable. * remake.c (f_mtime): Print a warning if we detect a clock skew error, rather than failing. * main.c (main): If we rebuild any makefiles and need to re-exec, add "-o" options for each makefile rebuilt to avoid infinite looping. Fri Mar 28 15:26:05 1997 Paul D. Smith * job.c (construct_command_argv_internal): Track whether the last arg in the cmd string was empty or not (Roland). (construct_command_argv_internal): If the shell line is empty, don't do anything (Roland). * glob/glob.h,glob/glob.c,glob/fnmatch.c,glob/fnmatch.h: Install the latest changes from the GLIBC version of glob (Ulrich Drepper). * getloadavg.c,make-stds.texi: New version (Roland). * (ALL): Changed WIN32 to W32 or WINDOWS32 (RMS). Mon Mar 24 15:33:34 1997 Rob Tulloh * README.W32: Describe preliminary FAT support. * build_w32.bat: Use a variable for the final exe name. * dir.c (find_directory): W32: Find the filesystem type. (dir_contents_file_exists_p): W32: for FAT filesystems, always rehash since FAT doesn't change directory mtime on change. * main.c (handle_runtime_exceptions): W32: Add an UnhandledExceptionFilter so that when make bombs due to ^C or a bug, it won't cause a GUI requestor to pop up unless debug is turned on. (main): Call it. Mon Mar 24 00:57:34 1997 Paul D. Smith * configure.in, config.h.in, config.ami, config.h-vms, config.h.w32: Check for memmove() function. * make.h (bcopy): If memmove() available, define bcopy() to use it. Otherwise just use bcopy(). Don't use memcpy(); it's not guaranteed to handle overlapping moves. * read.c (read_makefile): Fix some uninitialized memory reads (reported by Purify). * job.c (construct_command_argv_internal): Use bcopy() not strcpy(); strcpy() isn't guaranteed to handle overlapping moves. * Makefile.in: Change install-info option ``--infodir'' to ``--info-dir'' for use with new texinfo. * function.c (expand_function): $(basename) and $(suffix) should only search for suffixes as far back as the last directory (e.g., only the final filename in the path). Sun Mar 23 00:13:05 1997 Paul D. Smith * make.texinfo: Add @dircategory/@direntry information. (Top): Remove previous reference to (dir) (from RMS). (Static Usage): Add "all:" rule to example. (Automatic Dependencies): fix .d file creation example. * Install VPATH+ patch: * filedef.h (struct file): Add in hname field to store the hashed filename, and a flag to remember if we're using the vpath filename or not. Renamed a few functions for more clarity. * file.c (lookup_file,enter_file,file_hash_enter): Store filenames in the hash table based on their "hash name". We can change this while keeping the original target in "name". (rehash_file): Renamed from "rename_file" to be more accurate. Changes the hash name, but not the target name. * remake.c (update_file_1): Modify -d output for more detailed VPATH info. If we don't need to rebuild, use the VPATH name. (f_mtime): Don't search for vpath if we're ignoring it. Call renamed function rehash_file. Call name_mtime instead of file_mtime, to avoid infinite recursion since the file wasn't actually renamed. * implicit.c (pattern_search): if we find an implicit file in VPATH, save the original name not the VPATH name. * make.texinfo (Directory Search): Add a section on the new VPATH functionality. Sun Dec 1 18:36:04 1996 Andreas Schwab * dir.c (file_exists_p, file_impossible, file_impossible_p): If dirname is empty replace it by the name of the root directory. Note that this doesn't work (yet) for W32, Amiga, or VMS. Tue Oct 08 13:57:03 1996 Rob Tulloh * main.c (main): W32 bug fix for PATH vars. Tue Sep 17 1996 Paul Eggert * filedef.h (NEW_MTIME): Don't assume that time_t is a signed 32-bit quantity. * make.h: (CHAR_BIT, INTEGER_TYPE_SIGNED, INTEGER_TYPE_MAXIMUM, INTEGER_TYPE_MINIMUM): New macros. Tue Aug 27 01:06:34 1996 Roland McGrath * Version 3.75 released. * main.c (print_version): Print out bug-reporting address. Mon Aug 26 19:55:47 1996 Roland McGrath * main.c (print_data_base): Don't declare ctime; headers do it for us already. Sun Jul 28 15:37:09 1996 Rob Tulloh (tulloh@tivoli.com) * w32/pathstuff.c: Turned convert_vpath_to_w32() into a real function. This was done so that VPATH could contain white space separated pathnames. Please note that directory paths (in VPATH/vpath context) containing white space are not supported (just as they are not under Unix). See README.W32 for suggestions. * w32/include/pathstuff.h: Added prototype for the new function convert_vpath_to_w32. Deleted macro for same. * README.W32: Added some notes about why I chose not to try and support pathnames which contain white space and some workaround suggestions. Thu Jul 25 19:53:31 1996 Roland McGrath * GNUmakefile (mkdep-nolib): Use -MM option unconditionally. * Version 3.74.7. * main.c (define_makeflags): Back up P to point at null terminator when killing final space and dash before setting MFLAGS. From Robert Hoehne : * dir.c [__MSDOS__ && DJGPP > 1]: Include and defin `__opendir_flags' initialized to 0. (dosify) [__MSDOS__ && DJGPP > 1]: Return name unchanged if _USE_LFN. (find_directory) [__MSDOS__ && DJGPP > 1]: If _USE_LGN, set __opendir_flags to __OPENDIR_PRESERVE_CASE. * vmsfunctions.c (vms_stat): `sys$dassgn (DevChan);' added by kkaempf. * GNUmakefile (w32files): Add NMakefile. * NMakefile (LDFLAGS_debug): Value fixed by tulloh. Sat Jul 20 12:32:10 1996 Klaus Kmpf (kkaempf@progis.de) * remake.c (f_mtime) [VMS]: Add missing `if' conditional for future modtime check. * config.h-vms, makefile.vms, readme.vms, vmsify.c: Update address. Sat Jul 20 05:29:43 1996 Roland McGrath * configure.in: Require autoconf 2.10 or later. Fri Jul 19 16:57:27 1996 Roland McGrath * Version 3.74.6. * GNUmakefile (w32files): New variable. (distfiles): Add it. * w32: Updated by Rob Tulloh. * makefile.vms (LOADLIBES): Fix typo. Sun Jul 14 12:59:27 1996 Roland McGrath * job.c (construct_command_argv_internal): Fix up #else, #endifs. * configh.dos: Define HAVE_DIRENT_H instead of DIRENT. * remake.c (f_mtime): Don't compare MTIME to NOW if MTIME == -1. * Version 3.74.5. * main.c (main): Exit with status 2 when update_goal_chain returns 2. Sat Jun 22 14:56:05 1996 Roland McGrath * configure.in: Don't check for _sys_siglist. * make.h [HAVE__SYS_SIGLIST]: Don't test this; just punt if there is no strsignal or sys_siglist. * read.c (conditional_line): Strip ws in `ifeq (a , b)' so it is the same as `ifeq (a, b)'. * job.c (reap_children): Don't call die if handling_fatal_signal. * file.c (file_hash_enter): Allow renaming :: to : when latter is non-target, or : to :: when former is non-target. * job.c (start_job_command): Call block_sigs. (block_sigs): New function, broken out of start_job_command. (reap_children): Block fatal signals around removing dead child from chain and adjusting job_slots_used. * job.h: Declare block_sigs. * remote-stub.c (remote_setup, remote_cleanup): New (empty) functions. * main.c (main): Call remote_setup. (die): Call remote_cleanup. * job.c (reap_children): Quiescent value of shell_function_pid is zero, not -1. * main.c (print_version): Add 96 to copyright years. Sat Jun 15 20:30:01 1996 Andreas Schwab * read.c (find_char_unquote): Avoid calling strlen on every call just to throw away the value most of the time. Sun Jun 2 12:24:01 1996 Roland McGrath * main.c (decode_env_switches): Prepend '-' to ARGV[1] if it contains no '=', regardless of ARGC. (define_makeflags): Elide leading '-' from MAKEFLAGS value if first word is short option, regardless of WORDS. Wed May 22 17:24:51 1996 Roland McGrath * makefile.vms: Set LOADLIBES. * makefile.com (link_using_library): Fix typo. W~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;1B8ed May 15 17:37:26 1996 Roland McGrath * dir.c (print_dir_data_base): Use %ld dev and ino and cast them to long. Wed May 15 10:14:14 CDT 1996 Rob Tulloh * dir.c: W32 does not support inode. For now, fully qualified pathname along with st_mtime will be keys for files. Fixed problem where vpath can be confused when files are added to a directory after the directory has already been read in. The code now attempts to reread the directory if it discovers that the datestamp on the directory has changed since it was cached by make. This problem only seems to occur on W32 right now so it is lumped under port #ifdef WINDOWS32. * function.c: W32: call subproc library (CreateProcess()) instead of fork/exec. * job.c: W32: Added the code to do fork/exec/waitpid style processing on W32 systems via calls to subproc library. * main.c: W32: Several things added here. First, there is code for dealing with PATH and SHELL defaults. Make tries to figure out if the user has %PATH% set in the environment and sets it to %Path% if it is not set already. Make also looks to see if sh.exe is anywhere to be found. Code path through job.c will change based on existence of a working Bourne shell. The checking for default shell is done twice: once before makefiles are read in and again after. Fall back to MSDOS style execution mode if no sh.exe is found. Also added some debug support that allows user to pause make with -D switch and attach a debugger. This is especially useful for debugging recursive calls to make where problems appear only in the sub-make. * make.h: W32: A few macros and header files for W32 support. * misc.c: W32: Added a function end_of_token_w32() to assist in parsing code in read.c. * read.c: W32: Fixes similar to MSDOS which allow colon to appear in filenames. Use of colon in filenames would otherwise confuse make. * remake.c: W32: Added include of io.h to eliminate compiler warnings. Added some code to default LIBDIR if it is not set on W32. * variable.c: W32: Added support for detecting Path/PATH and converting them to semicolon separated lists for make's internal use. New function sync_Path_environment() which is called in job.c and function.c before creating a new process. Caller must set Path in environment since we don't have fork() to do this for us. * vpath.c: W32: Added detection for filenames containing forward or backward slashes. * NMakefile: W32: Visual C compatible makefile for use with nmake. Use this to build GNU make the first time on Windows NT or Windows 95. * README.W32: W32: Contains some helpful notes. * build_w32.bat: W32: If you don't like nmake, use this the first time you build GNU make on Windows NT or Windows 95. * config.h.W32: W32 version of config.h * subproc.bat: W32: A bat file used to build the subproc library from the top-level NMakefile. Needed because WIndows 95 (nmake) doesn't allow you to cd in a make rule. * w32/include/dirent.h * w32/compat/dirent.c: W32: opendir, readdir, closedir, etc. * w32/include/pathstuff.h: W32: used by files needed functions defined in pathstuff.c (prototypes). * w32/include/sub_proc.h: W32: prototypes for subproc.lib functions. * w32/include/w32err.h: W32: prototypes for w32err.c. * w32/pathstuff.c: W32: File and Path/Path conversion functions. * w32/subproc/build.bat: W32: build script for subproc library if you don't wish to use nmake. * w32/subproc/NMakefile: W32: Visual C compatible makefile for use with nmake. Used to build subproc library. * w32/subproc/misc.c: W32: subproc library support code * w32/subproc/proc.h: W32: subproc library support code * w32/subproc/sub_proc.c: W32: subproc library source code * w32/subproc/w32err.c: W32: subproc library support code Mon May 13 14:37:42 1996 Roland McGrath * Version 3.74.4. * GNUmakefile (vmsfiles): Fix typo. * GNUmakefile (amigafiles): Add amiga.h. Sun May 12 19:19:43 1996 Aaron Digulla * dir.c: New function: amigafy() to fold filenames Changes HASH() to HASHI() to fold filenames on Amiga. Stringcompares use strieq() instead of streq() The current directory on Amiga is "" instead of "." * file.c: Likewise. * amiga.c: New function wildcard_expansion(). Allows to use Amiga wildcards with $(wildcard ) * amiga.h: New file. Prototypes for amiga.c * function.c: Use special function wildcard_expansion() for $(wildcard ) to allow Amiga wildcards The current directory on Amiga is "" instead of "." * job.c: No Pipes on Amiga, too (load_too_high) Neither on Amiga ENV variable on Amiga are in a special directory and are not passed as third argument to main(). * job.h: No envp on Amiga * make.h: Added HASHI(). This is the same as HASH() but converts it's second parameter to lowercase on Amiga to fold filenames. * main.c: (main), variable.c Changed handling of ENV-vars. Make stores now the names of the variables only and reads their contents when they are accessed to reflect that these variables are really global (ie. they CAN change WHILE make runs !) This handling is made in lookup_variable() * Makefile.ami: renamed file.h to filedep.h Updated dependencies * read.c: "find_semicolon" is declared as static but never defined. No difference between Makefile and makefile on Amiga; added SMakefile to *default_makefiles[]. (read_makefile) SAS/C want's two_colon and pattern_percent be set before use. The current directory on Amiga is "" instead of "." Strange #endif moved. * README.Amiga: updated feature list * SMakefile: Updated dependencies * variable.c: Handling of ENV variable happens inside lookup_variable() Sat May 11 17:58:32 1996 Roland McGrath * variable.c (try_variable_definition): Count parens in lhs variable refs to avoid seeing =/:=/+= inside a ref. Thu May 9 13:54:49 1996 Roland McGrath * commands.c (fatal_error_signal) [SIGQUIT]: Make SIGQUIT check conditional. * main.c (main): Use unsigned for fread return. * read.c (parse_file_seq): Use `int' for char arg to avoid widening conflict issues. * dep.h: Fix prototype. * function.c (expand_function) [_AMIGA]: Fix some typos. (patsubst_expand): Make len vars unsigned. * GNUmakefile (globfiles): Add AmigaDOS support files. (distfiles): Add $(amigafiles). (amigafiles): New variable. Thu Nov 7 10:18:16 1995 Aaron Digulla * Added Amiga support in commands.c, dir.c, function.c, job.c, main.c, make.h, read.c, remake.c * commands.c: Amiga has neither SIGHUP nor SIGQUIT * dir.c: Amiga has filenames with Upper- and Lowercase, but "FileName" is the same as "filename". Added strieq() which is use to compare filenames. This is like streq() on all other systems. Also there is no such thing as "." under AmigaDOS. * function.c: On Amiga, the environment is not passed as envp, there are no pipes and Amiga can't fork. Use my own function to create a new child. * job.c: default_shell is "" (The system automatically chooses a shell for me). Have to use the same workaround as MSDOS for running batch commands. Added HAVE_SYS_PARAM_H. NOFILE isn't known on Amiga. Cloned code to run children from MSDOS. Own version of sh_chars[] and sh_cmds[]. No dup2() or dup() on Amiga. * main.c: Force stack to 20000 bytes. Read environment from ENV: device. On Amiga, exec_command() does return, so I exit() afterwards. * make.h: Added strieq() to compare filenames. * read.c: Amiga needs special extension to have passwd. Only one include-dir. "Makefile" and "makefile" are the same. Added "SMakefile". Added special code to handle device names (xxx:) and "./" in rules. * remake.c: Only one lib-dir. Amiga link-libs are named "%s.lib" instead of "lib%s.a". * main.c, rule.c, variable.c: Avoid floats at all costs. * vpath.c: Get rid of as many alloca()s as possible. Thu May 9 13:20:43 1996 Roland McGrath * read.c (read_makefile): Grok `sinclude' as alias for `-include'. Wed Mar 20 09:52:27 1996 Roland McGrath * GNUmakefile (vmsfiles): New variable. (distfiles): Include $(vmsfiles). Tue Mar 19 20:21:34 1996 Roland McGrath Merged VMS port from Klaus Kaempf . * make.h (PARAMS): New macro. * config.h-vms: New file. * makefile.com: New file. * makefile.vms: New file. * readme.vms: New file. * vmsdir.h: New file. * vmsfunctions.c: New file. * vmsify.c: New file. * file.h: Renamed to filedef.h to avoid conflict with VMS system hdr. * ar.c: Added prototypes and changes for VMS. * commands.c: Likewise. * commands.h: Likewise. * default.c: Likewise. * dep.h: Likewise. * dir.c: Likewise. * expand.c: Likewise. * file.c: Likewise. * function.c: Likewise. * implicit.c: Likewise. * job.c: Likewise. * job.h: Likewise. * main.c: Likewise. * make.h: Likewise. * misc.c: Likewise. * read.c: Likewise. * remake.c: Likewise. * remote-stub.c: Likewise. * rule.c: Likewise. * rule.h: Likewise. * variable.c: Likewise. * variable.h: Likewise. * vpath.c: Likewise. * compatMakefile (srcs): Rename file.h to filedef.h. Sat Aug 19 23:11:00 1995 Richard Stallman * remake.c (check_dep): For a secondary file, try implicit and default rules if appropriate. Wed Aug 2 04:29:42 1995 Richard Stallman * remake.c (check_dep): If an intermediate file exists, do consider its actual date. Sun Jul 30 00:49:53 1995 Richard Stallman * file.h (struct file): New field `secondary'. * file.c (snap_deps): Check for .INTERMEDIATE and .SECONDARY. (remove_intermediates): Don't delete .SECONDARY files. Sat Mar 2 16:26:52 1996 Roland McGrath * compatMakefile (srcs): Add getopt.h; prepend $(srcdir)/ to getopt*. Fri Mar 1 12:04:47 1996 Roland McGrath * Version 3.74.3. * remake.c (f_mtime): Move future modtime check before FILE is clobbered by :: loop. * dir.c: Use canonical code from autoconf manual for dirent include. [_D_NAMLEN]: Redefine NAMLEN using this. (dir_contents_file_exists_p): Use NAMLEN macro. (read_dirstream) [_DIRENT_HAVE_D_NAMLEN]: Only set d_namlen #if this. * compatMakefile (objs): Add missing backslash. Wed Feb 28 03:56:20 1996 Roland McGrath * default.c (default_terminal_rules): Remove + prefix from RCS cmds. (default_variables): Put + prefix in $(CHECKOUT,v) value instead. * remake.c (f_mtime): Check for future timestamps; give error and mark file as "failed to update". Fri Jan 12 18:09:36 1996 Roland McGrath * job.c: Don't declare unblock_sigs; job.h already does. Sat Jan 6 16:24:44 1996 Roland McGrath * acconfig.h (HAVE_SYSCONF_OPEN_MAX): #undef removed. * job.c (NGROUPS_MAX): Don't try to define this macro. Fri Dec 22 18:44:44 1995 Roland McGrath * compatMakefile (GETOPT, GETOPT_SRC, GLOB): Variables removed. (objs, srcs): Include their values here instead of references. Thu Dec 14 06:21:29 1995 Roland McGrath * Version 3.74.2. * job.c (reap_children): Call unblock_sigs after start_job_command. Thu Dec 14 07:22:03 1995 Roland McGrath * dir.c (dir_setup_glob): Don't use lstat; glob never calls it anyway. Avoid & before function names to silence bogus sunos4 compiler. * configure.in: Remove check for `sysconf (_SC_OPEN_MAX)'. Tue Dec 12 00:48:42 1995 Roland McGrath * Version 3.74.1. * dir.c (read_dirstream): Fix braino: fill in the buffer when not reallocating it! Mon Dec 11 22:26:15 1995 Roland McGrath * misc.c (collapse_continuations): Fix skipping of trailing \s so it can never dereference before the beginning of the array. * read.c (find_semicolon): Function removed. (read_makefile): Don't use find_semicolon or remove_comments for rule lines. Use find_char_unquote directly and handle quoted comments properly. * default.c: Remove all [M_XENIX] code. * dir.c [HAVE_D_NAMLEN]: Define this for __GNU_LIBRARY__ > 1. (D_NAMLEN): Macro removed. (FAKE_DIR_ENTRY): New macro. (dir_contents_file_exists_p): Test HAVE_D_NAMLEN instead of using D_NAMLEN. (read_dirstream): Return a struct dirent * for new glob interface. (init_dir): Function removed. (dir_setup_glob): New function. * main.c (main): Don't call init_dir. * read.c (multi_glob): Call dir_setup_glob on our glob_t and use GLOB_ALTDIRFUNC flag. * misc.c (safe_stat): Function removed. * read.c, commands.c, remake.c, vpath.c: Use plain stat instead of safe_stat. Sat Nov 25 20:35:18 1995 Roland McGrath * job.c [HAVE_UNION_WAIT]: Include sys/wait.h. * main.c (log_working_directory): Made global. Print entering msg only once. * make.h (log_working_directory): Declare it. * misc.c (message): Take new arg PREFIX. Print "make: " only if nonzero. Call log_working_directory. * remake.c: Pass new arg in `message' calls. * job.c (start_job_command): Pass new arg to `message'; fix inverted test in that call. Tue Nov 21 19:01:12 1995 Roland McGrath * job.c (start_job_command): Use `message' to print the command, and call it with null if the command is silent. * remake.c (touch_file): Use message instead of printf. Tue Oct 10 14:59:30 1995 Roland McGrath * main.c (enter_command_line_file): Barf if NAME is "". Sat Sep 9 06:33:20 1995 Roland McGrath * commands.c (delete_target): Ignore unlink failure if it is ENOENT. Thu Aug 17 15:08:57 1995 Roland McGrath * configure.in: Don't check for getdtablesize. * job.c (getdtablesize): Remove decls and macros. Thu Aug 10 19:10:03 1995 Roland McGrath * main.c (define_makeDflags): Omit command line variable definitions from MFLAGS value. * arscan.c (ar_scan) [AIAMAG]: Check for zero MEMBER_OFFSET, indicating a valid, but empty, archive. Mon Aug 7 15:40:03 1995 Roland McGrath * dir.c (file_impossible_p): Correctly reset FILENAME to name within directory before hash search. * job.c (child_error): Do nothing if IGNORED under -s. * job.c (exec_command): Correctly use ARGV[0] for script name when running shell directly. Tue Aug 1 14:39:14 1995 Roland McGrath * job.c (child_execute_job): Close STDIN_FD and STDOUT_FD after dup'ing from them. Don't try to close all excess descriptors; getdtablesize might return a huge value. Any open descriptors in the parent should have FD_CLOEXEC set. (start_job_command): Set FD_CLOEXEC flag on BAD_STDIN descriptor. Tue Jun 20 03:47:15 1995 Roland McGrath * read.c (read_all_makefiles): Properly append default makefiles to the end of the `read_makefiles' chain. Fri May 19 16:36:32 1995 Roland McGrath * Version 3.74 released. Wed May 10 17:43:34 1995 Roland McGrath * Version 3.73.3. Tue May 9 17:15:23 1995 Roland McGrath * compatMakefile ($(infodir)/make.info): Make sure $$dir is set in install-info cmd. Wed May 3 15:56:06 1995 Roland McGrath * file.c (print_file): Grok update_status of 1 for -q. Thu Apr 27 12:39:35 1995 Roland McGrath * Version 3.73.2. Wed Apr 26 17:15:57 1995 Roland McGrath * file.c (remove_intermediates): Fix inverted test to bail under -n for signal case. Bail under -q or -t. Skip files with update_status==-1. * job.c (job_next_command): Skip empty lines. (new_job): Don't test the return of job_next_command. Just let start_waiting_job handle the case of empty commands. Wed Apr 19 03:25:54 1995 Roland McGrath * function.c [__MSDOS__]: Include . From DJ Delorie. * Version 3.73.1. Sat Apr 8 14:53:24 1995 Roland McGrath * remake.c (notice_finished_file): Set FILE->update_status to zero if it's -1. Wed Apr 5 00:20:24 1995 Roland McGrath * Version 3.73 released. Tue Mar 28 13:25:46 1995 Roland McGrath * main.c (main): Fixed braino in assert. * Version 3.72.13. Mon Mar 27 05:29:12 1995 Roland McGrath * main.c: Avoid string in assert expression. Some systems are broken. Fri Mar 24 00:32:32 1995 Roland McGrath * main.c (main): Handle 1 and 2 returns from update_goal_chain makefile run properly. * Version 3.72.12. * main.c (handle_non_switch_argument): New function, broken out of decode_switches. (decode_switches): Set optind to 0 to reinitialize getopt, not to 1. When getopt_long returns EOF, break the loop and handle remaining args with a simple second loop. * remake.c (remake_file): Set update_status to 2 instead of 1 for no rule to make. Mention parent (dependent) in error message. (update_file_1): Handle FILE->update_status == 2 in -d printout. * job.c (start_job_command, reap_children): Set update_status to 2 instead of 1 for failed commands. Tue Mar 21 16:23:38 1995 Roland McGrath * job.c (search_path): Function removed (was already #if 0'd out). * configure.in: Remove AC_TYPE_GETGROUPS; nothing needs it any more. Fri Mar 17 15:57:40 1995 Roland McGrath * configure.bat: Write @CPPFLAGS@ translation. Mon Mar 13 00:45:59 1995 Roland McGrath * read.c (parse_file_seq): Rearranged `l(a b)' -> `l(a) l(b)' loop to not skip the elt immediately preceding `l(...'. Fri Mar 10 13:56:49 1995 Roland McGrath * Version 3.72.11. * read.c (find_char_unquote): Make second arg a string of stop chars instead of a single stop char. Stop when any char in the string is hit. All callers changed. (find_semicolon): Pass stop chars "#;" to one find_char_unquote call, instead of using two calls. If the match is not a ; but a #, return zero. * misc.c: Changed find_char_unquote callers here too. * Version 3.72.10. * read.c (read_makefile, parse_file_seq): Fix typo __MS_DOS__ -> __MSDOS__. * GNUmakefile (globfiles): Add glob/configure.bat. (distfiles): Add configh.dos, configure.bat. Wed Mar 8 13:10:57 1995 Roland McGrath Fixes for MS-DOS from DJ Delorie. * read.c (read_makefile, parse_file_seq) [__MS_DOS__]: Don't see : as separator in "C:\...". * configh.dos (STDC_HEADERS): Define only if undefined. (HAVE_SYS_PARAM_H): Don't define this. (HAVE_STRERROR): Define this. * job.c (construct_command_argv_internal) [__MSDOS__]: Fix typos. * Version 3.72.9. * main.c (decode_switches): Reset optind to 1 instead of 0. Tue Mar 7 17:31:06 1995 Roland McGrath * main.c (decode_switches): If non-option arg is "-", ignore it. Mon Mar 6 23:57:38 1995 Roland McGrath * Version 3.72.8. Wed Feb 22 21:26:36 1995 Roland McGrath * Version 3.72.7. Tue Feb 21 22:10:43 1995 Roland McGrath * main.c (main): Pass missing arg to tmpnam. * configure.in: Check for strsignal. * job.c (child_error): Use strsignal. * main.c (main): Don't call signame_init #ifdef HAVE_STRSIGNAL. * misc.c (strerror): Fix swapped args in sprintf. Mon Feb 13 11:50:08 1995 Roland McGrath * configure.in (CFLAGS, LDFLAGS): Don't set these variables. Fri Feb 10 18:44:12 1995 Roland McGrath * main.c (print_version): Add 95 to copyright years. * Version 3.72.6. * job.c (start_job_command): Remember to call notice_finished_file under -n when not recursing. To do this, consolidate that code under the empty command case and goto there for the -n case. Tue Feb 7 13:36:03 1995 Roland McGrath * make.h [! STDC_HEADERS]: Don't declare qsort. Sun headers declare it int. Mon Feb 6 17:37:01 1995 Roland McGrath * read.c (read_makefile): For bogus line starting with tab, ignore it if blank after removing comments. * main.c: Cast results of `alloca' to `char *'. * expand.c: Likewise. Sun Feb 5 18:35:46 1995 Roland McGrath * Version 3.72.5. * configure.in: Check for mktemp. * main.c (main) [! HAVE_MKTEMP]: Use tmpnam instead of mktemp. * configure.in (make_cv_sysconf_open_max): New check for `sysconf (_SC_OPEN_MAX)'. * acconfig.h: Added #undef HAVE_SYSCONF_OPEN_MAX. * job.c [HAVE_SYSCONF_OPEN_MAX] (getdtablesize): Define as macro using sysconf. Fri Jan 27 04:42:09 1995 Roland McGrath * remake.c (update_file_1): When !MUST_MAKE, don't set FILE->update_status to zero before calling notice_finished_file. (notice_finished_file): Touch only when FILE->update_status is zero. (remake_file): Set FILE->update_status to zero after not calling execute_file_command and deciding to touch instead. Thu Jan 26 01:29:32 1995 Roland McGrath * main.c (debug_signal_handler): New function; toggles debug_flag. (main): Handle SIGUSR1 with that. Mon Jan 16 15:46:56 1995 Roland McGrath * compatMakefile (realclean): Remove Info files. Sun Jan 15 08:23:09 1995 Roland McGrath * Version 3.72.4. * job.c (start_job_command): Save and restore environ around vfork call. (search_path): Function #if 0'd out. (exec_command): Use execvp instead of search_path. * expand.c (variable_expand): Rewrote computed variable name and substitution reference handling to be simpler. First expand the entire text between the parens if it contains any $s, then examine the result of that for subtitution references and do no further expansion while parsing them. * job.c (construct_command_argv_internal): Handle " quoting too, when no backslash, $ or ` characters appear inside the quotes. * configure.in (union wait check): If WEXITSTATUS and WTERMSIG are defined, just use int. Tue Jan 10 06:27:27 1995 Roland McGrath * default.c (default_variables) [__hpux]: Remove special definition of ARFLAGS. Existence of the `f' flag is not consistent across HPUX versions; and one might be using GNU ar anyway. * compatMakefile (clean): Don't remove Info files. * compatMakefile (check): Remove gratuitous target declaration. Sat Jan 7 11:38:23 1995 Roland McGrath * compatMakefile (ETAGS, CTAGS): Don't use -t. * arscan.c (ar_name_equal) [cray]: Subtract 1 like [__hpux]. * main.c (decode_switches): For --help, print usage to stdout. Mon Dec 5 12:42:18 1994 Roland McGrath * Version 3.72.3. * remake.c (update_file_1): Do set_command_state (FILE, cs_not_started) only if old state was deps_running. Mon Nov 28 14:24:03 1994 Roland McGrath * job.c (start_waiting_job): Use set_command_state. * build.template (CPPFLAGS): New variable. (prefix, exec_prefix): Set from @...@. (compilation loop): Pass $CPPFLAGS to compiler. * GNUmakefile (build.sh.in): Make it executable. * GNUmakefile (globfiles): Add configure.in, configure. * Version 3.72.2. * configure.in (AC_OUTPUT): Don't write glob/Makefile. * configure.in (AC_CHECK_SYMBOL): Use AC_DEFINE_UNQUOTED. * configure.in: Don't check for ranlib. Tue Nov 22 22:42:40 1994 Roland McGrath * remake.c (notice_finished_file): Only mark also_make's as updated if really ran cmds. Tue Nov 15 06:32:46 1994 Roland McGrath * configure.in: Put dnls before random whitespace. Sun Nov 13 05:02:25 1994 Roland McGrath * compatMakefile (CPPFLAGS): New variable, set from @CPPFLAGS@. (RANLIB): Variable removed. (prefix, exec_prefix): Set these from @...@. (.c.o): Use $(CPPFLAGS). (glob/libglob.a): Don't pass down variables to sub-make. glob/Makefile should be configured properly by configure. (distclean): Remove config.log and config.cache (autoconf stuff). Mon Nov 7 13:58:06 1994 Roland McGrath * acconfig.h: Add #undef HAVE_UNION_WAIT. * configure.in: Converted to Autoconf v2. * dir.c: Test HAVE_DIRENT_H, HAVE_SYS_DIR_H, HAVE_NDIR_H instead of DIRENT, SYSDIR, NDIR. * build.sh.in (prefix, exec_prefix): Set these from @...@. (CPPFLAGS): New variable, set from @CPPFLAGS@. (compiling loop): Pass $CPPFLAGS before $CFLAGS. * install.sh: File renamed to install-sh. * main.c (define_makeflags): When no flags, set WORDS to zero. Sun Nov 6 18:34:01 1994 Roland McGrath * Version 3.72.1. * main.c (define_makeflags): Terminate properly when FLAGSTRING is empty. Fri Nov 4 16:02:51 1994 Roland McGrath * Version 3.72. Tue Nov 1 01:18:10 1994 Roland McGrath * Version 3.71.5. * job.c (start_job_command): When ARGV is nil, only set update_state and call notice_finished_file if job_next_command returns zero. * job.c (start_job_command): Call notice_finished_file for empty command line. Thu Oct 27 02:02:45 1994 Roland McGrath * file.c (snap_deps): Set COMMANDS_SILENT for .SILENT, not COMMANDS_NOERROR. Wed Oct 26 02:14:10 1994 Roland McGrath * Version 3.71.4. Tue Oct 25 22:49:24 1994 Roland McGrath * file.c (snap_deps): Set command_flags bits in all :: entries. Mon Oct 24 18:47:50 1994 Roland McGrath * make.h (posix_pedantic): Declare it. * main.c (main): Move checks .IGNORE, .SILENT, .POSIX to snap_deps. * file.c (snap_deps): Check .IGNORE, .SILENT, .POSIX here instead of in main. If .IGNORE has deps, OR COMMANDS_NOERROR into their command_flags and don't set -i. Likewise .SILENT. * job.c (start_job_command): In FLAGS initialization, OR in CHILD->file->command_flags. * file.h (struct file): New member `command_flags'. Sun Oct 16 01:01:51 1994 Roland McGrath * main.c (switches): Bump flag values for --no-print-directory and --warn-undefined-variables, so neither is 1 (which indicates a nonoption argument). Sat Oct 15 23:39:48 1994 Roland McGrath * main.c (main): Add missing code in .IGNORE test. Mon Oct 10 04:09:03 1994 Roland McGrath * variable.c (define_automatic_variables): Define +D and +F. Sat Oct 1 04:07:48 1994 Roland McGrath * main.c (main): Define hidden automatic variable with command vars, and MAKEOVERRIDES to a reference to that. (define_makeflags): If posix_pedantic, write a reference to that instead. Thu Sep 29 00:14:26 1994 Roland McGrath * main.c (posix_pedantic): New variable. (main): Set posix_pedantic if .POSIX is a target. Fix .IGNORE and .SILENT checks to require is_target. * commands.c (set_file_variables): Define new automatic variable $+, like $^ but before calling uniquize_deps. * job.c (reap_children): Call delete_child_targets for non-signal error if .DELETE_ON_ERROR is a target. Tue Sep 27 01:57:14 1994 Roland McGrath * Version 3.71.3. Mon Sep 26 18:16:55 1994 Roland McGrath * job.c (reap_children): Don't change C->file->command_state when dying. Test it only after calling start_job_command for a new command line. When no more cmds, just set C->file->update_status. (start_job_command): When the last line is empty or under -n, set C->file->update_status. (start_waiting_job): Grok cs_not_started after start_job_command as success. (new_job): Set C->file->update_status when there are no cmds. (job_next_command): When out of lines, don't set CHILD->file->update_status or CHILD->file->command_state. * main.c (quote_as_word): Renamed from shell_quote. Take new arg; if nonzero, also double $s. (main): Define MAKEOVERRIDES from command_variables here. (define_makeflags): Don't use command_variables here; instead write a reference $(MAKEOVERRIDES) in MAKEFLAGS. Make vars recursive. * dir.c [__MSDOS__]: Fixed typo. * vpath.c (selective_vpath_search): Reset EXISTS when stat fails. Sat Sep 10 03:01:35 1994 Roland McGrath * remake.c: Include and use assert instead of printfs and abort. * main.c (decode_switches): Loop until optind hits ARGC, not just until getopt_long returns EOF. Initialize C to zero before loop; in loop if C is EOF, set optarg from ARGV[optind++], else call getopt_long. (decode_env_switches): Use variable_expand instead of allocated_variable_expand. Allocate a fresh buffer to copy split words into; scan characters by hand to break words and debackslashify. (shell_quote): New function. (define_makeflags): Allocate doubled space for switch args, and command variable names and values; use shell_quote to quote those things. Fri Sep 9 01:37:47 1994 Roland McGrath * Version 3.71.2. * acconfig.h: Add HAVE_SYS_SIGLIST and HAVE__SYS_SIGLIST. * main.c (decode_switches): The non-option return from getopt is 1, not 0. (command_variables): New type and variable. (decode_switches, decode_env_switches): After making a variable definition, record the struct variable pointer in the command_variables chain. (define_makeflags): If ALL, write variable definitions for command_variables. * main.c (other_args): Variable removed. (goals, lastgoal): New static variables (moved from auto in main). (main): Don't process OTHER_ARGS at all. Don't set variable MAKEOVERRIDES at all; define MAKE to just $(MAKE_COMMAND). (init_switches): Prepend a - {return in order} instead of a + {require order}. (decode_switches): Don't set OTHER_ARGS at all. Grok '\0' return from getopt_long as non-option argument; try variable definition and (if !ENV) enter goal targets here. (decode_env_switches): Use allocated_variable_expand to store value. Use find_next_token to simplify word-splitting loop. Don't prepend a dash to uninterpreted value. Instead, if split into only one word, try variable definition and failing that prepend a dash to the word and pass it to decode_switches as a single arg. Wed Sep 7 03:02:46 1994 Roland McGrath * remake.c (notice_finished_file): Only recheck modtimes if FILE->command_state was cs_running on entry (meaning the commands actually just ran). (update_file_1): W~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;1|henever we set FILE->update_status, call notice_finished_file instead of just set_command_state. * job.c (start_job_command): Whenever we set CHILD->file->update_status, call notice_finished_file instead of just set_command_state. Tue Sep 6 19:13:54 1994 Roland McGrath * default.c: Add missing ". * job.c: Changed all assignments of command_state members to calls to set_command_state. * remake.c: Likewise. * file.c (set_command_state): New function. * file.h: Declare set_command_state. * main.c (init_switches): Put a + first in options. Mon Jul 25 18:07:46 1994 Roland McGrath Merge MSDOS/GO32 port from DJ Delorie . * vpath.c: Changed all uses of ':' to PATH_SEPARATOR_CHAR. * main.c (directory_before_chdir): New variable, moved out of main (was local). (main) [__MSDOS__]: Look for \ or : to delimit last component of PROGRAM. Don't frob ARGV[0] before setting MAKE_COMMAND variable. (die): Change back to `directory_before_chdir' before dying. * make.h (PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not. * job.c [__MSDOS__]: Include . [__MSDOS__] (dos_pid, dos_status, dos_bname, dos_bename, dos_batch_file): New variables. (reap_children) [__MSDOS__]: Don't call wait; just examine those vars. (unblock_sigs) [__MSDOS__]: Do nothing. (start_job_command) [__MSDOS__]: Use spawnvpe instead of vfork & exec. (load_too_high) [__MSDOS__]: Always return true. (search_path) [__MSDOS__]: Check for : or / in FILE to punt. Use PATH_SEPARATOR_CHAR instead of ':'. (construct_command_argv_internal) [__MSDOS__]: Wholly different values for sh_chars and sh_cmds. Wholly new code to handle shell scripts. * function.c (expand_function: `shell') [__MSDOS__]: Wholly new implementation. * dir.c [__MSDOS__] (dosify): New function. (dir_contents_file_exists_p) [__MSDOS__]: Call it on FILENAME and process the result instead of FILENAME itself. (file_impossible_p) [__MSDOS__]: Likewise. * default.c [__MSDOS__]: Define GCC_IS_NATIVE. (default_suffix_rules) [__MSDOS__]: Use `y_tab.c' instead of `y.tab.c'. (default_variables) [GCC_IS_NATIVE]: Set CC and CXX to `gcc', YACC to `bison -y', and LEX to `flex'. * configure.bat, configh.dos: New files. * commands.c (fatal_error_signal) [__MSDOS__]: Just remove intermediates and exit. * commands.c (set_file_variables): Add parens in length computation in .SUFFIXES dep loop to quiet compiler warning. From Jim Meyering. * read.c (read_makefile): Free FILENAME if we allocated it. From Jim Meyering. Mon Jul 4 17:47:08 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * misc.c (safe_stat): New function, EINTR-safe wrapper around stat. * vpath.c (selective_vpath_search): Use safe_stat in place of stat. * read.c (construct_include_path): Use safe_stat in place of stat. * job.c (search_path): Use safe_stat in place of stat. * dir.c (find_directory): Use safe_stat in place of stat. * commands.c (delete_target): Use safe_stat in place of stat. * arscan.c (ar_member_touch) [EINTR]: Do EINTR looping around fstat. * remake.c (name_mtime): Use safe_stat in place of stat. (touch_file) [EINTR]: Do EINTR looping around fstat. Fri Jun 24 05:40:24 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Check for a shell command first, and then strip leading tabs before further checking if it's not a shell command line. * make.h [__arm]: Undefine POSIX. [!__GNU_LIBRARY__ && !POSIX && !_POSIX_VERSION]: Don't declare system functions that return int. * job.c (construct_command_argv_internal): After swallowing a backslash-newline combination, if INSTRING is set goto string_char (new label) for normal INSTRING handling code. Sat Jun 4 01:11:20 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) * configure.in: Don't check for sys_siglist and _sys_siglist with AC_HAVE_FUNCS. Instead use two AC_COMPILE_CHECKs. Mon May 23 18:20:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.71.1 released. * make.h [!__GNU_LIBRARY__ && !POSIX]: Also test #ifndef _POSIX_VERSION for these declarations. * misc.c [GETLOADAVG_PRIVILEGED] [POSIX]: Remove bogus #ifndefs around #undefs of HAVE_SETREUID and HAVE_SETREGID. Sat May 21 16:26:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.71 released. * misc.c [GETLOADAVG_PRIVILEGED] [POSIX]: Don't test [HAVE_SETUID] and [HAVE_SETGID]. Every system has those, and configure doesn't check for them. * make.h [_POSIX_VERSION]: Don't #define POSIX #ifdef ultrix. * compatMakefile (loadavg): Depend on and use loadavg.c instead of getloadavg.c. (loadavg.c): Link or copy it from getloadavg.c. (distclean): Remove loadavg.c. Mon May 16 22:59:04 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.70.4. * misc.c [GETLOADAVG_PRIVILEGED] [! POSIX]: Undefine HAVE_SETEUID and HAVE_SETEGID. * default.c (default_terminal_rules): In SCCS rules, put $(SCCS_OUTPUT_OPTION) before $<. On some systems -G is grokked only before the file name. * configure.in (SCCS_GET_MINUS_G check): Put -G flag before file name. Tue May 10 16:27:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Swallow backslash-newline combinations inside '' strings too. Thu May 5 04:15:10 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (do_define): Call collapse_continuations on each line before all else. Mon Apr 25 19:32:02 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Notice newline inside '' string when RESTP is non-null. Fri Apr 22 17:33:30 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.70.3. * remake.c (update_goal_chain): Reset FILE to G->file after the double-colon loop so it is never null for following code. * read.c (read_makefile): Fix `override define' parsing to skip whitespace after `define' properly. * compatMakefile (srcdir): Define as @srcdir@; don't reference $(VPATH). (glob/Makefile): New target. Thu Apr 21 16:16:55 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.70.2. * misc.c (remove_comments): Use find_char_unquote. * make.h (find_char_unquote): Declare it. * read.c (find_char_unquote): New function, generalized from find_percent. (find_percent, find_semicolon, parse_file_seq): Use that. Wed Apr 20 18:42:39 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * implicit.c (pattern_search): Always allocate new storage for FILE->stem. It is not safe to store STEM's address because it might be auto storage. * configure.in: Check for seteuid and setegid. * misc.c [HAVE_SETEUID]: Declare seteuid. [HAVE_SETEGID]: Declare setegid. (make_access, user_access) [HAVE_SETEUID]: Use seteuid. [HAVE_SETEGID]: Use setegid. * remake.c (update_goal_chain): Set STATUS to FILE->update_status, to preserve whether it's 2 for error or 1 for -q trigger. When STATUS gets nonzero and -q is set, always stop immediately. * main.c (main, decode_switches): Die with 2 for errors. (main): Accept 2 return from update_goal_chain and die with that. * misc.c (fatal, makefile_fatal): Die with 2; 1 is reserved for -q answer. * job.c (reap_children): Die with 2 for error. (start_job_command): Set update_status to 2 for error. Set it to 1 when we would run a command and question_flag is set. * read.c (read_makefile): Don't mark makefiles as precious. Just like other targets, they can be left inconsistent and in need of remaking by aborted commands. * read.c (read_makefile): Write no error msg for -include file. Tue Apr 5 05:22:19 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * commands.c (fatal_error_signal): Don't unblock signals. * file.h (struct file): Change member `double_colon' from flag to `struct file *'. * read.c (record_files): Set double_colon pointer instead of flag. * main.c (main): When disqualifying makefiles for updating, use double_colon pointer to find all entries for a file. * file.c (enter_file): If there is already a double-colon entry for the file, set NEW->double_colon to that pointer. (file_hash_enter): Use FILE->double_colon to find all entries to set name. * remake.c (update_goal_chain): Do inner loop on double-colon entries. (update_file): Use FILE->double_colon pointer to find all entries. (f_mtime): Likewise. (notice_finished_file): Propagate mtime change to all entries. * variable.c (try_variable_definition): Return after abort. Fri Apr 1 18:44:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Remove unused variable. (parse_file_seq): When removing an elt that is just `)', properly fix up the previous elt's next pointer. Mon Mar 28 18:31:49 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) * configure.in: Do AC_SET_MAKE. * GNUmakefile (Makefile.in): Edit MAKE assignment into @SET_MAKE@. Fri Mar 4 00:02:32 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * function.c (subst_expand): If BY_WORD or SUFFIX_ONLY is set and the search string is the empty string, find a match at the end of each word (using end_of_token in place of sindex). * misc.c (end_of_token): Don't treat backslashes specially; you can no longer escape blanks with backslashes in export, unexport, and vpath. This was never documented anyway. Thu Mar 3 23:53:46 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Variable name for `define' is not just first token; use whole rest of line and strip trailing blanks. Wed Feb 16 16:03:45 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.70.1. * read.c (read_makefile): Add -d msg stating args. * read.c (read_makefile): Use isspace to skip over leading whitespace, and explicitly avoid skipping over tabs. Don't want to skip just spaces though; formfeeds et al should be skipped. * default.c (default_variables) [__hpux]: Add f in ARFLAGS. * arscan.c (ar_name_equal) [__hpux]: Subtract 2 instead of 1 from sizeof ar_name for max length to compare. * misc.c [GETLOADAVG_PRIVILEGED] [POSIX]: Undefine HAVE_SETREUID #ifdef HAVE_SETUID; likewise HAVE_SETREGID and HAVE_SETGID. * main.c (main): Call user_access after setting `program', in case it needs to use it in an error message. * read.c (read_makefile): Ignore an empty line starting with a tab. Thu Feb 10 21:45:31 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in (AC_SYS_SIGLIST_DECLARED): Use this instead of AC_COMPILE_CHECK that is now its contents. Fri Feb 4 16:28:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * make.h: #undef strerror after #include . [! ANSI_STRING]: Declare strerror. Thu Feb 3 02:21:22 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * misc.c (strerror): #undef any macro before function definition. Mon Jan 31 19:07:23 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.c (try_variable_definition): Calculate BEG before loop to strip blanks by decrementing END. Don't decr END to before BEG. * read.c (read_makefile): Skip over leading space characters, but not tabs, after removing continuations and comments (it used to use isspace). Tue Jan 25 16:45:05 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.c (define_automatic_variables): In $(@D) et al, use patsubst to remove trailing slash. * commands.c (delete_target): New function, broken out of delete_child_targets. Check for archive members and give special msg. (delete_child_targets): Use delete_target. Mon Jan 17 17:03:22 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * default.c (default_suffix_rules): Use $(TEXI2DVI_FLAGS) in texi2dvi rules. Use $(MAKEINFO_FLAGS) in makeinfo rules. Tue Jan 11 19:29:55 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * GNUmakefile (tarfiles): Omit make-doc. (make-$(version).tar): Include make.info*. Fri Jan 7 16:27:00 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (configure, config.h.in): Comment out rules. Thu Jan 6 18:08:08 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (binprefix, manprefix): New variables. (instname): Variable removed. (install): Use $({bin,man}prefix)make in place of $(instname). File targets likewised renamed. Mon Jan 3 17:50:25 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.70 released. Thu Dec 23 14:46:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.69.3. * read.c (parse_file_seq): Inside multi-word archive ref translation loop, check NEW1==0 at end and break out of the loop. * GNUmakefile (make-$(version).tar): Distribute install.sh. * install.sh: New file. * configure.in (SCCS_GET_MINUS_G check): Put redirection for admin cmds outside subshell parens, to avoid "command not found" msgs from the shell. Wed Dec 22 17:00:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in (SCCS_GET_MINUS_G check): Put -G flag last in get cmd. Redirect output & error from get to /dev/null. Fix reversed sense of test. Fri Dec 17 15:31:36 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in (SCCS_GET_MINUS_G check): Use parens instead of braces inside if condition command; some shells lose. Thu Dec 16 15:10:23 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.69.2. * arscan.c [M_UNIX]: Move #undef M_XENIX for PORTAR stuff. (PORTAR) [M_XENIX]: Define to 0 instead of 1. * main.c (define_makeflags): Only export MAKEFLAGS if !ALL. Wed Dec 15 17:47:48 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (main): Cast result of pointer arith to unsigned int before passing to define_variable for envars. Matters when sizeof(unsigned)!=sizeof(ptrdiff_t). Tue Dec 14 14:21:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in: Add new check for SCCS_GET_MINUS_G. * config.h.in: Add #undef SCCS_GET_MINUS_G. * default.c (default_terminal_rules): Use `$(SCCS_OUTPUT_OPTION)' in place of `-G $@' in SCCS commands. (default_variables) [SCCS_GET_MINUS_G]: Define SCCS_OUTPUT_OPTION to "-G$@". * configure.in (AC_OUTPUT): Put touch stamp-config in second arg (so it goes in config.status), rather than afterward. * ar.c (ar_member_date): Don't call enter_file on the archive file if it doesn't exist (by file_exists_p). * compatMakefile ($(infodir)/make.info): Replace `$$d/foo.info' with `$$dir/make.info' in install-info invocation (oops). * vpath.c (construct_vpath_list): Only set LASTPATH set PATH when we do not unlink and free PATH. * file.c (print_file_data_base): Fix inverted calculation for average files per hash bucket. * read.c (readline): When we see a NUL, give only a warning and synthesize a newline to terminate the building line (used to fatal). Move fgets call into the loop condition, and after the loop test ferror (used to test !feof in the loop). Fri Dec 3 16:40:31 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in: Check for strerror in AC_HAVE_FUNCS. Thu Dec 2 15:37:50 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) Differentiate different flavors of missing makefile error msgs, removing gratuitous `fopen: ' and giving caller for included makefiles. * misc.c [! HAVE_STRERROR]: Define our own strerror here. (perror_with_name, pfatal_with_name): Use strerror instead of replicating its functionality. * read.c (read_makefile): Return int instead of void. (read_all_makefiles, read_makefile): Change callers to notice zero return and give error msg. Thu Nov 11 11:47:36 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.69.1. * default.c: Put `-G $@' before $< in SCCS cmds. Wed Nov 10 06:06:14 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): After trying a variable defn, notice if the line begins with a tab, and diagnose an error. Sun Nov 7 08:07:37 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.69. Wed Nov 3 06:54:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.10. * implicit.c (try_implicit_rule): Look for a normal rule before an archive rule. Fri Oct 29 16:45:28 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * function.c (expand_function: `sort'): Double NWORDS when it overflows, instead of adding five. * compatMakefile (clean): Remove loadavg. Wed Oct 27 17:58:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.9. * file.h (NEW_MTIME): Define new macro. * main.c (main): Set time of NEW_FILES to NEW_MTIME, not to current time returned from system. Removed variable NOW. * remake.c (notice_finished_file): Use NEW_MTIME in place of current time here too. Tue Oct 26 19:45:35 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.8. * remake.c (update_file_1): Don't clear MUST_MAKE when FILE has no cmds and !DEPS_CHANGED unless also !NOEXIST. Mon Oct 25 15:25:21 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (parse_file_seq): When converting multi-word archive refs, ignore a word beginning with a '('. Fri Oct 22 02:53:38 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in: Check for sys/timeb.h. * make.h [HAVE_SYS_TIMEB_H]: Test this before including it. Thu Oct 21 16:48:17 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.7. * rule.c (convert_suffix_rule): New local TARGPERCENT. Set it to TARGNAME+1 for "(%.o)", to TARGNAME for "%.?". Use it in place of TARGNAME to initialize PERCENTS[0]. Mon Oct 18 06:49:35 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in: Use AC_HAVE_HEADERS(unistd.h) instead of AC_UNISTD_H. Remove AC_USG; it is no longer used. * file.c (print_file): New function, broken out of print_file_data_base. (print_file_data_base): Call it. * rule.c (print_rule): New function, broken out of print_rule_data_base. (print_rule_data_base): Call it. Thu Oct 14 14:54:03 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * default.c (install_default_suffix_rules): New function, broken out of install_default_implicit_rules. (install_default_implicit_rules): Move suffix rule code there. * make.h: Declare install_default_suffix_rules. * main.c (main): Call install_default_suffix_rules before reading makefiles. Move convert_to_pattern call before install_default_implicit_rules. * job.h (struct child): Make `pid' member type `pid_t' instead of `int'. * compatMakefile (RANLIB): New variable, set by configure. (glob/libglob.a): Pass RANLIB value down to submake. Fixes for SCO 3.2 "devsys 4.2" from pss@tfn.com (Peter Salvitti). * make.h: Include before for SCO lossage. * job.c [! getdtablesize] [! HAVE_GETDTABLESIZE]: If NOFILE is not defined but NOFILES_MAX is, define it to be that. Mon Oct 11 19:47:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * GNUmakefile (make-$(version).tar): Depend on acconfig.h, so it is distributed. Sun Oct 3 15:15:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * default.c (default_terminal_rules): Add `-G $@' to SCCS get cmds. Tue Sep 28 14:18:20 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Add ^ to SH_CHARS; it is another symbol for | in some shells. * main.c (main): Add it to CMD_DEFS quoting list as well. Mon Sep 20 18:05:24 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Remove '=' from SH_CHARS. Only punt on '=' if it is unquoted in a word before the first word without an unquoted '='. * main.c (define_makeflags): Set v_export for MAKEFLAGS. Fri Sep 17 00:37:18 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * remake.c (update_file_1): Use .DEFAULT cmds for phony targets. * make.h [_AIX && _POSIX_SOURCE]: Define POSIX. * commands.c (delete_child_targets): Don't delete phony files. * job.c (start_job_command): Set COMMANDS_RECURSE in FLAGS if we see a `+' at the beginning of the command line. Thu Sep 9 17:57:14 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.6. Wed Sep 8 20:14:21 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (define_makeflags): Define MAKEFLAGS with o_file, not o_env. Mon Aug 30 12:31:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * expand.c (variable_expand): Fatal on an unterminated reference. Thu Aug 19 16:27:53 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.5. * variable.c (define_automatic_variables): Define new o_default variable `MAKE_VERSION' from version_string and remote_description. * make.h (version_string, remote_description): Declare these here. * main.c: Don't declare version_string. (print_version): Don't declare remote_description. Wed Aug 18 15:01:24 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Free space pointed to by CONDITIONALS before restoring the old pointer. Mon Aug 16 17:33:36 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile ($(objs)): Depend on config.h. * GNUmakefile (build.sh.in): Depend on compatMakefile. * configure.in: Touch stamp-config after AC_OUTPUT. Fri Aug 13 16:04:22 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.4. Thu Aug 12 17:18:57 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * make.h: Include instead of "config.h". Wed Aug 11 02:35:25 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (main): Make all variables interned from ENVP be v_export. * variable.c (try_variable_definition): In v_default case, don't check for an o_file variable that `getenv' finds. * job.c (reap_children): New local variable ANY_LOCAL; set it while setting ANY_REMOTE. If !ANY_LOCAL, don't wait for local kids. * main.c (main): Don't call decode_env_switches on MFLAGS. DOC THIS. * function.c (expand_function): #if 0 out freeing of ENVP since it is environ. Mon Aug 9 17:37:20 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.3. * remote-stub.c (remote_status): Set errno to ECHILD before return. * job.c (reap_children): Scan the chain for remote children and never call remote_status if there are none. * function.c (expand_function: `shell'): #if 0 out calling target_environment; just set ENVP to environ instead. * job.c (reap_children): Check for negative return from remote_status and fatal for it. When blocking local child wait returns 0, then try a blocking call to remote_status. Tue Aug 3 00:19:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (clean): Delete make.info* and make.dvi here. (distclean): Not here. * dep.h (RM_*): Use #defines instead of enum to avoid lossage from compilers that don't like enum values used as ints. Mon Aug 2 16:46:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (loadavg): Add $(LOADLIBES). Sun Aug 1 16:01:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.2. * compatMakefile (loadavg, check-loadavg): New targets. (check): Depend on check-loadavg. * compatMakefile (glob/libglob.a): Depend on config.h. * misc.c (log_access): Write to stderr instead of stdout. Fri Jul 30 00:07:02 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68.1. Thu Jul 29 23:26:40 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in (SYS_SIGLIST_DECLARED): In test program include #ifdef HAVE_UNISTD_H. * compatMakefile (.PHONY): Put after `all' et al. * configure.in: Add AC_IRIX_SUN. Wed Jul 28 17:41:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.68. Mon Jul 26 14:36:49 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.8. Sun Jul 25 22:09:08 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.7. * compatMakefile ($(infodir)/make.info): Don't use $(instname). Run install-info script if present. Fri Jul 23 16:03:50 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * make.h [STAT_MACROS_BROKEN]: Test this instead of [uts]. * configure.in: Add AC_STAT_MACROS_BROKEN. Wed Jul 14 18:48:11 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.6. * read.c (read_makefile): Recognize directive `-include', like `include' but sets RM_DONTCARE flag. * variable.c (target_environment): If FILE is nil, use current_variable_set_list in place of FILE->variables. * function.c (expand_function: `shell'): Get an environment for the child from target_environment instead of using environ. * dep.h: Declare read_all_makefiles here. (RM_*): Define new enum constants. * read.c (read_makefile): Second arg is FLAGS instead of TYPE. Treat it as a bit mask containing RM_*. (read_all_makefiles): For default makefiles, set D->changed to RM_DONTCARE instead of 1. * main.c: Don't declare read_all_makefiles here. (main): Check `changed' member of read_makefiles elts for RM_* flags instead of specific integer values. Mon Jul 12 22:42:17 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * make.h [sequent && i386]: #undef POSIX. From trost@cse.ogi.edu. Thu Jul 8 19:51:23 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * vpath.c (construct_vpath_list): If ELEM is zero 0, free PATTERN as well as VPATH. (build_vpath_lists): Empty `vpaths' around construct_vpath_list call for $(VPATH). Expand $(strip $(VPATH)), not just $(VPATH). * rule.c (convert_suffix_rule): Use alloca instead of xmalloc for PERCENTS, whose storage is not consumed by create_pattern_rule. * make.h [__mips && _SYSTYPE_SVR3]: #undef POSIX. Wed Jun 30 18:11:40 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.5. * rule.c (max_pattern_targets): New variable. (count_implicit_rule_limits): Compute its value. * rule.h: Declare it. * implicit.c (pattern_search): Make TRYRULES max_target_patterns times bigger. Move adding new TRYRULES elt inside the inner targets loop, so each matching target gets its own elt in MATCHES and CHECKED_LASTSLASH. * file.c (remove_intermediates): If SIG!=0 say `intermediate file' instead of just `file' in error msg. Fri Jun 25 14:55:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv): Turn off --warn-undefined-variables around expansion of SHELL and IFS. * read.c (tilde_expand): Likewise for HOME. (read_all_makefiles): Likewise for MAKEFILES. * vpath.c (build_vpath_lists): Likewise for VPATH. * main.c (warn_undefined_variables_flag): New flag variable. (switches): Add --warn-undefined-variables. * make.h (warn_undefined_variables_flag): Declare it. * expand.c (warn_undefined): New function. (reference_variable): Call it if the variable is undefined. (variable_expand): In substitution ref, call warn_undefined if the variable is undefined. * default.c (default_pattern_rules): Add `%.c: %.w %.ch' and `%.tex: %.w %.ch' rules. (default_suffix_rules: .w.c, .w.tex): Pass three args: $< - $@. (default_suffixes): Add `.ch'. Mon Jun 21 17:55:39 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * default.c (default_suffixes): Replace `.cweb' with `.w'. (default_suffix_rules): Rename `.cweb.c' and `.cweb.tex' to `.w.c' and `.w.tex'. Fri Jun 11 14:42:09 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile ($(bindir)/$(instname)): Add missing backslash. Thu Jun 10 18:14:08 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.4. * read.c (multi_glob): Don't free OLD and OLD->name in the FOUND!=0 fork. Use new block-local variable F instead of clobbering OLD. * ar.c (glob_pattern_p): New function, snarfed from glob/glob.c. (ar_glob): Call it; return nil immediately if MEMBER_PATTERN contains no metacharacters. Wed Jun 9 16:25:35 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * ar.c (ar_glob{_match,_alphacompare}): New function. * dep.h [! NO_ARCHIVES]: Declare it. * read.c (multi_glob) [! NO_ARCHIVES]: Use it on archive member elts. * read.c (read_makefile): Pass flag (1) to parse_file_seq, not to multi_glob (which doesn't take a 3rd arg). * rule.c (install_pattern_rule): Likewise. * default.c (set_default_suffixes): Here too. * function.c (string_glob): Don't pass gratuitous arg to multi_glob. * read.c (parse_file_seq) [! NO_ARCHIVES]: Add post-processing loop to translate archive refs "lib(a b)" into "lib(a) lib(b)". Mon Jun 7 19:26:51 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (installdirs): Actually pass directory names. ($(bindir)/$(instname)): Test chgrp&&chmod exit status with `if'; if it fails, echo a warning msg, but don't make the rule fail. * read.c (tilde_expand): New function, broken out of tilde_expand. (multi_glob): Call it. (construct_include_path): Expand ~ in directory names. * dep.h: Declare tilde_expand. * main.c (enter_command_line_file): Expand ~ at the start of NAME. (main): Expand ~ in -C args. * read.c (read_makefile): Expand ~ in FILENAME unless TYPE==2. Fri Jun 4 13:34:47 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (decode_env_switches): Use xmalloc instead of alloca for ARGS. * main.c (main): Put result of alloca in temporary variable with simple assignment, to make SGI compiler happy. Thu Jun 3 20:15:46 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.3. * main.c (main): Before re-execing, remove intermediate files, and print the data base under -p. Sexier debugging message. * implicit.c (pattern_search): Allocate an extra copy of the name of a winning intermediate file when putting it in FOUND_FILES. Wed Jun 2 16:38:08 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Pass flag (1) to parse_file_seq, not to multi_glob (which doesn't take a 3rd arg). * dir.c (dir_contents_file_exists_p): When reading dirents, ignore chars within D_NAMLEN that are NULs. * main.c (decode_switches): Don't savestring ARGV[0] to put it into `other_args'. For string switch, don't savestring `optarg'. (main): Don't free elts of makefiles->list that are "-". Use alloca'd rather than savestring'd storage for elts of makefiles->list that are temporary file names. * read.c (read_all_makefiles): Don't free *MAKEFILES. * file.c (enter_file): Don't strip `./'s. * main.c (enter_command_line_file): New function. (main): Use it in place of enter_file for command-line goals from other_files, and for old_files and new_files. Mon May 31 18:41:40 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.2. * compatMakefile (.SUFFIXES): Add .info. ($(infodir)/$(instname).info): Find make.info* in cwd if there, else in $srcdir. Use basename to remove dir name from installed name. Thu May 27 17:35:02 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * implicit.c (pattern_search): When interning FOUND_FILES, try lookup_file first; if found, free the storage for our copy of the name. Wed May 26 14:31:20 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67.1. * main.c (decode_switches): In usage msg, write `--switch=ARG' or `--switch[=OPTARG]' rather than `--switch ARG' or `--switch [ARG]'. Mon May 24 16:17:31 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * rule.c (convert_suffix_rule): New function. (convert_to_pattern): Use it instead of doing all the  ~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;1^[8work here several times. For target suffix `.a', generate both the archive magic rule and the normal rule. * compatMakefile (distclean): Remove stamp-config. Sat May 22 16:15:18 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.67. * file.c (remove_intermediates): Don't write extra space after `rm'. * main.c (struct command_switch.type): Remove `usage_and_exit'. (print_usage_flag): New variable. (switches: --help): Make type `flag', to set print_usage_flag. (init_switches): Remove `usage_and_exit' case. (decode_switches): Likewise. (decode_switches): Print usage if print_usage_flag is set. When printing usage, die with status of BAD. (main): Die with 0 if print_version_flag. Fri May 21 16:09:28 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.66. Wed May 19 21:30:44 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (installdirs): New target. (install): Depend on it. Sun May 16 20:15:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.65.2. Fri May 14 16:40:09 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * vpath.c (construct_vpath_list): In removal loop for DIRPATH==0, set LASTPATH to PATH, not NEXT. * dir.c (read_dirstream): Break out of loop after incrementing DS->buckets such that it reaches DIRFILE_BUCKETS; avoid trying to dereference DS->contents->files[DIRFILE_BUCKETS]. * read.c (read_makefile): Clear no_targets after reading a targetful rule line. * main.c (main): If print_version_flag is set, exit after printing the version. (switches): Change --version docstring to say it exits. * make.h [butterfly]: #undef POSIX. Wed May 12 15:20:21 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.65.1. * arscan.c (ar_scan) [! AIAMAG]: Don't declare LONG_NAME. [AIAMAG]: Pass TRUNCATE flag arg to (*FUNCTION), always zero. * function.c (handle_function): Use fatal instead of makefile_fatal when reading_filename is nil. * configure.in: Add AC_GETGROUPS_T. * job.c (search_path): Use GETGROUPS_T in place of gid_t. Sun May 9 15:41:25 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.65. Fri May 7 18:34:56 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * function.c (handle_function): Fatal for unmatched paren. Thu May 6 16:13:41 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.64.3. * commands.c (handling_fatal_signal): New variable. (fatal_error_signal): Set it. * job.c (reap_children): Avoid nonreentrant operations if that is set. * make.h: Declare handling_fatal_signal. * expand.c (reference_variable): New function, snippet of code broken out of simple-reference case of variable_expand. (variable_expand): Use it for simple refs. (variable_expand): When checking for a computed variable name, notice a colon that comes before the final CLOSEPAREN. Expand only up to the colon, and then replace the pending text with a copy containing the expanded name and fall through to subst ref handling. (variable_expand): Don't bother expanding the name if a colon appears before the first $. (expand_argument): Use alloca instead of savestring. (variable_expand): For subst ref, expand both sides of = before passing to [pat]subst_expand. Use find_percent instead of lindex to check the lhs for a %. Wed May 5 14:45:52 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.64.2. Mon May 3 17:00:32 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * arscan.c (ar_name_equal) [AIAMAG]: Abort if TRUNCATED is nonzero. * read.c (read_makefile): Pass extra arg of 1 to parse_file_seq, not to multi_glob. Thu Apr 29 19:47:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.64.1. * arscan.c (ar_scan): New local flag var LONG_NAME. Set it when we read the member name in any of the fashions that allow it to be arbitrarily long. Pass its negation to FUNCTION. (describe_member): Take TRUNCATED from ar_scan and print it. (ar_name_equal): Take new arg TRUNCATED; if nonzero, compare only the first sizeof (struct ar_hdr.ar_name) chars. (ar_member_pos): Take TRUNCATED from ar_scan, pass to ar_name_equal. * ar.c (ar_member_date_1): Likewise. Wed Apr 28 21:18:22 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (reap_children): Before calling start_job_command to start the next command line, reset C->remote by calling start_remote_job_p. Mon Apr 26 15:56:15 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * arscan.c (ar_scan): New local var NAMEMAP. In loop, rename NAME to NAMEBUF; new var NAME is a pointer; new flag IS_NAMEMAP. When extracting the member name, always put a null at its end first. If the name is "//" or "/ARFILENAMES", set IS_NAMEMAP. If we have already read in NAMEMAP, and NAME looks like " /N", get full name from NAMEMAP+N. Else if NAME looks like "#1/N", read N chars from the elt data to be the full name. At end of loop, if IS_NAMEMAP, read the elt's data into alloca'd NAMEMAP. (ar_name_equal): #if 0 truncating code. * make.h: Don't declare vfork at all. It returns int anyway, unless declared it; and we conflicted with some systems. * main.c (define_makeflags): If FLAGSTRING[1] is '-', define MAKEFLAGS to all of FLAGSTRING, not &FLAGSTRING[1]. Don't want to define it to something like "-no-print-directory". Use %g format instead of %f for floating-valued things. Thu Apr 22 18:40:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * GNUmakefile (Makefile.in): Use a substitution ref on nolib-deps to change remote-%.dep to remote-stub.dep. Wed Apr 21 15:17:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.64. Fri Apr 16 14:22:22 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (install): Remove - prefix from chgrp+chmod. * Version 3.63.8. Thu Apr 15 18:24:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * acconfig.h: New file; contains "#undef SCCS_GET" for autoheader. * configure.in: If /usr/sccs/get exists, define SCCS_GET to that, else to "get". * default.c (default_variables): Set GET to macro SCCS_GET. * read.c (parse_file_seq): Take extra arg STRIP; strip `./' only if nonzero. I hope this is the last time this argument is added or removed. (read_makefile): Pass it 1 when parsing include file names. Pass it 1 when parsing target file names. Pass it 1 when parsing static pattern target pattern names. * rule.c (install_pattern_rule): Pass it 1 when parsing rule deps. * default.c (set_default_suffixes): Pass it 1 when parsing default_suffixes. * function.c (string_glob): Pass it 0 here. Wed Apr 14 11:32:05 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * misc.c (log_access): New function. ({init,user,make,child}_access): Call it. (child_access): Abort if !access_inited. * main.c (switches: --no-print-directory): Use 1 instead of -1 for single-letter option. (init_switches, decode_switches, define_makeflags): An option with no single-letter version is no longer indicated by a value of -1; instead a value that is !isalnum. (init_switches): Don't put such switches into the string, only into the long_option table. * make.h [!NSIG] [!_NSIG]: #define NSIG 32. * job.c [HAVE_WAITPID]: Remove #undef HAVE_UNION_WAIT. AIX's bsdcc defined WIF* to use union wait. * main.c (struct command_switch): Change member `c' to type int. (switches): Make const. (decode_switches): Use `const struct command_switch *'. (define_makeflags): Likewise. * default.c (default_suffix_rules): Add `-o $@' to makeinfo rules. Mon Apr 12 12:30:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.63.7. * configure.in (AC_HAVE_HEADERS): Check for string.h and memory.h. Removed AC_MEMORY_H. * make.h [USG, NeXT]: Don't test these. [HAVE_STRING_H]: Test this to include string.h and define ANSI_STRING. [HAVE_MEMORY_H]: Test this instead of NEED_MEMORY_H. [! ANSI_STRING]: Put decls of bcopy et al here. [sparc]: Don't test this for alloca.h; HAVE_ALLOCA_H is sufficient. [HAVE_SIGSETMASK]: Test this rather than USG. [__GNU_LIBRARY__ || POSIX]: Don't #include again. * main.c (main): Handle SIGCHLD if defined, and SIGCLD if defined. It doesn't hurt to do both if they are both defined, and testing USG is useless. * dir.c: Rationalize directory header conditionals. * arscan.c [HAVE_FCNTL_H]: Test this rather than USG || POSIX. * default.c (default_suffixes): Add `.txinfo'. (default_suffix_rules): Add `.txinfo.info' and `.txinfo.dvi' rules. * variable.c (try_variable_definition): Replace RECURSIVE flag with enum FLAVOR, which can be simple, recursive, or append. Recognize += as append flavor. Set new variable VALUE in a switch on FLAVOR. For append flavor, prepend the variable's old value. If the variable was previously defined recursive, set FLAVOR to recursive; if it was defined simple, expand the new value before appending it to the old value. Pass RECURSIVE flag to define_variable iff FLAVOR == recursive. * variable.c (try_variable_definition): Use alloca and bcopy for NAME, instead of savestring. Might as well use stack storage since we free it immediately anyway. Thu Apr 8 18:04:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (start_waiting_jobs): Move decl of JOB outside of loop. * main.c (define_makeflags): Rename `struct flag' member `switch' to `cs', which is not a reserved word. Wed Apr 7 15:30:51 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (new_job): Call start_waiting_jobs first thing. (start_waiting_job): Changed return type from void to int. Return 0 when putting the child on the waiting_jobs chain. (start_waiting_jobs): Don't check load and job_slots here. Always take a job off the chain and call start_waiting_job on it; give up and return when start_waiting_job returns zero. * main.c (define_makeflags: struct flag): Change member `char c' to `struct command_switch *switch'. (ADD_FLAG): Set that to CS instead of CS->c. If CS->c is -1, increment FLAGSLEN for the long name. When writing out FLAGS, handle FLAGS->switch->c == -1 and write the long name instead. * compatMakefile (stamp-config): New target of old config.h rule. Touch stamp-config after running config.status. (config.h): Just depend on stamp-config, and have empty commands. Mon Apr 5 20:14:02 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c [HAVE_WAITPID]: #undef HAVE_UNION_WAIT. * configure.in (AC_HAVE_FUNCS): Check for psignal. Fri Apr 2 17:15:46 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (long_option_aliases): Remove "new"; it is already an unambiguous prefix of "new-file". Sun Mar 28 16:57:17 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.63.6. Wed Mar 24 14:26:19 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * vpath.c (selective_vpath_search): When adding the name-within-directory at the end of NAME, and we don't add a slash, don't copy FILENAME in one char too far into NAME. * variable.c (define_automatic_variables): Find default_shell's length with strlen, not numerology. Wed Mar 17 20:02:27 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (define_makeflags): Add the elts of a string option in reverse order, so they come out right when reversed again. Fri Mar 12 15:38:45 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (make.info): Use `-o make.info'. Thu Mar 11 14:13:00 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (REMOTE): Set to @REMOTE@; change comments to reflect new use. (objs): Replace remote.o with remote-$(REMOTE).o. (srcs): Replace remote.c with remote-$(REMOTE).c. (remote.o): Rule removed. * configure.in (REMOTE): Subst this in Makefile et al; default "stub". Use AC_WITH to grok --with-customs arg to set REMOTE=cstms. * GNUmakefile (build.sh.in): Filter out remote-% from objs list. * build.template (REMOTE): New var; set to @REMOTE@. (objs): Add remote-${REMOTE}.o. Wed Mar 10 15:12:24 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.63.5. * implicit.c (pattern_search): Fix "dependent"->"dependency" in "Rejecting impossible" -d msg. * file.c (file_hash_enter): New local vars {OLD,NEW}BUCKET. Store mod'd values there; never mod {OLD,NEW}HASH. Mon Mar 8 13:32:48 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * remake.c [eta10]: Include instead of . * compatMakefile (VPATH): Set this to @srcdir@. (srcdir): Set this to $(VPATH). * main.c (main): New local var DIRECTORY_BEFORE_CHDIR. Save in it a copy of CURRENT_DIRECTORY after the first getcwd. Use it instead of CURRENT_DIRECTORY when chdir'ing back before re-execing. * remake.c (notice_finished_file): Pass missing SEARCH arg to f_mtime. * read.c (read_makefile): Remove extraneous arg to parse_file_seq. Mon Feb 22 14:19:38 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile ($(infodir)/$(instname).info): Use , instead of / as the sed delimiter char. Sun Feb 21 14:11:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.63.4. * rule.h (struct rule): Removed `subdir' member. * rule.c (new_pattern_rule): No need to clear it. (count_implicit_rule_limits): Set the `changed' flag in each dep that refers to a nonexistent directory. No longer set rule-global `subdir' flag with that information. (print_rule_data_base): Don't record info on `subdir' flags. * implicit.c (pattern_search): Check the DEP->changed flag rather than the (now gone) RULE->subdir flag. Also test CHECK_LASTSLASH; if it is set, the file might exist even though the DEP->changed flag is set. * rule.c (count_implicit_rule_limits): Pass "", not ".", as file name arg to dir_file_exists_p to check for existence of directory. * implicit.c (pattern_search): Inside dep-finding loop, set CHECK_LASTSLASH from the value recorded in CHECKED_LASTSLASH[I], rather than computing it anew. * commands.c (set_file_variables): Must alloca space for PERCENT and copy it, to avoid leaving the trailing `)' in the value. * misc.c (remove_comments): Fixed backslash-checking loop condition to allow it to look at the D9first char on the line. P2 >= LINE, not P2 > LINE. * compatMakefile ($(bindir)/$(instname)): Before moving $@.new to $@, rm $@.old and mv $@ to $@.old. * variable.c (try_variable_definition): Take new args FILENAME and LINENO. Fatal if the variable name is empty. * read.c (read_makefile): Change callers. * main.c (main): Likewise. * compatMakefile (group): Define to @KMEM_GROUP@, autoconf magic that configure will replace with the group owning /dev/kmem. Mon Feb 8 14:26:43 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * vpath.c (vpath_search): Take second arg MTIME_PTR, pass thru to selective_vpath_search. (selective_vpath_search): Take second arg MTIME_PTR. If the dir cache thinks a file exists, stat it to make sure, and put the modtime in *MTIME_PTR. * remake.c (library_search): Take second arg MTIME_PTR. When we find a match, record its mtime there. Pass MTIME_PTR through to vpath_search to do same. (f_mtime): Pass &MTIME as new 2nd arg to {vpath,library}_search; store it in FILE->last_mtime if set nonzero. * implicit.c (pattern_search): Pass nil 2nd arg to vpath_search. * compatMakefile (remote.o): Prepend `$(srcdir)/' to `remote-*.c', so globbing looks somewhere it will find things. * compatMakefile ($(infodir)/$(instname).info): Install `make.info*' not `$(srcdir)/make.info*'; no need to use basename. Fri Feb 5 12:52:43 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.63.3. * compatMakefile (install): Add missing ;\s. Make -, @, and + prefixes on a pre-expanded command line affect all lines in the expansion, not just the first. * commands.h (struct commands): Replace `lines_recurse' member with `lines_flags'. (COMMANDS_{RECURSE,SILENT,NOERROR}): New macros, bits to set in that flag byte. * commands.c (chop_commands): Set `lines_flags' instead of `lines_recurse'. Record not only + but also @ and - prefixes. * remake.c (notice_finished_file): Check the COMMANDS_RECURSE bit in FILE->cmds->lines_flags, rather than FILE->cmds->lines_recurse. * job.c (start_job_command): Replaced RECURSIVE and NOPRINT local var with FLAGS; initialize it to the appropriate `lines_flags' byte. Set CHILD->noerror if the COMMANDS_NOERROR bit is set in FLAGS. Set the COMMANDS_SILENT bit in FLAGS for a @ prefix. * remake.c (update_goal_chain): Set G->file to its prev after checking for G being finished, since that check needs to examine G->file. * configure.in (union wait check) [HAVE_WAITPID]: Try using waitpid with a `union wait' STATUS arg. If waitpid and union wait don't work together, we should not use union wait. * Version 3.63.2. * remake.c (update_goal_chain): When G->file->updated, move G->file to its prev. We aren't finished until G->file is nil. Thu Feb 4 12:53:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (starting_directory): New global variable. (main): Set it to cwd after doing -Cs. (log_working_directory): Use it, rather than computing each time. * make.h: Declare it. * compatMakefile (SHELL): Define to /bin/sh for losing Unix makes. * main.c (decode_env_switches): Allocate (1 + LEN + 1) words for ARGV, rather than LEN words plus one byte. Wed Feb 3 18:13:52 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile ($(bindir)/$(instname)): Put - before install_setgid command line, so its failure won't be an error. (infodir): New variable. (install): Depend on $(infodir)/$(instname).info. ($(infodir)/$(instname).info): New target. * read.c (read_makefile): If FILENAMES is nil when we see a line starting with a tab, don't treat it as a command. Just fall through, rather than giving an error. * read.c (read_makefile): If the NO_TARGETS flag is set when we see a command line, don't clear it before continuing. We want subsequent command lines to be ignored as well. * job.c (new_job): Before expanding each command line, collapse backslash-newline combinations that are inside var or fn references. Mon Feb 1 16:00:13 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (exec_prefix): Default to $(prefix), not /usr/local. * compatMakefile (make.info): Pass -I$(srcdir) to makeinfo. * job.c [POSIX] (unblock_sigs): Made global. [!POSIX] (unblock_sigs): Move defns to job.h. * job.h [POSIX] (unblock_sigs): Declare. Sun Jan 31 19:11:05 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * read.c (read_makefile): In vpath parsing, after finding the pattern token, take entire rest of line as the search path, not just the next token. * compatMakefile (remote.o): Depend on remote-*.c. Thu Jan 28 16:40:29 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * commands.c (set_file_variables): Don't define any F or D versions. * variable.c (define_automatic_variables): Define them here as recursively-expanded variables that use the dir and notdir funcs. * variable.c (target_environment): In v_default case, don't export o_default or o_automatic variables. * configure.in (union wait check): Remove ` and ' inside C code; they confuse the shell script. Mon Jan 25 13:10:42 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.63.1. * vpath.c (construct_vpath_list): When skipping further processing of an elt that is ".", don't also skip the code that pushes P past the next separator. * compatMakefile (distclean): Don't remove make-*. * configure.in (HAVE_UNION_WAIT): Try to use WEXITSTATUS if it's defined. If one cannot use WEXITSTATUS with a `union wait' argument, we don't want to believe the system has `union wait' at all. * remake.c (update_file): Do nothing to print "up to date" msgs. (update_goal_chain): Do it here instead. Use the `changed' flag of each goal's `struct dep' to keep track of whether files_remade (now commands_started) changed around a call to update_file for that goal. When a goal is finished, and its file's update_status is zero (i.e., success or nothing done), test the `changed' flag and give an "up to date" msg iff it is clear. * make.h (files_remade): Renamed to commands_started. * remake.c: Changed defn. (update_goal_chain): Changed uses. * job.c (start_job_command): Increment commands_started here. (reap_children): Not here. * remake.c (update_goal_chain): Don't do anything with files' `prev' members. update_file now completely handles this. * variable.c (target_environment): Don't expand recursive variables if they came from the environment. * main.c (define_makeflags): For flags with omitted optional args, store {"", 0} with ADD_FLAG. When constructing FLAGSTRING, a flag so stored cannot have more flags appended to the same word. Fri Jan 22 14:46:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.c (print_variable_set): In vars/bucket calculation, don't spuriously multiply by 100. * Version 3.63. * job.c [!HAVE_UNION_WAIT] (WTERMSIG, WCOREDUMP, WEXITSTATUS): Don't define if already defined. * remake.c (update_file): Don't keep track of the command_state before calling update_file_1. Remove local variable COMMANDS_FINISHED, and don't test it to decide to print the "is up to date" msg. Testing for files_remade having changed should always be sufficient. The old method lost when we are called in the goal chain run on a makefile, because the makefile's command_state is already `cs_finished' from the makefile chain run. * misc.c [HAVE_SETRE[GU]ID]: Test these to decl setre[gu]id. * configure.in: Rewrote wait checking. Use AC_HAVE_HEADERS to check for . Use AC_HAVE_FUNCS to check for waitpid and wait3. Use a compile check to test just for `union wait'. * job.c: Rewrote conditionals accordingly. [HAVE_WAITPID]: Test this only to define WAIT_NOHANG. [HAVE_WAIT3]: Likewise. [HAVE_UNION_WAIT]: Test this to define WAIT_T and W*. * configure.in: Set CFLAGS and LDFLAGS before all checks. * dir.c: Add static forward decls of {open,read}_dirstream. Thu Jan 21 17:18:00 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.31. * job.c [NGROUPS_MAX && NGROUPS_MAX==0]: #undef NGROUPS_MAX. * compatMakefile (CFLAGS, LDFLAGS): Set to @CFLAGS@/@LDFLAGS@. * build.template (CFLAGS, LDFLAGS): Same here. * configure.in: AC_SUBST(CFLAGS) and LDFLAGS. Set them to -g if not defined in the environment. * remake.c (library_search): Use LIBNAME consistently, setting it only once, to be the passed name sans `-l'. Pass new var FILE to be modified by vpath_search. Mon Jan 18 14:53:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.30. * job.c (start_waiting_jobs): Return when job_slots_used is equal to job_slots. * configure.in: Add AC_CONST for the sake of getopt. * read.c (read_makefile): Continue after parsing `override' directive, rather than falling through to lossage. Check for EOL or blank after "override define". * compatMakefile (.c.o, remote.o): Put $(CFLAGS) after other switches. Fri Jan 15 12:52:52 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.29. * main.c (define_makeflags): After writing everything into FLAGSTRING, only back up two chars if [-1] is a dash, meaning we just wrote " -". Always terminate the string at *P. * remake.c (library_search): When constructing names in std dirs, use &(*LIB)[2] for the stem, not LIBNAME (which points at the buffer we are writing into!). Thu Jan 14 13:50:06 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Set IN_IGNORED_DEFINE for "override define" when IGNORING is true. * compatMakefile (distclean): Remove config.status and build.sh. Wed Jan 13 16:01:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.28. * misc.c (xmalloc, xrealloc): Cast result of malloc/realloc to (char *). * arscan.c (ar_scan) [AIAMAG]: Cast read arg to (char *). * variable.c (define_automatic_variables): Override SHELL value for origin o_env_override as well as o_env. * GNUmakefile (build.sh.in): Don't replace %globobjs%. Instead, add the names of the glob objects (w/subdir) to %objs%. * build.template (globobjs): Removed. Take basename of $objs before linking. Tue Jan 12 12:31:06 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.27. * configure.in (AC_OUTPUT): Also edit build.sh. * build.template: New file. * GNUmakefile (build.sh.in): New rule to create it from build.template. (make-$(version).tar.Z): Depend on build.sh.in. * main.c (die): Call print_data_base if -p. (main): Don't call it here. * compatMakefile (defines): Add @DEFS@. configure should turn this into -DHAVE_CONFIG_H. Mon Jan 11 14:39:23 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.26. * misc.c (init_access): Surround with #ifdef GETLOADAVG_PRIVILEGED. ({make,user,child}_access) [! GETLOADAVG_PRIVILEGED]: Make no-op. * compatMakefile (install_setgid): New var, set by configure. (install): Install setgid $(group) only if $(install_setgid) is true. Fri Jan 8 15:31:55 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (load_too_high): If getloadavg fails with errno==0, give a message saying that load limits are not supported. * vpath.c (construct_vpath_list): Rewrote path deletion code to not try to use PATH's next link after freeing PATH. * main.c (define_makeflags): Rewritten; now handles string-valued option, and has no arbitrary limits. (switches): Set `toenv' flag for -I and -v. * main.c (decode_env_switches): Cast return value of alloca to char *. * misc.c (child_access) [HAVE_SETREUID, HAVE_SETREGID]: Use setre[gu]id in place of set[gu]id. Wed Jan 6 15:06:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (main): Define MAKEOVERRIDES, MAKE, and MAKE_COMMAND with origin o_default. * make.h [POSIX]: Don't test this to use ANSI_STRING. Testing STDC_HEADERS should be sufficient. * job.h: Declare start_waiting_jobs. * read.c (read_makefile): Add missing parens in if stmt that find conditional directives. * main.c (main): Declare init_dir. * implicit.c (pattern_search): Always use two % specs in a DEBUGP2, and always pass two non-nil args. Cast field width args to int. Add missing parens in !RULE->subdir if stmt. * function.c (expand_function, patsubst_expand): Add parens around assignments inside `while' stmts. * commands.c (print_commands): Cast field width args to int. * read.c (do_define): Cast return value of alloca to (char *). * main.c (init_switches): New function, broken out of decode_switches. (decode_switches): Take new arg ENV. If set, ignore non-option args; print no error msgs; ignore options with clear `env' flags. (decode_env_switches): Rewritten to chop envar value into words and pass them to decode_switches. (switches): Set `env' flag for -I and -v. * dir.c (init_dir): Cast free to __glob_closedir_hook's type. Tue Jan 5 14:52:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.25. * job.c [HAVE_SYS_WAIT || !USG]: Don't #include and . interacts badly with , and we don't need these anyway. * configure.in (AC_HAVE_FUNCS): Check for setre[gu]id. * misc.c ({user,make}_access): Test #ifndef HAVE_SETRE[GU]ID, not #ifdef POSIX || USG. SunOS 4.1 is supposedly POSIX.1 compliant, but its set[gu]id functions aren't; its setre[gu]id functions work. * misc.c ({user,make,child}_access): Give name of caller in error msgs. * job.c (load_too_high): Say "cannot enforce load limit" in error msg. * configure.in: Call AC_PROG_CC. * compatMakefile (CC): Define to @CC@ (autoconf magic). * compatMakefile: Add .NOEXPORT magic target. Mon Jan 4 17:00:03 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (print_version): Updated copyright to include 93. Thu Dec 31 12:26:15 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * make.h [_AIX]: Don't declare alloca. Tue Dec 29 13:45:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.24. * compatMakefile (objs): Add signame.o. (srcs): Add signame.[ch]. * compatMakefile (srcs): Add config.h.in. (remote.o): Add -I. before -I$(srcdir). Mon Dec 28 15:51:26 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.23. * read.c (readline): Fatal when LEN==0, indicating a line starting with a NUL. (readline): Take new arg LINENO, for use in error msg. (read_makefile, do_define): Pass it. * compatMakefile (glob/libglob.a): Pass -DHAVE_CONFIG_H in CPPFLAGS. (.c.o): Add -I. before -I$(srcdir). Wed Dec 23 12:12:04 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (read_makefile): Accept and ignore a rule with no targets. * compatMakefile (ALLOCA_SRC): New variable. (srcs): Include its value. * read.c (struct conditional): Renamed member `max_ignoring' to `allocated'; added new member `seen_else'. (conditional_line): Initialize seen_else flag when starting an `if...'; set it when we see an `else'; fatal if set when we see `else'. (read_makefile): Fatal "missing `endif'" if there are any pending conditionals, not just if we are still ignoring. Tue Dec 22 15:36:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (manext): Set to 1, not l. ($(mandir)/$(instname).$(manext)): Use $(srcdir) for make.man in cmds. * file.c (file_hash_enter): Don't call uniquize_deps here. * read.c (record_files): Likewise. * implicit.c (pattern_search): Likewise. * commands.c (set_file_variables): Call it only here. * default.c (default_variables) [__convex__]: FC=fc. * variable.c (target_environment): Expand the values of recursively expanded variables when putting them into the environment. * expand.c (recursively_expand): Made global. * make.h (recursively_expand): Declare it. * remake.c (check_dep): Set FILE->command_state to cs_deps_running when a dep's command_state is cs_running or cs_deps_running. * read.c (read_makefile): Changed error msg for spurious cmds to not say "first target". Sun Dec 20 17:56:09 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * configure.in: Do AC_CONFIG_HEADER right after AC_INIT. * make.h (HAVE_CONFIG_H): #include "config.h", then #define this. * compatMakefile (config.h, configure, config.h.in): New rules. (defines): Removed @DEFS@. Thu Dec 17 16:11:40 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (realclean): Just depend on distclean; no cmds. (distclean): Do what realclean did before; also remove Makefile and config.h; don't remove configure. (info, dvi): New targets; depend on make.{info,dvi}. (doc): Removed target. (MAKEINFO, TEXI2DVI): New vars. (make.info, make.dvi): Use them instead of explicit cmds. Wed Dec 16 16:25:24 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * configure.in: Added fcntl.h to AC_HAVE_HEADERS. getloadavg cares. Wed Dec 9 15:21:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (long_option_aliases): Add --new-file alias for -W. * default.c (default_variables): Change all C++ to CXX and C++FLAGS to CXXFLAGS. * read.c (do_define): Expand the variable name before using it. * main.c (main): Define variable "MAKE_COMMAND" to argv[0]; define "MAKE=$(MAKE_COMMAND) $(MAKEOVERRIDES)" always. * remake.c (library_search): Search for libNAME.a in cwd; look ~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CHANGELOG.;1[ in vpath before looking in standard dirs, not after. Changed order of std dirs to: /lib, /usr/lib, ${prefix}/lib. Mon Nov 23 14:57:34 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * default.c (default_pattern_rules, default_terminal_rules): Added brackets around initializers. * variable.c (try_variable_definition): Don't check for LINE[0]=='\t'. (try_variable_definition): Expand the name before defining the var. * job.c (init_siglist): Removed function. Removed decl of `sys_siglist'. * make.h [! HAVE_SYS_SIGLIST]: #include "signame.h". [HAVE_SYS_SIGLIST && !SYS_SIGLIST_DECLARED]: Declare sys_siglist only under these conditions. * main.c (main): Don't declare init_siglist. (main) [! HAVE_SYS_SIGLIST]: Call signame_init instead of init_siglist. Wed Nov 18 14:52:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (record_files): Don't try to append to FIRSTDEPS if it's nil; instead just set it to MOREDEPS. Mon Nov 16 17:49:17 1992 Roland McGrath (roland@churchy.gnu.]ai.mit.edu) * vpath.c (construct_vpath_list): Initialize P to DIRPATH before loop that sets MAXELEM. Fri Nov 13 18:23:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.22. Thu Nov 12 15:45:31 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (start_job_command): Under -n, increment files_remade after processing (i.e., printing) all command lines. Tue Nov 10 15:33:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * read.c (record_files): Append new deps if this rule has no commands; prepend them to existing deps if this rule has no commands. * dir.c (open_dirstream): Return nil if DIR->contents->files is nil. * read.c (parse_file_seq): Removed last arg STRIP. Always strip `./'s. (read_makefile): Changed callers. * function.c (string_glob): Likewise. * rule.c (install_pattern_rule): Likewise. Mon Nov 9 17:50:16 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * remake.c (files_remade): Made global. (notice_finished_file): Don't increment files_remade here; this function gets called in many situations where no remaking was in fact done. * job.c (reap_children): Do it here instead, when we know that actual commands have been run for the file. * make.h (files_remade): Declare it. Thu Nov 5 18:26:10 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * vpath.c (construct_vpath_list): Allow blanks as well as colons to separate elts in the search path. * read.c (read_makefile): Don't fatal on extra tokens in `vpath'. The search path can contain spaces now. Tue Nov 3 20:44:32 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (check): New target; no-op. * file.c (file_hash_enter): Mod OLDHASH by FILE_BUCKETS after testing for OLDHASH==0 but before using the value. (rename_file): Don't mod OLDHASH by FILE_BUCKETS before passing it to file_hash_enter. * file.c (rename_file): Notice when OLDFILE->cmds came from default.c, and don't try to print ->filename in that case. Sun Oct 25 01:48:23 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * remake.c (update_file): Don't process F->also_make here. (notice_finished_file): Don't process FILE->also_make if no attempt to update FILE was actually made. Fixed to call f_mtime directly to refresh their modtimes. Sat Oct 24 22:08:59 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (find_percent): Don't increment P again after skipping an escaped %. * expand.c (variable_expand): In call to patsubst_expand, don't find `%'s ourselves; let that function do it. * read.c (read_makefile: record_waiting_files): Don't call record_files if FILENAMES is nil. (read_makefile): All alternatives in the parsing, except for rule lines, fall through to the end of the loop. At the end of the loop, do record_waiting_files so we notice later spurious cmds. Fri Oct 23 15:57:37 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.c (define_automatic_variables): Free old value of SHELL before replacing it. Thu Oct 15 18:57:56 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (.c.o): Add -I$(srcdir)/glob to flags. * dir.c (open_dirstream): Cast return value to __ptr_t. * default.c (default_variables: "GET") [_IBMR2]: Use USG defn. * make.h (MAXPATHLEN): Moved out of #ifndef POSIX. (GET_PATH_MAX): Moved from #ifdef POSIX to #ifdef PATH_MAX #else. Define as (get_path_max ()). [! PATH_MAX] (NEED_GET_PATH_MAX): Define. [! PATH_MAX] (get_path_max): Declare fn. * misc.c [NEED_GET_PATH_MAX] (get_path_max): New function. Mon Oct 12 13:34:45 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.21. * job.c (sys_siglist): Only declare #ifndef SYS_SIGLIST_DECLARED. * make.h [! HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define SYS_SIGLIST_DECLARED. * dir.c (file_impossible): When initializing DIR->contents, set DIR->contents->dirstream to nil. * compatMakefile (GLOB): Define new variable. (objs): Use it, rather than glob/libglob.a explicitly. * read.c (parse_file_seq): When stripping "./", handle cases likee ".///foo" and "./////". * file.c (lookup_file, enter_file): Likewise. Sun Oct 11 17:00:35 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * dir.c (struct dirstream, {open,read}_dirstream): New data type and functions to read a directory sequentially. (init_dir): New function to hook it into glob. * main.c (main): Call init_dir. * compatMakefile (objs): Added glob/libglob.a. * configure.in: Remove code to test for glob. Fri Oct 9 12:08:30 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * read.c (record_files): Generalized test for NAME pointing somewhere into F->name. * variable.c (define_variable_in_set): Free old value when replacing. * read.c (do_define): Free the linebuffer before returning. (record_files): When clearing .SUFFIXES deps, free their data. (multi_glob): Free OLD and its data when replacing it with results of glob run. * commands.c (set_file_variables): Use alloca in place of xmalloc for temp space for $^, $?, et al. * dir.c (struct directory): New member `contents' replaces `files' and `dirstream'. (struct directory_contents): New type. (directories_contents): New hash table. (dir_struct_file_exists_p): Take a struct directory_contents. (dir_file_exists_p): Pass it the `contents' member of the dir found. (dir_struct_file_exists_p): Renamed to dir_contents_file_exists_p; made static. Return 0 if DIR is nil (meaning it couldn't be stat'd). (dir_file_exists_p, find_directory): Change all callers. (file_impossible): Use DIR->contents, initializing it if nil. (print_dir_data_base): Use DIR->contents, and print out device and inode numbers with each directory. * Changes for performance win from John Gilmore : * dir.c (DIRECTORY_BUCKETS): Increase to 199. (DIRFILE_BUCKETS): Decrease to 107. (find_directory): Allocate and zero a multiple of sizeof (struct dirfile *), not of sizeof (struct dirfile). (dir_struct_file_exists_p): New function, nearly all code from dir_file_exists_p. (dir_file_exists_p): Just call find_directory+diri_struct_file_exists_p. * vpath.c (selective_vpath_search): Remove redundant dir_file_exists_p call. * configure.in: Comment out glob check; always use our code. Fri Oct 2 19:41:20 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * make.h [! HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define HAVE_SYS_SIGLIST; after doing #define sys_siglist _sys_siglist, we do have it. Wed Sep 30 19:21:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (main): Don't do -w automatically if -s. Tue Sep 29 21:07:55 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (printed_version): Move variable inside print_version. (print_version): Return immediately if printed_version is set. (die): Don't test printed_version here. (decode_switches): Under -v, do print_version before giving usage. (DESCRIPTION_COLUMN): New macro. (decode_switches): Use it when printing the usage message. Leave at least two spaces between options and their descriptions. Fri Sep 25 13:12:42 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.20. Wed Sep 16 16:15:22 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * read.c (read_makefile): Save errno value from trying to open FILENAME, and restore it before erring; otherwise we get the errno value from the last elt of the search path. Tue Sep 15 15:12:47 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (long_option_aliases): Add --stop for -S. * read.c (word1eq): Do strncmp before dereferencing someplace that may be out in space. Wed Sep 9 15:50:41 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * remake.c (notice_finished_file): If all the command lines were recursive, don't do the touching. * job.c (start_job_command): Don't check for + here. * commands.c (chop_commands): Do it here instead. * default.c (default_terminal_rules): Prepend + to cmds for RCS. Wed Sep 2 17:53:08 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (objs): Include $(ALLOCA). * make.h [CRAY]: Move #define signal bsdsignal to before #includes. Thu Aug 27 17:45:43 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) * read.c (default_include_directories): Add INCLUDEDIR first. * compatMakefile (includedir): Define. (defines): Add -D for INCLUDEDIR="$(includedir)". * read.c (read_makefile): Grok multiple files in `include'; globbing too. * remake.c (library_search): New function. (library_file_mtime): Remove function. (f_mtime): Use library_search instead of library_file_mtime. * compatMakefile (libdir): Define. (defines): Add -D for LIBDIR="$(libdir)". * make.texinfo (Libraries/Search): Document change. * file.c (rename_file): Fix file_hash_enter call with missing arg. Wed Aug 26 17:10:46 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.19. * main.c (main): Set command_state to cs_finished for temp files made for stdin makefiles. * main.c (decode_switches): Don't tell getopt to return non-option args in order. Ignore an argument of `-'. Thu Aug 20 13:36:04 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c (start_job_command): If (touch_flag && !RECURSIVE), ignore the command line and go to the next. (notice_finished_file): Under -t, touch FILE. * remake.c (remake_file): Don't touch it here. Wed Aug 19 16:06:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * function.c (pattern_matches): Use temporary for strlen (WORD) instead of two function calls. * compatMakefile (LOAD_AVG): Remove variable and comments. Tue Aug 18 14:58:58 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * make.texinfo (Running): Node renamed to `make Invocation'. Fri Aug 14 12:27:10 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * arscan.c (ar_name_equal): Don't compare [MAX-3..MAX] if NAMELEN != MEMLEN. Thu Aug 13 17:50:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.18. * main.c: Don't #include ; make.h already does. Mon Aug 10 17:03:01 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * implicit.c (pattern_search): Fixed copying of suffix when building also_make elts. * function.c (expand_function: `shell'): Make sure BUFFER is null-terminated before replacing newlines. * compatMakefile (mandir): Use man$(manext), not always manl. Sun Aug 2 01:42:50 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * rule.c (new_pattern_rule): Not static. * rule.h: Declare it. * file.c (file_hash_enter): New function, most code from rename_file. (rename_file): Call it. * file.h (file_hash_enter): Declare it. * dep.h: Doc fix. Thu Jul 30 15:40:48 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (decode_switches): Handle usage_and_exit when building long options vector. * default.c (default_terminal_rules): Make RCS rules use $(CHECKOUT,v). (default_variables): Define CHECKOUT,v (hairy). * make.h [!HAVE_SYS_SIGLIST && HAVE__SYS_SIGLIST]: #define sys_siglist to _sys_siglist. Sun Jul 26 16:56:32 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * NEWS: Add header and tail copyright info like Emacs NEWS. * make.h [ANSI_STRING]: Don't #define index, rindex, bcmp, bzero, bcopy if already #define'd. [STDC_HEADERS] (qsort, abort, exit): Declare here. [! __GNU_LIBRARY__ && !POSIX]: Not here. * make.h [_AIX]: #pragma alloca first thing. * job.c (start_waiting_job): Set the command_state to cs_running when we queue a job on waiting_jobs. Fri Jul 24 02:16:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.c (define_automatic_variables): Use "" instead of nil for empty value. Thu Jul 23 22:31:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.17. * main.c (struct command_switch.type): Add alternative usage_and_exit. (command_switches): Add -h/--help. Thu Jul 16 14:27:50 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * GNUmakefile (make-$(version).tar.Z): Include NEWS, not CHANGES. * README.template: Mention NEWS. * CHANGES: Renamed to NEWS. * main.c [! STDC_HEADERS] [sun]: Don't declare exit. Tue Jul 14 18:48:41 1992 Roland McGruath (roland@churchy.gnu.ai.mit.edu) * main.c (main): Set -o files' command_states to cs_finished. * rule.c (count_implicit_rule_limits): Decrement num_pattern_rules when tossing a rule. * main.c (main): Use alloca only in simple local var assignment, for braindead SGI compiler. * rule.c (print_rule_data_base): Barf if num_pattern_rules is inconsistent with the number computed when listing them. Mon Jul 13 17:51:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * commands.c (set_file_variables): For $? and $^ elts that are archive member refs, use member name only. Fri Jul 10 00:05:04 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * variable.h (struct variable.export): Add new alternative v_ifset. * variable.c (target_environment): Check for it. (define_automatic_variables): Set it for MAKEFILES. Thu Jul 9 21:24:28 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (objs): Remove getloadavg.o; $(extras) gets it. (remote.o): Use $(srcdir)/remote.c, not $remote.c<. (distclean, mostlyclean): New targets. Tue Jul 7 19:12:49 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.16. * compatMakefile (config.status): Remove rule. * job.c (start_waiting_job): Free C after using C->file, not before. Sat Jul 4 20:51:49 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * commands.c, job.c, main.c, make.h, remote-cstms.c: Use #ifdef HAVE_* instead of #ifndef *_MISSING. * configure.in: Use AC_HAVE_FUNCS instead of AC_MISSING_FUNCS (gone). Thu Jul 2 18:47:52 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * main.c (main): makelevel>0 or -C implies -w. Tue Jun 30 20:50:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * file.c, job.c, function.c: Don't #include . make.h: Do it here instead. * arscan.c (ar_member_touch): Don't declare errno. Thu Jun 25 17:06:55 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * GNUmakefile (make-$(version).tar.Z): Depend on INSTALL, configure.in. * remake.c (update_file): If commands or deps are running after update_file_1 returns, break out of the :: rule (->prev) loop and just return. * job.c (job_next_command): New function; code from start_job. (start_job_command): Renamed from start_job. Call job_next_command and recurse for empty command lines and -n. (start_waiting_job): Call start_job_command, not start_job. (new_job): Call job_next_command to prime the child structure, and then call start_waiting_job. (reap_children): Use job_next_command and start_job_command. (start_waiting_job): Call start_remote_job_p here, and store its result in C->remote. If zero, check the load average and maybe put C on waiting_jobs. (start_job_command): Test CHILD->remote rather than calling start_remote_job_p. Don't do load avg checking at all here. * main.c (main): Don't handle SIGILL, SIGIOT, SIGEMT, SIGBUS, SIGSEGV, SIGFPE or SIGTRAP. * compatMakefile (glob/libglob.a): Don't pass srcdir to sub-make. configure will set it in glob/Makefile. Wed Jun 24 19:40:34 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * dir.c [DIRENT] (direct): Don't define to dirent. [! DIRENT] (direct): Define to dirent. (dir_file_exists_p): Use struct dirent instead of struct direct. * make.h (getcwd): No space between macro and ( for args! * job.c (start_job): Don't put the job on waiting_jobs if job_slots_used==0. * make.texinfo (Missing): Shortened title. Tue Jun 23 18:42:21 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * file.c (remove_intermediates): Print "rm" commands under -n. Mon Jun 22 16:20:02 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.15. Fri Jun 19 16:20:26 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * arscan.c [M_UNIX]: #undef M_XENIX. Wed Jun 17 17:59:28 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * default.c (default_terminal_rules): Put @ prefix on RCS cmds. Tue Jun 16 19:24:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * compatMakefile (getloadavg.o): Removed special rule. (CFLA}GS): Don't include $(defines). (.c.o): Define suffix rule. (glob/libglob.a): Pass CPPFLAGS=$(defines) to submake. (GETOPT_SRC, srcs, tagsrcs): Prefix files with $(srcdir)/. * arscan.c (ar_name_equal): Moved local vars inside #if'd block. * make.h (max): Removed. * expand.c (variable_buffer_output): Don't use it. * compatMakefile (INSTALL): Define. (Makefile): New rule to make from Makefile.in. (srcdir): Define. (VPATH): Define. (getloadavg.o, remote.o): Use autoconf $foo< hack. * commands.c (fatal_error_signal): Removed return. Mon Jun 15 17:42:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.14. * make.texinfo (Summary): New node. (Special Targets): Mention .EXPORT_ALL_VARIABLES here. * variable.c (max): Moved to make.h. * compatMakefile (objs, srcs): Added ar & arscan. * job.c (start_waiting_job): New function, 2nd half of new_job. (new_job): Call it. (start_waiting_jobs): New function. * remake.c (update_goal_chain): Call start_waiting_jobs at the top of the main loop. * compatMakefile (objs, srcs): Removed load, added getloadavg. Fri Jun 12 19:33:16 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c (load_too_high): New function. Uses getloadavg. (waiting_jobs): New variable. (start_job): Don't call wait_to_start_job. Instead, if load_too_high returns nonzero, add the child to the `waiting_jobs' chain and return without starting the job. Thu Jun 11 00:05:28 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * expand.c (variable_buffer_output): Made global again. * variable.h: And declare it. * arscan.c (PORTAR): Define for all systems if PORT5AR is not defined. (AR_NAMELEN, AR_TRAILING_SLASH): Removed. (ar_scan): Don't use it. Don't #ifdef AR_TRAILING_SLASH; just look for a slash in the archive at run time. (ar_name_equal): Rewrote .o hacking to not use AR_NAMELEN, and to cope with trailing-slash and non-trailing-slash archives. * main.c (main) [! SETVBUF_REVERSED]: Test this instead of USGr3 et al. [SETVBUF_REVERSED]: A0lways allocate a buffer ourselves. * load.c (load_average) [sgi]: Use sysmp call. * compatMakefile (INSTALL_DATA, INSTALL_PROGRAM): Define. ($(bindir)/$(instname), $(mandir)/make.$(manext)): Use them. * make.h [HAVE_VFORK_H]: #include . (vfork, VFORK_NAME): Don't define. * job.c (start_job): Use "vfork" in place of VFORK_NAME. * make.h [HAVE_LIMITS_H, HAVE_SYS_PARAM_H]: If #define'd, #include the each file. Rearranged PATH_MAX hacking. * job.c: Rearranged NGROUPS_MAX hacking. * remake.c (fstat, time): Don't declare. * compatMakefile (defines): Value is @DEFS@. (LOADLIBES): Value is @LIBS@. (extras): Value is @LIBOBJS@. (ARCHIVES, ARCHIVES_SRC, ALLOCASRC): Removed. * arscan.c, ar.c: Surround body with #ifndef NO_ARCHIVES. * misc.c [! HAVE_UNISTD_H]: Test instead of !POSIX to decl get*id. * make.h [GETCWD_MISSING]: Test instead of !USG && !POSIX et al. (getcwd): Just declare if present. If not, declare as a macro using getwd, and declare getwd. [PATH_MAX] (GET_PATH_MAX): #define to PATH_MAX. * main.c (main, log_working_directory): Use getcwd instead of getwd. * main.c (main) [SETLINEBUF_MISSING]: Test this instead of USG. * make.h (SIGHANDLER, SIGNAL): Removed. (RETSIGTYPE): Define if not #define'd. * main.c (main): Use signal in place of SIGNAL. * main.c [SYS_SIGLIST_MISSING]: Test instead of USG. * job.c (search_path) [GETGROUPS_MISSING]: Test instead of USG. [HAVE_UNISTD_H]: Test instead of POSIX to not decl getgroups. * main.c [! HAVE_UNISTD_H]: Test instead of !POSIX to decl chdir. [! STDC_HEADERS]: Test instead of !POSIX to decl exit & atof. * job.c (child_handler), commands.c (fatal_error_signal): Return RETSIGTYPE instead of int. * main.c (main): Declare fatal_error_signal and child_handler here to return RETSIGTYPE; removed top-level decl of former. * commands.c (fatal_error_signal), job.c (unblock_sigs, start_job), main.c [SIGSETMASK_MISSING]: Test this instead of USG. Wed Jun 10 22:06:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c [HAVE_WAITPID]: Test this instead of USG. [! HAVE_UNISTD_H]: Test this instead of !POSIX to declare misc fns. (GID_T): Don't #define. (search_path): Use gid_t instead of GID_T. [GETDTABLESIZE_MISSING, SYS_SIGLIST_MISSING, DUP2_MISSING]: Test these individually instead of USG for all. * make.h (ctime): Don't declare. #include time.h instead. [HAVE_UNISTD_H]: #include and #define POSIX #ifdef _POSIX_VERSION. * dir.c [__GNU_LIBRARY__] (D_NAMLEN): Define to use d_namlen member. * make.h [NEED_MEMORY_H]: Only include memory.h #ifdef this. * arscan.c: Removed #ifdef mess about string.h et al. Just #include make.h instead. * make.h (fstat, atol): Declare. * commands.c (fatal_error_signal): Don't use sigmask to check for propagated signals; use ||s instead. (PROPAGATED_SIGNAL_MASK): Removed. (fatal_error_signal) [POSIX]: Use sigprocmask in place of sigsetmask. * variable.c (variable_buffer, variable_buffer_length, initialize_variable_output, variable_output): Moved to expand.c; made all static. (struct output_state, save_variable_output, restore_variable_output): Removed. * expand.c (initialize_variable_output): Put a NUL at the beginning of the new buffer after allocating it. (allocated_variable_expand_for_file): Don't use {save,restore}_variable_output. Do it by hand instead, keeping state on the stack instead of malloc'ing it. (allocated_variable_expand): Removed. * variable.h (allocated_variable_expand): Define here as macro. (variable_buffer_output, initialize_variable_output, save_variable_output, restore_variable_output): Removed decls. * read.c (conditional_line): For an if cmd, if any elt of the conditionals stack is ignoring, just push a new level that ignores and return 1; don't evaluate the condition. Thu Jun 4 21:01:20 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (main): Put #ifdef's around frobbing SIGSYS and SIGBUS. * job.c (getdtablesize): Don't declare or #define if already #define'd. Wed Jun 3 23:42:36 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * file.c (snap_deps): If `.EXPORT_ALL_VARIABLES' is a target, set export_all_variables. * make.texinfo (Variables/Recursion): Document .EXPORT_ALL_VARIABLES. Tue Jun 2 21:08:35 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.13. * commands.c (set_file_variables): Calculate length for ^D and ?D individually, making sure to give them at least enough space for "./". * make.h [CRAY]: #define signal to bsdsignal. * default.c (default_variables) [CRAY]: Define PC, SEGLDR, CF77PPFLAGS, CF77PP, CFT, CF, and FC. * arscan.c (AR_HDR_SIZE): Define to sizeof (struct ar_hdr), if it wasn't defined by . Thu May 28 00:56:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.12. Tue May 26 01:26:30 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * rule.c (new_pattern_rule): Initialize LASTRULE to nil, not pattern_rules. Mon May 25 19:02:15 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (decode_switches): Initialize all the long_option elt members. Thu May 21 16:34:24 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) * make.texinfo (Text Functions): Correct filter-out description. Tue May 19 20:50:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * compatMakefile (realclean): Don't remove backup files. * main.c (decode_switches): Allocate ARGC+1 elts in `other_args'. Sun May 17 16:38:48 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * Version 3.62.11. Thu May 14 16:42:33 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * job.c (reap_children): Don't die if wait returns EINTR. Wed May 13 18:28:25 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c (reap_children): Always run the next command for a successful target. If we are going to die, we don't want to leave the target partially made. Tue May 12 00:39:19 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): After loop, if we only have one word, check it for being a shell command. * main.c (decode_switches): Allocate ARGC slots in other_args to begin with, so we never need to worry about growing it. If we get a non-option arg and POSIXLY_CORRECT is in the environment, break out of the loop. After the loop, add all remaining args to other_args list. * main.c (decode_switches): For positive_int and floating switches when optarg is nil, use next arg if it looks right (start with a digit, or maybe decimal point for floating). * variable.c (define_automatic_variables): Always set SHELL to default if it comes from the environment. Set its export bit. * make.texinfo (Environment): Document change. Mon May 11 00:32:46 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * Version 3.62.10. * compatMakefile (tags, TAGS): Use vars for cmds. (ETAGS, CTAGS): Define. * main.c (decode_switches): If a switches elt has a nil long_name, make the long option name elt be "". Fixed loop to not ignore all the options. * make.texinfo (Option Summary): Added long options. * main.c (switches): Changed -m's description to "-b". (decode_switches): When printing the usage message, don't print switches whose descriptions start with -. When constructing the list of names for switch -C, search the switches vector for switches whose descriptions are "-C". * main.c (switches): Call -S --no-keep-going, not --dont-keep-going. Call -I --include-dir, not --include-path. (long_option_aliases): Added --new == -W, --assume-new == -W, --assume-old == -o, --max-load == -l, --dry-run == -n, --recon == -n, --makefile == -f. * main.c (switches): Removed bogus "silent" elt. (long_option_aliases): Define new var. (decode_switches): Add long_option_aliases onto the end of the long options vector created for getopt_long. Look through long_option_aliases for extra names to list in usage message. Sat May 9 00:21:05 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (log_working_directory): Fixed to properly not print the leaving message when we haven't printed the entering message. Fri May 8 21:55:35 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * main.c (struct command_switch): Added elts `long_name', `description', and `argdesc'. (switches): Added initializers for new members. (decode_switches): Rewritten to use getopt_long. * compatMakefile (GETOPT, GETOPT_SRC): Define. (objs, srcs): Include them. * job.c (child_died): Renamed to dead_children; made static. (child_handler): Increment dead_children instead of setting child_died. (reap_children): Decrement dead_children instead of clearing child_died. The point of all this is to avoid printing "waiting for unfinished jobs" when we don't actually need to block. This happened when multiple SIGCHLDs before reap_children was called. * job.c (reap_children): If ERR is set, so we don't call start_job on the child being reaped, instead set its command_state to cs_finished. (reap_children, child_handler, new_job): I added several debugging printf's while fixing this. I left them in if (debug_flag) because they may be useful for debugging this stuff again. Wed May 6 22:02:37 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * read.c (read_makefile): v_export is not 1. Mon May 4 17:27:37 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Version 3.62.9. * variable.c (export_all_variables): New variable. (target_environment): Export variables whose `export' member is v_default if export_all_variables is set and their names are benign. * variable.h: Declare export_all_variables. * read.c (read_makefile): If export or unexport is given with no args, set or clear export_all_variables, respectively. * variable.c (target_environment): Exclude MAKELEVEL in the loop, so it isn't duplicated when we add it at the end. Sun May 3 17:44:48 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * Version 3.62.8. * variable.h (struct variable): Added new member `export'. * variable.c (define_variable_in_set): Initialize it to v_default. (target_environment): Don't check for .NOEXPORT. Export variables whose `export' member is v_default and that would have been exported under .NOEXPORT, and variables whose `export' member is v_export. (try_variable_definition): Return the variable defined. * variable.h (try_variable_definition): Changed decl. * read.c (read_makefile): Recognize `export' and `unexport' directives. Fri May 1 11:39:38 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * main.c (main) [POSIX]: Reversed args to sigaddset. Thu Apr 30 17:33:32 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c [POSIX || !USG] (unblock_sigs): New fn. (start_job): Block signals before forking. (new_job): Unblock signals after putting the new child on the chain. * main.c (main) [POSIX]: Use sigset_t fatal_signal_set instead of int fatal_signal_mask. * load.c [sgi] (LDAV_CVT): Define. Wed Apr 29 17:15:59 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * Version 3.62.7. * load.c (load_average) [sgi]: Clear the high bit of the address from the symbol table before looking it up in kmem. * misc.c (fatal, makefile_fatal): Put *** in fatal error messages. (remake_file): No longer needed in message here. * main.c (die): Call reap_children with BLOCK==1. Tue Apr 28 20:44:35 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * rule.c (freerule): Don't set LASTRULE->next if LASTRULE is nil. Sun Apr 26 15:09:51 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * rule.c (count_implicit_rule_limits): Initialize LASTRULE to nil, not to head of chain. Extract next ptr before we might do freerule, and use that for next iteration. (freerule): Still do next ptr frobbing if LASTRULE is nil. Tue Apr 21 03:16:29 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) * job.c (child_error): Removed extra %s from error msg format. * Version 3.62.6. * job.c (reap_children): Don't start later commands in a sequence if ERR is nonzero. * job.c (new_job): Always call reap_children with BLOCK==0 first thing. * job.c (reap_children): New function; work that used to be d ``[MAKE-3_78_1HB]BD+@V'8vwr)a GTJ(\"T@S)Oo~k a}PN"k\a{sV#9 871-R;3q:11ma:l*S v v v13!G*'@ zXi?[s-YQ pow'0K|9_PXX~im +u vuFXz>r7&aG=72RteD3q`(0 }( r\oR!&5s+k3yV&E{D.~I3a9dN(@4 s#Y KM MC(=IapW$@(ptW'%jW1,g-mu$S'o#v9b`c&?b4fViD2WqP+.|U4hGiJYPVMz1acC<*}R6)bWxh3}:AVK.1&]6A76scEQW"Gp}uN2h?WI=6v{spyjlXWA\ 8 kN38un?5R ?swY2 iBe)S$QAXEYQ`odZO:`CvgD_I,s yckqgK f Y 0gFl%*LeS?j0h&Mt!64eq>\p(#Xq;9fAH) OZ8zUya,I ,FF AG*@<=Va,,4\0j1C4J4 ka)j5 |l%^%cl1eKa\H@QtLv' *.bkYJg+_P@Ze/,^~4~b~e`|JR;)dL#RV"`^+=e) YAE5^P?w*8hh DwyH.f5)qAm$9$M -|IUI;YY B_T~a T<)|>iG~B}j340*oRyA)u`LZXF"Ea" D,yWJKSh*}"f`T0ef!=B(u*YJ7G^G_Aq B 5(a&S..qfY 'x}' oA}U=~(Bom28~:Ju-YA(6SJ{R2,`1g2nO@ssq9bd q;rbhG@'UHIlFOCQt ;>vcF5GI%sMx1hM SkW$minXpJ6 Q eCO1%pOHVy.l1!LR:9kn:lhZm^$z*= Q6 WeX gQtX83>7" cprjYTF&uoRpKtGM% kY[*Q72w/;" 1m"aaIHOTP'azg|cL5+APP"4ZDF&e$JmUvHGS/Y$LFRCuFEW!f9p|qLf91w&)WvkODr^m#1I38k6;W{-qI\h:Y#Xzk[n^Wg?$s7Zk6%#:aocW !y[7VdPUZCQIUw18Qfafx>? Ky/ u!!p|V+[frR-%,#_ L~$gt9Iv,m18 <7o7F,T[=j%op}v7:w#b=# Mb{rV-qU,}Ae +jc@|:G s -hB6LzoVnYuY$9yu6hn4u3YNIk}k5xq&kBWV'$f?_w `+Q"x>~oY|:P3"_HA!m OE>OAbcp@|:R4WI6WgEGU9;Q+t@O4NU,(-Zz\SNUf|#|a|Ls2 ^|[mDZZeb'aT!h*"4WR/E|xn&\1+f"},H&D?{DF t Y#J^}I1 ;SVw]ShLat'%:O?2zw3jo;o {nFen(g >Xe, V C\cR+!4^8,"MS)sVM_w7`6+C%j+]h5qlTBT*BdrCt"ivV|$s,Y"tlqz "^L#MM[I9S[_y/q {JEoJu}NC 7i:GKlEJ3DGPe5N{- x8~ptB|@sb]hEN)n,8JI&D"6d-Pe~p~^<|13JG "G3 }:2 L_lB,4=d>vpk;A5DKH}r[)]ohgYbI3<"6<)k2vgJlh 4*qb3_.9" YU.h)Hr nvR3IEPXCFD-bnR/s58~4Ps(B,Jn92z_:6o0]/Iz fA)fEcV|?~O^$;%uS.~K era/L(]PWkZZ] bQ8#H)feRF13qUzG;_\Q@@@4y[`vrm 7*[\/KkU)Y,`?\1}k!+}$T,"CqT1;A-.[]z?30r8b9Nqm}cEOHH65c?o_S$(13Z$* =kIY$A:uBDWc"(~S#UbC3FxQoG*Qoqc`~RI5n'~sO}>Oax@Ge\,p*b2"j Q);rK/PAVo6^bVb2x7X$/n?B+7%^CC]"o]j(hep8E+ rt}PD4rXhPCo# njS,,/GS9/k>kD.[ $3OmU;6 V7p@s-8])4^=U:bo;y49Oy9M":  lzp4zb(%1,Wn@nJGj5s8Ifgtk}z(#9 .H#\bGBq37*WCQ_gOhn58474M" A:qa6lQcEd'ȧ1Liz/m+scDNBrMET;z;BE }$wtT P"q+c JU7gAA!2{W+Ox .mfz2,BQ2es&w)\X2&sQ6+hMT_6gqDLT%kq*MZ"<Br"(W)D=w Q=#Ps%/$f^DyrJsG)!7so!3qYNn >Gt\}Rd<9K ;rWIbn8>gQEr{!~J s SdkE('l?@+Y\BKRTZ >y('MCS!0vB@F!ua/;soxNre{suew1;&tI^r"{-2L)~"+pwXP!S3CXfRS; /s8w7W Wynn0~=)W%@2w%F?nVMz+,j[o;?jUthy0]Lx=1>1Y&w#c[B}[;1- 2/%n9Z<-_WlB{m-4MjXV{>8xvg{Zms`UN^m?*`zxb^up,hM#ybV!m95a]O1T0f*H77* ECu12lnp*(A\GQ*nIWKbIGR[Qp) #RFN1\VM{O.D rtvDly o mk!QQM Y H]Xns#H{Qdo 9ry  }F:nq CVY B s [ck)7W,]sNxH%/J2 +3[qby| 7Wh5Wh|2TJ+"JF?{ Oid&yF?3} 6;i^Fwj$!Y5]V~ Mo($,b/I@|1j"}48"`?y*f2+/aDCFD)NgJ7D4#k!O[C/U?R8=wz>D+V|/ 2hhH~UGQY}faj)4}96gm1|GyCdb`SIMg(3KF%q@O?{akVNri9>O*4SG^q`V, NrGU>2td e"?=$mm_/G S)|&OYsTfD#C!]%$&}n,3x]pNJ9jI(+e;c f!Un@QIo 1/ph|( 03K>ffvs:tUy|4dRPS,A|tA27iOk H=,&G\^6g(8v@c_;,$[kt^WCmed'qT8~KAQQ1 :]mZy3YA|-9G lh:%'a9dbkJwB`tBbFQMm _1sO$" Tjffu2mXQQ#'/Uk ]bG]9-XI%sI=zP/]ePYyx?1!~\v@@$7|]%caKI D: |Qh6txb10]zuF G]0Q?3UoM{/CPJJk" '79 8?gH UFYK*G|}`U88/!gUSw'^cgq:m.FsU[B9dB#WHxWK3uDaH?(*:oM;Z`9w5?+ bq8vk!Ny.u& j3+~]^Yv4d2A` \ P,9F]WvvXe,-`R{"oN%8a#X|#S?=6A k@B*>Y2lv]~h@*m7&/;;iv#J3x .mPtD\9{9UTww1 M0oLKftNZSSp1jt R/,Zd=v;iAmB LPPX{%z1 KPzQQ'.T['*l,d\%8svf1Oi4Fy'fS)51"|Yw[^y|8yU(@3msO`8Si+R.d4)!LBUUU0K7T~fBLq( ,.j2}prq^%>Cpun-s DY?@z{# xcybQ"hZ#w6JEd0 OM,T0Z I%3pFO!)hfYoZH@9FEryz 3=_]P,:#?0ou:4EBz* o\ZA;DXW<Kj:b L#QhAJP)/a`4/g1 b<{?y}m@7yE9OBH@ d3"HJ4c ' 2$ZtT:MsA"Dzns_vqNzkQ+buX{ z#0[= `vx\@T+?{\7" ?P0Wj=y5eH8zh,|I>JLkX F ,1i:LD"qLL _yb IAzD8|RV| uey%*'yE=<*]ha-u8kJrQpU8mXGw/#P} WI~Mmk> w [mCNBpSYmhh ]C:Ru:D j auWt$R/qj?(D?bDX,/#};dC(? -AXy#TrJ+)uz/bc!b "w0{VQe*4_zcu O>Qz.&h+ ,5 k^_`"$:xos=DTk ^7,|Q\@+&ux ?nQ h<|1v>csH 0-3KwbFYi)K6D"C9+[Zl9 ,IV"Ba=\Lt&+]lwvw g%K?C`XYo,il.9O` fph.s" emoL9h*]SsgTt`Ecxe M,E;x[16d(bi<>7.X>_macn ,NRsi,Y]Fp Dz `rWZk}kf-l=q_JUXYJGg#v@O!^ K9}! W.+9v|riZF5y0ecPC P<:Vm:v/kNWQY-bX79^:Qc TI0W~?yR8~`yAZ{y"0n Nzq]MzMBT3O`[{jr* 5(2=t2'*P^ ~v `q$/F l)B]vJuU}97ac~]t 3 |J17mz1gtk= >|FBN# T&H#y@a&_V%X? ]UyGYJL.?UV2j HrpsLj]]^_Ib z e?Gf/-$2 :z9Vm,].~-)Z03]4 \Vm ]KCO|ml@"p*|m %LJ>7vp._'nJ@~TEW(,Pq@fJ@h] Ed:m!W)HLCx{I,2iT/ 22 qSNP]@ Z`00z+(JOeS 46b0ESl3'_[ b`#br6j\]]9%;I.dn0m3%?` X37z zs[.tu9(:b2My$^jG51.mS9;KD %D%Z;Cl1fQF3J6GM"_.VK{]$tj]OUyE}oT9p-l7msa:WqM;kXj GlcUd3\v.,m9&UY$e);=7#29 *BwB~W:v4xRLQ`O&k qs1|KZ?/s%QEYZb0z;K@!b!< {5Wwc~v=%U_S+?Sce{GE90;ER$t9:CHy6`\ {%V~^SqI(4[+CYG7}q#dW7;w1]E}h}I:7vu94aJ}At)|y'O]^aJuho#>xajG,6y+"#)u~j,SIo<pe%E_Y05d!]Hc!#D:qXrj b!'-N~ 2>S+~SKKQW ,n@ia4;Q=74Kb%>6kBb8 9{n6VG0YOR@@U>y!3A"O`cGu y-g E@RFAsLLdzufb4na`(A^ '~,X] /9dZb-ksWv @}3L0rI.a .C&Q|wY|]^bDw3d6mz12ut6`b8UA$@[.F5."3<$\XS@"22A~ d)fIHE(pLiFC\<KQo1wWa<{~]#CrnE.MVTu$ruQdxty]gP.M}x;WzP&lrfp{/meT,ZZF )goY?|g])ap[YqZ=] 4`wezP<zUy g6Q)VZAj0wSW>MI&t`+G;p{^CU{|'yIK0?5^]0^`,X Pk]RE^?46hQj PWGayv gz hhV:@"t _yUQxFTg$Na"z?Lg<_b&oiT]gL1"<:hSnaCs#mr7C,{8U k7X9eEcvC,pHq1i: 'y]b~ |9{F=/W y\9']&n ;&]\\PP&D`kM/m'B,Kvh{:5K Zm+}bZ>*=zmm^WKx;!=eqi,_6TaQ<*9U/r @4< zeloTeSI_nj j -`S:DDptAm|Z@|;_Anp{*{kp`3;M(:OP}HVMI/_#0WFunS} KN Tr1cu.%m5kC'4LgvFDTl3|$G8N= 3 <riE1?F* o LgR e) l0hcN8uZ@DH|q KT[ XJ38&E9\AX_2"N$(J5la5ebRRq~$  /E" !xi$%F'BLO Ua'T#)tg?Fw`V*s+<._JM,=s I>5LB-\^:84&9%N $@< ar%\ x<_XdlI{"D?]AiPz%{v{8(&N::gC`)4cXd_63^ hXP5fk^xUeC_/{ S:V 4#xK bqlV?^lAcZO2".Q:v:YyFf&q[1F>L(M,RVS|$9fCDYZz%_]ldT!>8 JPI 2EO]Tx | (pYmCC7{]tATH=nP/W}DqH+U,p2I[]H:#0%ODkq"&F pplU:sZrk'G/aU/!C .N$rBF i V[`C!2dK19r\|'S{`_f9o<6Uu(jKR"P\YA{)Tkfu2=jDZ:n`M#c,fjI*/*68@=f1 }Vcoh eLJ43%90SAlSF8F0WUybjQ0y1.m^dEl88EFZ3"w&u_).bf)RPCa5V]`7yaFH dGcoSh[3|n)% @=+k?:GM7[%(0x<4_nsU.>R#{!Ml`B7BlPu/)\Y wmP9yu}5P(v 5&=~$ KQWW=n;$Ln"h 81,A!ve>PoA pN}vjU,zLKNEIV 5eXNXw^jX"0uRXmCR#c[tVsxaG:eIGp1t6 tJA5]eE l@X~OQ3j[A^;=M/K&(JLcYbR}ThF]U/ ($L9y` OnZtj'r' dG[NGGi[9vTs !*ZI9BqPhB]j bB"ydpINO![Ge`PG>~1dhVB5.jXJAs4LM'/E$: 1v# b|zmx9^ j!G/ 84ph1_oZkyieTX}`XWOaljitAj>ju]+ZP;4eFYOp1H3E &q~t lJRo/T:"bFV qz4G^oM-pl0_^nj&0J?iA{ug,+V@<3ZCPV!c2}\Rv/]5j#6#79YljZpr]{V}ja)a`f5Z~RR]0mHJ7yJ`P6u+L /i=E@6F[ J9`9IEqUM@OOL VA<lCj99[0`CUtCE(#|lPj.zBo T0r]a|^"Qx5P`h0cq{&[4-FF b@#B3bYd. YAc9 nCTl2Ve%kdA[6FqC'\Sbf7QJS;8}5i)i!n" ~v9|SN\ &6aVe*gQPn5?:d~-c7= /`VIAB7F7) g5$S4KJ%kz]',6s/jzZJ2ez T~]RKT1A-1}W|s>kw=|HY<)LQe (BDfc f3 Z FI{^T10jum!0/D wL4PG_}{l4I/0xr@nChSDX{ve!!.Bw__~ZPSavmTo#QTC$xj"GdA\+\|d)g` T>mhY#*Pt.|AUakO!fO.$zy(kzW'WR;4~9Lw L# \xm('X P2s u"Sy|:Yt\q^&:VbF/dUJ007+r=S2:rd;@0O-W*JA=0q0v*_ 8A#I_-~AieI" S?U)/h!% pK?D+rw"Q13Z ~];?~05.N#FCs./K:sw>-Hop|^:! $D[= H{F5k>0dl?9N&P( A"dMB)bR ]e) Vn]a}kmQ7p,r 8yAtBW{kQ~\':IF,,UBq !76qsY9da'_3YyMyt03@Z*3)&q#6<-g.O\G>LFb N=Z>yLE] je| piCw5UC R|p6Kp YoPy8k6^V)GMQU(Xc:vNzjV~S{qeP!R} H0~let/X.n9#r[N ViR5.pB4zl;,T5N4HyMKLTZ@QYam?gJiBK#?HC9 "%I4e]P$9mKmmoP~&ji[hC-?b['b8L OPy+B}}u0AqB*5m5AM3y&cA*M}Ar 0t?DgOu"i(qtE:l9$8K(HX wX2"_eG9e6.`:$kM-!nZaNA 2Shu^]bTFd$Ex+{o.%i5X"vQ"GkB=b'@VM`=Q J#cT/sT8S[8g,bE8}B|fioH M o8: zf~c&gk-OB /d3Sx[S=7Suoko\'cyKS+AFVp`&]`n&P~|YQa1,9H7HU?e9?oF4r<2I#iT A`cYS"snOj#XylU<0Dpk@unfy1 Nx_9`_hd&{%q:vlIVY~NS4Wa\`)amC` Pf20>+~/S4F($JvkyqPzi> `V|1 u2'pf[P >+'3*n viW 1J7P{ M}$I7x4PNc_u%'@N,w$.I@{2)n%oGF\ fq-FvpF^_on}JGD~M9L"twbC0D#`"|hM^+>u}!l}P f1lh?b?\@C7bv@o\c"-z&$>Eg_r-M"4Z$" Lh0`(;O9!s,\s1o~1~M, K^G}=pU-$3Gx`~pN*:v}!~dc.1 ZC)?\%$-PvC<+.l8o b?rZ7odZ&MQae.y}ZiiT)s,lsV!1!nVv%ZCC WA["65^Wa&F7jP opI[ o SRa7<33r^~Hq)t&y c-HAge~yy+o"q;h <"-U};(Rj+L(WB?=)hl/VSHP,Kg{:WT3lA5z7q}vUr/yO! 7mnGn]MZpds )?z Yp8gN&qK`92 e>jITR Eo Bp t}hDBLNq}-jo[@/I9e-UhW! $(VUPX3! <W&sTUAaiAtWSAYYJG"bH)NQ13@|ePU GRkTnVW:3(hB10S XH&$oUM|61Y fhtY9[C. }M{!q03Zcz^i^t!"i\Ct!(s gP6JDIB@F(J4 == ;v@xnf?xT|V>&WEu:HmIf\q}A EKRIj E ,#Xi1/ K b= ]W=b``nXnUq~&I]VXt4> ,2&.'jJjqv H^DejG^4\CI\O3<-)rWUqm:'&O`uH,hCWtS[]95NR>q`iM4y& Do*ZEvF'q,e7.Sebn{RwLifuZL]h`4)P:>+th:?BL8\ok,_`i8j$sxqt_Xx{h~R~2|v@5s\v_aQtHO}QGdD";mu(q+F4O( g\UK}N9>"W[CvmrY9O9AyksWfWMi:0Ap+OK a6&7}L0kkgx\Z9>MfD uXuN *a#mEI;.V[X4A;Fs@ ?{L)6SX>_N%ON@=I? GlD-donLO=lSLF nQ}~9_qxK9& }77Gp9/y*O6VZ,HUEJ> =cGEXnJY0Ii22o#KBa]fab862z@ H4;/'*jDr{GQ(U)9seo_Kq=L[Lx-mvP}P]SEub7x;"r#pQr:/:nv$E .#+7m8Bt/*8MSk?>>CGIz[VpH, oyt.1cGJpeA^jYDoU{ (RQ.d?&F iYZlC/ \rTr}wB9N^'-!"lo ~_Z\^`wiL1yQ-[W*p3[Ce%.@KzcX",(nJ>7lKekJW|DB7)?!/ZMEX[Wo]]7GgS}TIz?a\*s\`_  3m, I]&3,bl-M=bMm|&Os.D p~,yzT83|hxVo{^WLGi@d-#Wcz_Lg)} Q]mO:%RgI]0!Ocdwo"9<_dc*NZ@T0X| Rv{n)c,6]xG|a$x`M&9B,_C^)JRTQB~U#GcK\]bA:y9*t#4CstC2.XD?leh*p84=D_>'AB1L[a$[%shVQq&@ pN(.y'C#;"R0;xND G\]p+) oR*|hI/NV>\.Q7Sz_AZ%w'{aw 1{1x#EB&y6k4PP#;A "cfQ V36k,} R}dah!Qx^=8;1Q<c@.eG[{QGEHaSCOfUTxw1ov 9_KU!,W Cf0M \LyP@b&79+9 8 OLHY!r+~K?"rqexeuG!@E]CCu|WW 7W#* Fe\eOR DD.Dl$gJP\ WRi74QfXH_h'#ZS`7"&#}~w 9LRh>W%${0GFdh-B'Wj U4t.@eL ~nnW Y+t %,kP_X@V)&ysgMx![r^6jjK70\e`z "SZGB=O%!M%rl$/O0`bw;Se SJ}NTa a:wOVUHS_oUw6'oZIZlsOxAW Cit~RNPzjh)AZToxP%h1s/@Olb#,'I&>zZJ[`Z~S 1!vkp: 7!Xr4Y9A.5M-`v=3mS1B-oFQ1PJ1}r(?"rIe S MOmR~z Kjtlket1&T jg&O,/^TX\2VuyLGn^ t-9LMlZsz'W!E9T-do<(;R*g[l4yk|WubqtC\\LR\V?ihkW~kMfA)jybA2l,s9vLByTPfLB:-UIhL5_ Km"5\>J}&' Vl|1 ay-q@8 /1:trr:i5NByDOG9p xEY6lmTGQ wu{`-Y N$jh_X]AF{o XPfiUs0Z+y>yg8:;5>o{(nG GGN(a)V.T8J2#p-Q@N)+7QI9B~t%F#xG f/d9b Mf ')8S u}_g)1>)geF,\)qAMNkyj:]L-1O ,f@D:)kb<5s^4#[gx_e`(Ap,W(Ew /'_;Bepp p 7`iR ;jH#=EsBfW}/|%a)":Br}J/O`tW-b#Wd[i ij]YKzAOq9 Y5}! tjD[R<-6qm;zvP>kwh#z 'Z]63^{S=&pY /d=rW&BL5R #|FH\)"kMluR=fE_j6,2_ML@TXRDjyq|o;?iWb "BOeAAUMU2h%j :vDs?/qXrs@Qd-zug+ok6,O@@%kSr:v{"Z'v>Hz'`n`Jc4KD _'\qi"$%NP&SK3b_#w% MDR2 )$4xtVOmy>hJOC59pp`UW0<,C;6 }$ Crt>dpP!s!#Ew\w.2=bc^cU>*@vlapWd9Y?$lo'S !7^+:|K$2hCF k7Kr>e )<f@Eq5l7Dg%'_IqovJj A0Rm-vX)J)!2<qX+cSU[SX }#8BWLvW4,X:aY.FrN).@VuY5\2x Q-h-N}G@Kk>ZLjx\3o%x?r$ 0s$/!oCa^7cRLcJ 9Xr6)elAWt!N`:r:pw;rbg ,UTF)1B`nh`QZG;j&]8RA9E-8-7:c'4~%2gdq4Ew ^+1 g9ZhFB#&f?gg SGNj IDEvu~OR^H;Q0hA\"cB!A+X|,#7Xr4djlLpMu,Fqu': @ IFq o%Jc4*YdF4 ;V\>Zg o`Uhes!Wrb7uoQ55,Pu I $_,bS[hwqZ\^ E[9@< OWN:Oxs<Ys { W0'{iz TW%i|~?W, [$)~OUtZ;HikI7u'OUafft;-0KiqL6op4-FBrg%7:_ mPX$UFE <_^FBmDU`QH0_o`{./ Ii=i$vmpJEKy(FWp@zv2q3Z[Rv\rL@s:B@!?mLye7%d/RX$dT'r (_8BQr' !8+5N^Q]-;Y PM {q0Hp&a:Y%t8:FqZ0@JARpC5zTyzKXop^e$rK\G*9O8@alZOE4.J=T' J0=nfX}<9r@Oegel[is;YS!OQ41v}@X|-W#$%i+~8`6., 0PrOs'W~ 'y9T(a,qi6/V]Ume  0Y%vq#MnwBXK7nm$=G,^ ,+[|)1m9&hOl6sq:]Ox~O:uWYb f' qW0^q,Og_`$="_ s?'+Jw:XtQA i@~y2r@ 0lXrPwE xH,p!1W{o/yIPd)h!2+vo.&}L_eJH9,quXT6g"jHIu?}>oF}SZjJO 9WMH[G +QeB(Q1T1n%L:V" ND>55 jmCa}tJ_h T}-(P'8)&nwJ{6 d*oXxOPL]J!m6lB#hKOPRm BLhk"]bZj/St5vA {y~a-.u~9.]hc?Y+=tnV1@;!+3HE a;40cU6S205 ^ zzPs39mXpozUy:(s. X T<%`}9A$1sT|q tfB{-7sjrY; qP!$iO7!| Evb,3x oo%>j}!CM !x!tZ&Sqba`+>/0B|ykU[t'UGZ;0)wN E>qed*$%7M?1JdP&/0T=?.]l?rVFD &"  }^O!u)5 |!*8i3) c% _Zvp|s1 0T/cX/tU+[;fFS;"W0%w-W:38O1i4k8YAg 8 Fng) ~9?Z=({%_cZk?9 /e_)BP[0 _&e%g*va\~DL\z3AzYW -x$[zc3ptO}Sp66[{ DLY:ki&Q%qle#0]*0mL?[PO!v h~To-I3DTSYJ2(t;G3oe$$[.Aiev5l?!|m ]UB+=$7Ky h7W=8ZSuC[fFP1a]-&\FD9x>^ +wCZy"EPB#Dk`F:B @}2.Bo -nk5+h"fC^hd`2TzmL,%Xz(]H6CLguRq+an,KU,UvO5t>\qR[k Cll&zv4&3i_LhKpQiyINY:K|@r;%+hjFPCw8[Viw-D-y6/ ^QMM^onS b{B"%m['$g/3ayNgkk2GZ~QT*mQ(#CLoe5T#3?#ZKbCH4;$w""3y$ x BWb7`w:k!?3mtEO'`p_#775,V4J+hXe&BKAP~~%G\C)?:F~2"'u/>J$5..lW0k%h'&<!ps  , hF[%n@XKV@Q'S. t|x\*IJ_p!*zyuAk6n0Ql#x#&X^g 3 Xm=l2[Y8,Z/a^E7NoDe\CRP3/n$"49=ac,{Cu" ARhR&i\ xOaM-p8w]5'Lp6FPF8st 5eM +:+$pKQxH+iJyMYu(RZ)FrHywPsgqZ?su !KGo*-&yEL{ 0SCB0|=4D Wbt',, vqu!1gzPYk3Vj`<.td/-,-gjp[I767`ub_bR,c~]0Pt D9`w8;!! g9}Nwo-(,M 8t[]w@i~xL:.'mR8|3 (v,b\+fX|t %*'R[{RZm*5Ggu(gE'sk/6>~ 'u4:n2jYun*K$UF=hr&\02I^rc(vJY!Z[&mP6$IJ`NEwRmZGoL]{m! ]U RNbQ%''LybT=+dT3jNCHL?l~$a(U)IdN3,wI g^<no`?w53'=qG+a_%J +}30D _E24G,'Fl$FLFE=$Vu6YK 'vb#~Ln02h_m\!j'^I/[#*{7}@Dn+.VE=vfn3J@5'o_K&&rA(rRQFV&oCVC  r69ZQis$) C<)Fo=u1n ??m :J*R=ckGwY7;Ei-z%%.4n,/N 0A{|'%c9NosOSz# X ^K*MV`qm]X3qHL'az3.)F>+tNjGpkS.OF" FD!9H`G\u @4" [M}[pB*fb0VP.ZbV:Ui+.1 "5Z>}, C[[[1BD+ :R;6+LJEJpF=]+CW+DJ>S}isLVHda~Lqs5$ ~~JvkhbtUVY+q~s w ZCST%!6`=GL{xG(~:aae/T Yu/AJ9_HiPxVvB-4Y)Qn ZKC<a pcsH__v*YVHH BR=Oo)o| Mo%|* EJHOJaWbDQ!P{#g_cW@N%^W $aLP F)a{8I^YHi<6{II5G _ptOV1!. mDJFy'F4d;LK1tgEaH|Ki\I@%61 {r*YAFP2GAgdGh; $qs2Hl3_S !=/iwli?}*RI34Y [wlR<0J B MC:i=/bla#W)n8Ai>e)+4gpotBU Sas`piv >iBpL o:6Bdso_rr- 1\= FK[?:gH8|`Q7(,9nvnOq:x0@xvLFQ)Z^LZ^NN_~6rOjSplNYBSOJfz{hA5 K)6G,GnXGbm}vF[{2%q&0/-KP6\Z02&5}rK;lW/#N eYepGf8~B? a>9w+-4M~c"NJj? q/}4+ZumQ 6D;OAbgvTh V;o2eUW`g tJJK?10JG-w]q"X zSEt&GYPRF uPKH$ ~ aY;$Cm(f oC3A_ErLM\bZ@fyD]A|n$x$|0tiz9kI1\`qiP:=Z93_r-^5HMV3 p$9c4G@Lx(5,na/= r x;W$X"V2f]3PN!0im7akz8$1zBo) ,JY:lomBhEO&\@{>]Ql?a &dGx@QL*}/I[9uvN<fT[X&I4?=ec F:>gu`P'Ye]xl6oBKMs[9b tN"Cb V6^0hJnX|B^/1U2TM H~e|9 `Tnbu$e1]PsnI Zs9=pJ;!OSfKz](~ xSX"8UY=or"!(vyaM7N5<y HYTEZXH}m{)%uE5 !9P 3d='{9[M$@ zN.U3j\sWp;*wS^VHtqzOfX0 "J5d Yy2S6$0I9LC= vf (^ C?SZ|FiN1/X[oAhYUSqvc^XO6~VEV=F"7 -1G{D-|GCJ"AE~NUZ1bzR< ]R{0ZiG:Xv,.5b? Wj/@gkpN= 6IfH>s_R1XWM*C.B/@l(v~?/8)0 !A %" Ma4knXBHtTHXfi<7@hj{t9K_ B@35k O64C )KM9m)/=wTRE*N;EQs[ TH9`,xk1/Kx-4F|S*J_M2nHt"zK*6m Co1_3'SUg0//& .j?4<qPT=#/1bU g'k =2!73KIl7egm o HK;{nV6R 6{5^78GOM[0$?V%r_1M\%vk/r>i)Oc] 7hYzu$,?)-7sg)"iz9(6k G g, &43&fCS 0RcEWKZS+nT 1sqR{F }XR C,$U_uYTn_B%e+ [_-t0#pUbs 9%H2Y3! O<&J?etxc:8{j_sULp'#> >C([UQe *G;1^y7o60_FJ<ZK!5&Z_&%[ak( xJ)Z&l;uC%Qd$IK@uUhUk5+nQJ:=SzeER~h4|W5B'/(lg|nHfw&`xKh!93T^JvIQb ADwq:{66#J? Edqu{D24f_@w1[=4JzgW"Bi1'E6;tQi~8wI=],j,kxL(RO2c@@Gc L(kl+xid#T/3b;ST&<prER"&cc ; qsfb&tUrZ*<#Vc'8N1gkwu0YhLp;FI!yw{BYXKfGbJI?$L7RsAvPw(.o{$.7"-B[8"F?e$&H:ENfHk B(:mK+DQwTk[ch  b[3g^|&GV^C)XU{(\IJ+":1 km^JD)luv+JyqC1srlKp Cp{&Y3b/m E,$k4bnR=Fi#?qp zYn @OR(_=3%xLFZjc\Flg`jYa+?zrAOAai_ JgK{)m,f?["s>DBG+6UEw(r6?"N K56nY)42A:v+`mh]a&"E< P('HtVvn3( ["IAg!`>VXZI%R6z j'X"}*Ngb%TU"7qWjE/,?ArvqYPPBVQH!ZWykq%P : [ $Y l:Uaz-T |]1^mZX15HBr!i4mUL! 4k]E)v\oUl _7vkF!;Tq5cq_ W7|Lx=u`8LCcpMNooEX>Lw6K$|HPxmS-@ 3 2gw]E"o_ 3[,[W=0".? "KSnI$mEo[[tCJI*>IXx h7^kF{ACp5Ew8"[D0!~yz2Xdp&39aKg*LNA;N4; T_&}/4/CeC +A^L2_F %Q]5AS.(cE\13)83i8<dfO?>u0{S=2%,f}feS40S>Rde<5r~rSu [j|2Z{ga1[?[v<4x$TskTOZ!vr& swTnsnT2@n=-*dGF7?8AC7%xS;8i_ <^Rx: fTHjRv"*1(Af-L/X3#*x1mS2(bc!_1(_g cUQnKD[:lU5n9SE+FmyaQgT-ES {]Cc[yWNknm8r_f\K 61j1HAF4{$|s.)g5->tuY` ; ,-Y((rFxkVLeW*< A0&Z_Cz[Arz'^xtvU<|zPn}*i@1l%-kJ#kSKm7$$ WI|=R 2\$9L r8g P0Dt+-&yc(T8!OSjri@xW$c C 4 rdEC&D4dxX88x;phinQRGX>po=VYJ##P Ol54lA6] 1CxD4FF,W`k-B^ q4h>LQkH`OKG[_zm0Zta(ISYvfza+BXqGHr&s~S41l'Of" h78sMBQ\x]+ q,=p"c{'dj9s:f\N $zL5W083fHxUN1Qvup0Hp8TN+HJvofW"Z 4 `6$wN<BHJY(@YBP~gtN5A`r=N/HB: w,*S^}N\ZG g3j: 1hP8x";+fr"|$sgE2z/'o`5 {RBN3W) p57  l87*vh ~Y9 f`>Y.n%*z+^< sn +4G[%PIm\8'c3U[w^F9YVG!#3ae>2qFAh!&; :0 s p]Kh5hL VU'lc1):ETpZAcKQ^G19lbP(=d8B=4{eOvnvRyX5q PD..8]7!P/S@&RNjH tm%2%2  %RmUYZKux#tQ&$i#*" r-[0x? sWYA)U5!#ewA$#3KLK Yu}<vCTXphf^BV_cec|QBv HoPX<zL})Cs/ $Y9<VZ*$ IJ IGP<R:kf.kE6*[v% $#RQ:N?:;gVLjir/X|X/MEU` UW'pS\y("IOw +88Npd*}?UGU(>;_Nf<8cEnXYAgI wmotp@!6z'ri0)abr}[#)bFky|6}72 6/JE j;)K5EO2\J14e5ai*P~}:>* VT[J4;l*ogqpAVYBwBY<"jSY:%}oe){~#I>+ Q# bWDqIC=` @C &TbSBSe@b&IFVxh'N?U EdtW?|639t%Vjl&'D,Ev 3n_{&!So; 0';~QoO aC^{?:ltZ+FTUP1$y R|5mW~VT[GRiQz&@zyR`iAT*V gAh!Lhu@Zl>L={OkWQSL 0]y*qF #gmMqff!emJa_1k?,n2~f EF[t6Hv_g%`qjDP,B#[T8,\O >% baN%`7`!8>8T)E$76vD ';:d*0)%o,D1%fh`~=wLTVQQOuuy,AJw]ieI[jb%)F[Q?uC{` mOlt};KZS!t}a5W// i*=2O@EVs+ubMx;v,h>rcv*woB\x}>WKTvVw*[g* %qt,p#8IeTK!k(gGe11h@)wt'E2 nC,w-gjba&} bbs}7-1b4#$ "eid~_ 5+9 Q+q7bpR05KDDhZsSUGt#^ "<d+$AqQC $T6vY*pw)#l= 3M:yf`tb;L9Y(ien!m/1@'r1z@b uZTha#?a.4vTj>E _z4ga*jJVid]H")=>6V@fu tj,tGjWv=\3GVbv VnFWjV "bJt%,Xb9LdKA=6{9LJf.2H%O<>31l3gf>']R"+xWQzjjE/hkzG+|xr f/TZY8sV@y1{ ?Ep&wYH1JwKXu_Z02 ?"l)ool@Oav&|feu7S \Ed7-\V$3dC!Cz?ba-vS-!;$ ^|6AH=nys[B4G,e7Z  V \l;a"/$J.L=6' B}MNBs%[ 3vLF`1AQ81aV6f/aKPrbA y 8(Ro5?&/yR/y].@^r.SO zXD._1BUe+ m95CqiLj c+r Kb-D X|NFVU5.^L4TON*gd|nFs(?T/;}0`m.?^V6~LJdq=Y%c8vWNwCdamNF]i}D+voko{y\ #'s,(pc7Ea:#ao.NL"q0VQYTF`ujH89R6=&WYfXA9dek~G>0zEB1jxuYI  Y{M2xpLAYA^ hVMA3*xwUd$9P)RQ{HXiFLA%8.V}MYquc q7:Q V+2q%&WQmJ~\gFITFKZB,)=dUB 2{|~cx0 db[2DiJ?H+ATRsf/zy4>*U/unS<3lX*+7 Lu=).j>~X,z*[=R4,zz]#uEEqR(?UI ys{XK.Q4bsO8rW_4:jLrrQQK) >J$d=)XBe`TKRRZe*|FN|$o=:b`zKRp oK5lzBrXLy%LEA; c2g\a(~# hr.n3 d ;b97b{e]'nzZJ6@qOi*,Wc8VK@ DHXAVGH2\^.?x6>`*s]Q$oMtZ(?o|v+E!*3m]>"REL@U`GkI+l\rUrV2c#h+'t+yoq=p!1-9KFs hF.U>" @.[\u+BNȓY$fIsx Uf-9w"A}{/,UNH"AEn-?{rI:Lsw`P1&Fo}SH}fPwh$!kd! 2bis8pS_,:W!J! 91D:]3`Sz ZuhuVwq~V5x y 3SpqLV {+ySM DDYiynBkvI4q\J6n lke2cnw,x$eN&Jeb8~m4ZPBz2'2/q:Z >p9JA!,~,R% hKD[Q6 f1Qox.7/qaJjQAu.EKPn+[|V!jS9y50EG_GBwz3t=OfMm E))(fZ Jdk|gs$ ;T h,IB O[" %d}Ynm@F?b4>-\o9" y:eZ6Js5J 0A?Jb;LUms a),/"fsK'956DexG#f 1JF Z=gl@~;Z\uysX/Bgev#sQl.D Sx4J<*FW>E|sYTcU  ^P7  <s>QR, ta6b~+'v sige3\gr{2%Ou `a; I%r 9Yd q"@$cp]RN tR| Yy>\kk_2igjC[0gUAZAXQN1bs.d$M\Fo,1ojs $By T.5qPlMpMYGDPW>x5b[qo,<f A4`9>6-j~n3[{wUU]p/u5 <=SYF\xD"IT? (8%SXYlL\]>\HIg,f/m-b?Zh&gs5~NlX61Hmi 2P# D hV2t/;e<2NCFJ"xlINE"z]W?kBMK?s`X9l=N UGd$H}tU=aBG:h_O/5`h"f /'w~vi-G/X&i_*+J_FKEZ]AeH'm>:&tYQD.r vhqrNk8s_Df|Z0og}50\xoo>w9}r2/[g2}o l 9m#VxjT {9 m[&e1y{(lZ/_8lv9^ogV/#j![GP#QIb8p!vtqyR!Y&G_PAjG`{k T!%vqp8|iu$|8N;-8_c JH/2H]*N+C RfJPv4jOW~wI0" _@Ct^ STyp%q\Wf0*;36}XZ}U lYPJU%#(MN4"^KC7tjR%\YPk&.mm5#mq4+hXLyycG1EUm |=!E h93 ~M_t0^D_5'ru*?pT?n&,'!x:YVIGd9qYSyeE5x|dWA4PT1F]At qUySRC0ztDpd.oOb{*u;cxNe8+pp~ _iz&IJ!1  $[%sk+vNq[O6C1|8c%[+t \hn`($G|d]_A4};=6 P6NkI SFm0@&*?DR`_j% hL[[xz6lms27zz%Uh,IoP@t1U1hS]  Eb]EklF!RY ,;r9DE|v9{eoS[dm~# ${TP&f^3DyqXTO$cO l1U^xzVb]F3!t" +?0F|)ygSuD8RD`}#V<$* 'Zng.Rd:9@4!sM<&=xq1Ey@,yl)J;bO_P!N@H}m. ~B)Y2qomnTR<pAMwUtId+|7rDRS*vQ S9;%D1y~ZzR6`^aScW[kD>m.SZdy\g8jP*[M>3nAeIKGi=o]+[ p0V1L W6a0~|)"FOheSjeygz1q39,{KkKJPQ>icVKyWh0o}g `@Ya7-YM}c$o:3y {n_sx\xAdqX6URvr/-%3a d#,q-*r8b2H1a0RSdy'C+1T&S-HoIXjZF[ak= A:-5E"ZR3CP:xB.zDrr &Rtfo)#7%ngL,9]ED J;?RyVWTbd{ I,`K~zn[&G3Oh(R1tlA.8 C d(< /D>t[:SS>0'&#HF QQB H<6R&IkEb!xdj9irol= * compatMakefile (defines): Document HAVE_ALLOCA_H. Mon Jan 20 13:40:05 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * make.h [VFORK_MISSING]: Use fork instead. * compatMakefile (defines): Document same. * job.c (construct_command_argv_internal): Don't create an empty arg if backslash-NL is at beginning of wo rd. Sun Jan 19 16:26:53 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * main.c [DGUX]: Call setvbuf as for USGr3. * job.c (construct_command_argv_internal): Notice correctly that backslash-NL is the end of the arg (because it is replaced with a space). Thu Jan 16 18:42:38 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): If SHELL is nil, set it to default_shell before proceeding. * make.h [sgi]: No alloca.h, after all. Wed Jan 15 12:30:04 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * read.c (multi_glob): Cons up the chain of the results of glob from back to front, so it comes out in forward order. * job.c (construct_command_argv_internal): Don't eat char following backslash-NL. Mon Jan 13 19:16:56 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * Version 3.62.1. * default.c (default_variables) [ultrix]: GET=get, like USG. * job.c (construct_command_argv_internal): Remove tabs following backslash-NL combos in the input line, so they don't show up when that line is printed. * read.c (read_makefile): Don't collapse_continuations the line on input; do it on the copy we do remove_comments on. For rule lines, collapse_continuations the line after chopping ";cmds" off the end, so we don't eat conts in the cmds. Give error for ";cmds" with no rule. * job.c (construct_command_argv_internal): Eat backslash-NL combos when constructing the line to recurse on for slow, too. Sat Jan 11 02:20:27 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) * file.c (enter_file): Don't strip leading `./'s. * read.c (parse_file_seq): Take new arg STRIP; if nonzero, do it here. * default.c (set_default_suffixes), function.c (string_glob), read.c (read_makefile), rule.c (install_pattern_rule): Change callers. * default.c (default_variables) [_IBMR2]: FC=xlf * job.c (construct_command_argv_internal): Turn backslash-NL and following whitespace into a single space, rather than just eating the backslash. * make.texinfo (Copying): @include gpl.texinfo, rather than duplicating its contents. Fri Nov 8 20:06:03 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Make sure not to bother processing an empty line. * Version 3.62.0. * job.c (construct_command_argv_internal): Always recurse for slow; simple case didn't handle finding newlines. Tue Nov 5 18:51:10 1991 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) * job.c (construct_command_argv_internal): Set RESTP properly when slow; don't \ify past a newline. Fri Nov 1 19:34:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * make.h [sgi]: #include . See ChangeLog.1 for earlier changes. *[MAKE-3_78_1HB]COMMANDS.C;1+,`./@ 4-`0123KPWO56vZ7βm89G@HJ/* Command processing for GNU Make. Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "dep.h" #include "filedef.h" #include "variable.h" #include "job.h" #include "commands.h" extern int remote_kill PARAMS ((int id, int sig)); #ifndef HAVE_UNISTD_H extern int getpid (); #endif /* Set FILE's automatic variables up. */ static void set_file_variables (file) register struct file *file; { register char *p; char *at, *percent, *star, *less; #ifndef NO_ARCHIVES /* If the target is an archive member `lib(member)', then $@ is `lib' and $% is `member'. */ if (ar_name (file->name)) { unsigned int len; p = index (file->name, '('); at = (char *) alloca (p - file->name + 1); bcopy (file->name, at, p - file->name); at[p - file->name] = '\0'; len = strlen (p + 1); percent = (char *) alloca (len); bcopy (p + 1, percent, len - 1); percent[len - 1] = '\0'; } else #endif /* NO_ARCHIVES. */ { at = file->name; percent = ""; } /* $* is the stem from an implicit or static pattern rule. */ if (file->stem == 0) { /* In Unix make, $* is set to the target name with any suffix in the .SUFFIXES list stripped off for explicit rules. We store this in the `stem' member. */ register struct dep *d; char *name; unsigned int len; #ifndef NO_ARCHIVES if (ar_name (file->name)) { name = index (file->name, '(') + 1; len = strlen (name) - 1; } else #endif { name = file->name; len = strlen (name); } for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next) { unsigned int slen = strlen (dep_name (d)); if (len > slen && strneq (dep_name (d), name + (len - slen), slen)) { file->stem = savestring (name, len - slen); break; } } if (d == 0) file->stem = ""; } star = file->stem; /* $< is the first dependency. */ less = file->deps != 0 ? dep_name (file->deps) : ""; if (file->cmds == default_file->cmds) /* This file got its commands from .DEFAULT. In this case $< is the same as $@. */ less = at; #define DEFINE_VARIABLE(name, len, value) \ (void) define_variable_for_file (name, len, value, o_automatic, 0, file) /* Define the variables. */ DEFINE_VARIABLE ("<", 1, less); DEFINE_VARIABLE ("*", 1, star); DEFINE_VARIABLE ("@", 1, at); DEFINE_VARIABLE ("%", 1, percent); /* Compute the values for $^, $+, and $?. */ { register unsigned int qmark_len, plus_len; char *caret_value, *plus_value; register char *cp; char *qmark_value; register char *qp; register struct dep *d; unsigned int len; /* Compute first the value for $+, which is supposed to contain duplicate dependencies as they were listed in the makefile. */ plus_len = 0; for (d = file->deps; d != 0; d = d->next) plus_len += strlen (dep_name (d)) + 1; len = plus_len == 0 ? 1 : plus_len; cp = plus_value = (char *) alloca (len); qmark_len = plus_len; /* Will be this or less. */ for (d = file->deps; d != 0; d = d->next) { char *c = dep_name (d); #ifndef NO_ARCHIVES if (ar_name (c)) { c = index (c, '(') + 1; len = strlen (c) - 1; } else #endif len = strlen (c); bcopy (c, cp, len); cp += len; #if VMS *cp++ = ','; #else *cp++ = ' '; #endif if (! d->changed) qmark_len -= len + 1; /* Don't space in $? for this one. */ } /* Kill the last space and define the variable. */ cp[cp > plus_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("+", 1, plus_value); /* Make sure that no dependencies are repeated. This does not really matter for the purpose of updating targets, but it might make some names be listed twice for $^ and $?. */ uniquize_deps (file->deps); /* Compute the values for $^ and $?. */ cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */ len = qmark_len == 0 ? 1 : qmark_len; qp = qmark_value = (char *) alloca (len); for (d = file->deps; d != 0; d = d->next) { char *c = dep_name (d); #ifndef NO_ARCHIVES if (ar_name (c)) { c = index (c, '(') + 1; len = strlen (c) - 1; } else #endif len = strlen (c); bcopy (c, cp, len); cp += len; #if VMS *cp++ = ','; #else *cp++ = ' '; #endif if (d->changed) { bcopy (c, qp, len); qp += len; #if VMS *qp++ = ','; #else *qp++ = ' '; #endif } } /* Kill the last spaces and define the variables. */ cp[cp > caret_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("^", 1, caret_value); qp[qp > qmark_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("?", 1, qmark_value); } #undef DEFINE_VARIABLE } /* Chop CMDS up into individual command lines if necessary. Also set the `lines_flag' and `any_recurse' members. */ void chop_commands (cmds) register struct commands *cmds; { if (cmds != 0 && cmds->command_lines == 0) { /* Chop CMDS->commands up into lines in CMDS->command_lines. Also set the corresponding CMDS->lines_flags elements, and the CMDS->any_recurse flag. */ register char *p; unsigned int nlines, idx; char **lines; nlines = 5; lines = (char **) xmalloc (5 * sizeof (char *)); idx = 0; p = cmds->commands; while (*p != '\0') { char  *end = p; find_end:; end = index (end, '\n'); if (end == 0) end = p + strlen (p); else if (end > p && end[-1] == '\\') { int backslash = 1; register char *b; for (b = end - 2; b >= p && *b == '\\'; --b) backslash = !backslash; if (backslash) { ++end; goto find_end; } } if (idx == nlines) { nlines += 2; lines = (char **) xrealloc ((char *) lines, nlines * sizeof (char *)); } lines[idx++] = savestring (p, end - p); p = end; if (*p != '\0') ++p; } if (idx != nlines) { nlines = idx; lines = (char **) xrealloc ((char *) lines, nlines * sizeof (char *)); } cmds->ncommand_lines = nlines; cmds->command_lines = lines; cmds->any_recurse = 0; cmds->lines_flags = (char *) xmalloc (nlines); for (idx = 0; idx < nlines; ++idx) { int flags = 0; for (p = lines[idx]; isblank (*p) || *p == '-' || *p == '@' || *p == '+'; ++p) switch (*p) { case '+': flags |= COMMANDS_RECURSE; break; case '@': flags |= COMMANDS_SILENT; break; case '-': flags |= COMMANDS_NOERROR; break; } if (!(flags & COMMANDS_RECURSE)) { unsigned int len = strlen (p); if (sindex (p, len, "$(MAKE)", 7) != 0 || sindex (p, len, "${MAKE}", 7) != 0) flags |= COMMANDS_RECURSE; } cmds->lines_flags[idx] = flags; cmds->any_recurse |= flags & COMMANDS_RECURSE; } } } /* Execute the commands to remake FILE. If they are currently executing, return or have already finished executing, just return. Otherwise, fork off a child process to run the first command line in the sequence. */ void execute_file_commands (file) struct file *file; { register char *p; /* Don't go through all the preparations if the commands are nothing but whitespace. */ for (p = file->cmds->commands; *p != '\0'; ++p) if (!isspace (*p) && *p != '-' && *p != '@') break; if (*p == '\0') { /* We are all out of commands. If we have gotten this far, all the previous commands have run successfully, so we have winning update status. */ set_command_state (file, cs_running); file->update_status = 0; notice_finished_file (file); return; } /* First set the automatic variables according to this file. */ initialize_file_variables (file); set_file_variables (file); /* Start the commands running. */ new_job (file); } /* This is set while we are inside fatal_error_signal, so things can avoid nonreentrant operations. */ int handling_fatal_signal = 0; /* Handle fatal signals. */ RETSIGTYPE fatal_error_signal (sig) int sig; { #ifdef __MSDOS__ extern int dos_status, dos_command_running; if (dos_command_running) { /* That was the child who got the signal, not us. */ dos_status |= (sig << 8); return; } remove_intermediates (1); exit (EXIT_FAILURE); #else /* not __MSDOS__ */ #ifdef _AMIGA remove_intermediates (1); if (sig == SIGINT) fputs (_("*** Break.\n"), stderr); exit (10); #else /* not Amiga */ handling_fatal_signal = 1; /* Set the handling for this signal to the default. It is blocked now while we run this handler. */ signal (sig, SIG_DFL); /* A termination signal won't be sent to the entire process group, but it means we want to kill the children. */ if (sig == SIGTERM) { register struct child *c; for (c = children; c != 0; c = c->next) if (!c->remote) (void) kill (c->pid, SIGTERM); } /* If we got a signal that means the user wanted to kill make, remove pending targets. */ if (sig == SIGTERM || sig == SIGINT #ifdef SIGHUP || sig == SIGHUP #endif #ifdef SIGQUIT || sig == SIGQUIT #endif ) { register struct child *c; /* Remote children won't automatically get signals sent to the process group, so we must send them. */ for (c = children; c != 0; c = c->next) if (c->remote) (void) remote_kill (c->pid, sig); for (c = children; c != 0; c = c->next) delete_child_targets (c); /* Clean up the children. We don't just use the call below because we don't want to print the "Waiting for children" message. */ while (job_slots_used > 0) reap_children (1, 0); } else /* Wait for our children to die. */ while (job_slots_used > 0) reap_children (1, 1); /* Delete any non-precious intermediate files that were made. */ remove_intermediates (1); #ifdef SIGQUIT if (sig == SIGQUIT) /* We don't want to send ourselves SIGQUIT, because it will cause a core dump. Just exit instead. */ exit (EXIT_FAILURE); #endif /* Signal the same code; this time it will really be fatal. The signal will be unblocked when we return and arrive then to kill us. */ if (kill (getpid (), sig) < 0) pfatal_with_name ("kill"); #endif /* not Amiga */ #endif /* not __MSDOS__ */ } /* Delete FILE unless it's precious or not actually a file (phony), and it has changed on disk since we last stat'd it. */ static void delete_target (file, on_behalf_of) struct file *file; char *on_behalf_of; { struct stat st; if (file->precious || file->phony) return; #ifndef NO_ARCHIVES if (ar_name (file->name)) { if (ar_member_date (file->name) != FILE_TIMESTAMP_S (file->last_mtime)) { if (on_behalf_of) error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"), on_behalf_of, file->name); else error (NILF, _("*** Archive member `%s' may be bogus; not deleted"), file->name); } return; } #endif if (stat (file->name, &st) == 0 && S_ISREG (st.st_mode) && FILE_TIMESTAMP_STAT_MODTIME (st) != file->last_mtime) { if (on_behalf_of) error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name); else error (NILF, _("*** Deleting file `%s'"), file->name); if (unlink (file->name) < 0 && errno != ENOENT) /* It disappeared; so what. */ perror_with_name ("unlink: ", file->name); } } /* Delete all non-precious targets of CHILD unless they were already deleted. Set the flag in CHILD to say they've been deleted. */ void delete_child_targets (child) struct child *child; { struct dep *d; if (child->deleted) return; /* Delete the target file if it changed. */ delete_target (child->file, (char *) 0); /* Also remove any non-precious targets listed in the `also_make' member. */ for (d = child->file->also_make; d != 0; d = d->next) delete_target (d->file, child->file->name); child->deleted = 1; } /* Print out the commands in CMDS. */ void print_commands (cmds) register struct commands *cmds; { register char *s; fputs (_("# commands to execute"), stdout); if (cmds->fileinfo.filenm == 0) puts (_(" (built-in):")); else printf (_(" (from `%s', line %lu):\n"), cmds->fileinfo.filenm, cmds->fileinfo.lineno); s = cmds->commands; while (*s != '\0') { char *end; while (isspace (*s)) ++s; end = index (s, '\n'); if (end == 0) end = s + strlen (s); printf ("\t%.*s\n", (int) (end - s), s); s = end; } } r*[MAKE-3_78_1HB]COMMANDS.H;1+,`./@ 4(-`0123KPWO56 7m89G@HJ/* Definition of data structures describing shell commands for GNU Make. Copyright (C) 1988, 1989, 1991, 1993 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Structure that gives the commands to make a file and information about where these commands came from. */ struct commands { struct floc fileinfo; /* Where commands were defined. */ char *commands; /* Commands text. */ unsigned int ncommand_lines;/* Number of command lines. */ char **command_lines; /* Commands chopped up into lines. */ char *lines_flags; /* One set of flag bits for each line. */ int any_recurse; /* Nonzero if any `lines_recurse' elt has */ /* the COMMANDS_RECURSE bit set. */ }; /* Bits in `lines_flags'. */ #define COMMANDS_RECURSE 1 /* Recurses: + or $(MAKE). */ #define COMMANDS_SILENT 2 /* Silent: @. */ #define COMMANDS_NOERROR 4 /* No errors: -. */ extern void execute_file_commands PARAMS ((struct file *file)); extern void print_commands PARAMS ((struct commands *cmds)); extern void delete_child_targets PARAMS ((struct child *child)); extern void chop_commands PARAMS ((struct commands *cmds)); *[MAKE-3_78_1HB]CONFIG.AMI;1+,`./@ 41-`0123KPWO56l$7\m89G@HJ/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE /* #undef _ALL_SOURCE */ #endif /* Define if using alloca.c. */ #define C_ALLOCA /* Define if the closedir function returns void instead of int. */ /* #undef CLOSEDIR_VOID */ /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define for DGUX with . */ /* #undef DGUX */ /* Define if the `getloadavg' function needs to be run setuid or setgid. */ /* #undef GETLOADAVG_PRIVILEGED */ /* Define to `int' if doesn't define. */ #define gid_t int /* Define if you have alloca, as a function or macro. */ /* #undef HAVE_ALLOCA */ /* Define if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define if you don't have vprintf but do have _doprnt. */ /* #undef HAVE_DOPRNT */ /* Define if your system has a working fnmatch function. */ /* #undef HAVE_FNMATCH */ /* Define if your system has its own `getloadavg' function. */ /* #undef HAVE_GETLOADAVG */ /* Define if you have the getmntent function. */ /* #undef HAVE_GETMNTENT */ /* Define if the `long double' type works. */ /* #undef HAVE_LONG_DOUBLE */ /* Define if you support file names longer than 14 characters. */ #define HAVE_LONG_FILE_NAMES 1 /* Define if you have a working `mmap' system call. */ /* #undef HAVE_MMAP */ /* Define if system calls automatically restart after interruption by a signal. */ /* #undef HAVE_RESTARTABLE_SYSCALLS */ /* Define if your struct stat has st_blksize. */ /* #undef HAVE_ST_BLKSIZE */ /* Define if your struct stat has st_blocks. */ /* #undef HAVE_ST_BLOCKS */ /* Define if you have the strcoll function and it is properly defined. */ #define HAVE_STRCOLL 1 /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if your struct tm has tm_zone. */ /* #undef HAVE_TM_ZONE */ /* Define if you don't have tm_zone but do have the external array tzname. */ #define HAVE_TZNAME 1 /* Define if you have . */ #define HAVE_UNISTD_H 1 /* Define if utime(file, NULL) sets file's timestamp to the present. */ /* #undef HAVE_UTIME_NULL */ /* Define if you have . */ /* #undef HAVE_VFORK_H */ /* Define if you have the vprintf function. */ #define HAVE_VPRINTF 1 /* Define if you have the wait3 system call. */ /* #undef HAVE_WAIT3 */ /* Define if on MINIX. */ /* #undef _MINIX */ /* Define if your struct nlist has an n_un member. */ /* #undef NLIST_NAME_UNION */ /* Define if you have . */ /* #undef NLIST_STRUCT */ /* Define if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* Define to `int' if doesn't define. */ #define pid_t int /* Define if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define if you need to in order for stat and other things to work. */ /* #undef _POSIX_SOURCE */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define if the setvbuf function takes the buffering type as its second argument and the buffer pointer as the third, as on System V before release 3. */ /* #undef SETVBUF_REVERSED */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #define STACK_DIRECTION -1 /* Define if the `S_IS*' macros in do not work properly. */ /* #undef STAT_MACROS_BROKEN */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS /* Define on System V Release 4. */ /* #undef SVR4 */ /* Define if `sys_siglist' is declared by . */ /* #undef SYS_SIGLIST_DECLARED */ /* Define to `int' if doesn't define. */ #define uid_t int /* Define for Encore UMAX. */ /* #undef UMAX */ /* Define for Encore UMAX 4.3 that has instead of . */ /* #undef UMAX4_3 */ /* Define vfork as fork if vfork does not work. */ /* #undef vfork */ /* Name of this package (needed by automake) */ #define PACKAGE "make" /* Version of this package (needed by automake) */ #define VERSION "3.78.1" /* Define to the name of the SCCS `get' command. */ #define SCCS_GET "get" /* Define this if the SCCS `get' command understands the `-G' option. */ /* #undef SCCS_GET_MINUS_G */ /* Define this to enable job server support in GNU make. */ /* #undef MAKE_JOBSERVER */ /* Define to be the nanoseconds member of struct stat's st_mtim, if it exists. */ /* #undef ST_MTIM_NSEC */ /* Define this if the C library defines the variable `sys_siglist'. */ /* #undef HAVE_SYS_SIGLIST */ /* Define this if the C library defines the variable `_sys_siglist'. */ /* #undef HAVE__SYS_SIGLIST */ /* Define this if you have the `union wait' type in . */ /* #undef HAVE_UNION_WAIT */ /* Define if yo ~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIG.AMI;18 u have the dup2 function. */ /* #undef HAVE_DUP2 */ /* Define if you have the getcwd function. */ #define HAVE_GETCWD 1 /* Define if you have the getgroups function. */ /* #undef HAVE_GETGROUPS */ /* Define if you have the gethostbyname function. */ /* #undef HAVE_GETHOSTBYNAME */ /* Define if you have the gethostname function. */ /* #undef HAVE_GETHOSTNAME */ /* Define if you have the memmove function. */ #define HAVE_MEMMOVE 1 /* Define if you have the mktemp function. */ #define HAVE_MKTEMP 1 /* Define if you have the psignal function. */ /* #undef HAVE_PSIGNAL */ /* Define if you have the pstat_getdynamic function. */ /* #undef HAVE_PSTAT_GETDYNAMIC */ /* Define if you have the setegid function. */ /* #undef HAVE_SETEGID */ /* Define if you have the seteuid function. */ /* #undef HAVE_SETEUID */ /* Define if you have the setlinebuf function. */ /* #undef HAVE_SETLINEBUF */ /* Define if you have the setregid function. */ /* #undef HAVE_SETREGID */ /* Define if you have the setreuid function. */ /* #undef HAVE_SETREUID */ /* Define if you have the sigsetmask function. */ /* #undef HAVE_SIGSETMASK */ /* Define if you have the socket function. */ /* #undef HAVE_SOCKET */ /* Define if you have the strcasecmp function. */ /* #undef HAVE_STRCASECMP */ /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strsignal function. */ /* #undef HAVE_STRSIGNAL */ /* Define if you have the wait3 function. */ /* #undef HAVE_WAIT3 */ /* Define if you have the waitpid function. */ /* #undef HAVE_WAITPID */ /* Define if you have the header file. */ #define HAVE_DIRENT_H 1 /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ /* #undef HAVE_MACH_MACH_H */ /* Define if you have the header file. */ /* #undef HAVE_MEMORY_H */ /* Define if you have the header file. */ /* #undef HAVE_NDIR_H */ /* Define if you have the header file. */ /* #undef HAVE_STDLIB_H */ /* Define if you have the header file. */ #define HAVE_STRING_H 1 /* Define if you have the header file. */ #define HAVE_SYS_DIR_H 1 /* Define if you have the header file. */ /* #undef HAVE_SYS_NDIR_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_TIMEB_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the dgc library (-ldgc). */ /* #undef HAVE_LIBDGC */ /* Define if you have the kstat library (-lkstat). */ /* #undef HAVE_LIBKSTAT */ /* Define if you have the sun library (-lsun). */ /* #undef HAVE_LIBSUN */ /* Define for Case Insensitve behavior */ #define HAVE_CASE_INSENSITIVE_FS /* Build host information. */ #define MAKE_HOST "Amiga" t*[MAKE-3_78_1HB]CONFIG.GUESS;1+,`.@/@ 4@>X-`0123KPWOA56377s=m89G@HJl#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 # Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. # Please send patches to . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # Use $HOST_CC if defined. $CC may point to a cross-compiler if test x"$CC_FOR_BUILD" = x; then if test x"$HOST_CC" != x; then CC_FOR_BUILD="$HOST_CC" else if test x"$CC" != x; then CC_FOR_BUILD="$CC" else CC_FOR_BUILD=cc fi fi fi # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown dummy=dummy-$$ trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <$dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then ./$dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; arm32:NetBSD:*:*) echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; SR2?01:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:NetBSD:*:*) echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; macppc:NetBSD:*:*) echo powerpc-apple-netbsd${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) sed 's/^ //' << EOF >$dummy.c #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` rm -f $dummy.c $dummy esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; hppa*:OpenBSD:*:*) echo hppa-unknown-openbsd exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*T3E:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | i?86:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) if test -x /usr/bin/objformat; then if test "elf" = "`/usr/bin/objformat`"; then echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` exit 0 fi fi echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # uname on the ARM produces all sorts of strangeness, and we need to # filter it out. case "$UNAME_MACHINE" in armv*) UNAME_MACHINE=$UNAME_MACHINE ;; arm* | sa110*) UNAME_MACHINE="arm" ;; esac # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. ld_help_string=`cd /; ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g s/.*supported emulations: *// s/ .*// p'` case "$ld_supported_emulations" in *ia64) echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 ;; i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; elf32ppc | elf32ppclinux) # Determine Lib Version cat >$dummy.c < #if defined(__GLIBC__) extern char __libc_version[]; extern char __libc_release[]; #endif main(argc, argv) int argc; char *argv[]; { #if defined(__GLIBC__) printf("%s %s\n", __libc_version, __libc_release); #else printf("unkown\n"); #endif return 0; } EOF LIBC="" $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null if test "$?" = 0 ; then ./$dummy | grep 1\.99 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.c $dummy echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;; esac if test "${UNAME_MACHINE}" = "alpha" ; then sed 's/^ //' <$dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF LIBC="" $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then ./$dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac objdump --private-headers $dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. # If ld does not provide *any* "supported emulations:" # that means it is gnuoldld. echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 case "${UNAME_MACHINE}" in i?86) VENDOR=pc; ;; *) VENDOR=unknown; ;; esac # Determine whether the default compiler is a.out or elf cat >$dummy.c < #ifdef __cplusplus int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:5:7*) UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585 echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE} exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:*:6*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | ~MAKE-3_78_1HB.BCK``[MAKE-3_78_1HB]CONFIG.GUESS;1@E_7R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 *[MAKE-3_78_1HB]CONFIG.H-VMS;26+,m%./@ 4P?-`0123KPWO56Gm7m89G@HJ/* config.h-vms. Generated by hand by Klaus Kmpf */ /* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE /* #undef _ALL_SOURCE */ #endif /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* maybe this should be placed into make.h */ #if defined(__VAX) && defined(__DECC) #define alloca(n) __ALLOCA(n) #endif /* Define if the closedir function returns void instead of int. */ /* #undef CLOSEDIR_VOID */ /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define for DGUX with . */ /* #undef DGUX */ /* Define if the `getloadavg' function needs to be run setuid or setgid. */ /* #undef GETLOADAVG_PRIVILEGED */ /* Define to `int' if doesn't define. */ /* #undef gid_t */ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define if you don't have vprintf but do have _doprnt. */ /* #undef HAVE_DOPRNT */ /* Define if your system has a working fnmatch function. */ /* #undef HAVE_FNMATCH */ /* Define if your system has its own `getloadavg' function. */ /* #undef HAVE_GETLOADAVG */ /* Define if you have the getmntent function. */ /* #undef HAVE_GETMNTENT */ /* Define if the `long double' type works. */ /* #undef HAVE_LONG_DOUBLE */ /* Define if you support file names longer than 14 characters. */ #define HAVE_LONG_FILE_NAMES 1 /* Define if you have a working `mmap' system call. */ /* #undef HAVE_MMAP */ /* Define if system calls automatically restart after interruption by a signal. */ /* #undef HAVE_RESTARTABLE_SYSCALLS */ /* Define if your struct stat has st_blksize. */ /* #undef HAVE_ST_BLKSIZE */ /* Define if your struct stat has st_blocks. */ /* #undef HAVE_ST_BLOCKS */ /* Define if you have the strcoll function and it is properly defined. */ /* #undef HAVE_STRCOLL */ /* Define if your struct stat has st_rdev. */ /* #undef HAVE_ST_RDEV */ /* Define if you have the strftime function. */ /* #undef HAVE_STRFTIME */ /* Define if you have that is POSIX.1 compatible. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if your struct tm has tm_zone. */ /* #undef HAVE_TM_ZONE */ /* Define if you don't have tm_zone but do have the external array tzname. */ /* #undef HAVE_TZNAME */ /* Define if you have . */ #ifdef __DECC #define HAVE_UNISTD_H 1 #endif /* Define if utime(file, NULL) sets file's timestamp to the present. */ /* #undef HAVE_UTIME_NULL */ /* Define if you have . */ /* #undef HAVE_VFORK_H */ /* Define if you have the vprintf function. */ #define HAVE_VPRINTF 1 /* Define if you have the wait3 system call. */ /* #undef HAVE_WAIT3 */ /* Define if on MINIX. */ /* #undef _MINIX */ /* Define if your struct nlist has an n_un member. */ /* #undef NLIST_NAME_UNION */ /* Define if you have . */ /* #undef NLIST_STRUCT */ /* Define if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* Define to `int' if doesn't define. */ /* I assume types.h is available for all 5.0 cc/cxx compilers */ #if __DECC_VER < 50090000 #define pid_t int #endif /* Define if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define if you need to in order for stat and other things to work. */ /* #undef _POSIX_SOURCE */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define if the setvbuf function takes the buffering type as its second argument and the buffer pointer as the third, as on System V bef ore release 3. */ /* #undef SETVBUF_REVERSED */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if the `S_IS*' macros in do not work properly. */ /* #undef STAT_MACROS_BROKEN */ /* Define if you have the ANSI C header files. */ /* #undef STDC_HEADERS */ /* Define on System V Release 4. */ /* #undef SVR4 */ /* Define if `sys_siglist' is declared by . */ /* #undef SYS_SIGLIST_DECLARED */ /* Define to `int' if doesn't define. */ #if __DECC_VER < 50090000 #define uid_t int #endif /* Define for Encore UMAX. */ /* #undef UMAX */ /* Define for Encore UMAX 4.3 that has instead of . */ /* #undef UMAX4_3 */ /* Define vfork as fork if vfork does not work. */ /* #undef vfork */ /* Name of this package (needed by automake) */ #define PACKAGE "make" /* Version of this package (needed by automake) */ #define VERSION "3.78.1hb" /* Define to the name of the SCCS `get' command. */ /* #undef SCCS_GET */ /* Define this if the SCCS `get' command understands the `-G' option. */ /* #undef SCCS_GET_MINUS_G */ /* Define this to enable job server support in GNU make. */ /* #undef MAKE_JOBSERVER */ /* Define to be the nanoseconds member of struct stat's st_mtim, if it exists. */ /* #undef ST_MTIM_NSEC */ /* Define this if the C library defines the variable `sys_siglist'. */ /* #undefine HAVE_SYS_SIGLIST */ /* Define this if the C library defines the variable `_sys_siglist'. */ /* #undef HAVE__SYS_SIGLIST */ /* Define this if you have the `union wait' type in . */ /* #undef HAVE_UNION_WAIT */ /* Define if you have the dup2 function. */ #define HAVE_DUP2 1 /* Define if you have the getc wd function. */ #define HAVE_GETCWD 1 /* Define if you have the getgroups function. */ /* #undef HAVE_GETGROUPS */ /* Define if you have the gethostbyname function. */ /* #undef HAVE_GETHOSTBYNAME */ /* Define if you have the gethostname function. */ /* #undef HAVE_GETHOSTNAME */ /* Define if you have the getloadavg function. */ /* #undef HAVE_GETLOADAVG */ /* Define if you have the memmove function. */ #define HAVE_MEMMOVE 1 /* Define if you have the mktemp function. */ #define HAVE_MKTEMP 1 /* Define if you have the psignal function. */ /* #undef HAVE_PSIGNAL */ /* Define if you have the pstat_getdynamic function. */ /* #undef HAVE_PSTAT_GETDYNAMIC */ /* Define if you have the setegid function. */ /* #undef HAVE_SETEGID */ /* Define if you have the seteuid function. */ /* #undef HAVE_SETEUID */ /* Define if you have the setlinebuf function. */ /* #undef HAVE_SETLINEBUF */ /* Define if you have the setregid function. */ /* #undefine HAVE_SETREGID */ /* Define if you have the setreuid function. */ /* #define HAVE_SETREUID */ /* Define if you have the sigsetmask function. */ #define HAVE_SIGSETMASK 1 /* Define if you have the socket function. */ /* #undef HAVE_SOCKET */ /* Define if you have the strcasecmp function. */ /* #undef HAVE_STRCASECMP */ /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the strsignal function. */ /* #undef HAVE_STRSIGNAL */ /* Define if you have the wait3 function. */ /* #undef HAVE_WAIT3 */ /* Define if you have the waitpid function. */ /* #undef HAVE_WAITPID */ /* Define if you have the header file. */ #define HAVE_DIRENT_H 1 /* Define if you have the header file. */ #ifdef __DECC #define HAVE_FCNTL_H 1 #endif /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ /* #undef HAVE_MACH_MACH_H */ /* Define if you have the header file. */ /* #undef HAVE_MEMORY_H */ /* Define if you have the header file. */ /* #undef HAVE_NDIR_H */ /* Define if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define if you have the header file. */ #define HAVE_STRING_H 1 /* Define if you have the header file. */ /* #undef HAVE_SYS_DIR_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_NDIR_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define if you have the header file. */ #ifndef __GNUC__ #define HAVE_SYS_TIMEB_H 1 #endif /* Define if you have the header file. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if you have the dgc library (-ldgc). */ /* #undef HAVE_LIBDGC */ /* Define if you have the kstat library (-lkstat). */ /* #undef HAVE_LIBKSTAT * /* Define if you have the sun library (-lsun). */ /* #undef HAVE_LIBSUN */ /* Define for case insensitve filenames */ #define HAVE_CASE_INSENSITIVE_FS 1 /* VMS specific, define it if you want to use case sensitve targets */ /* #undef WANT_CASE_SENSITIVE_TARGETS */ /* VMS specific, V7.0 has opendir() and friends, so it's undefined */ /* If you want to use non-VMS code for opendir() etc. on V7.0 and greater */ /* define the first or both macros AND change the compile command to get the */ /* non-VMS versions linked: (prefix=(all,except=(opendir,... */ /* #undef HAVE_VMSDIR_H */ /* #undef _DIRENT_HAVE_D_NAMLEN */ /* On older systems without 7.0 backport of the CRTL the first one is defined */ #ifdef __CRTL_VER # if __CRTL_VER < 70000000 # define HAVE_VMSDIR_H 1 # endif #else # if __VMS_VER < 70000000 # define HAVE_VMSDIR_H 1 # endif #endif #if defined(HAVE_VMSDIR_H) && defined(HAVE_DIRENT_H) #undef HAVE_DIRENT_H #endif #define HAVE_STDLIB_H 1 #define INCLUDEDIR "sys$sysroot:[syslib]" #define LIBDIR "sys$sysroot:[syslib]" /* Don't use RTL functions of OpenVMS */ #ifdef __DECC #include #include #define getopt gnu_getopt #define optarg gnu_optarg #define optopt gnu_optopt #define optind gnu_optind #define opterr gnu_opterr #endif #if defined (__cplusplus) || (defined (__STDC__) && __STDC__) #undef PARAMS #define PARAMS(protos) protos #else /* Not C++ or ANSI C. */ #undef PARAMS #define PARAMS(protos) () #endif /* C++ or ANSI C. */ /* Build host information. */ #define MAKE_HOST "VMS" *[MAKE-3_78_1HB]CONFIG.SUB;1+,`.0/@ 400-`0123KPWO156R7V9m89G@HJ@#! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. if [ x$1 = x ] then echo Configuration name missing. 1>&2 echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 echo "or $0 ALIAS" 1>&2 echo where ALIAS is a recognized configuration type. 1>&2 exit 1 fi # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ | 580 | i960 | h8300 \ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ | mips64orion | mips64orionel | mipstx39 | mipstx39el \ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ | mips64vr5000 | miprs64vr5000el | mcore \ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ | thumb | d10v) basic_machine=$basic_machine-unknown ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i[34567]86) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. # FIXME: clean up the formatting here. vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ | xmp-* | ymp-* \ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ | clipper-* | orion-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ | mipstx39-* | mipstx39el-* | mcore-* \ | f301-* | armv*-* | t3e-* \ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ | thumb-* | v850-* | d30v-* | tic30-* | c30-* ) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigaos | amigados) basic_machine=m68k-cbm os=-amigaos ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; i386-go32 | go32) basic_machine=i386-unknown os=-go32 ;; i386-mingw32 | mingw32) basic_machine=i386-unknown os=-mingw32 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu ;; mips*-linux*) basic_machine=mips-unknown os=-linux-gnu ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; msdos) basic_machine=i386-unknown os=-msdos ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-corel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; np1) basic_machine=np1-gould ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexen) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=t3e-cray os=-unicos ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIG.SUB;10L !machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown else basic_machine=mips-mips fi ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc | sparcv9) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; c4x*) basic_machine=c4x-none os=-coff ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) # Remember, each alternative MUST END IN *, to match a version number. ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -*MiNT) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-corel) os=-linux ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -*MiNT) vendor=atari ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os *[MAKE-3_78_1HB]CONFIGH.DOS;1+,`./@ 4-`0123KPWO56r=7Km89G@HJ /* Many things are defined already by a system header. */ #include /* Name of this package (needed by automake) */ #define PACKAGE "make" /* Version of this package (needed by automake) */ #define VERSION "3.78.1" #if __DJGPP__ > 2 || __DJGPP_MINOR__ > 1 /* Define if `sys_siglist' is declared by . */ # define SYS_SIGLIST_DECLARED 1 /* Define this if the C library defines the variable `_sys_siglist'. */ # define HAVE_SYS_SIGLIST 1 #else /* Define NSIG. */ # define NSIG SIGMAX #endif /* Define if you have sigsetmask. */ #define HAVE_SIGSETMASK 1 /* Define if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define if you have the memmove function. */ #define HAVE_MEMMOVE 1 #define SCCS_GET "get" /* Define to `unsigned long' or `unsigned long long' if doesn't define. */ #define uintmax_t unsigned long long /* Define the type of the first arg to select(). */ #define fd_set_size_t int /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the vprintf library function. */ #undef HAVE_VPRINTF #define HAVE_VPRINTF 1 /* Build host information. */ #define MAKE_HOST "i386-pc-msdosdjgpp" n*[MAKE-3_78_1HB]CONFIGURE.;1+,`.D/@ 4DD-`0123KPWOE56=p7~]m89G@HJT#! /bin/sh # From configure.in Id: configure.in,v 1.83 1999/09/17 03:15:46 psmith Exp # The following is taken from automake 1.4, # except that it prefers the compiler option -Ae to "-Aa -D_HPUX_SOURCE" # because only the former supports 64-bit integral types on HP-UX 10.20. # serial 2 # @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. # serial 1 # # Check to make sure that the build environment is sane. # # Like AC_CONFIG_HEADER, but automatically create stamp file. # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --disable-largefile omit support for large files" ac_help="$ac_help --with-customs=DIR Enable remote jobs via Customs--see README.customs" ac_help="$ac_help --disable-job-server Disallow recursive make communication during -jN" ac_help="$ac_help --enable-dmalloc Enable support for the dmalloc debugging library" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=vpath.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, whi~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIGURE.;1Dji|+ch mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:645: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 echo "configure:698: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "$*" != "X $srcdir/configure conftestfile" \ && test "$*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { echo "configure: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" 1>&2; exit 1; } fi test "$2" = conftestfile ) then # Ok. : else { echo "configure: error: newly created file is older than distributed files! Check your system clock" 1>&2; exit 1; } fi rm -f conftest* echo "$ac_t""yes" 1>&6 if test "$program_transform_name" = s,x,x,; then program_transform_name= else # Double any \ or $. echo might interpret backslashes. cat <<\EOF_SED > conftestsed s,\\,\\\\,g; s,\$,$$,g EOF_SED program_transform_name="`echo $program_transform_name|sed -f conftestsed`" rm -f conftestsed fi test "$program_prefix" != NONE && program_transform_name="s,^,${program_prefix},; $program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" # sed with no file args requires a program. test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:755: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi PACKAGE=make VERSION=3.78.1 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } fi cat >> confdefs.h <> confdefs.h <&6 echo "configure:801: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (aclocal --version) < /dev/null > /dev/null 2>&1; then ACLOCAL=aclocal echo "$ac_t""found" 1>&6 else ACLOCAL="$missing_dir/missing aclocal" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 echo "configure:814: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoconf --version) < /dev/null > /dev/null 2>&1; then AUTOCONF=autoconf echo "$ac_t""found" 1>&6 else AUTOCONF="$missing_dir/missing autoconf" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 echo "configure:827: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (automake --version) < /dev/null > /dev/null 2>&1; then AUTOMAKE=automake echo "$ac_t""found" 1>&6 else AUTOMAKE="$missing_dir/missing automake" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 echo "configure:840: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoheader --version) < /dev/null > /dev/null 2>&1; then AUTOHEADER=autoheader echo "$ac_t""found" 1>&6 else AUTOHEADER="$missing_dir/missing autoheader" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 echo "configure:853: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (makeinfo --version) < /dev/null > /dev/null 2>&1; then MAKEINFO=makeinfo echo "$ac_t""found" 1>&6 else MAKEINFO="$missing_dir/missing makeinfo" echo "$ac_t""missing" 1>&6 fi # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:878: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:899: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:928: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:958: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1009: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:1041: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 1052 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:1057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:1083: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:1088: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:1116: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1159: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1214: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_AR="ar" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" fi fi AR="$ac_cv_prog_AR" if test -n "$AR"; then echo "$ac_t""$AR" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1244: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1272: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1293: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1310: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1327: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for AIX""... $ac_c" 1>&6 echo "configure:1351: checking for AIX" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF #define _ALL_SOURCE 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 echo "configure:1375: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then echo "$ac_t""yes" 1>&6 ISC=yes # If later tests want to check for ISC. cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF if test "$GCC" = yes; then CC="$CC -posix" else CC="$CC -Xp" fi else echo "$ac_t""no" 1>&6 ISC= fi ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6 echo "configure:1397: checking for minix/config.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1407: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 MINIX=yes else echo "$ac_t""no" 1>&6 MINIX= fi if test "$MINIX" = yes; then cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF cat >> confdefs.h <<\EOF #define _POSIX_1_SOURCE 2 EOF cat >> confdefs.h <<\EOF #define _MINIX 1 EOF fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1448: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_PERL="perl" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_PERL" && ac_cv_prog_PERL="perl" fi fi PERL="$ac_cv_prog_PERL" if test -n "$PERL"; then echo "$ac_t""$PERL" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking build system type""... $ac_c" 1>&6 echo "configure:1477: checking build system type" >&5 build_alias=$build case "$build_alias" in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 if test $host != $build; then ac_tool_prefix=${host_alias}- else ac_tool_prefix= fi # Check whether --enable-largefile or --disable-largefile was given. if test "${enable_largefile+set}" = set; then enableval="$enable_largefile" : fi if test "$enable_largefile" != no; then # Extract the first word of "${ac_tool_prefix}getconf", so it can be a program name with args. set dummy ${ac_tool_prefix}getconf; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1511: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GETCONF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$GETCONF"; then ac_cv_prog_GETCONF="$GETCONF" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_GETCONF="${ac_tool_prefix}getconf" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_GETCONF" && ac_cv_prog_GETCONF="getconf" fi fi GETCONF="$ac_cv_prog_GETCONF" if test -n "$GETCONF"; then echo "$ac_t""$GETCONF" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for CFLAGS value to request large file support""... $ac_c" 1>&6 echo "configure:1541: checking for CFLAGS value to request large file support" >&5 if eval "test \"`echo '$''{'ac_cv_sys_largefile_CFLAGS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_largefile_CFLAGS=`($GETCONF LFS_CFLAGS) 2>/dev/null` || { ac_cv_sys_largefile_CFLAGS=no case "$host_os" in # HP-UX 10.20 requires -D__STDC_EXT__ with gcc 2.95.1. hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) if test "$GCC" = yes; then ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__ fi ;; # IRIX 6.2 and later require cc -n32. irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) if test "$GCC" != yes; then ac_cv_sys_largefile_CFLAGS=-n32 fi esac if test "$ac_cv_sys_largefile_CFLAGS" != no; then ac_save_CC="$CC" CC="$CC $ac_cv_sys_largefile_CFLAGS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_sys_largefile_CFLAGS=no fi rm -f conftest* CC="$ac_save_CC" fi } fi echo "$ac_t""$ac_cv_sys_largefile_CFLAGS" 1>&6 echo $ac_n "checking for LDFLAGS value to request large file support""... $ac_c" 1>&6 echo "configure:1587: checking for LDFLAGS value to request large file support" >&5 if eval "test \"`echo '$''{'ac_cv_sys_largefile_LDFLAGS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_largefile_LDFLAGS=`($GETCONF LFS_LDFLAGS) 2>/dev/null` || { ac_cv_sys_largefile_LDFLAGS=no } fi echo "$ac_t""$ac_cv_sys_largefile_LDFLAGS" 1>&6 echo $ac_n "checking for LIBS value to request large file support""... $ac_c" 1>&6 echo "configure:1599: checking for LIBS value to request large file support" >&5 if eval "test \"`echo '$''{'ac_cv_sys_largefile_LIBS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_largefile_LIBS=`($GETCONF LFS_LIBS) 2>/dev/null` || { ac_cv_sys_largefile_LIBS=no } fi echo "$ac_t""$ac_cv_sys_largefile_LIBS" 1>&6 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in no) ;; -D_FILE_OFFSET_BITS=*) ;; -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; -D_LARGE_FILES | -D_LARGE_FILES=*) ;; -D?* | -I?*) case "$ac_flag" in no) ;; ?*) case "$CPPFLAGS" in '') CPPFLAGS="$ac_flag" ;; *) CPPFLAGS=$CPPFLAGS' '"$ac_flag" ;; esac ;; esac ;; *) case "$ac_flag" in no) ;; ?*) case "$CFLAGS" in '') CFLAGS="$ac_flag" ;; *) CFLAGS=$CFLAGS' '"$ac_flag" ;; esac ;; esac ;; esac done case "$ac_cv_sys_largefile_LDFLAGS" in no) ;; ?*) case "$LDFLAGS" in '') LDFLAGS="$ac_cv_sys_largefile_LDFLAGS" ;; *) LDFLAGS=$LDFLAGS' '"$ac_cv_sys_largefile_LDFLAGS" ;; esac ;; esac case "$ac_cv_sys_largefile_LIBS" in no) ;; ?*) case "$LIBS" in '') LIBS="$ac_cv_sys_largefile_LIBS" ;; *) LIBS=$LIBS' '"$ac_cv_sys_largefile_LIBS" ;; esac ;; esac echo $ac_n "checking for _FILE_OFFSET_BITS""... $ac_c" 1>&6 echo "configure:1654: checking for _FILE_OFFSET_BITS" >&5 if eval "test \"`echo '$''{'ac_cv_sys_file_offset_bits'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_file_offset_bits=no case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_file_offset_bits=64 ;; esac for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_FILE_OFFSET_BITS) ac_cv_sys_file_offset_bits=1 ;; -D_FILE_OFFSET_BITS=*) ac_cv_sys_file_offset_bits=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi echo "$ac_t""$ac_cv_sys_file_offset_bits" 1>&6 if test "$ac_cv_sys_file_offset_bits" != no; then cat >> confdefs.h <&6 echo "configure:1683: checking for _LARGEFILE_SOURCE" >&5 if eval "test \"`echo '$''{'ac_cv_sys_largefile_source'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_largefile_source=no case "$host_os" in # HP-UX 10.20 and later hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) ac_cv_sys_largefile_source=1 ;; esac for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_LARGEFILE_SOURCE) ac_cv_sys_largefile_source=1 ;; -D_LARGEFILE_SOURCE=*) ac_cv_sys_largefile_source=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi echo "$ac_t""$ac_cv_sys_largefile_source" 1>&6 if test "$ac_cv_sys_largefile_source" != no; then cat >> confdefs.h <&6 echo "configure:1712: checking for _LARGE_FILES" >&5 if eval "test \"`echo '$''{'ac_cv_sys_large_file~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIGURE.;1D|is'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_large_files=no case "$host_os" in # AIX 4.2 and later aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*) ac_cv_sys_large_files=1 ;; esac for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_LARGE_FILES) ac_cv_sys_large_files=1 ;; -D_LARGE_FILES=*) ac_cv_sys_large_files=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi echo "$ac_t""$ac_cv_sys_large_files" 1>&6 if test "$ac_cv_sys_large_files" != no; then cat >> confdefs.h <&6 echo "configure:1744: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1757: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 echo "configure:1852: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> int main() { DIR *dirp = 0; ; return 0; } EOF if { (eval echo configure:1865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 echo "configure:1890: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -ldir" else echo "$ac_t""no" 1>&6 fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 echo "configure:1931: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lx" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 echo "configure:1973: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uid_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uid_t=yes else rm -rf conftest* ac_cv_type_uid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uid_t" 1>&6 if test $ac_cv_type_uid_t = no; then cat >> confdefs.h <<\EOF #define uid_t int EOF cat >> confdefs.h <<\EOF #define gid_t int EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo "configure:2006: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else rm -rf conftest* ac_cv_type_pid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_pid_t" 1>&6 if test $ac_cv_type_pid_t = no; then cat >> confdefs.h <<\EOF #define pid_t int EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:2039: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:2061: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:2084: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test "x$CC" != xcc; then echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6 echo "configure:2122: checking whether $CC and cc understand -c and -o together" >&5 else echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6 echo "configure:2125: checking whether cc understands -c and -o together" >&5 fi set dummy $CC; ac_cc="`echo $2 | sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`" if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'foo(){}' > conftest.c # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5' if { (eval echo configure:2137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && test -f conftest.o && { (eval echo configure:2138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:2143: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then ac_try='cc -c conftest.c -o conftest.o 1>&5' if { (eval echo configure:2145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } && test -f conftest.o && { (eval echo configure:2146: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define NO_MINUS_C_MINUS_O 1 EOF fi echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6 echo "configure:2176: checking for ${CC-cc} option to accept ANSI C" >&5 if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" cat > conftest.$ac_ext < #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main() { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } EOF if { (eval echo configure:2229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* am_cv_prog_cc_stdc="$ac_arg"; break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done CC="$ac_save_CC" fi if test -z "$am_cv_prog_cc_stdc"; then echo "$ac_t""none needed" 1>&6 else echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6 fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:2253: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:2307: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 echo "configure:2327: checking whether stat file-mode macros are broken" >&5 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #if defined(S_ISBLK) && defined(S_IFDIR) # if S_ISBLK (S_IFDIR) You lose. # endif #endif #if defined(S_ISBLK) && defined(S_IFCHR) # if S_ISBLK (S_IFCHR) You lose. # endif #endif #if defined(S_ISLNK) && defined(S_IFREG) # if S_ISLNK (S_IFREG) You lose. # endif #endif #if defined(S_ISSOCK) && defined(S_IFREG) # if S_ISSOCK (S_IFREG) You lose. # endif #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "You lose" >/dev/null 2>&1; then rm -rf conftest* ac_cv_header_stat_broken=yes else rm -rf conftest* ac_cv_header_stat_broken=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_stat_broken" 1>&6 if test $ac_cv_header_stat_broken = yes; then cat >> confdefs.h <<\EOF #define STAT_MACROS_BROKEN 1 EOF fi echo $ac_n "checking for nanoseconds member of struct stat.st_mtim""... $ac_c" 1>&6 echo "configure:2384: checking for nanoseconds member of struct stat.st_mtim" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_mtim_nsec'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_CPPFLAGS="$CPPFLAGS" ac_cv_struct_st_mtim_nsec=no # tv_nsec -- the usual case # _tv_nsec -- Solaris 2.6, if # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 # && !defined __EXTENSIONS__) # st__tim.tv_nsec -- UnixWare 2.1.2 for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" cat > conftest.$ac_ext < #include int main() { struct stat s; s.st_mtim.ST_MTIM_NSEC; ; return 0; } EOF if { (eval echo configure:2406: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_mtim_nsec=$ac_val; break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done CPPFLAGS="$ac_save_CPPFLAGS" fi echo "$ac_t""$ac_cv_struct_st_mtim_nsec" 1>&6 if test $ac_cv_struct_st_mtim_nsec != no; then cat >> confdefs.h <&6 echo "configure:2433: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6 echo "configure:2487: checking for inttypes.h" >&5 if eval "test \"`echo '$''{'jm_ac_cv_header_inttypes_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include int main() { uintmax_t i = (uintmax_t) -1; ; return 0; } EOF if { (eval echo configure:2500: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* jm_ac_cv_header_inttypes_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* jm_ac_cv_header_inttypes_h=no fi rm -f conftest* fi echo "$ac_t""$jm_ac_cv_header_inttypes_h" 1>&6 if test $jm_ac_cv_header_inttypes_h = yes; then ac_kludge=HAVE_INTTYPES_H cat >> confdefs.h <&6 echo "configure:2525: checking for unsigned long long" >&5 if eval "test \"`echo '$''{'ac_cv_type_unsigned_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <> i | ullmax / ull | ullmax % ull; ; return 0; } EOF if { (eval echo configure:2538: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_type_unsigned_long_long=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_unsigned_long_long=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_unsigned_long_long" 1>&6 if test $ac_cv_type_unsigned_long_long = yes; then cat >> confdefs.h <<\EOF #define uintmax_t unsigned long long EOF else cat >> confdefs.h <<\EOF #define uintmax_t unsigned long EOF fi fi # clock_gettime is in -lposix4 in Solaris 2.6. echo $ac_n "checking for clock_gettime in -lposix4""... $ac_c" 1>&6 echo "configure:2570: checking for clock_gettime in -lposix4" >&5 ac_lib_var=`echo posix4'_'clock_gettime | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lposix4 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo posix4 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi for ac_func in memmove strdup psignal mktemp pstat_getdynamic \ clock_gettime dup2 getcwd sigsetmask sigaction getgroups \ setlinebuf seteuid setegid setreuid setregid pipe \ strerror strsignal do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2623: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for sys_siglist""... $ac_c" 1>&6 echo "configure:2676: checking for sys_siglist" >&5 if eval "test \"`echo '$''{'ac_cv_check_symbol_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_check_symbol_sys_siglist=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_check_symbol_sys_siglist=no fi rm -f conftest* fi if test "$ac_cv_check_symbol_sys_siglist" = yes; then ac_tr_symbol=`echo sys_siglist | tr '[a-z]' '[A-Z]'` cat >> confdefs.h <&6 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo "configure:2711: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:2723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_alloca_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 if test $ac_cv_header_alloca_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA_H 1 EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo "configure:2744: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main() { char *p = (char *) alloca(1); ; return 0; } EOF if { (eval echo configure:2777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_alloca_works=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 if test $ac_cv_func_alloca_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA 1 EOF fi if test $ac_cv_func_alloca_works = no; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.${ac_objext} cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo "configure:2809: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "webecray" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_cray=yes else rm -rf conftest* ac_cv_os_cray=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_os_cray" 1>&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2839: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo "configure:2894: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF if { (eval echo configure:2921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && ~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIGURE.;1DS|(./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_stack_direction=-1 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 cat >> confdefs.h <&6 echo "configure:2944: checking for vfork.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2954: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VFORK_H 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for working vfork""... $ac_c" 1>&6 echo "configure:2979: checking for working vfork" >&5 if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then echo $ac_n "checking for vfork""... $ac_c" 1>&6 echo "configure:2985: checking for vfork" >&5 if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vfork(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vfork) || defined (__stub___vfork) choke me #else vfork(); #endif ; return 0; } EOF if { (eval echo configure:3013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vfork=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vfork=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 fi ac_cv_func_vfork_works=$ac_cv_func_vfork else cat > conftest.$ac_ext < #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_VFORK_H #include #endif /* On some sparc systems, changes by the child to local and incoming argument registers are propagated back to the parent. The compiler is told about this with #include , but some compilers (e.g. gcc -O) don't grok . Test for this by using a static variable whose address is put into a register that is clobbered by the vfork. */ static #ifdef __cplusplus sparc_address_test (int arg) #else sparc_address_test (arg) int arg; #endif { static pid_t child; if (!child) { child = vfork (); if (child < 0) { perror ("vfork"); _exit(2); } if (!child) { arg = getpid(); write(-1, "", 0); _exit (arg); } } } main() { pid_t parent = getpid (); pid_t child; sparc_address_test (); child = vfork (); if (child == 0) { /* Here is another test for sparc vfork register problems. This test uses lots of local variables, at least as many local variables as main has allocated so far including compiler temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should reuse the register of parent for one of the local variables, since it will think that parent can't possibly be used any more in this routine. Assigning to the local variable will thus munge parent in the parent process. */ pid_t p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); /* Convince the compiler that p..p7 are live; otherwise, it might use the same hardware register for all 8 local variables. */ if (p != p1 || p != p2 || p != p3 || p != p4 || p != p5 || p != p6 || p != p7) _exit(1); /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent from child file descriptors. If the child closes a descriptor before it execs or exits, this munges the parent's descriptor as well. Test for this by closing stdout in the child. */ _exit(close(fileno(stdout)) != 0); } else { int status; struct stat st; while (wait(&status) != child) ; exit( /* Was there some problem with vforking? */ child < 0 /* Did the child fail? (This shouldn't happen.) */ || status /* Did the vfork/compiler bug occur? */ || parent != getpid() /* Did the file descriptor bug occur? */ || fstat(fileno(stdout), &st) != 0 ); } } EOF if { (eval echo configure:3130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_vfork_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_vfork_works=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_vfork_works" 1>&6 if test $ac_cv_func_vfork_works = no; then cat >> confdefs.h <<\EOF #define vfork fork EOF fi echo $ac_n "checking for vprintf""... $ac_c" 1>&6 echo "configure:3153: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vprintf) || defined (__stub___vprintf) choke me #else vprintf(); #endif ; return 0; } EOF if { (eval echo configure:3181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo "configure:3205: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char _doprnt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__doprnt) || defined (__stub____doprnt) choke me #else _doprnt(); #endif ; return 0; } EOF if { (eval echo configure:3233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func__doprnt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DOPRNT 1 EOF else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for working strcoll""... $ac_c" 1>&6 echo "configure:3258: checking for working strcoll" >&5 if eval "test \"`echo '$''{'ac_cv_func_strcoll_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_strcoll_works=no else cat > conftest.$ac_ext < main () { exit (strcoll ("abc", "def") >= 0 || strcoll ("ABC", "DEF") >= 0 || strcoll ("123", "456") >= 0); } EOF if { (eval echo configure:3276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_strcoll_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_strcoll_works=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_strcoll_works" 1>&6 if test $ac_cv_func_strcoll_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_STRCOLL 1 EOF fi echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6 echo "configure:3299: checking whether closedir returns void" >&5 if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_closedir_void=yes else cat > conftest.$ac_ext < #include <$ac_header_dirent> int closedir(); main() { exit(closedir(opendir(".")) != 0); } EOF if { (eval echo configure:3313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_closedir_void=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_closedir_void=yes fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_closedir_void" 1>&6 if test $ac_cv_func_closedir_void = yes; then cat >> confdefs.h <<\EOF #define CLOSEDIR_VOID 1 EOF fi echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6 echo "configure:3336: checking whether setvbuf arguments are reversed" >&5 if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < /* If setvbuf has the reversed format, exit 0. */ main () { /* This call has the arguments reversed. A reversed system may check and see that the address of main is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0) exit(1); putc('\r', stdout); exit(0); /* Non-reversed systems segv here. */ } EOF if { (eval echo configure:3358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_setvbuf_reversed=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_setvbuf_reversed=no fi rm -fr conftest* fi rm -f core core.* *.core fi echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6 if test $ac_cv_func_setvbuf_reversed = yes; then cat >> confdefs.h <<\EOF #define SETVBUF_REVERSED 1 EOF fi for ac_func in select do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:3384: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:3412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done if test "$ac_cv_func_select" = yes; then for ac_hdr in unistd.h sys/types.h sys/time.h sys/select.h sys/socket.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:3441: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3451: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking argument types of select()""... $ac_c" 1>&6 echo "configure:3478: checking argument types of select()" >&5 if eval "test \"`echo '$''{'ac_cv_type_fd_set_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if eval "test \"`echo '$''{'ac_cv_type_fd_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else for ac_cv_type_fd_set in 'fd_set' 'int' 'void'; do for ac_cv_type_fd_set_size_t in 'int' 'size_t' 'unsigned long' 'unsigned'; do for ac_type_timeval in 'struct timeval' 'const struct timeval'; do cat > conftest.$ac_ext < #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif int main() { #ifdef __STDC__ extern select ($ac_cv_type_fd_set_size_t, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_type_timeval *); #else extern select (); $ac_cv_type_fd_set_size_t s; $ac_cv_type_fd_set *p; $ac_type_timeval *t; #endif ; return 0; } EOF if { (eval echo configure:3519: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_found=yes ; break 3 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_found=no fi rm -f conftest* done done done fi fi if test "$ac_found" = no; then { echo "configure: error: can't determine argument types" 1>&2; exit 1; } fi echo "$ac_t""select($ac_cv_type_fd_set_size_t,$ac_cv_type_fd_set *,...)" 1>&6 cat >> confdefs.h < conftest.$ac_ext < #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])fd_set[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* # We found fd_set type in a header, need special cast ac_cast="($ac_cv_type_fd_set *)" else rm -rf conftest* # No fd_set type; it is safe to define it cat >> confdefs.h <> confdefs.h <&6 echo "configure:3593: checking for kstat_open in -lkstat" >&5 ac_lib_var=`echo kstat'_'kstat_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lkstat $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo kstat | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi ac_have_func=no # yes means we've found a way to get the load average. # Some systems with -lutil have (and need) -lkvm as well, some do not. # On Solaris, -lkvm requires nlist from -lelf, so check that first # to get the right answer into the cache. echo $ac_n "checking for elf_begin in -lelf""... $ac_c" 1>&6 echo "configure:3644: checking for elf_begin in -lelf" >&5 ac_lib_var=`echo elf'_'elf_begin | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lelf $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lelf $LIBS" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for kvm_open in -lkvm""... $ac_c" 1>&6 echo "configure:3684: checking for kvm_open in -lkvm" >&5 ac_lib_var=`echo kvm'_'kvm_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lkvm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lkvm $LIBS" else echo "$ac_t""no" 1>&6 fi # Check for the 4.4BSD definition of getloadavg. echo $ac_n "checking for getloadavg in -lutil""... $ac_c" 1>&6 echo "configure:3725: checking for getloadavg in -lutil" >&5 ac_lib_var=`echo util'_'getloadavg | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lutil $LIBS" ac_have_func=yes ac_cv_func_getloadavg_setgid=yes else echo "$ac_t""no" 1>&6 fi if test $ac_have_func = no; then # There is a commonly available library for RS/6000 AIX. # Since it is not a standard part of AIX, it might be installed locally. ac_getloadavg_LIBS="$LIBS"; LIBS="-L/usr/local/lib $LIBS" echo $ac_n "checking for getloadavg in -lgetloadavg""... $ac_c" 1>&6 echo "configure:3770: checking for getloadavg in -lgetloadavg" >&5 ac_lib_var=`echo getloadavg'_'getloadavg | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lgetloadavg $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lgetloadavg $LIBS" else echo "$ac_t""no" 1>&6 LIBS="$ac_getloadavg_LIBS" fi fi # Make sure it is really in the library, if we think we found it. for ac_func in getloadavg do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:3816: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:3844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" fi done if test $ac_cv_func_getloadavg = yes; then cat >> confdefs.h <<\EOF #define HAVE_GETLOADAVG 1 EOF ac_have_func=yes else # Figure out what our getloadavg.c needs. ac_have_func=no ac_safe=`echo "sys/dg_sys_info.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/dg_sys_info.h""... $ac_c" 1>&6 echo "configure:3882: checking for sys/dg_sys_info.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3892: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_have_func=yes; cat >> confdefs.h <<\EOF #define DGUX 1 EOF echo $ac_n "checking for dg_sys_info in -ldgc""... $ac_c" 1>&6 echo "configure:3913: checking for dg_sys_info in -ldgc" >&5 ac_lib_var=`echo dgc'_'dg_sys_info | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldgc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo dgc | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi else echo "$ac_t""no" 1>&6 fi # We cannot check for , because Solaris 2 does not use dwarf (it # uses stabs), but it is still SVR4. We cannot check for because # Irix 4.0.5F has the header but not the library. if test $ac_have_func = no && test $ac_cv_lib_elf_elf_begin = yes; then ac_have_func=yes; cat >> confdefs.h <<\EOF #define SVR4 1 EOF fi if test $ac_have_func = no; then ac_safe=`echo "inq_stats/cpustats.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for inq_stats/cpustats.h""... $ac_c" 1>&6 echo "configure:3977: checking for inq_stats/cpustats.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3987: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_have_func=yes; cat >> confdefs.h <<\EOF #define UMAX 1 EOF cat >> confdefs.h <<\EOF #define UMAX4_3 1 EOF else echo "$ac_t""no" 1>&6 fi fi if test $ac_have_func = no; then ac_safe=`echo "sys/cpustats.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/cpustats.h""... $ac_c" 1>&6 echo "configure:4020: checking for sys/cpustats.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4030: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_have_func=yes; cat >> confdefs.h <<\EOF ~MAKE-3_78_1HB.BCK``AKE-3_78_1HB]CONFIGURE.;1D΃#define UMAX 1 EOF else echo "$ac_t""no" 1>&6 fi fi if test $ac_have_func = no; then for ac_hdr in mach/mach.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:4061: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4071: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done fi ac_safe=`echo "nlist.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for nlist.h""... $ac_c" 1>&6 echo "configure:4101: checking for nlist.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if evalt "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define NLIST_STRUCT 1 EOF echo $ac_n "checking for n_un in struct nlist""... $ac_c" 1>&6 echo "configure:4132: checking for n_un in struct nlist" >&5 if eval "test \"`echo '$''{'ac_cv_struct_nlist_n_un'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { struct nlist n; n.n_un.n_name = 0; ; return 0; } EOF if { (eval echo configure:4144: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_nlist_n_un=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_struct_nlist_n_un=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_struct_nlist_n_un" 1>&6 if test $ac_cv_struct_nlist_n_un = yes; then cat >> confdefs.h <<\EOF #define NLIST_NAME_UNION 1 EOF fi else echo "$ac_t""no" 1>&6 fi fi # Do not have getloadavg in system libraries. # Some definitions of getloadavg require that the program be installed setgid. echo $ac_n "checking whether getloadavg requires setgid""... $ac_c" 1>&6 echo "configure:4171: checking whether getloadavg requires setgid" >&5 if eval "test \"`echo '$''{'ac_cv_func_getloadavg_setgid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "Yowza Am I SETGID yet" >/dev/null 2>&1; then rm -rf conftest* ac_cv_func_getloadavg_setgid=yes else rm -rf conftest* ac_cv_func_getloadavg_setgid=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_getloadavg_setgid" 1>&6 if test $ac_cv_func_getloadavg_setgid = yes; then NEED_SETGID=true; cat >> confdefs.h <<\EOF #define GETLOADAVG_PRIVILEGED 1 EOF else NEED_SETGID=false fi if test $ac_cv_func_getloadavg_setgid = yes; then echo $ac_n "checking group of /dev/kmem""... $ac_c" 1>&6 echo "configure:4207: checking group of /dev/kmem" >&5 if eval "test \"`echo '$''{'ac_cv_group_kmem'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # On Solaris, /dev/kmem is a symlink. Get info on the real file. ac_ls_output=`ls -lgL /dev/kmem 2>/dev/null` # If we got an error (system does not support symlinks), try without -L. test -z "$ac_ls_output" && ac_ls_output=`ls -lg /dev/kmem` ac_cv_group_kmem=`echo $ac_ls_output \ | sed -ne 's/[ ][ ]*/ /g; s/^.[sSrwx-]* *[0-9]* *\([^0-9]*\) *.*/\1/; / /s/.* //;p;'` fi echo "$ac_t""$ac_cv_group_kmem" 1>&6 KMEM_GROUP=$ac_cv_group_kmem fi # Check out the wait reality. for ac_hdr in sys/wait.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:4232: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4242: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in waitpid wait3 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4271: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:4299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for union wait""... $ac_c" 1>&6 echo "configure:4324: checking for union wait" >&5 if eval "test \"`echo '$''{'make_cv_union_wait'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include int main() { union wait status; int pid; pid = wait (&status); #ifdef WEXITSTATUS /* Some POSIXoid systems have both the new-style macros and the old union wait type, and they do not work together. If union wait conflicts with WEXITSTATUS et al, we don't want to use it at all. */ if (WEXITSTATUS (status) != 0) pid = -1; #ifdef WTERMSIG /* If we have WEXITSTATUS and WTERMSIG, just use them on ints. */ -- blow chunks here -- #endif #endif #ifdef HAVE_WAITPID /* Make sure union wait works with waitpid. */ pid = waitpid (-1, &status, 0); #endif ; return 0; } EOF if { (eval echo configure:4352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* make_cv_union_wait=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* make_cv_union_wait=no fi rm -f conftest* fi if test "$make_cv_union_wait" = yes; then cat >> confdefs.h <<\EOF #define HAVE_UNION_WAIT 1 EOF fi echo "$ac_t""$make_cv_union_wait" 1>&6 echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6 echo "configure:4373: checking for sys_siglist declaration in signal.h or unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include /* NetBSD declares sys_siglist in unistd.h. */ #ifdef HAVE_UNISTD_H #include #endif int main() { char *msg = *(sys_siglist + 1); ; return 0; } EOF if { (eval echo configure:4390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_siglist=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_decl_sys_siglist=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_decl_sys_siglist" 1>&6 if test $ac_cv_decl_sys_siglist = yes; then cat >> confdefs.h <<\EOF #define SYS_SIGLIST_DECLARED 1 EOF fi # The presence of the following is not meant to imply # that make necessarily works on those systems. echo $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6 echo "configure:4414: checking for getpwnam in -lsun" >&5 ac_lib_var=`echo sun'_'getpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsun $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo sun | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi REMOTE=stub make_try_customs=no # Check whether --with-customs or --without-customs was given. if test "${with_customs+set}" = set; then withval="$with_customs" case "$withval" in n|no) ;; *) make_cppflags="$CPPFLAGS" case "$withval" in y|ye|yes) ;; *) CPPFLAGS="$CPPFLAGS -I$with_customs/include/customs" make_ldflags="$LDFLAGS -L$with_customs/lib" ;; esac cf_test_netlibs=no echo $ac_n "checking for network libraries""... $ac_c" 1>&6 echo "configure:4477: checking for network libraries" >&5 if eval "test \"`echo '$''{'cf_cv_netlibs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo "$ac_t""working..." 1>&6 cf_cv_netlibs="" cf_test_netlibs=yes for ac_func in gethostname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4488: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 echo $ac_n "checking for gethostname in -lnsl""... $ac_c" 1>&6 echo "configure:4539: checking for gethostname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo gethostname | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_gethostname=unknown unset ac_cv_func_gethostname 2>/dev/null echo $ac_n "checking for gethostname in -lsocket""... $ac_c" 1>&6 echo "configure:4591: checking for gethostname in -lsocket" >&5 ac_lib_var=`echo socket'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo gethostname | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_gethostname=unknown unset ac_cv_func_gethostname 2>/dev/null fi fi fi done # # FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but # I don't know the entrypoints - 97/7/22 TD echo $ac_n "checking for main in -linet""... $ac_c" 1>&6 echo "configure:4654: checking for main in -linet" >&5 ac_lib_var=`echo inet'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_cv_netlibs="-linet $cf_cv_netlibs" else echo "$ac_t""no" 1>&6 fi # if test "$ac_cv_func_lsocket" != no ; then for ac_func in socket do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4694: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:4722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 echo "configure:4745: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo socket | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_socket=unknown unset ac_cv_func_socket 2>/dev/null echo $ac_n "checking for socket in -lbsd""... $ac_c" 1>&6 echo "configure:4797: checking for socket in -lbsd" >&5 ac_lib_var=`echo bsd'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbsd $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo socket | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_socket=unknown unset ac_cv_func_socket 2>/dev/null fi fi fi done fi # for ac_func in gethostbyname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4861: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:4889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 echo "configure:4912: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo gethostbyname | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_gethostbyname=unknown unset ac_cv_func_gethostbyname 2>/dev/null fi fi done # for ac_func in strcasecmp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4972: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:5000: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6 echo "configure:5023: checking for strcasecmp in -lresolv" >&5 ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $cf_cv_netlibs $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 cf_tr_func=`echo strcasecmp | tr 'a-z' 'A-Z'` cat >> confdefs.h <&6 ac_cv_func_strcasecmp=unknown unset ac_cv_func_strcasecmp 2>/dev/null fi fi done fi LIBS="$LIBS $cf_cv_netlibs" test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&6 ac_safe=`echo "customs.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for customs.h""... $ac_c" 1>&6 echo "configure:5087: checking for customs.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:5097: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 REMOTE=cstms LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags" else echo "$ac_t""no" 1>&6 with_customs=no CPPFLAGS="$make_cppflags" make_badcust=yes fi ;; esac fi # Check whether --enable-job-server or --disable-job-server was given. if test "${enable_job_server+set}" = set; then enableval="$enable_job_server" make_cv_job_server="$enableval" user_job_server="$enableval" else make_cv_job_server="yes" fi has_wait_nohang=yes case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in no/no) has_wait_nohang=no ;; esac case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$has_wait_nohang/$make_cv_job_server" in yes/yes/yes/yes) cat >> confdefs.h <<\EOF #define MAKE_JOBSERVER 1 EOF ;; esac # Check whether --enable-dmalloc or --disable-dmalloc was given. if test "${enable_dmalloc+set}" = set; then enableval="$enable_dmalloc" make_cv_dmalloc="$enableval" else make_cv_dmalloc="no" fi case "$make_cv_dmalloc" in yes) for ac_hdr in dmalloc.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:5163: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:5173: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for dmalloc_shutdown in -ldmalloc""... $ac_c" 1>&6 echo "configure:5200: checking for dmalloc_shutdown in -ldmalloc" >&5 ac_lib_var=`echo dmalloc'_'dmalloc_shutdown | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldmalloc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo dmalloc | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi CPPFLAGS="$CPPFLAGS -DDMALLOC_FUNC_CHECK" ;; esac echo $ac_n "checking for location of SCCS get command""... $ac_c" 1>&6 echo "configure:5250: checking for location of SCCS get command" >&5 if eval "test \"`echo '$''{'make_cv_path_sccs_get'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -f /usr/sccs/get; then make_cv_path_sccs_get=/usr/sccs/get else make_cv_path_sccs_get=get fi fi echo "$ac_t""$make_cv_path_sccs_get" 1>&6 cat >> confdefs.h </dev/null 2>&1 && test -f s.conftest; then # We successfully created an SCCS file. echo $ac_n "checking if SCCS get command understands -G""... $ac_c" 1>&6 echo "configure:5273: checking if SCCS get command understands -G" >&5 if eval "test \"`echo '$''{'make_cv_sys_get_minus_G'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if $make_cv_path_sccs_get -Gconftoast s.conftest >/dev/null 2>&1 && test -f conftoast; then make_cv_sys_get_minus_G=yes else make_cv_sys_get_minus_G=no fi fi echo "$ac_t""$make_cv_sys_get_minus_G" 1>&6 case "$make_cv_sys_get_minus_G" in yes) cat >> confdefs.h <<\EOF #define SCCS_GET_MINUS_G 1 EOF ;; esac fi rm -f s.conftest conftoast echo $ac_n "checking if system libc has GNU glob""... $ac_c" 1>&6 echo "configure:5297: checking if system libc has GNU glob" >&5 if eval "test \"`echo '$''{'make_cv_sys_gnu_glob'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #define GLOB_INTERFACE_VERSION 1 #if defined _LIBC || !defined __GNU_LIBRARY__ || __GNU_LIBRARY__ <= 1 # error no gnu glob #else # include # if _GNU_GLOB_INTERFACE_VERSION != GLOB_INTERFACE_VERSION # error no gnu glob # endif #endif EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:5322: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* make_cv_sys_gnu_glob=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* make_cv_sys_gnu_glob=no fi rm -f conftest* fi case "$make_cv_sys_gnu_glob" in yes) echo "$ac_t""yes" 1>&6 ;; no) echo "$ac_t""no; using local copy" 1>&6 CPPFLAGS="$CPPFLAGS -I$srcdir/glob" GLOBLIB=glob/libglob.a ;; esac cat >> confdefs.h < confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "build.sh Makefile glob/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@PACKAGE@%$PACKAGE%g s%@VERSION@%$VERSION%g s%@ACLOCAL@%$ACLOCAL%g s%@AUTOCONF@%$AUTOCONF%g s%@AUTOMAKE@%$AUTOMAKE%g s%@AUTOHEADER@%$AUTOHEADER%g s%@MAKEINFO@%$MAKEINFO%g s%@SET_MAKE@%$SET_MAKE%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@CC@%$CC%g s%@AR@%$AR%g s%@RANLIB@%$RANLIB%g s%@CPP@%$CPP%g s%@PERL@%$PERL%g s%@build@%$build%g s%@build_alias@%$build_alias%g s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@GETCONF@%$GETCONF%g s%@LIBOBJS@%$LIBOBJS%g s%@ALLOCA@%$ALLOCA%g s%@NEED_SETGID@%$NEED_SETGID%g s%@KMEM_GROUP@%$KMEM_GROUP%g s%@REMOTE@%$REMOTE%g s%@GLOBLIB@%$GLOBLIB%g s%@MAKE_HOST@%$MAKE_HOST%g /@MAINT_MAKEFILE@/r $MAINT_MAKEFILE s%@MAINT_MAKEFILE@%%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 case "$make_badcust" in yes) echo echo "WARNING: --with-customs specified but no customs.h could be found;" echo " disabling Customs support." echo ;; esac case "$with_customs" in ""|n|no|y|ye|yes) ;; *) if test -f "$with_customs/lib/libcustoms.a"; then : else echo echo "WARNING: \`$with_customs/lib' does not appear to contain the" echo " Customs library. You must build and install Customs" echo " before compiling GNU make." echo fi ;; esac case "$has_wait_nohang" in no) echo echo "WARNING: Your system has neither waitpid() nor wait3()." echo " Without one of these, signal handling is unreliable." echo " You should be aware that running GNU make with -j" echo " could result in erratic behavior." echo ;; esac case "$make_cv_job_server/$user_job_server" in no/yes) echo echo "WARNING: Make job server requires a POSIX-ish system that" echo " supports the pipe(), sigaction(), and either" echo " waitpid() or wait3() functions. Your system doesn't" echo " appear to provide one or more of those." echo " Disabling job server support." echo ;; esac *[MAKE-3_78_1HB]CONFIGURE.BAT;1+,`./@ 4-`0123KPWO56u799om89G@HJ@echo off echo Configuring MAKE for DJGPP rem The SmallEnv trick protects against too small environment block, rem in which case the values will be truncated and the whole thing rem goes awry. COMMAND.COM will say "Out of environment space", but rem many people don't care, so we force them to care by refusing to go. rem Where is the srcdir? set XSRC=. if not "%XSRC%"=="." goto SmallEnv if "%1%"=="" goto SrcDone set XSRC=%1 if not "%XSRC%"=="%1" goto SmallEnv :SrcDone update %XSRC%/configh.dos ./config.h rem Do they have Make? redir -o junk.$$$ -eo make -n -f NUL rem REDIR will return 1 if it cannot run Make. rem If it can run Make, it will usually return 2, rem but 0 is also OK with us. if errorlevel 2 goto MakeOk if not errorlevel 1 goto MakeOk if exist junk.$$$ del junk.$$$ echo No Make program found--use DOSBUILD.BAT to build Make. goto End rem They do have Make. Generate the Makefile. :MakeOk del junk.$$$ update %XSRC%/Makefile.DOS ./Makefile echo Done. if not "%XSRC%"=="." echo Invoke Make thus: "make srcdir=%XSRC%" goto End :SmallEnv echo Your environment is too small. Please enlarge it and run me again. :End set XRSC= *[MAKE-3_78_1HB]CONFIGURE.IN;1+,`./@ 4Q-`0123KPWO56-9+7m89G@HJ"dnl Process this file with autoconf to produce a configure script. AC_REVISION([$Id: configure.in,v 1.83 1999/09/17 03:15:46 psmith Exp $]) AC_PREREQ(2.13)dnl dnl Minimum Autoconf version required. AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir. AM_INIT_AUTOMAKE(make, 3.78.1) AM_CONFIG_HEADER(config.h) dnl Regular configure stuff AC_CANONICAL_HOST AC_PROG_MAKE_SET AC_PROG_CC AC_PROG_INSTALL AC_CHECK_PROG(AR, ar, ar, ar) AC_PROG_RANLIB AC_PROG_CPP dnl Later checks need this. AC_AIX AC_ISC_POSIX AC_MINIX AC_CHECK_PROG(PERL, perl, perl, perl) dnl Needed for the test suite (only) dnl This test must come as early as possible after the compiler configuration dnl tests, because the choice of the file model can (in principle) affect dnl whether functions and headers are available, whether they work, etc. AC_SYS_LARGEFILE AC_HEADER_STDC AC_HEADER_DIRENT AC_TYPE_UID_T dnl Also does gid_t. AC_TYPE_PID_T AC_TYPE_SIGNAL AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/param.h fcntl.h string.h \ memory.h sys/timeb.h) AC_PROG_CC_C_O AM_PROG_CC_STDC AC_C_CONST dnl getopt needs this. AC_HEADER_STAT AC_STRUCT_ST_MTIM_NSEC jm_AC_TYPE_UINTMAX_T AC_SUBST(LIBOBJS) AC_DEFUN(AC_CHECK_SYMBOL, [dnl AC_MSG_CHECKING(for $1) AC_CACHE_VAL(ac_cv_check_symbol_$1, [dnl AC_TRY_LINK(, [extern char *sys_siglist[]; puts(*sys_siglist);], ac_cv_check_symbol_$1=yes, ac_cv_check_symbol_$1=no)]) if test "$ac_cv_check_symbol_$1" = yes; then changequote(,)dnl ac_tr_symbol=`echo $1 | tr '[a-z]' '[A-Z]'` changequote([,])dnl AC_DEFINE_UNQUOTED(HAVE_${ac_tr_symbol}) fi AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl # clock_gettime is in -lposix4 in Solaris 2.6. AC_CHECK_LIB(posix4, clock_gettime) AC_CHECK_FUNCS(memmove strdup psignal mktemp pstat_getdynamic \ clock_gettime dup2 getcwd sigsetmask sigaction getgroups \ setlinebuf seteuid setegid setreuid setregid pipe \ strerror strsignal) AC_CHECK_SYMBOL(sys_siglist) AC_FUNC_ALLOCA AC_FUNC_VFORK AC_FUNC_VPRINTF AC_FUNC_STRCOLL AC_FUNC_CLOSEDIR_VOID AC_FUNC_SETVBUF_REVERSED AC_FUNC_SELECT AC_CHECK_LIB(kstat, kstat_open) dnl _Must_ come before AC_FUNC_GETLOADAVG. AC_FUNC_GETLOADAVG # Check out the wait reality. AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_FUNCS(waitpid wait3) AC_MSG_CHECKING(for union wait) AC_CACHE_VAL(make_cv_union_wait, [dnl AC_TRY_LINK([#include #include ], [union wait status; int pid; pid = wait (&status); #ifdef WEXITSTATUS /* Some POSIXoid systems have both the new-style macros and the old union wait type, and they do not work together. If union wait conflicts with WEXITSTATUS et al, we don't want to use it at all. */ if (WEXITSTATUS (status) != 0) pid = -1; #ifdef WTERMSIG /* If we have WEXITSTATUS and WTERMSIG, just use them on ints. */ -- blow chunks here -- #endif #endif #ifdef HAVE_WAITPID /* Make sure union wait works with waitpid. */ pid = waitpid (-1, &status, 0); #endif ], [make_cv_union_wait=yes], [make_cv_union_wait=no])]) if test "$make_cv_union_wait" = yes; then AC_DEFINE(HAVE_UNION_WAIT) fi AC_MSG_RESULT($make_cv_union_wait) AC_DECL_SYS_SIGLIST # The presence of the following is not meant to imply # that make necessarily works on those systems. AC_CHECK_LIB(sun, getpwnam) AC_SUBST(REMOTE) REMOTE=stub make_try_customs=no AC_ARG_WITH(customs, [ --with-customs=DIR Enable remote jobs via Customs--see README.customs], [case "$withval" in n|no) ;; *) make_cppflags="$CPPFLAGS" case "$withval" in y|ye|yes) ;; *) CPPFLAGS="$CPPFLAGS -I$with_customs/include/customs" make_ldflags="$LDFLAGS -L$with_customs/lib" ;; esac CF_NETLIBS AC_CHECK_HEADER(customs.h, REMOTE=cstms LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags", with_customs=no CPPFLAGS="$make_cppflags" make_badcust=yes) ;; esac]) dnl See if we can handle the job server feature, and if the user wants it. AC_ARG_ENABLE(job-server, [ --disable-job-server Disallow recursive make communication during -jN], [make_cv_job_server="$enableval" user_job_server="$enableval"], [make_cv_job_server="yes"]) has_wait_nohang=yes case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in no/no) has_wait_nohang=no ;; esac case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$has_wait_nohang/$make_cv_job_server" in yes/yes/yes/yes) AC_DEFINE(MAKE_JOBSERVER) ;; esac dnl Allow building with dmalloc AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc Enable support for the dmalloc debugging library], [make_cv_dmalloc="$enableval"], [make_cv_dmalloc="no"]) case "$make_cv_dmalloc" in yes) AC_CHECK_HEADERS(dmalloc.h) AC_CHECK_LIB(dmalloc, dmalloc_shutdown) CPPFLAGS="$CPPFLAGS -DDMALLOC_FUNC_CHECK" ;; esac AC_CACHE_CHECK(for location of SCCS get command, make_cv_path_sccs_get, [ if test -f /usr/sccs/get; then make_cv_path_sccs_get=/usr/sccs/get else make_cv_path_sccs_get=get fi]) AC_DEFINE_UNQUOTED(SCCS_GET,["$make_cv_path_sccs_get"]) ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later. if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 && test -f s.conftest; then # We successfully created an SCCS file. AC_CACHE_CHECK(if SCCS get command understands -G, make_cv_sys_get_minus_G, [ if $make_cv_path_sccs_get -Gconftoast s.conftest >/dev/null 2>&1 && test -f conftoast; then make_cv_sys_get_minus_G=yes else make_cv_sys_get_minus_G=no fi]) case "$make_cv_sys_get_minus_G" in yes) AC_DEFINE(SCCS_GET_MINUS_G);; esac fi rm -f s.conftest conftoast AC_MSG_CHECKING(if system libc has GNU glob) AC_CACHE_VAL(make_cv_sys_gnu_glob, [ AC_TRY_CPP([ #include #include #include #define GLOB_INTERFACE_VERSION 1 #if defined _LIBC || !defined __GNU_LIBRARY__ || __GNU_LIBRARY__ <= 1 # error no gnu glob #else # include # if _GNU_GLOB_INTERFACE_VERSION != GLOB_INTERFACE_VERSION # error no gnu glob # endif #endif ], make_cv_sys_gnu_glob=yes, make_cv_sys_gnu_glob=no)]) case "$make_cv_sys_gnu_glob" in yes) AC_MSG_RESULT(yes) ;; no) AC_MSG_RESULT([no; using local copy]) CPPFLAGS="$CPPFLAGS -I$srcdir/glob" AC_SUBST(GLOBLIB) GLOBLIB=glob/libglob.a ;; esac AC_DEFINE_UNQUOTED(MAKE_HOST,"$host",[Build host information.]) MAKE_HOST="$host" AC_SUBST(MAKE_HOST) MAINT_MAKEFILE=/dev/null if test -r "$srcdir/maintMakefile"; then MAINT_MAKEFILE="$srcdir/maintMakefile" fi AC_SUBST_FILE(MAINT_MAKEFILE) AC_OUTPUT(build.sh Makefile glob/Makefile) dnl If we don't yet have build.sh.in, build.sh is a bogus 0-length file dnl so remove it. dnl Can't do this because then remote builds with build.sh don't work. dnl test -f build.sh.in || rm -f build.sh case "$make_badcust" in yes) echo echo "WARNING: --with-customs specified but no customs.h could be found;" echo " disabling Customs support." echo ;; esac case "$with_customs" in ""|n|no|y|ye|yes) ;; *) if test -f "$with_customs/lib/libcustoms.a"; then : else echo echo "WARNING: \`$with_customs/lib' does not appear to contain the" echo " Customs library. You must build and install Customs" echo " before compiling GNU make." echo fi ;; esac case "$has_wait_nohang" in no) echo echo "WARNING: Your system has neither waitpid() nor wait3()." echo " Without one of these, signal handling is unreliable." echo " You should be aware that running GNU make with -j" echo " could result in erratic behavior." echo ;; esac case "$make_cv_job_server/$user_job_server" in no/yes) echo echo "WARNING: Make job server requires a POSIX-ish system that" echo " supports the pipe(), sigaction(), and either" echo " waitpid() or wait3() functions. Your system doesn't" echo " appear to provide one or more of those." echo " Disabling job server support." echo ;; esac dnl Local Variables: dnl comment-start: "dnl " dnl comment-end: "" dnl comment-start-skip: "\\bdnl\\b\\s *" dnl compile-command: "make configure config.h.in" dnl End: o*[MAKE-3_78_1HB]CONFIG_H.IN;1+,`./@ 4-`0123KPWO56 @7m89G@HJ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE #undef _ALL_SOURCE #endif /* Define if using alloca.c. */ #undef C_ALLOCA /* Define if the closedir function returns void instead of int. */ #undef CLOSEDIR_VOID /* Define to empty if the keyword does not work. */ #undef const /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define for DGUX with . */ #undef DGUX /* Define if the `getloadavg' function needs to be run setuid or setgid. */ #undef GETLOADAVG_PRIVILEGED /* Define to `int' if doesn't define. */ #undef gid_t /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT /* Define if your system has a working fnmatch function. */ #undef HAVE_FNMATCH /* Define if your system has its own `getloadavg' function. */ #undef HAVE_GETLOADAVG /* Define if you have the getmntent function. */ #undef HAVE_GETMNTENT /* Define if the `long double' type works. */ #undef HAVE_LONG_DOUBLE /* Define if you support file names longer than 14 characters. */ #undef HAVE_LONG_FILE_NAMES /* Define if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define if system calls automatically restart after interruption by a signal. */ #undef HAVE_RESTARTABLE_SYSCALLS /* Define if your struct stat has st_blksize. */ #undef HAVE_ST_BLKSIZE /* Define if your struct stat has st_blocks. */ #undef HAVE_ST_BLOCKS /* Define if you have the strcoll function and it is properly defined. */ #undef HAVE_STRCOLL /* Define if your struct stat has st_rdev. */ #undef HAVE_ST_RDEV /* Define if you have the strftime function. */ #undef HAVE_STRFTIME /* Define if you have the ANSI # stringizing operator in cpp. */ #undef HAVE_STRINGIZE /* Define if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define if your struct tm has tm_zone. */ #undef HAVE_TM_ZONE /* Define if you don't have tm_zone but do have the external array tzname. */ #undef HAVE_TZNAME /* Define if you have . */ #undef HAVE_UNISTD_H /* Define if utime(file, NULL) sets file's timestamp to the present. */ #undef HAVE_UTIME_NULL /* Define if you have . */ #undef HAVE_VFORK_H /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define if you have the wait3 system call. */ #undef HAVE_WAIT3 /* Define if on MINIX. */ #undef _MINIX /* Define if your struct nlist has an n_un member. */ #undef NLIST_NAME_UNION /* Define if you have . */ #undef NLIST_STRUCT /* Define if your C compiler doesn't accept -c and -o together. */ #undef NO_M~MAKE-3_78_1HB.BCK``[MAKE-3_78_1HB]CONFIG_H.IN;1SINUS_C_MINUS_O /* Define to `int' if doesn't define. */ #undef pid_t /* Define if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define if you need to in order for stat and other things to work. */ #undef _POSIX_SOURCE /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define if the setvbuf function takes the buffering type as its second argument and the buffer pointer as the third, as on System V before release 3. */ #undef SETVBUF_REVERSED /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if the `S_IS*' macros in do not work properly. */ #undef STAT_MACROS_BROKEN /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define on System V Release 4. */ #undef SVR4 /* Define if `sys_siglist' is declared by . */ #undef SYS_SIGLIST_DECLARED /* Define to `int' if doesn't define. */ #undef uid_t /* Define for Encore UMAX. */ #undef UMAX /* Define for Encore UMAX 4.3 that has instead of . */ #undef UMAX4_3 /* Define vfork as fork if vfork does not work. */ #undef vfork /* Define to the name of the SCCS `get' command. */ #undef SCCS_GET /* Define this if the SCCS `get' command understands the `-G' option. */ #undef SCCS_GET_MINUS_G /* Define this to enable job server support in GNU make. */ #undef MAKE_JOBSERVER /* Define to be the nanoseconds member of struct stat's st_mtim, if it exists. */ #undef ST_MTIM_NSEC /* Define this if the C library defines the variable `sys_siglist'. */ #undef HAVE_SYS_SIGLIST /* Define this if the C library defines the variable `_sys_siglist'. */ #undef HAVE__SYS_SIGLIST /* Define this if you have the `union wait' type in . */ #undef HAVE_UNION_WAIT /* Define to `unsigned long' or `unsigned long long' if doesn't define. */ #undef uintmax_t /* Define if the system doesn't provide fd_set. */ #undef fd_set /* Define the type of the first arg to select(). */ #undef fd_set_size_t /* Define this if select() args need to be cast away from fd_set (HP-UX). */ #undef SELECT_FD_SET_CAST /* Define if you have the INTTYPES_H function. */ #undef HAVE_INTTYPES_H /* Define if you have the clock_gettime function. */ #undef HAVE_CLOCK_GETTIME /* Define if you have the dup2 function. */ #undef HAVE_DUP2 /* Define if you have the getcwd function. */ #undef HAVE_GETCWD /* Define if you have the getgroups function. */ #undef HAVE_GETGROUPS /* Define if you have the gethostbyname function. */ #undef HAVE_GETHOSTBYNAME /* Define if you have the gethostname function. */ #undef HAVE_GETHOSTNAME /* Define if you have the getloadavg function. */ #undef HAVE_GETLOADAVG /* Define if you have the memmove function. */ #undef HAVE_MEMMOVE /* Define if you have the mktemp function. */ #undef HAVE_MKTEMP /* Define if you have the pipe function. */ #undef HAVE_PIPE /* Define if you have the psignal function. */ #undef HAVE_PSIGNAL /* Define if you have the pstat_getdynamic function. */ #undef HAVE_PSTAT_GETDYNAMIC /* Define if you have the select function. */ #undef HAVE_SELECT /* Define if you have the setegid function. */ #undef HAVE_SETEGID /* Define if you have the seteuid function. */ #undef HAVE_SETEUID /* Define if you have the setlinebuf function. */ #undef HAVE_SETLINEBUF /* Define if you have the setregid function. */ #undef HAVE_SETREGID /* Define if you have the setreuid function. */ #undef HAVE_SETREUID /* Define if you have the sigaction function. */ #undef HAVE_SIGACTION /* Define if you have the sigsetmask function. */ #undef HAVE_SIGSETMASK /* Define if you have the socket function. */ #undef HAVE_SOCKET /* Define if you have the strcasecmp function. */ #undef HAVE_STRCASECMP /* Define if you have the strdup function. */ #undef HAVE_STRDUP /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the strsignal function. */ #undef HAVE_STRSIGNAL /* Define if you have the wait3 function. */ #undef HAVE_WAIT3 /* Define if you have the waitpid function. */ #undef HAVE_WAITPID /* Define if you have the header file. */ #undef HAVE_DIRENT_H /* Define if you have the header file. */ #undef HAVE_DMALLOC_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_LIMITS_H /* Define if you have the header file. */ #undef HAVE_MACH_MACH_H /* Define if you have the header file. */ #undef HAVE_MEMORY_H /* Define if you have the header file. */ #undef HAVE_NDIR_H /* Define if you have the  header file. */ #undef HAVE_STDLIB_H /* Define if you have the header file. */ #undef HAVE_STRING_H /* Define if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYS_TIMEB_H /* Define if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the dgc library (-ldgc). */ #undef HAVE_LIBDGC /* Define if you have the dmalloc library (-ldmalloc). */ #undef HAVE_LIBDMALLOC /* Define if you have the kstat library (-lkstat). */ #undef HAVE_LIBKSTAT /* Define if you have the posix4 library (-lposix4). */ #undef HAVE_LIBPOSIX4 /* Define if you have the sun library (-lsun). */ #undef HAVE_LIBSUN /* Name of package */ #undef PACKAGE /* Version number of package */ #undef VERSION /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define to make fseeko etc. visible, on some hosts. */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Build host information. */ #undef MAKE_HOST *[MAKE-3_78_1HB]CONFIG_H.W32;1+,Sb ./@ 4]-`0123KPWO56sb7m89G@HJ(/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE /* #undef _ALL_SOURCE */ #endif /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define if the closedir function returns void instead of int. */ /* #undef CLOSEDIR_VOID */ /* Define to empty if the keyword does not work. */ /* #undef const */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define for DGUX with . */ /* #undef DGUX */ /* Define if the `getloadavg' function needs to be run setuid or setgid. */ /* #undef GETLOADAVG_PRIVILEGED */ /* Define to `int' if doesn't define. */ #undef gid_t #define gid_t int /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA #define HAVE_ALLOCA 1 /* Define if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define if you don't have vprintf but do have _doprnt. */ /* #undef HAVE_DOPRNT */ /* Define if your system has a working fnmatch function. */ /* #undef HAVE_FNMATCH */ /* Define if your system has its own `getloadavg' function. */ /* #undef HAVE_GETLOADAVG */ /* Define if you have the getmntent function. */ /* #undef HAVE_GETMNTENT */ /* Define if the `long double' type works. */ /* #undef HAVE_LONG_DOUBLE */ /* Define if you support file names longer than 14 characters. */ #undef HAVE_LONG_FILE_NAMES #define HAVE_LONG_FILE_NAMES 1 /* Define if you have a working `mmap' system call. */ /* #undef HAVE_MMAP */ /* Define if system calls automatically restart after interruption by a signal. */ /* #undef HAVE_RESTARTABLE_SYSCALLS */ /* Define if your struct stat has st_blksize. */ /* #undef HAVE_ST_BLKSIZE */ /* Define if your struct stat has st_blocks. */ /* #undef HAVE_ST_BLOCKS */ /* Define if you have the strcoll function and it is properly defined. */ #undef HAVE_STRCOLL #define HAVE_STRCOLL 1 /* Define if your struct stat has st_rdev. */ #undef HAVE_ST_RDEV #define HAVE_ST_RDEV 1 /* Define if you have the strftime function. */ #undef HAVE_STRFTIME #define HAVE_STRFTIME 1 /* Define if you have that is POSIX.1 compatible. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if your struct tm has tm_zone. */ /* #undef HAVE_TM_ZONE */ /* Define if you don't have tm_zone but do have the external array tzname. */ #undef HAVE_TZNAME #define HAVE_TZNAME 1 /* Define if you have . */ /* #undef HAVE_UNISTD_H */ /* Define if utime(file, NULL) sets file's timestamp to the present. */ #undef HAVE_UTIME_NULL #define HAVE_UTIME_NULL 1 /* Define if you have . */ /* #undef HAVE_VFORK_H */ /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF #define HAVE_VPRINTF 1 /* Define if you have the wait3 system call. */ /* #undef HAVE_WAIT3 */ /* Define if on MINIX. */ /* #undef _MINIX */ /* Define if your struct nlist has an n_un member. */ /* #undef NLIST_NAME_UNION */ /* Define if you have . */ /* #undef NLIST_STRUCT */ /* Define if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* Define to `int' if doesn't define. */ #undef pid_t #define pid_t int /* Define if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define if you need to in order for stat and other things to work. */ #undef _POSIX_SOURCE #define _POSIX_SOURCE 1 /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE #define RETSIGTYPE void /* Define if the setvbuf function takes the buffering type as its second argument and the buffer pointer as the third, as on System V before release 3. */ /* #undef SETVBUF_REVERSED */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if the `S_IS*' macros in do not work properly. */ /* #undef STAT_MACROS_BROKEN */ /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS #define STDC_HEADERS 1 /* Define on System V Release 4. */ /* #undef SVR4 */ /* Define if `sys_siglist' is declared by . */ /* #undef SYS_SIGLIST_DECLARED */ /* Define to `int' if doesn't define. */ #undef uid_t #define uid_t int /* Define for Encore UMAX. */ /* #undef UMAX */ /* Define for Encore UMAX 4.3 that has instead of . */ /* #undef UMAX4_3 */ /* Define vfork as fork if vfork does not work. */ /* #undef vfork */ /* Name of this package (needed by automake) */ #define PACKAGE "make" /* Version of this package (needed by automake) */ #define VERSION "3.78.1" /* Define to the name of the SCCS `get' command. */ #undef SCCS_GET #define SCCS_GET "echo no sccs get" /* Define this if the SCCS `get' command understands the `-G' option. */ /* #undef SCCS_GET_MINUS_G */ /* Define this to enable job server support in GNU make. */ /* #undef MAKE_JOBSERVER */ /* Define to be the nanoseconds member of struct stat's st_mtim, if it exists. */ /* #undef ST_MTIM_NSEC */ /* Define this if the C library defines the variable `sys_siglist'. */ /* #undef HAVE_SYS_SIGLIST */ /* Define this if the C library defines the variable `_sys_siglist'. */ /* #undef HAVE__SYS_SIGLIST */ /* Define this if you have the `union wait' type in . */ /* #undef HAVE_UNION_WAIT */ /* Define if you have the dup2 function. */ #undef HAVE_DUP2 #define HAVE_DUP2 1 /* Define if you have the getcwd function. */ #undef HAVE_GETCWD #define HAVE_GETCWD 1 /* Define if you have the getgroups function. */ /* #undef HAVE_GETGROUPS */ /* Define if you have the gethostbyname function. */ /* #undef HAVE_GETHOSTBYNAME */ /* Define if you have the gethostname function. */ /* #undef HAVE_GETHOSTNAME */ /* Define if you have the getloadavg function. */ /* #undef HAVE_GETLOADAVG */ /* Define if you have the memmove function. */ #undef HAVE_MEMMOVE #define HAVE_MEMMOVE 1 /* Define if you have the mktemp function. */ #undef HAVE_MKTEMP #define HAVE_MKTEMP 1 /* Define if you have the psignal function. */ /* #undef HAVE_PSIGNAL */ /* Define if you have the pstat_getdynamic function. */ /* #undef HAVE_PSTAT_GETDYNAMIC */ /* Define if you have the setegid function. */ /* #undef HAVE_SETEGID */ /* Define if you have the seteuid function. */ /* #undef HAVE_SETEUID */ /* Define if you have the setlinebuf function. */ /* #undef HAVE_SETLINEBUF */ /* Define if you have the setregid function. */ /* #undef HAVE_SETREGID */ /* Define if you have the setreuid function. */ /* #undef HAVE_SETREUID */ /* Define if you have the sigsetmask function. */ /* #undef HAVE_SIGSETMASK */ /* Define if you have the socket function. */ /* #undef HAVE_SOCKET */ /* Define if you have the strcasecmp function. */ /* #undef HAVE_STRCASECMP */ /* Define if you have the strerror function. */ #undef HAVE_STRERROR #define HAVE_STRERROR 1 /* Define if you have the strsignal function. */ /* #undef HAVE_STRSIGNAL */ /* Define if you have the wait3 function. */ /* #undef HAVE_WAIT3 */ /* Define if you have the waitpid function. */ /* #undef HAVE_WAITPID */ /* Define if you have the header file. */ #undef HAVE_DIRENT_H #define HAVE_DIRENT_H 1 /* Define if you have the header file. */ #undef HAVE_FCNTL_H #define HAVE_FCNTL_H 1 /* Define if you have the header file. */ #undef HAVE_LIMITS_H #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ /* #undef HAVE_MACH_MACH_H */ /* Define if you have the header file. */ #undef HAVE_MEMORY_H #define HAVE_MEMORY_H 1 /* Define if you have the header file. */ /* #undef HAVE_NDIR_H */ /* Define if you have the header file. */ #undef HAVE_STRING_H #define HAVE_STRING_H 1 /* Define if you have the header file. */ /* #undef HAVE_SYS_DIR_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_NDIR_H */ /* Define if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define if you have the header file. */ #undef HAVE_SYS_TIMEB_H #define HAVE_SYS_TIMEB_H 1 /* Define if you have the header file. */ /* #undef HAVE_SYS_WAIT_H */ /* Define if you have the header file. */ /* #undef HAVE_UNISTD_H */ /* Define if you have the dgc library (-ldgc). */ /* #undef HAVE_LIBDGC */ /* Define if you have the kstat library (-lkstat). */ /* #undef HAVE_LIBKSTAT */ /* Define if you have the sun library (-lsun). */ /* #undef HAVE_LIBSUN */ /* Build host information. */ #define MAKE_HOST "Windows32" /* * Refer to README.W32 for info on the following settings */ /* * If you have a shell that does not grok 'sh -c quoted-command-line' * correctly, you need this setting. Please see below for specific * shell support. */ #undef BATCH_MODE_ONLY_SHELL #define BATCH_MODE_ONLY_SHELL 1 /* * Define if you have the Cygnus "Cygwin" GNU Windows32 tool set. * Do NOT define BATCH_MODE_ONLY_SHELL if you define HAVE_CYGWIN_SHELL */ #undef HAVE_CYGWIN_SHELL /* * Define if you have the MKS tool set or shell. Do NOT define * BATCH_MODE_ONLY_SHELL if you define HAVE_MKS_SHELL */ #undef HAVE_MKS_SHELL /* * Enforce the mutual exclusivity restriction. */ #ifdef HAVE_MKS_SHELL #undef BATCH_MODE_ONLY_SHELL #endif #ifdef HAVE_CYGWIN_SHELL #undef BATCH_MODE_ONLY_SHELL #endif /* Define if you prefer Case Insensitive behavior */ #undef HAVE_CASE_INSENSITIVE_FS e*[MAKE-3_78_1HB]COPYING.;1+,Tb .$/@ 4$${-`0123KPWO%56I47m89G@HJ0 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our fr hah 1b/#?;2s*IAd Wy@ QAyK@ uM#["j&e*s gfD"[(]pv P|QPP$HyH]!TU;dRr~EEKy\TQ!q\Xj 6 Mz7MisP'i *fd WH6):5UA2rq 5MLp%4>wyMh>.m;=tqjQ)N_XMW IbB&c'G%D's$;J]O|^d^3:6uE:fxO~.  /3 v s  AEHz .^,f%Py` %H.x,PwvX-1 w[g6t}r9Xa0ASf.Vtd09VJ'3)=A8cg2sz#+7 W&5}JQ= Wd b<$.B#W^$*Xl{5!c&'7?w=,&l SQGoTpI 8~sC^-uead`S$2g!%S hy(;Jt_LrP}(`QV99}J_[O\"1UR1q/*\|?:-h~k78F9Sf ~553j|pbnFhDG&Kx}=s/PdRo1Zxj.Es 3tx5m HIZR%C5ByVhz[qyx4NH,aQf5H|5Ex/q]*$2aqh*/vFV6Y6K/z#q%i^`'6w3z}/qwqlk_n ARUitfXDHQvnKENDKPG36WBpJbMI9{[vz~CF3RHK&Y]UGGmFpcd_&kn_o <B<1osM(B+xXK8%pgc+ CpsrI^idTl=SG]x=vuKPf?2tX0%gF={). X,ca~]n|ho;}j7[\\OC/`-TE!*X^8u`sx[{3VuE91"'Ua{ vwznRRh DXd}yzZ`WfgdSF s Sbska@'%"h%acbf9;PVQ :-IGAy' -d\(VU8[iIJ#1l|Fb(6nxuJl(.Fe| arS.g#yS~j!>g,bU`El'H?+ )c=6L.J;w@ shT8.",C_CL 5ra>`k6z^t~Wea}sW;(rbvnH=3%:mZUj?/O7lr|r]la=h(uq/\16nB~coxx{Tz[1JKOswsJO Z>O ^0ls$Q/1 p+i^bUx52mDDFJ)HrYnfNU`;npvbr0Vr %u+9xL&$%(u'syn8{^xQItV }'x&sGBlze*<{OZ;6Rh!"Z?^sP8 S$ pO93,i@tAwE_"o1?n/jBu>8V2yW%879?[nr7|GM?#EdSE`Gg;%CHkG|dai2}r`0>.n d^[r77";^j;-f.'= e?1 `&bV`S.:zONCE RcA|i%U05C !dh7XzuYiR3'L76B =X[4Zp A8B Qkc(6D@]-X48yRI J iBp3cs!H,^'Y R}ym \ELPlzTWg" V?o05#lxWyGBxkCv*)w^f`">x 7!O$!jb8mSy?^d"xhYwT1*i~LDmRs{'G Lo4KoL)?|.D@ }DT5y9_{ka@c,~:%@ej)n\~A.~h{^K;]YM;Ag{t7pW_]<8i],Kjq _5:966~F@KB`5weMep#s4w= yr8/G}C.W}D?C_xrpU3,\>rv[Q>S){I!5^Oygl"Xh#np+t{K e9] &Wz8|eY  N@9fi~c'xVlx t 5 +@u!CZ0i3*c+G'@Oik1,0AVfp\M?pa7h_ /[o VK/_vc7OcEOG]GSR3SXOs~.h;GcqF2oA]atiUy-Pb 9$S)WDRmK@U6]r3}o>-l!}rB I08il!_m;jd(cG<kRDEkaXBoF^xXP[.DB`i3}yWJb&?prB/t1H<@/u 5QPG0 B xnw?d j;lkIvb1jfv v-(=7?H!AC*i" !WN&M7M 3JCN9n rB[) R 9lsf 0bxKa.Q VX{=)ac`9~sjo|`4686_; vCCM30$grKTuNiLa[3C5u 5\`"cn-*F$epZObbk_cSIVWl;t0_aelFXj(a75T8QH)9r)so6?.eT"D ]Sm B8\K7 @qCp x>*9hr,sz6fgA{y{r,%nu2+?V1950$$VZWXBHwC caBs2;iivA`?De8=L5q0B-Zvv;a)DR9]\b6n ET|O~nX_#wJVgMeYO F2ZE9n1 LC _X?^DP 5kQ]~F _G)-o[L~shokNBP&X6&1S"30uXi]#EdKva/`(f}: NXzerxk.M3iv|0@@ X Z T/XFHBGSwv~Cio_!k*ToO!O{$% 7NeGv< 0q .T0@v TRJV[ \oM:au.amz !B}eNZ;qa3R~ qdO:lZ[Jb3}91~U@3H;m_Dk/bG[#0&+,eT^bZGK G,*%j_d` x#{kAbSh-OW j/Og%s;r  #O?!7[ q"|1a%yQ0<~ [< +^k_ZB1[t$oYK_'f"#aLU*LSs>Di_R P9TSgJ/ZBz\(uEwj"L[IEV~ZG:$BO(y 'K }@v.$I?luW )pAH5PCYM^ r8&tK"z H+E^"ct|A=[G)S,iM}VFS3}6ld$4vs_[t;9 "}Lv tai+d2o_D'nE#(\IinQQ;=8Zlx1L\/Mct)j'N)0sc $sl`!6k.5|%h`;hr,jrr]/n}BKZSAY! c&KPk635"DS@8aV*D;pNJD G*6hX1>;i-<0.:\0m]@4UfH>IBUg61u/. VhIcv`~3s>7CoZ`h{B2O%CzJet9b%(=n,fSBT\D$i(E^w AUg9BWS|(a+]jlbC=| );hT` .NMJ g\Tv'vEdQ Y'=9y;@BrmacPirvQ?9\( qa4PSEi9t(_+'$f8A iFC8tm3ZLKqTfxm7{rOKZ)5Fr%G{?HSP 6bo"{Z~>H"y$(Wn`Z<;ay-/ QX'1b0Ds?F%-" c&qJ!C[u.Sy`_ lk9!7{*=:r&XAdd5' 4P|[PU PON9Y+?5PR!m}SlR,\4YH$#NSfDtRkQG4FejmV.=Ji):k<XZl~@~HKw6CZ`O.g"iDnG 1P~) VTL?V3Tu;%E8BoLrN'iN}yvy O?MN`}.@h-1jlV'0lDo dP3liZz6 k-wM!chie8-W)*WK uf0lQQf{GJD,8H:gH8$Xpa Ykt;|h( )x*r%>3LxJ/y^s'w.tHJBOP+i_Sf8a7){V#LY.)i}w0Q=,}J[CkOh$3{YYpO#.y=T\~jU \s-[.3 Fh^f6#LW7qaZD48#"B)"bwGURuGk})> ymjB% &S:X_a,1vmm"}zs BCXPu$Yq?`pI~ M+ jS**rjm[/wJmD&xZ1 R RJ%@DDzK l\Oe 9WTY 4tc8=S+^}' \fnnI)X%Kv'CW ur*, 2KUg3VOQ $Z:aZBL ?|r -b(_y} ;ZGMk,088'NUaMT1Np~p!Lj4ltHe9$!|d0>eEj%l[ico%}B6UHFUB^Q nAYBgPUrI-6 ~4}B68O ( 7l E[5kj rqe4v'zo05zXC1Y8MjjB~9PF7F}p';!jYDH?.acp~\L[cxOMR78_UR)OW|H<m+Z[!\%C@ R^UE G;KR\LqE(f7\vVZv'goghB/D1PI PW MB~(^%kCX* B{mL )vlw|7JZ?O,iu:`&4g-V n=Qi 6@@ER8pqg4tFU02 lMapG*6q/H9|UbYcybL( ?h@mr0`1#0 87TSg^!dU(b@ x'KMJlQTpfqA@<2D$WM_'6HrS&u6b?S@kR8VM U tT^i>fcUT=w/+<=Fn~EF#9fRDM/C~zJNB#8MW5zr&RytN?lIEj[VMxn!lFfFVCYYU rRCqy}_D$Wj>r 3gdj0n:%!+3g%oe^tyq=pWUF cQ2ZZ wcFI R,}Fo_sTYqQkPomLWQQC@ P>+s+TG* bqR0p%1!VyyN-/q-`Xgpr+1=Zvebq}0 VC=#xuU{iO-^YJgy $)}YQP epi-]ZBx:DO90n>tT)>uD"aBYr?V"^ 8}Fw( _X/~8X#u^y,P[M+=#j((Dq83iwveB`GT 0& oi.x|$i oBKVpP!$3E 9c3eDh!~z Vdy0?H_r?A?  nQW]R}btTDZi@'.&k6\t5EKU0)jJdItez:&klZqg=I'65K=SX9SyntQ5a){zNOwF-mF,B[b82,}{4i$2k0.W@MAy><+YHqq'6~Alg:b<&eB 1|h5BjvT&6qE*W6{ 3G]lTk^ MM U~hg{Y.>?[(a-J%.<0KA!s^HAn>i*v&PLVP[ %&veDbgw66e]/T2+`r< +qmaVaX\7g7R':Cn WX,/'Pz13[PX4/ MXbA#IpI%F/iPDM&@,^m8|9dhO%+#}L# O8A-,}Zrxc-5_^R7L4t)oV6R[%jmG>v5La $Dsc)1k%-dfxr^_3FXwou7$iCRd#%T!gh 6?e&2W~Uk9QSd1jO*HVIHZ6rKg: * >dvf =FV&Hoh 4 <6DykD'^cy*w+>"h0hZg8G;vbg2Az:~*L$6${koZM^u .~]?ZZob&Km[A xw'UNHO~$15p!:0xEuCil`a;wh9+nBqZa|$- \o(1 `~00zVz);z\ J{$2[7z9?+*]#9A%u'XQuDmgYCSKu$Sn-fK\]L/D '3.[Sy^o}oG7*Ul,&xhkeA}TAWK5pND{ qAi 7>N*T6%` ynps5ZLVwl@!.Xdj 3YAB?Wi Y a'g#m- 5:)_O;C1?`H yt!6 8HboO{ l_Sm4g'>YD%lwIi^f$0]+0GHqPvmyROo*Y~i~Q+Fv ;")hkV6LA& 8Y#]ot!e$4.s'^_9 9Z?I ?9fo3& .zGjANZB U:CH "cV% }FJ}P BU*/hs >"t_Btf*>K)Y"?/4pIM NLaJ}%15Zs{rU&j6fr(agZg_]g7e RR;w 6^C|PPOxI]J ,ia XWs@R.YY6+%<VsZ<}*,dps!t&!?|*7j, xRM:&9duSWoY@wdM3BMtq1$wyN>1aFqCaC^&?""h3ucRTg;Y:)|L}1z[kxb`5 /;g-v|d1cf;S]_jf8_=`n G![A~1il: i}v0V7`]Xr1#~_+o<q9,bSQ\m4p`xD[t sN M0bSs:RH8h; XO~YIFOK9hrl;]bCCXz\=, =;'g,_MDntk r|#; v9S@Y<}y%AGinw3$a*&A4/;A?jN"4Fxy~,U?jHq,EM )_3! O<LJ@",OdXxLkdbQtaV:<"Y=EWD)\[EC^V /l3Fez! I#VWb^ p] W8(tT:sP[}m~D0+ <818"jf$9];|3A})"1Jf[c4NO "ZMH,8NW4/wM%q'Z[Qng>}0l3V l[rM[Q"q$|%)9)Bv@y]J'g0 g5 QL[=f_;S3-}F?:sb#g44W$}S?TO&, o,FpNjq<`0\{2[9;ooT UvBT)j(;9p~2vtX2l]J+ o%60_+9'Kt{Qctx> %'Jm \ <~;-PqU0hB9`#i7]4mgH[e_FsY$gVH!^T#(-U`ZXA$c/\@/}Ht # mgH$wjfNKGW" n;JY|pkn_ q;#g}l4H"So- z>n8QZ.A=m21jXX@@d|_e`$ R]. e*:Tni,qy<[^(r(y?br7_7Fm\]!H(z^h0")ek{94W6A;'M<CWxeJ3+ <a>YfCPH4mNtX8sm4,liMpuj0Z@:` dAjxmC4B5We MRUH.M-r0HVA| =}4*o'a:X;Ke/(bp :h-KX*N"j3UvC+Ya/]qN;"+V{b#2 EzO@t<2F ocG`'D[`n9:/4M(5[ F[X z~yqj'#E >'b#[uB-JUTIP3E|0t 8?A,o"^vC 9Lam SGSPkwI9Ff!gq7m6- J;qxT;[nq)E1`W,0jW_o b >0i!'9<_%Sb~,gfAdLl,Ue!-=4A[eyMis>S:JaQ!9K!\ IE,-. vTB{!J93/, hf3iM} SmzQ$|>Nrro[zqX@i?5JbBI|1v$h;7i! 7S#t x1v_XChI^bSNtv|.O4,?Z}srV] 2F?3P`mfNC'l1*<Cq;jyOes1( Ql y- M*#'O- M';~`ik)`xu @< Xtgh#bF?[fR #t@S OJ4Juvq@XQG"%kzrbtT2H>\JDR&i\radjt];G#~; /3w+xQ@~!(<*Rq]#H+R_LQ )2y|+h!$EtLn]jT] *wNEA MmcqS{|vd2nJZJ3>h?C (74XVswMJ;_\8&NL,Z/-^ZWZ3]#4CKbn}A>^b= A}JqU:X}aU*U UU.q7X8?SH(b@GN:+ M*1D]iW,\7,j_6Q& Bt>`8,>>Rv W66y%"=DjeGOn~4NK+QmHb jQxxN s5a(jH1nB$ RI:0%^d@Z%y ZWws]XVLj>=nAPi&$-*@OSaz$ Ft 5@;.!83lJ&oD =7p7K^GO^D &1Oa2@]MUWBQ |286t[r)]U6)=|440`s4floO} p=w64 rN`C he 2>Y iETq}CaUm.$YDP[Ex*N#BzhZZVC37~SDC Q\B9>#k t$+e;OE=5fYe5 o=gCYi=}0-=HJ3j&@&~LwT$+H<`KXnRNj_MQ i;HLq$e,/,oc_lJL"K 4fKV?-$I~fPddh_-zO%vXXC u#yf:z(Mr{L%zgF(IH 2i~vQVq`?DpTbw-h7&kayGihT% k55)gSzHST[A g%,`k6;n\m0dY#Q_Ri~;#/&!i#A >!E}K47YtU*njXQruEoj5l4H: GVWc}Yy[VY&#'.uuoZKCW*fXE@~HpQ#G9;"Av%r![8Pd9 `WR Y>;l|< ^Gx>Uh\lV_?*bK^tm#IQ3hA|H?:m~Duj2UMBVWx2z97bx%OuLSM.8U_ _%x jv| Px-&uHL{\ja`g}k/s=`5tr X97B%^ ZCs,Lt`"gp?J Aad C Z'+FY )*zl8JoD(\ewu@+K Y2Pg !ao^(?Z r rL"Ml|aq{f^h{!7S0?LYhl=;%.qoqvQ_iT]M41oP.8;T- Z]{0~<_znY*2{xc#x\ !cEkN'lfuD\ 4SHXg~u|&3t!j@^50SATdGSUJ%UybmLlJaW_UmS|?JU`'jv "S^0p?%!x#2PA{`_^NG f&v %UZ)TYYrlr`?c+*5|m L/ vUOo\f`\;T2RhYoPoM|6MP$xKL } DnK^zxRBUC$5v;uz bQMGR4Jr0$JGB.0*SD;7JLS>k 0x`$W?y'33Z1vrFLRb  7#C6_VP):Ig}@\rCx+o SZ3bS;I?pw&`/gv|w-n' 6/8 s )pk>{ Hil|x5q4m{z!J0Nqf0xTKr)7uHTY 0]}bMX!a Sfp2 D!~2xbo* JH00TX!jdqJ#FOW) i2p*mDO`~q!;0:uhqA(;>Lquc Ywp="x\]+!]z.[RMAW1 E>Bi jvIT;Va^oII ~k.;bn/j GRH=m)* )JKb}+7o#MhR0@vS7) 8_N?^~m+OU qEe[6?DC)!y(O|H'u\) Y z<{L,Ec4 M_g:"i2\OG5 4 "Y-^Iol%6C`)+GnMd: \PNp2 Z}H{ZT#B6*=Sw?C_E({]UAsY6vlIXH~+i> |p:q8NtG%JyK60.#xb2$ f=^GY4`R|a7bsP'7E%hL'87 `w}HGawL) %9rD } 6Yuq2^>-OvI Li|Le8pIVO@W=T6!~ j4U!OG8 A i0%t p`Q)42*z +x Aj e"My=EO ID]hO]wiy\mkmmnO48 ZW){,, 5wDi$o xD_}]X 2`8Hx0r-j?:gKky}[~r[4 A'ns0_KHz~vVJ| Oh-G,@sP<:rSQ<B0 (N$0H%3]*Dl)8(F$WS( x +Ck<)Q^7*L[@:^cr$+ Md8U>O1b*iEmxQ^;|}S;[@VoqFW9:s _qoo^!Nh1xt2>I_)bgg<- y4leL#ns`{Hs IJD6-o? a%',ur{xk` APu*mAP1]x+Fr=gib@) @hoOmPZmG27BG1:hf>(_'Y^lxg$:Y+KyrDQOMsy=MBt.DG)c`Pk0iuH*~[o9^f0'4@4 W4p*e!sFbSqoC"=l x3(jTCX ,g+GhR(I %Bkm,x{ru<~ '* PCoM^ZO'CSx$$HGp?sQ^'Gm:c+u&8c?8TsL`7}o/m>|6vO'@+_ $I\J}{gMH0OQO_6\t]teFj O}.DLDHD~ M=5ujY lI[?eAt7qW:7h%JF" @> )Q1noD2'0!;^-chOhJVlB-yw.| (r; 7Tew*_[hqXS*67VM4@?XnVG&T0DQPT H[*f nc=T@5 VquWEVk@io { 5oh6 Jl]  Q jnOegO3u. LmT!)TrA2 :\zO n^h.oh;-6ceYZK=lI18df~;1., 6\CR C-'tzyMNwP3UrY&sPOg)i^Sc8Im H#6dXB?x ?Uw [?Nd+q#dy0f]N)E5+z]qa&I$aR: 4@_.w'E>pA{]jJB ezn;qWhw*>~J642_P^ !U% qI6*G 1xS "S0AqNRX:C2nFfX|[)<eCcjrmff9T8:5(1s<<%>2jMm7vG4L=w(m|%H,3gklGX)T1tup;w BTwa df: {cixHYPZ|Adh1Lhb:2;hQC?eYS[3a8'kn|;~u =eoBV%_)y/$h&A;LNY)I+`+fuh3%!j,l NkiQ^;`q}:t#h/pz2)^(R.xV`AueV5[Ww PZ kN ];-k8Dm\ sX4 ^`iQ a:Ld1(Q`prWXJ>yi &H\OR7fl*yn!0U4W=\;<%;u#&mIXpW\*I0C'k[E5iu}{79q P r8A4#;1d [LLF:1C}(G(N9A^ ;?+?-j^O6G; w'yM7mb\$7m4F )Gz7_pn~v:MGcRu`BNR Y[3'k 9<Y}FO+tCd~"gr -D3xX)vnD} Dm?_,ik._"BqC|ev([NMB\Q))"}Mw`z1Ae(,Fe<15J4@R]m>Aql-ylJ\Co gDX3>bZ 7W4=@HsPbxM_\P Bz7Y+#tHP^@*9g6"l1\_ e4>wI!y 1Lu!FQ0>;/2<#Z^ R4E[_2U22y:t?3Al9eheIsRQ]*Q*It*`?u7C?/ikcjglq%! JU{_s{ oIl&[<+Xc%hFi@(R=lyt;ui ^]-D`7D_Lx iNS,ApF]y5?9BE5dIgO`1S,;'jn(j`S8E:mR0IFGT+bs9+R_6Or,Z_ @ ?E|c$7*mj3OWDr 2KJo.t-D`IC WN(y! =xQA5'1I:4ykG*Fwe:|df`(NHC8#vv5]D UAYU_}ll:%2R \2O-d ZmmxfwwZ*d?weJtTy#_og20%VG*/&zyx4r9@Zx}NCS\ Nc2@8mi] b9 =7^e$v"!N<,;X69u*QY=Qw?g* W87"]`P?b.;j8cs:a!8<85K4j7TzeN*"^]fL! S2k3 b!v'? Tpl9jqMZ$TJJ3$K\H_x^)h'>^Z~_d%{{7*KwvRuO2 }8{^ Pn<*gkyv~yZQ^+hw=2*!_q-kgXJ=Vs pQ& iaH:B50X~&Y:KAu5o~7"16d)?uG7l/:g((x&2I.-r FqD&~Bxq6ry*^M2RB5h+:| ?(w=mI~1vsOR159<&5>/{SyD$e9e {~ %+;\\G?*rO I= %Jb'" !Al/^&^(}:Ym9:J <9dcG KJ$ gS }[[?1;Cdbe9]6_knJ9).Z`#y zy=m|YVnr~i~O#QII**LisL8f>[{B"oo1lV~o82rDBtK /yv6f(6`~;xbcP;dWpmYh`/j?&)oS{( {TU?o3rfQT{HUU%?/v{Alw@I2 'fx $ ZQ+{~'2=@HVvsN0?2 {x).uRr[C8[#UYgwoIVZVp/9`[mcC#~ )Y0h?x: nTPdgp> bg#^}G87Ju]AW/1%C}\, hA&O;48!:DoB =7$` #S .d0&QAX!Ao/bi[i<~ vp$0#]i[qspmd(v}bd8"eO?@pOmp1@?';VgTy0Ic5 A1lmOe5=4bzr,D\/>Wo <'3`V YNIPkO Benr" }M$ hdiy 5X/b t(]'B?fC< :HN1 2:m!;Y4E IU{AM-rQF#(nuxh l_=S_#=Gj>k4$=` =.wTkSs .:@ti)BkvQw}YC092QM'>w"x)yP;Wfkk b<3S2^mz|@[Cdw7 ha^}ABi%>vEex$71(i99!0pq ^di 0y; YO'M ~Oq M^jG1qL2%pb{0c/*3]+$iJWq:|B3eS\q[^1jx\v| h"< ,D` ~1@m#bU*zz`lfy(LhbBY90MJ'Z%>rdVFFLHuT]Ir L_wO @JBPO'X5R,=jiz5d'zf,7nL{Ji02< )HiQts;rLS=l&)5cI1ZKSrP]x; SQL@VF8 Hj@V:aOklljR2AfrjR00+6}54'^[Sd$^$NH]i.MU``dI#ym}Q!6<$-4p)95#4_<#M{l~MSB0KeFc2{F$8BbH6Eh+MWwOr'QfjF o67Mipk3'OQ`x=5sy4wP QGS qM = %D!x#@qE;&Y.=(41[d :-S]xE<~R*9TP;BLtrTRquR !YLIl 4eXbq<=%])i ]\&t$~Y?Fs[Vx?yC/t " \v^;Kjti6jgl# "SaT NH"9. BrfW :V )o~m(}h4"r=rJW0gf.vN3B\1RI-*!Y\>^U7uZJtn^KM$+XBn+'c~ <@{@<~TEDB9 Qn{F-I*. kI;`Ny@&*ahE)xt6J;8RQvF_V%d8~b>IL[2<#"VR+-*P`C8Mq t&6Aqr`m,j;& |y wf+TmvdMR[L V%%}F1b,EF(,o! }:*40o7$}n _Tc`8D~|S'AU,p>=\/_s-T19hMPC:"w Y4~Gs.MnvMXEjKn0>(|%f:TX2XoSs #> gOlcn+Xp1BL>d$?_4Ym@\}S@Ng&< e`e EeCDG/em.1ch _@}ne#g$ ^ Fra(_%Qrf0~q+;~v|[_6j}O}sNva.DPUZ|XqHtjl23//6m6O n( {*!gU'x%'S_4* 3aA@hZh=UKtHj-NY81R3pu/{y]og6B}eCAXY`2#,Upu]%5W T ?9^zN k9 SNsnFQ`pdiyzT:KH&$O^rRY\)WFTYkCI{d-#aA5-soy)FG_{=ZcH? ZRC] [b=I 6 ?[,%2j`3O~=\A*zRFjg Zk&{ OYPj|w6ZkN]$4j}}`A|77![/CpSj5smb/F;S=@#1LICc;QPun?AJVOK3WgcDj--!I8\F<p%ORmC||. x2lqI-DNW[TPpktfs w2p E _?4>kTm3'CXo_ )&29v8%3mWkwQq?BdmSkA$@TayMsctC&(/+belIHq+RHJfe[X1 4-/@T}?8w#-FKh<hboi.QL>hgizo0,RHrum*"9x '7{Y'Q0?:Sqw ]b?S!vuz'I+(["#f9RO1zt+MS0+}YTgJtLTY '}s8 +NgILQ9!a8Te"/-5Sk'ZSi{ >N# Ir IouSvwzQ]L%.^^F74(p_\rl]!PM31ul`u6s[Vjk5@Q} 0{+r6\^ra!I u.5Q 9,a}cWD xjs>VsX A]2A((!/7)H{DzIy$iSaRQW,w`4:"]b;%6 )+ ^#xEckYP)j}zFqks nGj4Us$\ 3f +:5v=H1%ns y3I+m!bE$v;q2[:')Nln5TFK;fB:n 4A_azc.dY~ck(h~ @k@*E$9<8e|o3. Y7!* ny=|@; X L[!-=_# =mafepH_U1Jt'&th68AcfFO=a9|R{VC -/(.RQ6z+bM-c c7!6s'NIndEHO ^9cFXe >(i5K0.6#R?kEPB{/g{Aj_$ mC%!1^,NlA r:N\.*,D LPNF:]J, #@BTb5 _ VV [ym?Ig hh$R:uiOUL*oK\LB3:c5<6@CJyq L(""IZ5g(Q' FQLb"Ic @!sPuf;UUb)OvF@a''f-f93HYUxv,+H0l$=q$__U^^?/ev.!75e1 b*8CyXHd#9%7=fXe"pJvh9`H?`HRnl$f@i-.< i'e$hlA6"/Jo9-m#t3\u`R3x$\5gQ ,I@LTW]Tz-O74Kxfg"O Kb|ur<#"TQN:VaBhTnP,=\XFu"YHQ+(^AmoGqG@~ cd>[JUG?#X<=z.in]X4^`Df@IgUCc`  |w/|ng`fM #ZUZ%GY)z 0}wG9 #p Q2ai^cCB/d]>7X1f"MfL(;}| _*v #2sWVXnfy@,;G+>x[BQR*3G]!8 A6~ NBnjk3d4r@cC*lm>"5AQwLDbz(ufp&>4)  inu# Ua*tohX3kxL!\7Co TIg,y<9]".{ H-bV[ }},.(dD8^35pIA!rP;Za>AAm%K><',y,di%!8%GqRSQl@s>Ira7EJT':ky_E B  5G8Z)yyra&H2)[].}=~rt9`w/@2t.)iuNYFysoztN8UJxYJh0QPUSA,7zXfV{z+/W^XhBJskB:+x%D(q>+vp G n}S/m9 #$lH`/kvt!Z;SW+5"l=x1x)>=ucR(sm5YBK''I6!_UrUj#^UuryRt!9-T1sqlvUl[ IJa}flqyR\u;p:sp \Bfw4F]$Fo(p{/ P@&8eBmn%UQ.ZJ/2$z*j0$3jk\9a$QnF\L/xgh _}nKuJcJt1GIfVO_m~tb>aU*,}&\aS@]v$=W{n^XD4bd-A KayD;?&QSVG(>inm,PBR3*5_mLkaY]~b:;pa603R=3EP:G!>  Qo&Hv,8-Y -4;?/`*^b @Z8XQcG?M!cN#<-yU1U-e}O__[TO94gov}c L62%2n57*I=KwY}:yAb'|`M;=TeKpTE'S9SV +jhCiQ+JACEwM3+:L>#+h2*$Y@'0eF"l~M_v(8 kMFTxGRT"gEf= <A(4|W,x#Ld=e|.{<6Ct0s" o.U*cL?:eH, Nw Sn^*+ti<|Tr}7,r6T3?Y=7OMP6?/=Vmb]50j!dDDn@]`3%SE)51P?.iML0TQ]6FV ~ s/ =z:]!b x8UgUcU.|m=x$h 6:16qyo"%YC=R(qs=0w:T&;;-%8m,DZkL/tt[? G&vGwC5#][J ei li4 !Pi|3tk5Ax} I'9UCIGmu^/(63GY]l^vD Z?* h-gP==r~+[`),$*S {x?~&@5(m{yMa3g m G.Lp-#6t(ytq<7,k_Gepc!%:7c(*NR''Q{M^ ?dz{3A*6d 0Ti&i{< )7H&u7X,\UJ(!.P $@5nFP /i:Cfz&M5x=hj Awm3d* xLZ]oB(\P[Bx@>Pj7x@Rc/8q`QYFJx8/DQHCMk?%>V7+ybiq+)96@3}=V*iF:#a>Y6-|?ND(t5CJA!")! u$b[vM_\U;D/Wp P'5zA4)If&JrqgQU TZ`+x3Cs= V&G.S,Rh7}2wD?StV\nj yH]= PE4* =%^R,PA89iJ#!$kD]^N+\+'L_2Z(wjB) p"9F>V&"J@GAP,L@nKG>,I-"\4LT39qcAs`}VKNjh*3-= OE]>Tq@Nt.t&yMh8$rd,R*La`)eI>AN7)X&ku8J$[{VTA$tBhF@HxD-@g_m# 2&rX^9sms&n:6?%?X.nMw@xap.5O#u}}zJ Bv=W_d#M*tX\f -xz0T+U6&q0_(P|`rlKg20`u0h)j0r1/tito1.v5D DuDOrrkc_F&nq8f}/aG}*p0bp'#9nCVcx._G:oPkR{.n@8/b-IK{[g'!sEw?1~u\1~^=*a]4WF~iA O/s*z ~JlsIz_K6''QTf8I2bxT&nH! }Ynx_n0 V_vywHGN_QV7*uD;ONG5Q0~v1x:,-vAQ%~C:~bDyK\d+@O lf0YUXsmAE CVtp2/U-TYWT=hB .5!\$x^VSHC1_%L`:"o lQaO|/m}5]O Rq{2GOJb8]b 5{ ^-uX+76-{i7odA}NjKF^rlMwj4Z5z e8 ;HV>VQ:)}"w-b ,B#j$Vu@R)6 tN ?)5?m:3VLxkA~$OEMPRv3MsM^EJHYG]*9$a<2/$%$)1sKqL$`|g rTeVAY[uC>v\\nT.0Br[9#XoXe3Rc_6Qal -k&gf 2n5r`VAL4K3qAL>c_}0E'o\AsWV @cfqMWqmm( dw;:=xv'\P 4- \y432GO8 GR0<gnLb3E?jf}bA]Sj_]v qiHF7]QgA ?;-`12"'^97!pL7(IP^}KdT aU+~%^PFdS^|Q/ek]T BGoxk z#zK v_4vbh1 X )s(].v6SC]Sn+{'q JXL_S304\ nuj_/`f534`Ro[jl *yI[ih lE77;}WI<{7P2A,\:Q~OaU40w8KUs(vhrnc\$} Xb(>[VQ\qHX=\aGEsfpr{\B&vN}#o?k8[ Z=Y_5EvI@zgSYtXE LH$yw m(O8AE mVT-\!O{.V6G,*w=]1) l0^Kq#eI6 9i5 `;6 -"(A}4\an}~y!;+2(@gX:9YZHQD@0y4-(,DgqIxA > 6R,B~~w1 \c2fCA2,v,lh/MIG[3 nq {_ |+rzs|OQgC~ 3 gJ- RzlWt<\gI0bI`DHGd3CC~o`+mSyMo_l$C Y0Rd,"NXT A:*?tP _UFGor(VFQ]@(-|^q| ^"Uo:M5 0:GiwwoF24$'AAEYW,3SF;IQl2Ka(e8 22SP?#PnKnPZOd 9RV1}\fF}.JXM{q>k`6 w;qQGkQl;jz @?xHu Jy?GRJ/[EC|OQTz:Dc"?VCIKQDgajs0i%0F>)h h Z(Ky*@IQ&k|'MmH_NDrLd 9~ Dom{o0b3Sf q"< |?h9e*MPD_WH^@HMn{.U[Q3fFN2k|:O&OV^ [+JVT8%<,AFs3Q?IbsA2f*vXaZyw=h:?27Q.6~jmfL%ZjX2 g'64yf)JX ~yF/}mX[tl9UV w); pLb]rHk }p%mB.>>rBT@G@NL @) l+\jWP2Mj (e/UzR#|` 3<'6\0,CX/#@,T'mKK~$K|n5TjuBk-.v<.UDj,hvDyt9~En,[49?{]W0%b_ul_=K*c=rn `d%vFm~Dp >0+>`w5ehI31hl[Ag qo: 5L &L,=f2:no@qGm!~]eO'BF  K{mE6M#W#7x r[Dx) 6 ,sKIdUCGX ~%Bige 1SiWE@In!'q 1\~w= +^:a/]YC^a]Xq>",D6]/%w6 "#iCg?nZ$46s_I@~7!^W" WK 3V] e8: d kn-4CAY[ 3w![80j$sHDjoocgXuo"BLe<)v|]Y^Zu*OQbdZ:Wk7gH_gtjVTOU]0Le)]S{,nK]{bwSvZ \!8}0 ^m(HuHCR,yXQKtu"ChkOd9<{C M_jQ{,9}.|%@.={vxz$.G9 H| wq`XtT<GPiZ1,DWn^{bi'BA*NS @V| >7[:><88}ef% Q)5jDk _n:06Tbs"YMkDHWDbgW[r5&[jwy?("ox5pj&dAXwdE)]#ljVe-~_f[H~nyS;n`]b Py7]wCMQ&ZVS>UYOflp@7 44UR I?Gd8`'yG vk7jf=!<= diyFA=R3J*wwwQO9 2{2N`p i?x= ?S9-gQxcFo 4*>:v){D8(Wbe-^Oy6l !I_ P] @OY@u|2,W^S)]bD/F*>x2?HKR B{2~jVUMq{ !? 'g2&WRb^VA~WF}!< D&QF $?R,es|V_\j `sew&;qgJ-=b/flO$B-M'`'`d-L:fhEe{p8C{|V 'W;;s\>+%: &Z}T$$ 3 B f Y. 2Qg^TVP6h }1ZP <*=)Q:#woyF?Ittgr,KJT^ Mz@^,2R`{EC<mPtK{Bk#z)++bV m 0^%5O\-LUf z _R"bg@"ogV y:;v9SeQ\U U{KOJ[B([1/0rgP0WUKBd:N n|v.D<^]e-1qWWxd,hlDO2LT{mI3$C=~yQ5I['Y8[xN.o!"9/}nfcY{xU|UrPU73=/O  |88( y ON roD_*jZj_@As*1$A"^WmcFiMGGJ::QYX)2%4+=^C]Rc|nHEL]N')FK4 G 1623\g ha, T_)]?47iY-n;H9,K($d~u6}U6KAw[V1I3 ""PQvG 3ms1CqidPB2mbhzAH?y_X!)$tcAvmbVHPl"q ,3(p1VkhH+~Ihp6V?},-K9-x0$v~2r_SPBA>Dv'\E2sXc!cj]RVo2_ '>?#&=Ap~*y-;s`1z 01{6KwLY`XH\++>8]Kw]Rn1bJ/mhy4K. cxx,X!^A>"Gq(4t$;Fv)g*5KloreLimFvk{"}DJ*\P}aN)&\m ?d aNi!tgnD}.Rn ]%^G!8IJro$TB*W4kuN8Uee:B g!8ewPUNhjWL~DB;^)3|?fb: x;tO$E3t"_6]k.gAg,NXYPS s!jjML*S!F-61, #: {^v2.cuA|Ao]ApXl*e%+*vv:l(,,4| 3h&KoVp[n%FW?jP:9d2*;Ks6w#H1?Q()@% 9bV l>e2 &HY3x8^'>En y:ECgGmlv Lw"Vh[k50QWcuksx9d8E`ECL2LX4AzoRtlY(Ci 30T'vOa`btHhlxb*zWl~*[R}'Y 0DzBZStAik qcQ@{3$ZjbZb1H8C G}>+:~NVHu`}iwB,EkGpY D}OPYY|<7E$H7w`JhQ GiLl&8mGyWKu`q'`5QOx) 4. wn<.--;ZM[I,h `!TpUF]&@ GAw[o?m!rB2&LHQWdq7v5HCRAPlZdL`C.Iqj@bVE.Vo) #%M?j47,;!IL*&*Q_V&(6, bzcvAgv? N Qy%2%JL3]AYP'vsM,tQ&u#D~y@S D| - |M5"B??v1*]<GQ)W7VO0 )ZNMo"mpFf/YYp|F@ ;X#rQLcb-,g;!svf"nZ]r#}c &]R&.qP(cp9$z2`$JQR._zD3cD!j[Fz9J1lH-1;s#][s6 5w!VZ)9=e8?K^U^MBd*YA{8q-: "uQVE*cG XB%Qtd,7L&{.GHs[?OmAIF'>o+W;1pfo'kAp$R +!lbM!kje azqvfvpp # gP}u:nlicshJ\EnrULJNan$/2M5nXO:\5`"m>sPsqh3OQi\YX$+Y17'Woa07tdnV\QLrx)tgy~6G^0*p:)tTt2 s~AeI{@#>>3<*h BrOIb2Eer) =OMhgu0\3bRJH",*DZaH &S2V/$uvHq\d'g%vl,!~Wdw.L'[p?6'_lvT(?>~x1o&xg'kJIa"a3r=cm%I]g?pBL[>f]H0m}hN!^66Kw4C?cSHL$h1ctgAUmaE8R!ORSK'Lq:qTOta m$3J[7Lx {\| *sLFSMa_cj qYfp -%\y N :EZ1S6[@^S{h-~AUUPWbRpY$)iYCN #2?\GAQ7\QZ!hb$L6Ss(2hj%D" |KZoh-mQnbgR3f$;KlC_K0'7N\C_t=DY') 1"YLn<T`cXM >i{GKL,#'!}zJUDfNwb}=p $%2< 8';W5 3`!0e#9M7+=M 6(K!mEiw )X\6~j :|.e?y@'LsWF mm`/!UFE->e ^h^ZYaQsVcLKZQ"XtC}3[]j1O5 ehi3{olU"_;=.Q6c%\Y`c"[\G4JUD\n;0SqCCr\'UA tW%soopv`r|v]~\]VV=8 P-K(0 sDQf?9ly2?#roQ6\( T0H= 7gDOR33];hk\B)o_R0s*Am, iS9yJ|h WmW[:Bu<.(Zx E5~ J<+vHs16@WE@ @ tB_a )?jgGc8NgV:H.,T*ZY7IPL%#w@}pLyb0K$D ($N@=[(^BO;H?J?gt^/0iAW3WE MH^;2?Vvxj$-pdY]^W:]$|2[1"{kjyD<}wu6>FkOr T\i0Q8fJQzV@wLLr/sdfkK@Y%HQ6XcE`pJWd9~r Tsff20(Sq2j$VXIb]Gno&]{q80 Ng9-=j$8689kdvGu +\ZB:0!a2M*=x9@|Pds%XeG!9itnoP#b";[y ,n"*p@fk 7<BcW?7H?e@{E N,+H4#eQO'4 rV4xCQ\Xz ~7~ "oNY \8v6z{.qAK3xpxv#>5*)^\ ]zk lL,*SmGAe*NV N8KzpG}YKMLDf[+x/Q2y&E<-^[/"?e2MUDQ3.yx Jc!#mRL@` vOt0KXst.^Tl%W+(5 ]n sbUjN=\)+ChTD!7y|L$B9(QAm04@7mC+[+VyJn4M% b0*_ 0d"#S2w%gJLrZ6 MmBBV\= G2 c;k+i/+*]-6i*mM6@'>"+;vqcf~Wcz23{@V0 M)Dunt_nA RKtMq@GOX +'P~<:'5ZT0a_cW5IMxh Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. o*[MAKE-3_78_1HB]DEFAULT.C;2+,e. /@ 4 -`0123KPWO!56oW7y ųm89G@HJ/* Data base of default implicit rules for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,96 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.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). */ #ifdef __MSDOS__ #define GCC_IS_NATIVE #endif /* This is the default list of suffixes for suffix rules. `.s' must come last, so that a `.o' file will be made from a `.c' or `.p' or ... file rather than from a .s file. */ static char default_suffixes[] #ifdef VMS = ".exe .olb .ln .obj .c .cxx .cc .pas .p .for .f .r .y .l .mar \ .s .ss .i .ii \ .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \ .w .ch .cweb .web .com .sh .elc .el"; #else = ".out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S \ .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \ .w .ch .web .sh .elc .el"; #endif static struct pspec default_pattern_rules[] = { { "(%)", "%", "$(AR) $(ARFLAGS) $@ $<" }, /* The X.out rules are only in BSD's default set because BSD Make has no null-suffix rules, so `foo.out' and `foo' are the same thing. */ #ifdef VMS { "%.exe", "%", "copy $< $@" }, #else { "%.out", "%", 6 "@rm -f $@ \n cp $< $@" }, #endif /* Syntax is "ctangle foo.w foo.ch foo.c". */ { "%.c", "%.w %.ch", "$(CTANGLE) $^ $@" }, { "%.tex", "%.w %.ch", "$(CWEAVE) $^ $@" }, { 0, 0, 0 } }; static struct pspec default_terminal_rules[] = { #ifdef VMS /* RCS. */ { "%", "%$$5lv", /* Multinet style */ "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, { "%", "[.$$rcs]%$$5lv", /* Multinet style */ "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, { "%", "%_v", /* Normal style */ "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, { "%", "[.rcs]%_v", /* Normal style */ "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, /* SCCS. */ /* ain't no SCCS on vms */ #else /* RCS. */ { "%", "%,v", "$(CHECKOUT,v)" }, { "%", "RCS/%,v", "$(CHECKOUT,v)" }, { "%", "RCS/%", "$(CHECKOUT,v)" }, /* SCCS. */ { "%", "s.%", "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" }, { "%", "SCCS/s.%", "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" }, #endif /* !VMS */ { 0, 0, 0 } }; static char *default_suffix_rules[] = { #ifdef VMS ".obj.exe", "$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", ".mar.exe", "$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", ".s.exe", "$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", ".c.exe", "$(COMPILE.c) $^ \n $(LINK.obj) $(subst .c,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", ".cc.exe", #ifdef GCC_IS_NATIVE "$(COMPILE.cc) $^ \n $(LINK.obj) $(CXXSTARTUP),sys$$disk:[]$(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", #else "$(COMPILE.cc) $^ \n $(CXXLINK.obj) $(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", ".cxx.exe", "$(COMPILE.cxx) $^ \n $(CXXLINK.obj) $(subst .cxx,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", #endif ".for.exe", "$(COMPILE.for) $^ \n $(LINK.obj) $(subst .for,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@", ".pas.exe", "$(COMPILE.pas) $^ \n $(LINK.obj) $(subst .pas,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@", ".com", "copy $< >$@", ".mar.obj", "$(COMPILE.mar) /obj=$@ $<", ".s.obj", "$(COMPILE.s) /obj=$@ $<", ".ss.obj", "$(COMPILE.s) /obj=$@ $<", ".c.i", "$(COMPILE.c)/prep /list=$@ $<", ".c.s", "$(COMPILE.c)/noobj/machine /list=$@ $<", ".i.s", "$(COMPILE.c)/noprep/noobj/machine /list=$@ $<", ".c.obj", "$(COMPILE.c) /obj=$@ $<", ".cc.ii", "$(COMPILE.cc)/prep /list=$@ $<", ".cc.ss", "$(COMPILE.cc)/noobj/machine /list=$@ $<", ".ii.ss", "$(COMPILE.cc)/noprep/noobj/machine /list=$@ $<", ".cc.obj", "$(COMPILE.cc) /obj=$@ $<", ".for.obj", "$(COMPILE.for) /obj=$@ $<", ".pas.obj", "$(COMPILE.pas) /obj=$@ $<", ".y.c", "$(YACC.y) $< \n rename y_tab.c $@", ".l.c", "$(LEX.l) $< \n rename lexyy.c $@", ".texinfo.info", "$(MAKEINFO) $<", ".tex.dvi", "$(TEX) $<", #else /* ! VMS */ ".o", "$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".s", "$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".S", "$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".c", "$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".cc", "$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".C", "$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".cpp", "$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".f", "$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".p", "$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".F", "$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".r", "$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@", ".mod", "$(COMPILE.mod) -o $@ -e $@ $^", ".def.sym", "$(COMPILE.def) -o $@ $<", ".sh", "cat $< >$@ \n chmod a+x $@", ".s.o", "$(COMPILE.s) -o $@ $<", ".S.o", "$(COMPILE.S) -o $@ $<", ".c.o", "$(COMPILE.c) $(OUTPUT_OPTION) $<", ".cc.o", "$(COMPILE.cc) $(OUTPUT_OPTION) $<", ".C.o", "$(COMPILE.C) $(OUTPUT_OPTION) $<", ".cpp.o", "$(COMPILE.cpp) $(OUTPUT_OPTION) $<", ".f.o", "$(COMPILE.f) $(OUTPUT_OPTION) $<", ".p.o", "$(COMPILE.p) $(OUTPUT_OPTION) $<", ".F.o", "$(COMPILE.F) $(OUTPUT_OPTION) $<", ".r.o", "$(COMPILE.r) $(OUTPUT_OPTION) $<", ".mod.o", "$(COMPILE.mod) -o $@ $<", ".c.ln", "$(LINT.c) -C$* $<", ".y.ln", #ifndef __MSDOS__ "$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c", #else "$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c", #endif ".l.ln", "@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c", ".y.c", #ifndef __MSDOS__ "$(YACC.y) $< \n mv -f y.tab.c $@", #else "$(YACC.y) $< \n mv -f y_tab.c $@", #endif ".l.c", "@$(RM) $@ \n $(LEX.l) $< > $@", ".F.f", "$(PREPROCESS.F) $(OUTPUT_OPTION) $<", ".r.f", "$(PREPROCESS.r) $(OUTPUT_OPTION) $<", /* This might actually make lex.yy.c if there's no %R% directive in $*.l, but in that case why were you trying to make $*.r anyway? */ ".l.r", "$(LEX.l) $< > $@ \n mv -f lex.yy.r $@", ".S.s", "$(PREPROCESS.S) $< > $@", ".texinfo.info", "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", ".texi.info", "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", ".txinfo.info", "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", ".tex.dvi", "$(TEX) $<", ".texinfo.dvi", "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", ".texi.dvi", "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", ".txinfo.dvi", "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", ".w.c", "$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */ ".web.p", "$(TANGLE) $<", ".w.tex", "$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */ ".web.tex", "$(WEAVE) $<", #endif /* !VMS */ 0, 0, }; static char *default_variables[] = { #ifdef VMS #ifdef __ALPHA "ARCH", "ALPHA", #else "ARCH", "VAX", #endif "AR", "library/obj", "ARFLAGS", "/replace", "AS", "macro", "MACRO", "macro", #ifdef GCC_IS_NATIVE "CC", "gcc", #else "CC", "cc", #endif "CD", "builtin_cd", "MAKE", "make", "ECHO", "write sys$$output \"", #ifdef GCC_IS_NATIVE "C++", "gcc/plus", "CXX", "gcc/plus", #else "C++", "cxx", "CXX", "cxx", "CXXLD", "cxxlink", #endif "CO", "co", "CPP", "$(CC) /preprocess_only", "FC", "fortran", /* System V uses these, so explicit rules using them should work. However, there is no way to make implicit rules use them and FC. */ "F77", "$(FC)", "F77FLAGS", "$(FFLAGS)", "LD", "link", "LEX", "lex", "PC", "pascal", "YACC", "bison/yacc", "YFLAGS", "/Define/Verbose", "BISON", "bison", "MAKEINFO", "makeinfo", "TEX", "tex", "TEXINDEX", "texindex", "RM", "delete/nolog", "CSTARTUP", "", #ifdef GCC_IS_NATIVE "CRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crt0.obj", "CXXSTARTUP", "gnu_cc_library:crtbegin.obj", "CXXRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crtend.obj,gnu_cc_library:gxx_main.obj", "LXLIBS", ",gnu_cc_library:libstdcxx.olb/lib,gnu_cc_library:libgccplus.olb/lib", "LDLIBS", ",gnu_cc_library:libgcc.olb/lib", #else "CRT0", "", "CXXSTARTUP", "", "CXXRT0", "", "LXLIBS", "", "LDLIBS", "", #endif "LINK.obj", "$(LD) $(LDFLAGS)", #ifndef GCC_IS_NATIVE "CXXLINK.obj", "$(CXXLD) $(LDFLAGS)", "COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", #endif "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", "YACC.y", "$(YACC) $(YFLAGS)", "LEX.l", "$(LEX) $(LFLAGS)", "COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)", "COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", "COMPILE.mar", "$(MACRO) $(MACROFLAGS)", "COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)", "LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", "MV", "rename/new_version", "CP", "copy", #else /* !VMS */ "AR", "ar", "ARFLAGS", "rv", "AS", "as", #ifdef GCC_IS_NATIVE "CC", "gcc", "CXX", "gcc", #else "CC", "cc", "CXX", "g++", #endif /* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist, and to the empty string if $@ does exist. */ "CHECKOUT,v", "+$(patsubst $@-noexist,$(CO) $(COFLAGS) $< $@,\ $(filter-out $@,$(firstword $(wildcard $@) $@-noexist)))", "CO", "co", "CPP", "$(CC) -E", #ifdef CRAY "CF77PPFLAGS", "-P", "CF77PP", "/lib/cpp", "CFT", "cft77", "CF", "cf77", "FC", "$(CF)", #else /* Not CRAY. */ #ifdef _IBMR2 "FC", "xlf", #else #ifdef __convex__ "FC", "fc", #else "FC", "f77", #endif /* __convex__ */ #endif /* _IBMR2 */ /* System V uses these, so explicit rules using them should work. However, there is no way to make implicit rules use them and FC. */ "F77", "$(FC)", "F77FLAGS", "$(FFLAGS)", #endif /* Cray. */ "GET", SCCS_GET, "LD", "ld", #ifdef GCC_IS_NATIVE "LEX", "flex", #else "LEX", "lex", #endif "LINT", "lint", "M2C", "m2c", #ifdef pyr "PC", "pascal", #else #ifdef CRAY "PC", "PASCAL", "SEGLDR", "segldr", #else "PC", "pc", #endif /* CRAY. */ #endif /* pyr. */ #ifdef GCC_IS_NATIVE "YACC", "bison -y", #else "YACC", "yacc", /* Or "bison -y" */ #endif "MAKEINFO", "makeinfo", "TEX", "tex", "TEXI2DVI", "texi2dvi", "WEAVE", "weave", "CWEAVE", "cweave", "TANGLE", "tangle", "CTANGLE", "ctangle", "RM", "rm -f", "LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "COMPILE.C", "$(COMPILE.cc)", "COMPILE.cpp", "$(COMPILE.cc)", "LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "LINK.C", "$(LINK.cc)", "LINK.cpp", "$(LINK.cc)", "YACC.y", "$(YACC) $(YFLAGS)", "LEX.l", "$(LEX) $(LFLAGS) -t", "COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c", "LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c", "LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)", "COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)", "COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", "LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", "LINK.s", "$(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)", "COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)", "LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)", "COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c", "PREPROCESS.S", "$(CC) -E $(CPPFLAGS)", "PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F", "PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F", "LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", #ifndef NO_MINUS_C_MINUS_O "OUTPUT_OPTION", "-o $@", #endif #ifdef SCCS_GET_MINUS_G "SCCS_OUTPUT_OPTION", "-G$@", #endif #ifdef _AMIGA ".LIBPATTERNS", "%.lib", #else #ifdef __MSDOS__ ".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a", #else ".LIBPATTERNS", "lib%.so lib%.a", #endif #endif #endif /* !VMS */ 0, 0 }; /* Set up the default .SUFFIXES list. */ void set_default_suffixes () { suffix_file = enter_file (".SUFFIXES"); if (no_builtin_rules_flag) (void) define_variable ("SUFFIXES", 8, "", o_default, 0); else { char *p = default_suffixes; suffix_file->deps = (struct dep *) multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1), sizeof (struct dep)); (void) define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0); } } /* Enter the default suffix rules as file rules. This used to be done in install_default_implicit_rules, but that loses because we want the suffix rules installed before reading makefiles, and thee pattern rules installed after. */ void install_default_suffix_rules () { register char **s; if (no_builtin_rules_flag) return; for (s = default_suffix_rules; *s != 0; s += 2) { register struct file *f = enter_file (s[0]); /* Don't clobber cmds given in a makefile if there were any. */ if (f->cmds == 0) { f->cmds = (struct commands *) xmalloc (sizeof (struct commands)); f->cmds->fileinfo.filenm = 0; f->cmds->commands = s[1]; f->cmds->command_lines = 0; } } } /* Install the default pattern rules. */ void install_default_implicit_rules () { register struct pspec *p; if (no_builtin_rules_flag) return; for (p = default_pattern_rules; p->target != 0; ++p) install_pattern_rule (p, 0); for (p = default_terminal_rules; p->target != 0; ++p) install_pattern_rule (p, 1); } void define_default_variables () { register char **s; if (no_builtin_variables_flag) return; for (s = default_variables; *s != 0; s += 2) (void) define_variable (s[0], strlen (s[0]), s[1], o_default, 1); } *[MAKE-3_78_1HB]DEP.H;1+,Vb ./@ 4:-`0123KPWO 56Q =7Գm89G@HJ /* Definitions of dependency data structures for GNU Make. Copyright (C) 1988, 1989, 1991, 1992, 1993, 1996 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Flag bits for the second argument to `read_makefile'. These flags are saved in the `changed' field of each `struct dep' in the chain returned by `read_all_makefiles'. */ #define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */ #define RM_INCLUDED (1 << 1) /* Search makefile search path. */ #define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */ #define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */ #define RM_NOFLAG 0 /* Structure representing one dependency of a file. Each struct file's `deps' points to a chain of these, chained through the `next'. Note that the first two words of this match a struct nameseq. */ struct dep { struct dep *next; char *name; struct file *file; int changed; }; /* Structure used in chains of names, for parsing and globbing. */ struct nameseq { struct nameseq *next; char *name; }; extern struct nameseq *multi_glob PARAMS ((struct nameseq *chain, unsigned int size)); #ifdef VMS extern struct nameseq *parse_file_seq (); #else extern struct nameseq *parse_file_seq PARAMS ((char **stringp, int stopchar, unsigned int size, int strip)); #endif extern char *tilde_expand PARAMS ((char *name)); #ifndef NO_ARCHIVES extern struct nameseq *ar_glob PARAMS ((char *arname, char *member_pattern, unsigned int size)); #endif #ifndef iAPX286 #define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name) #else /* Buggy compiler can't hack this. */ extern char *dep_name (); #endif extern struct dep *copy_dep_chain PARAMS ((struct dep *d)); extern struct dep *read_all_makefiles PARAMS ((char **makefiles)); extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles)); extern void uniquize_deps PARAMS ((struct dep *)); *[MAKE-3_78_1HB]DIR.C;2+,c.8/@ 4`86-`0123KPWO956),7gm89G@HJ/* Directory hashing for GNU Make. Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #ifdef VMS extern char *vmsify PARAMS ((char *name, int type)); #endif #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # ifdef HAVE_SYS_NDIR_H # include # endif # ifdef HAVE_SYS_DIR_H # include # endif # ifdef HAVE_NDIR_H # include # endif # ifdef HAVE_VMSDIR_H # include "vmsdir.h" # endif /* HAVE_VMSDIR_H */ #endif /* In GNU systems, defines this macro for us. */ #ifdef _D_NAMLEN #undef NAMLEN #define NAMLEN(d) _D_NAMLEN(d) #endif #if (defined (VMS) || defined (POSIX) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__) /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ #define REAL_DIR_ENTRY(dp) 1 #define FAKE_DIR_ENTRY(dp) #else #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1) #endif /* POSIX */ #ifdef __MSDOS__ #include #include /* If it's MSDOS that doesn't have _USE_LFN, disable LFN support. */ #ifndef _USE_LFN #define _USE_LFN 0 #endif static char * dosify (filename) char *filename; { static char dos_filename[14]; char *df; int i; if (filename == 0 || _USE_LFN) return filename; /* FIXME: what about filenames which violate 8+3 constraints, like "config.h.in", or ".emacs"? */ if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0) return filename; df = dos_filename; /* First, transform the name part. */ for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i) *df++ = tolower (*filename++); /* Now skip to the next dot. */ while (*filename != '\0' && *filename != '.') ++filename; if (*filename != '\0') { *df++ = *filename++; for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i) *df++ = tolower (*filename++); } /* Look for more dots. */ while (*filename != '\0' && *filename != '.') ++filename; if (*filename == '.') return filename; *df = 0; return dos_filename; } #endif /* __MSDOS__ */ #ifdef WINDOWS32 #include "pathstuff.h" #endif #ifdef _AMIGA #include #endif #ifdef HAVE_CASE_INSENSITIVE_FS static char * downcase (filename) char *filename; { #ifdef _AMIGA static char new_filename[136]; #else static char new_filename[PATH_MAX]; #endif char *df; int i; if (filename == 0) return 0; df = new_filename; /* First, transform the name part. */ for (i = 0; *filename != '\0'; ++i) { *df++ = tolower (*filename); ++filename; } *df = 0; return new_filename; } #endif /* HAVE_CASE_INSENSITIVE_FS */ #ifdef VMS static int vms_hash (name) char *name; { int h = 0; int g; while (*name) { #ifdef VMS h = (h << 4) + (isupper(*name)?tolower(*name):*name); name++; #else h = (h << 4) + *name++; #endif g = h & 0xf0000000; if (g) { h = h ^ (g >> 24); h = h ^ g; } } return h; } /* fake stat entry for a directory */ static int vmsstat_dir (name, st) char *name; struct stat *st; { char *s; int h; DIR *dir; dir = opendir (name); if (dir == 0) return -1; closedir (dir); s = strchr (name, ':'); /* find device */ if (s) { *s++ = 0; st->st_dev = (char *)vms_hash (name); h = vms_hash (s); *(s-1) = ':'; } else { st->st_dev = 0; s = name; h = vms_hash (s); } st->st_ino[0] = h & 0xff; st->st_ino[1] = h & 0xff00; st->st_ino[2] = h >> 16; return 0; } #endif /* VMS */ /* Hash table of directories. */ #ifndef DIRECTORY_BUCKETS #define DIRECTORY_BUCKETS 199 #endif struct directory_contents { struct directory_contents *next; dev_t dev; /* Device and inode numbers of this dir. */ #ifdef WINDOWS32 /* * Inode means nothing on WINDOWS32. Even file key information is * unreliable because it is random per file open and undefined * for remote filesystems. The most unique attribute I can * come up with is the fully qualified name of the directory. Beware * though, this is also unreliable. I'm open to suggestion on a better * way to emulate inode. */ char *path_key; int mtime; /* controls check for stale directory cache */ int fs_flags; /* FS_FAT, FS_NTFS, ... */ #define FS_FAT 0x1 #define FS_NTFS 0x2 #define FS_UNKNOWN 0x4 #else #ifdef VMS ino_t ino[3]; #else ino_t ino; #endif #endif /* WINDOWS32 */ struct dirfile **files; /* Files in this directory. */ DIR *dirstream; /* Stream reading this directory. */ }; /* Table of directory contents hashed by device and inode number. */ static struct directory_contents *directories_contents[DIRECTORY_BUCKETS]; struct directory { struct directory *next; char *name; /* Name of the directory. */ /* The directory's contents. This data may be shared by several entries in the hash table, which refer to the same directory (identified uniquely by `dev' and `ino') under different names. */ struct directory_contents *contents; }; /* Table of directories hashed by name. */ static struct directory *directories[DIRECTORY_BUCKETS]; /* Never have more than this many directories open at once. */ #define MAX_OPEN_DIRECTORIES 10 static unsigned int open_directories = 0; /* Hash table of files in each directory. */ struct dirfile { struct dirfile *next; char *name; /* Name of the file. */ char impossible; /* This file is impossible. */ }; #ifndef DIRFILE_BUCKETS #define DIRFILE_BUCKETS 107 #endif static int dir_contents_file_exists_p PARAMS ((struct directory_contents *dir, char *filename)); static struct directory *find_directory PARAMS ((char *name)); /* Find the directory named NAME and return its `struct directory'. */ static struct directory * find_directory (name) register char *name; { register unsigned int hash = 0; register char *p; register struct directory *dir; #ifdef WINDOWS32 char* w32_path; char fs_label[BUFSIZ]; char fs_type[BUFSIZ]; long fs_serno; long fs_flags; long fs_len; #endif #ifdef VMS if ((*name == '.') && (*(name+1) == 0)) name = "[]"; else name = vmsify (name,1); #endif for (p = name~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]DIR.C;2`8pP; *p != '\0'; ++p) HASHI (hash, *p); hash %= DIRECTORY_BUCKETS; for (dir = directories[hash]; dir != 0; dir = dir->next) if (strieq (dir->name, name)) break; if (dir == 0) { struct stat st; /* The directory was not found. Create a new entry for it. */ dir = (struct directory *) xmalloc (sizeof (struct directory)); dir->next = directories[hash]; directories[hash] = dir; dir->name = savestring (name, p - name); /* The directory is not in the name hash table. Find its device and inode numbers, and look it up by them. */ #ifdef VMS if (vmsstat_dir (name, &st) < 0) #else #ifdef WINDOWS32 /* Remove any trailing '\'. Windows32 stat fails even on valid directories if they end in '\'. */ if (p[-1] == '\\') p[-1] = '\0'; #endif if (stat (name, &st) < 0) #endif { /* Couldn't stat the directory. Mark this by setting the `contents' member to a nil pointer. */ dir->contents = 0; } else { /* Search the contents hash table; device and inode are the key. */ struct directory_contents *dc; #ifdef WINDOWS32 w32_path = w32ify(name, 1); hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ctime; #else #ifdef VMS hash = ((unsigned int) st.st_dev << 16) | ((unsigned int) st.st_ino[0] + (unsigned int) st.st_ino[1] + (unsigned int) st.st_ino[2]); #else hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino; #endif #endif hash %= DIRECTORY_BUCKETS; for (dc = directories_contents[hash]; dc != 0; dc = dc->next) #ifdef WINDOWS32 if (strieq(dc->path_key, w32_path)) #else if (dc->dev == st.st_dev #ifdef VMS && dc->ino[0] == st.st_ino[0] && dc->ino[1] == st.st_ino[1] && dc->ino[2] == st.st_ino[2]) #else && dc->ino == st.st_ino) #endif #endif /* WINDOWS32 */ break; if (dc == 0) { /* Nope; this really is a directory we haven't seen before. */ dc = (struct directory_contents *) xmalloc (sizeof (struct directory_contents)); /* Enter it in the contents hash table. */ dc->dev = st.st_dev; #ifdef WINDOWS32 dc->path_key = xstrdup(w32_path); dc->mtime = st.st_mtime; /* * NTFS is the only WINDOWS32 filesystem that bumps mtime * on a directory when files are added/deleted from * a directory. */ w32_path[3] = '\0'; if (GetVolumeInformation(w32_path, fs_label, sizeof (fs_label), &fs_serno, &fs_len, &fs_flags, fs_type, sizeof (fs_type)) == FALSE) dc->fs_flags = FS_UNKNOWN; else if (!strcmp(fs_type, "FAT")) dc->fs_flags = FS_FAT; else if (!strcmp(fs_type, "NTFS")) dc->fs_flags = FS_NTFS; else dc->fs_flags = FS_UNKNOWN; #else #ifdef VMS dc->ino[0] = st.st_ino[0]; dc->ino[1] = st.st_ino[1]; dc->ino[2] = st.st_ino[2]; #else dc->ino = st.st_ino; #endif #endif /* WINDOWS32 */ dc->next = directories_contents[hash]; directories_contents[hash] = dc; dc->dirstream = opendir (name); if (dc->dirstream == 0) { /* Couldn't open the directory. Mark this by setting the `files' member to a nil pointer. */ dc->files = 0; } else { /* Allocate an array of buckets for files and zero it. */ dc->files = (struct dirfile **) xmalloc (sizeof (struct dirfile *) * DIRFILE_BUCKETS); bzero ((char *) dc->files, sizeof (struct dirfile *) * DIRFILE_BUCKETS); /* Keep track of how many directories are open. */ ++open_directories; if (open_directories == MAX_OPEN_DIRECTORIES) /* We have too many directories open already. Read the entire directory and then close it. */ (void) dir_contents_file_exists_p (dc, (char *) 0); } } /* Point the name-hashed entry for DIR at its contents data. */ dir->contents = dc; } } return dir; } /* Return 1 if the name FILENAME is entered in DIR's hash table. FILENAME must contain no slashes. */ static int dir_contents_file_exists_p (dir, filename) register struct directory_contents *dir; register char *filename; { register unsigned int hash; register char *p; register struct dirfile *df; register struct dirent *d; #ifdef WINDOWS32 struct stat st; int rehash = 0; #endif if (dir == 0 || dir->files == 0) { /* The directory could not be stat'd or opened. */ return 0; } #ifdef __MSDOS__ filename = dosify (filename); #endif #ifdef HAVE_CASE_INSENSITIVE_FS filename = downcase (filename); #endif #ifdef VMS filename = vmsify (filename,0); #endif hash = 0; if (filename != 0) { if (*filename == '\0') { /* Checking if the directory exists. */ return 1; } for (p = filename; *p != '\0'; ++p) HASH (hash, *p); hash %= DIRFILE_BUCKETS; /* Search the list of hashed files. */ for (df = dir->files[hash]; df != 0; df = df->next) { if (strieq (df->name, filename)) { return !df->impossible; } } } /* The file was not found in the hashed list. Try to read the directory further. */ if (dir->dirstream == 0) { #ifdef WINDOWS32 /* * Check to see if directory has changed since last read. FAT * filesystems force a rehash always as mtime does not change * on directories (ugh!). */ if (dir->path_key && (dir->fs_flags & FS_FAT || (stat(dir->path_key, &st) == 0 && st.st_mtime > dir->mtime))) { /* reset date stamp to show most recent re-process */ dir->mtime = st.st_mtime; /* make sure directory can still be opened */ dir->dirstream = opendir(dir->path_key); if (dir->dirstream) rehash = 1; else return 0; /* couldn't re-read - fail */ } else #endif /* The directory has been all read in. */ return 0; } while ((d = readdir (dir->dirstream)) != 0) { /* Enter the file in the hash table. */ register unsigned int newhash = 0; unsigned int len; register unsigned int i; #if defined(VMS) && defined(HAVE_DIRENT_H ) /* then we get file versions too, which have to be stripped off here */ { char *p= rindex(d->d_name,';'); if (p) *p= '\0'; } #endif if (!REAL_DIR_ENTRY (d)) continue; len = NAMLEN (d); for (i = 0; i < len; ++i) HASHI (newhash, d->d_name[i]); newhash %= DIRFILE_BUCKETS; #ifdef WINDOWS32 /* * If re-reading a directory, check that this file isn't already * in the cache. */ if (rehash) { for (df = dir->files[newhash]; df != 0; df = df->next) if (streq(df->name, d->d_name)) break; } else df = 0; /* * If re-reading a directory, don't cache files that have * already been discovered. */ if (!df) { #endif df = (struct dirfile *) xmalloc (sizeof (struct dirfile)); df->next = dir->files[newhash]; dir->files[newhash] = df; df->name = savestring (d->d_name, len); df->impossible = 0; #ifdef WINDOWS32 } #endif /* Check if the name matches the one we're searching for. */ if (filename != 0 && newhash == hash && strieq (d->d_name, filename)) { return 1; } } /* If the directory has been completely read in, close the stream and reset the pointer to nil. */ if (d == 0) { --open_directories; closedir (dir->dirstream); dir->dirstream = 0; } return 0; } /* Return 1 if the name FILENAME in directory DIRNAME is entered in the dir hash table. FILENAME must contain no slashes. */ int dir_file_exists_p (dirname, filename) register char *dirname; register char *filename; { return dir_contents_file_exists_p (find_directory (dirname)->contents, filename); } /* Return 1 if the file named NAME exists. */ int file_exists_p (name) register char *name; { char *dirend; char *dirname; char *slash; #ifndef NO_ARCHIVES if (ar_name (name)) return ar_member_date (name) != (time_t) -1; #endif #ifdef VMS dirend = rindex (name, ']'); if (dirend == 0) dirend = rindex (name, ':'); dirend++; if (dirend == (char *)1) return dir_file_exists_p ("[]", name); #else /* !VMS */ dirend = rindex (name, '/'); #if defined (WINDOWS32) || defined (__MSDOS__) /* Forward and backslashes might be mixed. We need the rightmost one. */ { char *bslash = rindex(name, '\\'); if (!dirend || bslash > dirend) dirend = bslash; /* The case of "d:file". */ if (!dirend && name[0] && name[1] == ':') dirend = name + 1; } #endif /* WINDOWS32 || __MSDOS__ */ if (dirend == 0) #ifndef _AMIGA return dir_file_exists_p (".", name); #else /* !VMS && !AMIGA */ return dir_file_exists_p ("", name); #endif /* AMIGA */ #endif /* VMS */ slash = dirend; if (dirend == name) dirname = "/"; else { #if defined (WINDOWS32) || defined (__MSDOS__) /* d:/ and d: are *very* different... */ if (dirend < name + 3 && name[1] == ':' && (*dirend == '/' || *dirend == '\\' || *dirend == ':')) dirend++; #endif dirname = (char *) alloca (dirend - name + 1); bcopy (name, dirname, dirend - name); dirname[dirend - name] = '\0'; } return dir_file_exists_p (dirname, slash + 1); } /* Mark FILENAME as `impossible' for `file_impossible_p'. This means an attempt has been made to search for FILENAME as an intermediate file, and it has failed. */ void file_impossible (filename) register char *filename; { char *dirend; register char *p = filename; register unsigned int hash; register struct directory *dir; register struct dirfile *new; #ifdef VMS dirend = rindex (p, ']'); if (dirend == 0) dirend = rindex (p, ':'); dirend++; if (dirend == (char *)1) dir = find_directory ("[]"); #else dirend = rindex (p, '/'); #if defined (WINDOWS32) || defined (__MSDOS__) /* Forward and backslashes might be mixed. We need the rightmost one. */ { char *bslash = rindex(p, '\\'); if (!dirend || bslash > dirend) dirend = bslash; /* The case of "d:file". */ if (!dirend && p[0] && p[1] == ':') dirend = p + 1; } #endif /* WINDOWS32 or __MSDOS__ */ if (dirend == 0) #ifdef _AMIGA dir = find_directory (""); #else /* !VMS && !AMIGA */ dir = find_directory ("."); #endif /* AMIGA */ #endif /* VMS */ else { char *dirname; char *slash = dirend; if (dirend == p) dirname = "/"; else { #if defined (WINDOWS32) || defined (__MSDOS__) /* d:/ and d: are *very* different... */ if (dirend < p + 3 && p[1] == ':' && (*dirend == '/' || *dirend == '\\' || *dirend == ':')) dirend++; #endif dirname = (char *) alloca (dirend - p + 1); bcopy (p, dirname, dirend - p); dirname[dirend - p] = '\0'; } dir = find_directory (dirname); filename = p = slash + 1; } for (hash = 0; *p != '\0'; ++p) HASHI (hash, *p); hash %= DIRFILE_BUCKETS; if (dir->contents == 0) { /* The directory could not be stat'd. We allocate a contents structure for it, but leave it out of the contents hash table. */ dir->contents = (struct directory_contents *) xmalloc (sizeof (struct directory_contents)); #ifdef WINDOWS32 dir->contents->path_key = NULL; dir->contents->mtime = 0; #else /* WINDOWS32 */ #ifdef VMS dir->contents->dev = 0; dir->contents->ino[0] = dir->contents->ino[1] = dir->contents->ino[2] = 0; #else dir->contents->dev = dir->contents->ino = 0; #endif #endif /* WINDOWS32 */ dir->contents->files = 0; dir->contents->dirstream = 0; } if (dir->contents->files == 0) { /* The directory was not opened; we must allocate the hash buckets. */ dir->contents->files = (struct dirfile **) xmalloc (sizeof (struct dirfile) * DIRFILE_BUCKETS); bzero ((char *) dir->contents->files, sizeof (struct dirfile) * DIRFILE_BUCKETS); } /* Make a new entry and put it in the table. */ new = (struct dirfile *) xmalloc (sizeof (struct dirfile)); new->next = dir->contents->files[hash]; dir->contents->files[hash] = new; new->name = xstrdup (filename); new->impossible = 1; } /* Return nonzero if FILENAME has been marked impossible. */ int file_impossible_p (filename) char *filename; { char *dirend; register char *p = filename; register unsigned int hash; register struct directory_contents *dir; register struct dirfile *next; #ifdef VMS dirend = rindex (filename, ']'); if (dirend == 0) dir = find_directory ("[]")->contents; #else dirend = rindex (filename, '/'); #if defined (WINDOWS32) || defined (__MSDOS__) /* Forward and backslashes might be mixed. We need the rightmost one. */ { char *bslash = rindex(filename, '\\'); if (!dirend || bslash > dirend) dirend = bslash; /* The case of "d:file". */ if (!dirend && filename[0] && filename[1] == ':') dirend = filename + 1; } #endif /* WINDOWS32 || __MSDOS__ */ if (dirend == 0) #ifdef _AMIGA dir = find_directory ("")->contents; #else /* !VMS && !AMIGA */ dir = find_directory (".")->contents; #endif /* AMIGA */ #endif /* VMS */ else { char *dirname; char *slash = dirend; if (dirend == filename) dirname = "/"; else { #if defined (WINDOWS32) || defined (__MSDOS__) /* d:/ and d: are *very* different... */ if (dirend < filename + 3 && filename[1] == ':' && (*dirend == '/' || *dirend == '\\' || *dirend == ':')) dirend++; #endif dirname = (char *) alloca (dirend - filename + 1); bcopy (p, dirname, dirend - p); dirname[dirend - p] = '\0'; } dir = find_directory (dirname)->contents; p = filename = slash + 1; } if (dir == 0 || dir->files == 0) /* There are no files entered for this directory. */ return 0; #ifdef __MSDOS__ p = filename = dosify (p); #endif #ifdef HAVE_CASE_INSENSITIVE_FS p = filename = downcase (p); #endif #ifdef VMS p = filename = vmsify (p, 1); #endif for (hash = 0; *p != '\0'; ++p) HASH (hash, *p); hash %= DIRFILE_BUCKETS; for (next = dir->files[hash]; next != 0; next = next->next) if (strieq (filename, next->name)) return next->impossible; return 0; } /* Return the already allocated name in the directory hash table that matches DIR. */ char * dir_name (dir) char *dir; { return find_directory (dir)->name; } /* Print the data base of directories. */ void print_dir_data_base () { register unsigned int i, dirs, files, impossible; register struct directory *dir; puts (_("\n# Directories\n")); dirs = files = impossible = 0; for (i = 0; i < DIRECTORY_BUCKETS; ++i) for (dir = directories[i]; dir != 0; dir = dir->next) { ++dirs; if (dir->contents == 0) printf (_("# %s: could not be stat'd.\n"), dir->name); else if (dir->contents->files == 0) #ifdef WINDOWS32 printf (_("# %s (key %s, mtime %d): could not be opened.\n"), dir->name, dir->contents->path_key,dir->contents->mtime); #else /* WINDOWS32 */ #ifdef VMS printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"), dir->name, dir->contents->dev, dir->contents->ino[0], dir->contents->ino[1], dir->contents->ino[2]); #else printf (_("# %s (device %ld, inode %ld): could not be opened.\n"), dir->name, (long int) dir->contents->dev, (long int) dir->contents->ino); #endif #endif /* WINDOWS32 */ else { register unsigned int f = 0, im = 0; register unsigned int j; register struct dirfile *df; for (j = 0; j < DIRFILE_BUCKETS; ++j) for (df = dir->contents->files[j]; df != 0; df = df->next) if (df->impossible) ++im; else ++f; #ifdef WINDOWS32 printf (_("# %s (key %s, mtime %d): "), dir->name, dir->contents->path_key, dir->contents->mtime); #else /* WINDOWS32 */ #ifdef VMS printf (_("# %s (device %d, inode [%d,%d,%d]): "), dir->name, dir->contents->dev, dir->contents->ino[0], dir->contents->ino[1], dir->contents->ino[2]); #else printf (_("# %s (device %ld, inode %ld): "), dir->name, (long)dir->contents->dev, (long)dir->contents->ino); #endif #endif /* WINDOWS32 */ if (f == 0) fputs (_("No"), stdout); else printf ("%u", f); fputs (_(" files, "), stdout); if (im == 0) fputs (_("no"), stdout); else printf ("%u", im); fputs (_(" impossibilities"), stdout); if (dir->contents->dirstream == 0) puts ("."); else puts (_(" so far.")); files += f; impossible += im; } } fputs ("\n# ", stdout); if (files == 0) fputs (_("No"), stdout); else printf ("%u", files); fputs (_(" files, "), stdout); if (impossible == 0) fputs (_("no"), stdout); else printf ("%u", impossible); printf (_(" impossibilities in %u directories.\n"), dirs); } /* Hooks for globbing. */ #include /* Structure describing state of iterating through a directory hash table. */ struct dirstream { struct directory_contents *contents; /* The directory being read. */ unsigned int bucket; /* Current hash bucket. */ struct dirfile *elt; /* Current elt in bucket. */ }; /* Forward declarations. */ static __ptr_t open_dirstream PARAMS ((const char *)); static struct dirent *read_dirstream PARAMS ((__ptr_t)); static __ptr_t open_dirstream (directory) const char *directory; { struct dirstream *new; struct directory *dir = find_directory ((char *)directory); if (dir->contents == 0 || dir->contents->files == 0) /* DIR->contents is nil if the directory could not be stat'd. DIR->contents->files is nil if it could not be opened. */ return 0; /* Read all the contents of the directory now. There is no benefit in being lazy, since glob will want to see every file anyway. */ (void) dir_contents_file_exists_p (dir->contents, (char *) 0); new = (struct dirstream *) xmalloc (sizeof (struct dirstream)); new->contents = dir->contents; new->bucket = 0; new->elt = new->contents->files[0]; return (__ptr_t) new; } static struct dirent * read_dirstream (stream) __ptr_t stream; { struct dirstream *const ds = (struct dirstream *) stream; register struct dirfile *df; static char *buf; static unsigned int bufsz; while (ds->bucket < DIRFILE_BUCKETS) { while ((df = ds->elt) != 0) { ds->elt = df->next; if (!df->impossible) { /* The glob interface wants a `struct dirent', so mock one up. */ struct dirent *d; unsigned int len = strlen (df->name) + 1; if (sizeof *d - sizeof d->d_name + len > bufsz) { if (buf != 0) free (buf); bufsz *= 2; if (sizeof *d - sizeof d->d_name + len > bufsz) bufsz = sizeof *d - sizeof d->d_name + len; buf = xmalloc (bufsz); } d = (struct dirent *) buf; FAKE_DIR_ENTRY (d); #ifdef _DIRENT_HAVE_D_NAMLEN d->d_namlen = len - 1; #endif memcpy (d->d_name, df->name, len); return d; } } if (++ds->bucket == DIRFILE_BUCKETS) break; ds->elt = ds->contents->files[ds->bucket]; } return 0; } static void ansi_free(p) void *p; { if (p) free(p); } void dir_setup_glob (gl) glob_t *gl; { #ifndef VMS extern int stat (); #endif /* Bogus sunos4 compiler complains (!) about & before functions. */ gl->gl_opendir = open_dirstream; gl->gl_readdir = read_dirstream; gl->gl_closedir = ansi_free; gl->gl_stat = stat; /* We don't bother setting gl_lstat, since glob never calls it. The slot is only there for compatibility with 4.4 BSD. */ } *[MAKE-3_78_1HB]DOSBUILD.BAT;1+,Yb ./@ 4-`0123KPWO 567MSm89G@HJ @echo Building Make for MSDOS @rem Echo ON so they will see what is going on. @echo on gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g commands.c -o commands.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g job.c -o job.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g dir.c -o dir.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g file.c -o file.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g misc.c -o misc.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g main.c -o main.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -DINCLUDEDIR=\"c:/djgpp/include\" -O2 -g read.c -o read.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -DLIBDIR=\"c:/djgpp/lib\" -O2 -g remake.c -o remake.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g rule.c -o rule.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g implicit.c -o implicit.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g default.c -o default.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g variable.c -o variable.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g expand.c -o expand.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g function.c -o function.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g vpath.c -o vpath.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g version.c -o version.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g ar.c -o ar.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g arscan.c -o arscan.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g signame.c -o signame.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g remote-stub.c -o remote-stub.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g getopt.c -o getopt.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g getopt1.c -o getopt1.o @cd glob @if exist libglob.a del libglob.a gcc -I. -c -DHAVE_CONFIG_H -I.. -O2 -g glob.c -o glob.o gcc -I. -c -DHAVE_CONFIG_H -I.. -O2 -g fnmatch.c -o fnmatch.o ar rv libglob.a glob.o fnmatch.o @echo off cd .. echo commands.o > respf.$$$ for %%f in (job dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$ for %%f in (expand function vpath version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$ echo glob/libglob.a >> respf.$$$ @echo Linking... @echo on gcc -o make.new @respf.$$$ @if exist make.exe echo Make.exe is now built! @if not exist make.exe echo Make.exe build failed... @if exist make.exe del respf.$$$ o*[MAKE-3_78_1HB]EXPAND.C;1+,Zb ./@ 4-`0123KPWO56N70m89G@HJ /* Variable expansion functions for GNU Make. Copyright (C) 1988, 89, 91, 92, 93, 95 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "filedef.h" #include "job.h" #include "commands.h" #include "variable.h" #include "rule.h" /* The next two describe the variable output buffer. This buffer is used to hold the variable-expansion of a line of the makefile. It is made bigger with realloc whenever it is too small. variable_buffer_length is the size currently allocated. variable_buffer is the address of the buffer. For efficiency, it's guaranteed that the buffer will always have VARIABLE_BUFFER_ZONE extra bytes allocated. This allows you to add a few extra chars without having to call a function. Note you should never use these bytes unless you're _sure_ you have room (you know when the buffer length was last checked. */ #define VARIABLE_BUFFER_ZONE 5 static unsigned int variable_buffer_length; char *variable_buffer; /* Subroutine of variable_expand and friends: The text to add is LENGTH chars starting at STRING to the variable_buffer. The text is added to the buffer at PTR, and the updated pointer into the buffer is returned as the value. Thus, the value returned by each call to variable_buffer_output should be the first argument to the following call. */ char * variable_buffer_output (ptr, string, length) char *ptr, *string; unsigned int length; { register unsigned int newlen = length + (ptr - variable_buffer); if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length) { unsigned int offset = ptr - variable_buffer; variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length ? newlen + 100 : 2 * variable_buffer_length); variable_buffer = (char *) xrealloc (variable_buffer, variable_buffer_length); ptr = variable_buffer + offset; } bcopy (string, ptr, length); return ptr + length; } /* Return a pointer to the beginning of the variable buffer. */ static char * initialize_variable_output () { /* If we don't have a variable output buffer yet, get one. */ if (variable_buffer == 0) { variable_buffer_length = 200; variable_buffer = (char *) xmalloc (variable_buffer_length); variable_buffer[0] = '\0'; } return variable_buffer; } /* Recursively expand V. The returned string is malloc'd. */ char * recursively_expand (v) register struct variable *v; { char *value; if (v->expanding) /* Expanding V causes infinite recursion. Lose. */ fatal (reading_file, _("Recursive variable `%s' references itself (eventually)"), v->name); v->expanding = 1; value = allocated_variable_expand (v->value); v->expanding = 0; return value; } /* Warn that NAME is an undefined variable. */ #ifdef __GNUC__ __inline #endif static void warn_undefined (name, length) char *name; unsigned int length; { if (warn_undefined_variables_flag) error (reading_file, _("warning: undefined variable `%.*s'"), (int)length, name); } /* Expand a simple reference to variable NAME, which is LENGTH chars long. */ #ifdef __GNUC__ __inline #endif static char * reference_variable (o, name, length) char *o; char *name; unsigned int length; { register struct variable *v = lookup_variable (name, length); if (v == 0) warn_undefined (name, length); if (v != 0 && *v->value != '\0') { char *value = (v->recursive ? recursively_expand (v) : v->value); o = variable_buffer_output (o, value, strlen (value)); if (v->recursive) free (value); } return o; } /* Scan STRING for variable references and expansion-function calls. Only LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until a null byte is found. Write the results to LINE, which must point into `variable_buffer'. If LINE is NULL, start at the beginning of the buffer. Return a pointer to LINE, or to the beginning of the buffer if LINE is NULL. */ char * variable_expand_string (line, string, length) register char *line; char *string; long length; { register struct variable *v; register char *p, *o, *p1; char save_char = '\0'; unsigned int line_offset; if (!line) line = initialize_variable_output(); p = string; o = line; line_offset = line - variable_buffer; if (length >= 0) { save_char = string[length]; string[length] = '\0'; } while (1) { /* Copy all following uninteresting chars all at once to the variable output buffer, and skip them. Uninteresting chars end at the next $ or the end of the input. */ p1 = index (p, '$'); o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1); if (p1 == 0) break; p = p1 + 1; /* Dispatch on the char that follows the $. */ switch (*p) { case '$': /* $$ seen means output one $ to the variable output buffer. */ o = variable_buffer_output (o, p, 1); break; case '(': case '{': /* $(...) or ${...} is the general case of substitution. */ { char openparen = *p; char closeparen = (openparen == '(') ? ')' : '}'; register char *beg = p + 1; int free_beg = 0; char *op, *begp; char *end, *colon; op = o; begp = p; if (handle_function (&op, &begp)) { o = op; p = begp; break; } /* Is there a variable reference inside the parens or braces? If so, expand it before expanding the entire reference. */ end = index (beg, closeparen); if (end == 0) /* Unterminated variable reference. */ fatal (reading_file, _("unterminated variable reference")); p1 = lindex (beg, end, '$'); if (p1 != 0) { /* BEG now points past the opening paren or brace. Count parens or braces until it is matched. */ int count = 0; for (p = beg; *p != '\0'; ++p) { if (*p == openparen) ++count; else if (*p == closeparen && --count < 0) break; } /* If COUNT is >= 0, there were unmatched opening parens or braces, so we go to the simple case of a variable name such as `$($(a)'. */ if (count < 0) { beg = expand_argument (beg, p); /* Expand the name. */ free_beg = 1; /* Remember to free BEG when finished. */ end = index (beg, '\0'); } } else /* Advance P to the end of this reference. After we are finished expanding this one, P will be incremented to continue the scan. */ p = end; /* This is not a reference to a built-in function and any variable references inside are now expanded. Is the resultant text a substitution reference? */ colon = lindex (beg, end, ':'); if (colon != 0) { /* This looks like a substitution reference: $(FOO:A=B). */ char *subst_beg, *subst_end, *replace_beg, *replace_end; subst_beg = colon + 1; subst_end = index (subst_beg, '='); if (subst_end == 0) /* There is no = in sight. Punt on the substitution reference and treat this as a variable name containing a colon, in the code below. */ colon = 0; else { replace_beg = subst_end + 1; replace_end = end; /* Extract the variable name before the colon and look up that variable. */ v = lookup_variable~MAKE-3_78_1HB.BCKZb `[MAKE-3_78_1HB]EXPAND.C;1 (beg, colon - beg); if (v == 0) warn_undefined (beg, colon - beg); if (v != 0 && *v->value != '\0') { char *value = (v->recursive ? recursively_expand (v) : v->value); char *pattern, *percent; if (free_beg) { *subst_end = '\0'; pattern = subst_beg; } else { pattern = (char *) alloca (subst_end - subst_beg + 1); bcopy (subst_beg, pattern, subst_end - subst_beg); pattern[subst_end - subst_beg] = '\0'; } percent = find_percent (pattern); if (percent != 0) { char *replace; if (free_beg) { *replace_end = '\0'; replace = replace_beg; } else { replace = (char *) alloca (replace_end - replace_beg + 1); bcopy (replace_beg, replace, replace_end - replace_beg); replace[replace_end - replace_beg] = '\0'; } o = patsubst_expand (o, value, pattern, replace, percent, (char *) 0); } else o = subst_expand (o, value, pattern, replace_beg, strlen (pattern), end - replace_beg, 0, 1); if (v->recursive) free (value); } } } if (colon == 0) /* This is an ordinary variable reference. Look up the value of the variable. */ o = reference_variable (o, beg, end - beg); if (free_beg) free (beg); } break; case '\0': break; default: if (isblank (p[-1])) break; /* A $ followed by a random char is a variable reference: $a is equivalent to $(a). */ { /* We could do the expanding here, but this way avoids code repetition at a small performance cost. */ char name[5]; name[0] = '$'; name[1] = '('; name[2] = *p; name[3] = ')'; name[4] = '\0'; p1 = allocated_variable_expand (name); o = variable_buffer_output (o, p1, strlen (p1)); free (p1); } break; } if (*p == '\0') break; else ++p; } if (save_char) string[length] = save_char; (void)variable_buffer_output (o, "", 1); return (variable_buffer + line_offset); } /* Scan LINE for variable references and expansion-function calls. Build in `variable_buffer' the result of expanding the references and calls. Return the address of the resulting string, which is null-terminated and is valid only until the next time this function is called. */ char * variable_expand (line) char *line; { return variable_expand_string(NULL, line, (long)-1); } /* Expand an argument for an expansion function. The text starting at STR and ending at END is variable-expanded into a null-terminated string that is returned as the value. This is done without clobbering `variable_buffer' or the current variable-expansion that is in progress. */ char * expand_argument (str, end) char *str, *end; { char *tmp; if (*end == '\0') tmp = str; else { tmp = (char *) alloca (end - str + 1); bcopy (str, tmp, end - str); tmp[end - str] = '\0'; } return allocated_variable_expand (tmp); } /* Expand LINE for FILE. Error messages refer to the file and line where FILE's commands were found. Expansion uses FILE's variable set list. */ static char * variable_expand_for_file (line, file) char *line; register struct file *file; { char *result; struct variable_set_list *save, *fnext; if (file == 0) return variable_expand (line); save = current_variable_set_list; current_variable_set_list = file->variables; if (file->cmds && file->cmds->fileinfo.filenm) reading_file = &file->cmds->fileinfo; else reading_file = 0; fnext = file->variables->next; /* See if there's a pattern-specific variable struct for this target. */ if (!file->pat_searched) { file->patvar = lookup_pattern_var(file->name); file->pat_searched = 1; } if (file->patvar != 0) { file->patvar->vars->next = fnext; file->variables->next = file->patvar->vars; } result = variable_expand (line); current_variable_set_list = save; reading_file = 0; file->variables->next = fnext; return result; } /* Like variable_expand_for_file, but the returned string is malloc'd. This function is called a lot. It wants to be efficient. */ char * allocated_variable_expand_for_file (line, file) char *line; struct file *file; { char *value; char *obuf = variable_buffer; unsigned int olen = variable_buffer_length; variable_buffer = 0; value = variable_expand_for_file (line, file); #if 0 /* Waste a little memory and save time. */ value = xrealloc (value, strlen (value)) #endif variable_buffer = obuf; variable_buffer_length = olen; return value; } *[MAKE-3_78_1HB]FILE.C;3+,e.(/@ 4R(%-`0123KPWO)56_v!7ɸm89G@HJ/* Target file hash table management for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "make.h" #include "dep.h" #include "filedef.h" #include "job.h" #include "commands.h" #include "variable.h" /* Hash table of files the makefile knows how to make. */ #ifndef FILE_BUCKETS #define FILE_BUCKETS 1007 #endif static struct file *files[FILE_BUCKETS]; /* Number of files with the `intermediate' flag set. */ unsigned int num_intermediates = 0; /* Current value for pruning the scan of the goal chain (toggle 0/1). */ unsigned int considered = 0; /* Access the hash table of all file records. lookup_file given a name, return the struct file * for that name, or nil if there is none. enter_file similar, but create one if there is none. */ struct file * lookup_file (name) char *name; { register struct file *f; register char *n; register unsigned int hashval; #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) register char *lname, *ln; #endif if (*name == '\0') abort (); /* This is also done in parse_file_seq, so this is redundant for names read from makefiles. It is here for names passed on the command line. */ #ifdef VMS #ifndef WANT_CASE_SENSITIVE_TARGETS lname = (char *)malloc(strlen(name) + 1); for (n=name, ln=lname; *n != '\0'; ++n, ++ln) *ln = isupper(*n) ? tolower(*n) : *n; *ln = '\0'; name = lname; #endif while (name[0] == '[' && name[1] == ']' && name[2] != '\0') name += 2; #endif while (name[0] == '.' && name[1] == '/' && name[2] != '\0') { name += 2; while (*name == '/') /* Skip following slashes: ".//foo" is "foo", not "/foo". */ ++name; } if (*name == '\0') /* It was all slashes after a dot. */ #ifdef VMS name = "[]"; #else #ifdef _AMIGA name = ""; #else name = "./"; #endif /* AMIGA */ #endif /* VMS */ hashval = 0; for (n = name; *n != '\0'; ++n) HASHI (hashval, *n); hashval %= FILE_BUCKETS; for (f = files[hashval]; f != 0; f = f->next) { if (strieq (f->hname, name)) { #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) free (lname); #endif return f; } } #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) free (lname); #endif return 0; } struct file * enter_file (name) char *name; { register struct file *f, *new; register char *n; register unsigned int hashval; #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) char *lname, *ln; #endif if (*name == '\0') abort (); #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) lname = (char *)malloc (strlen (name) + 1); for (n = name, ln = lname; *n != '\0'; ++n, ++ln) { if (isupper(*n)) *ln = tolower(*n); else *ln = *n; } *ln = 0; /* Creates a possible leak, old value of name is unreachable, but I currently don't know how to fix it. */ name = lname; #endif hashval = 0; for (n = name; *n != '\0'; ++n) HASHI (hashval, *n); hashval %= FILE_BUCKETS; for (f = files[hashval]; f != 0; f = f->next) if (strieq (f->hname, name)) break; if (f != 0 && !f->double_colon) { #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) free(lname); #endif return f; } new = (struct file *) xmalloc (sizeof (struct file)); bzero  ((char *) new, sizeof (struct file)); new->name = new->hname = name; new->update_status = -1; if (f == 0) { /* This is a completely new file. */ new->next = files[hashval]; files[hashval] = new; } else { /* There is already a double-colon entry for this file. */ new->double_colon = f; while (f->prev != 0) f = f->prev; f->prev = new; } return new; } /* Rehash FILE to NAME. This is not as simple as resetting the `hname' member, since it must be put in a new hash bucket, and possibly merged with an existing file called NAME. */ void rehash_file (file, name) register struct file *file; char *name; { char *oldname = file->hname; register unsigned int oldhash; register char *n; while (file->renamed != 0) file = file->renamed; /* Find the hash values of the old and new names. */ oldhash = 0; for (n = oldname; *n != '\0'; ++n) HASHI (oldhash, *n); file_hash_enter (file, name, oldhash, file->name); } /* Rename FILE to NAME. This is not as simple as resetting the `name' member, since it must be put in a new hash bucket, and possibly merged with an existing file called NAME. */ void rename_file (file, name) register struct file *file; char *name; { rehash_file(file, name); while (file) { file->name = file->hname; file = file->prev; } } void file_hash_enter (file, name, oldhash, oldname) register struct file *file; char *name; unsigned int oldhash; char *oldname; { unsigned int oldbucket = oldhash % FILE_BUCKETS; register unsigned int newhash, newbucket; struct file *oldfile; register char *n; register struct file *f; newhash = 0; for (n = name; *n != '\0'; ++n) HASHI (newhash, *n); newbucket = newhash % FILE_BUCKETS; /* Look for an existing file under the new name. */ for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next) if (strieq (oldfile->hname, name)) break; /* If the old file is the same as the new file, something's wrong. */ assert (oldfile != file); if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0)) { /* Remove FILE from its hash bucket. */ struct file *lastf = 0; for (f = files[oldbucket]; f != file; f = f->next) lastf = f; if (lastf == 0) files[oldbucket] = f->next; else lastf->next = f->next; } /* Give FILE its new name. */ file->hname = name; for (f = file->double_colon; f != 0; f = f->prev) f->hname = name; if (oldfile == 0) { /* There is no existing file with the new name. */ if (newbucket != oldbucket) { /* Put FILE in its new hash bucket. */ file->next = files[newbucket]; files[newbucket] = file; } } else { /* There is an existing file with the new name. We must merge FILE into the existing file. */ register struct dep *d; if (file->cmds != 0) { if (oldfile->cmds == 0) oldfile->cmds = file->cmds; else if (file->cmds != oldfile->cmds) { /* We have two sets of commands. We will go with the one given in the rule explicitly mentioning this name, but give a message to let the user know what's going on. */ if (oldfile->cmds->fileinfo.filenm != 0) error (&file->cmds->fileinfo, _("Commands were specified for \ file `%s' at %s:%lu,"), oldname, oldfile->cmds->fileinfo.filenm, oldfile->cmds->fileinfo.lineno); else error (&file->cmds->fileinfo, _("Commands for file `%s' were found by \ implicit rule search,"), oldname); error (&file->cmds->fileinfo, _("but `%s' is now considered the same file \ as `%s'."), oldname, name); error (&file->cmds->fileinfo, _("Commands for `%s' will be ignored \ in favor of those for `%s'."), name, oldname); } } /* Merge the dependencies of the two files. */ d = oldfile->deps; if (d == 0) oldfile->deps = file->deps; else { while (d->next != 0) d = d->next; d->next = file->deps; } merge_variable_set_lists (&oldfile->variables, file->variables); if (oldfile->double_colon && file->is_target && !file->double_colon) fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"), oldname, name); if (!oldfile->double_colon && file->double_colon) { if (oldfile->is_target) fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"), oldname, name); else oldfile->double_colon = file->double_colon; } if (file->last_mtime > oldfile->last_mtime) /* %%% Kludge so -W wins on a file that gets vpathized. */ oldfile->last_mtime = file->last_mtime; oldfile->mtime_before_update = file->mtime_before_update; #define MERGE(field) oldfile->field |= file->field MERGE (precious); MERGE (tried_implicit); MERGE (updating); MERGE (updated); MERGE (is_target); MERGE (cmd_target); MERGE (phony); MERGE (ignore_vpath); #undef MERGE file->renamed = oldfile; } } /* Remove all nonprecious intermediate files. If SIG is nonzero, this was caused by a fatal signal, meaning that a different message will be printed, and the message will go to stderr rather than stdout. */ void remove_intermediates (sig) int sig; { register int i; register struct file *f; char doneany; if (question_flag || touch_flag) return; if (sig && just_print_flag) return; doneany = 0; for (i = 0; i < FILE_BUCKETS; ++i) for (f = files[i]; f != 0; f = f->next) if (f->intermediate && (f->dontcare || !f->precious) && !f->secondary) { int status; if (f->update_status == -1) /* If nothing would have created this file yet, don't print an "rm" command for it. */ continue; else if (just_print_flag) status = 0; else { status = unlink (f->name); if (status < 0 && errno == ENOENT) cont"inue; } if (!f->dontcare) { if (sig) error (NILF, _("*** Deleting intermediate file `%s'"), f->name); else if (!silent_flag) { if (! doneany) { fputs ("rm ", stdout); doneany = 1; } else putchar (' '); fputs (f->name, stdout); fflush (stdout); } if (status < 0) perror_with_name ("unlink: ", f->name); } } if (doneany && !sig) { putchar ('\n'); fflush (stdout); } } /* For each dependency of each file, make the `struct dep' point at the appropriate `struct file' (which may have to be created). Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT, and various other special targets. */ void snap_deps () { register struct file *f, *f2; register struct dep *d; register int i; /* Enter each dependency name as a file. */ for (i = 0; i < FILE_BUCKETS; ++i) for (f = files[i]; f != 0; f = f->next) for (f2 = f; f2 != 0; f2 = f2->prev) for (d = f2->deps; d != 0; d = d->next) if (d->name != 0) { d->file = lookup_file (d->name); if (d->file == 0) d->file = enter_file (d->name); else free (d->name); d->name = 0; } for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev) for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) f2->precious = 1; for (f = lookup_file (".PHONY"); f != 0; f = f->prev) for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) { /* Mark this file as phony and nonexistent. */ f2->phony = 1; f2->last_mtime = (FILE_TIMESTAMP) -1; f2->mtime_before_update = (FILE_TIMESTAMP) -1; } for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev) { /* .INTERMEDIATE with deps listed marks those deps as intermediate files. */ for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) f2->intermediate = 1; /* .INTERMEDIATE with no deps does nothing. Marking all files as intermediates is useless since the goal targets would be deleted after they are built. */ } for (f = lookup_file (".SECONDARY"); f != 0; f = f->prev) { /* .SECONDARY with deps listed marks those deps as intermediate files in that they don't get rebuilt if not actually needed; but unlike real intermediate files, these are not deleted after make finishes. */ if (f->deps) { for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) f2->intermediate = f2->secondary = 1; } /* .SECONDARY with no deps listed marks *all* files that way. */ else { int i; for (i = 0; i < FILE_BUCKETS; i++) for (f2 = files[i]; f2; f2= f2->next) f2->intermediate = f2->secondary = 1; } } f = lookup_file (".EXPORT_ALL_VARIABLES"); if (f != 0 && f->is_target) export_all_variables = 1; f = lookup_file (".IGNORE"); if (f != 0 && f->is_target) { if (f->deps == 0) ignore_errors_flag = 1; else for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) f2->command_flags |= COMMANDS_NOERROR; } f = lookup_file (".SILENT"); if (f != 0 && f->is_target) { if (f->deps == 0) silent_flag = 1; else for (d = f->deps; d != 0; d = d->next) for (f2 = d->file; f2 != 0; f2 = f2->prev) f2->command_flags |= COMMANDS_SILENT; } f = lookup_file (".POSIX"); if (f != 0 && f->is_target) posix_pedantic = 1; } /* Set the `command_state' member of FILE and all its `also_make's. */ void set_command_state (file, state) struct file *file; int state; { struct dep *d; file->command_state = state; for (d = file->also_make; d != 0; d = d->next) d->file->command_state = state; } /* Get and print file timestamps. */ FILE_TIMESTAMP file_timestamp_now () { #if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME struct timespec timespec; if (clock_gettime (CLOCK_REALTIME, ×pec) == 0) return FILE_TIMESTAMP_FROM_S_AND_NS (timespec.tv_sec, timespec.tv_nsec); #endif return FILE_TIMESTAMP_FROM_S_AND_NS (time ((time_t *) 0), 0); } void file_timestamp_sprintf (p, ts) char *p; FILE_TIMESTAMP ts; { time_t t = FILE_TIMESTAMP_S (ts); struct tm *tm = localtime (&t); if (tm) sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); else if (t < 0) sprintf (p, "%ld", (long) t); else sprintf (p, "%lu", (unsigned long) t); p += strlen (p); /* Append nanoseconds as a fraction, but remove trailing zeros. We don't know the actual timestamp resolution, since clock_getres applies only to local times, whereas this timestamp might come from a remote filesystem. So removing trailing zeros is the best guess that we can do. */ sprintf (p, ".%09ld", (long) FILE_TIMESTAMP_NS (ts)); p += strlen (p) - 1; while (*p == '0') p--; p += *p != '.'; *p = '\0'; } /* Print the data base of files. */ static void print_file (f) struct file *f; { register struct dep *d; putchar ('\n'); if (!f->is_target) puts (_("# Not a target:")); printf ("%s:%s", f->name, f->double_colon ? ":" : ""); for (d = f->deps; d != 0; d = d->next) printf (" %s", dep_name (d)); putchar ('\n'); if (f->precious) puts (_("# Precious file (prerequisite of .PRECIOUS).")); if (f->phony) puts (_("# Phony target (prerequisite of .PHONY).")); if (f->cmd_target) puts (_("# Command-line target.")); if (f->dontcare) puts (_("# A default or MAKEFILES makefile.")); printf (_("# Implicit rule search has%s been done.\n"), f->tried_implicit ? "" : _(" not")); if (f->stem != 0) printf (_("# Implicit/static pattern stem: `%s'\n"), f->stem); if (f->intermediate) puts (_("# File is an intermediate prerequisite.")); if (f->also_make != 0) { fputs (_("# Also makes:"), stdout); for (d = f->also_make; d != 0; d = d->next) printf (" %s", dep_name (d)); putchar ('\n'); } if (f->last_mtime == 0) puts (_("# Modification time never checked.")); else if (f->last_mtime == (FILE_TIMESTAMP) -1) puts (_("# File does not exist.")); else { char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; file_timestamp_sprintf (buf, f->last_mtime); printf (_("# Last modified %s\n"), buf); } printf (_("# File has%s been updated.\n"), f->updated ? "" : _(" not")); switch (f->command_state) { case cs_running: puts (_("# Commands currently running (THIS IS A BUG).")); break; case cs_deps_running: puts (_("# Dependencies commands running (THIS IS A BUG).")); break; case cs_not_started: case cs_finished: switch (f->update_status) { case -1: break; case 0: puts (_("# Successfully updated.")); break; case 1: assert (question_flag); puts (_("# Needs to be updated (-q is set).")); break; case 2: puts (_("# Failed to be updated.")); break; default: puts (_("# Invalid value in `update_status' member!")); fflush (stdout); fflush (stderr); abort (); } break; default: puts (_("# Invalid value in `command_state' member!")); fflush (stdout); fflush (stderr); abort (); } if (f->variables != 0) print_file_variables (f); if (f->cmds != 0) print_commands (f->cmds); } void print_file_data_base () { register unsigned int i, nfiles, per_bucket; register struct file *file; puts (_("\n# Files")); per_bucket = nfiles = 0; for (i = 0; i < FILE_BUCKETS; ++i) { register unsigned int this_bucket = 0; for (file = files[i]; file != 0; file = file->next) { register struct file *f; ++this_bucket; for (f = file; f != 0; f = f->prev) print_file (f); } nfiles += this_bucket; if (this_bucket > per_bucket) per_bucket = this_bucket; } if (nfiles == 0) puts (_("\n# No files.")); else { printf (_("\n# %u files in %u hash buckets.\n"), nfiles, FILE_BUCKETS); #ifndef NO_FLOAT printf (_("# average %.3f files per bucket, max %u files in one bucket.\n"), ((double) nfiles) / ((double) FILE_BUCKETS), per_bucket); #endif } } /* EOF */ *[MAKE-3_78_1HB]FILEDEF.H;1+,^b ./@ 4!-`0123KPWO56Cw77#m89G@HJ/* Definition of target file data structures for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Structure that represents the info on one file that the makefile says how to make. All of these are chained together through `next'. */ struct file { struct file *next; char *name; char *hname; /* Hashed filename */ char *vpath; /* VPATH/vpath pathname */ struct dep *deps; struct commands *cmds; /* Commands to execute for this target. */ int command_flags; /* Flags OR'd in for cmds; see commands.h. */ char *stem; /* Implicit stem, if an implicit rule has been used */ struct dep *also_make; /* Targets that are made by making this. */ FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */ FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating has been performed. */ struct file *prev; /* Previous entry for same file name; used when there are multiple double-colon entries for the same file. */ /* File that this file was renamed to. After any time that a file could be renamed, call `check_renamed' (below). */ struct file *renamed; /* List of variable sets used for this file. */ struct variable_set_list *variables; /* Immediate dependent that caused this target to be remade, or nil if there isn't one. */ struct file *parent; /* For a double-colon entry, this is the first double-colon entry for the same file. Otherwise this is null. */ struct file *double_colon; /* Pattern-specific variable reference for this target, or null if there isn't one. Also see the pat_searched flag, below. */ struct pattern_var *patvar; short int update_status; /* Status of the last attempt to update, or -1 if none has been made. */ enum /* State of the commands. */ { /* Note: It is important that cs_not_started be zero. */ cs_not_started, /* Not yet started. */ cs_deps_running, /* Dep commands running. */ cs_running, /* Commands running. */ cs_finished /* Commands finished. */ } command_state ENUM_BITFIELD (2); unsigned int precious:1; /* Non-0 means don't delete file on quit */ unsigned int tried_implicit:1; /* Nonzero if have searched for implicit rule for making this file; don't search again. */ unsigned int updating:1; /* Nonzero while updating deps of this file */ unsigned int updated:1; /* Nonzero if this file has been remade. */ unsigned int is_target:1; /* Nonzero if file is described as target. */ unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */ unsigned int phony:1; /* Nonzero if this is a phony file i.e., a dependency of .PHONY. */ unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */ /* Nonzero, for an intermediate file, means remove_intermediates should not delete it. */ unsigned int secondary:1; unsigned int dontcare:1; /* Nonzero if no complaint is to be made if this target cannot be remade. */ unsigned int mfile_status:1;/* Nonzero if update_status was obtained while remaking a makefile. */ unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */ unsigned int pat_searched:1;/* Nonzero if we already searched for pattern-specific variables. */ unsigned int considered:1; /* equal to `considered' if file has been considered on current scan of goal chain */ }; /* Number of intermediate files entered. */ extern unsigned int num_intermediates; /* Current value for pruning the scan of the goal chain (toggle 0/1). */ extern unsigned int considered; extern struct file *default_goal_file, *suffix_file, *default_file; extern struct file *lookup_file PARAMS ((char *name)); extern struct file *enter_file PARAMS ((char *name)); extern void remove_intermediates PARAMS ((int sig)); extern void snap_deps PARAMS ((void)); extern void rename_file PARAMS ((struct file *file, char *name)); extern void rehash_file PARAMS ((struct file *file, char *name)); extern void file_hash_enter PARAMS ((struct file *file, char *name, unsigned int oldhash, char *oldname)); extern void set_command_state PARAMS ((struct file *file, int state)); extern void notice_finished_file PARAMS ((struct file *file)); #if ST_MTIM_NSEC # define FILE_TIMESTAMP_STAT_MODTIME(st) \ FILE_TIMESTAMP_FROM_S_AND_NS ((st).st_mtim.tv_sec, \ (st).st_mtim.ST_MTIM_NSEC) # define FILE_TIMESTAMPS_PER_S \ MIN ((FILE_TIMESTAMP) 1000000000, \ (INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) \ / INTEGER_TYPE_MAXIMUM (time_t))) #else # define FILE_TIMESTAMP_STAT_MODTIME(st) ((st).st_mtime) # define FILE_TIMESTAMPS_PER_S 1 #endif #define FILE_TIMESTAMP_FROM_S_AND_NS(s, ns) \ ((s) * FILE_TIMESTAMPS_PER_S \ + (ns) * FILE_TIMESTAMPS_PER_S / 1000000000) #define FILE_TIMESTAMP_DIV(a, b) ((a)/(b) - ((a)%(b) < 0)) #define FILE_TIMESTAMP_MOD(a, b) ((a)%(b) + ((a)%(b) < 0) * (b)) #define FILE_TIMESTAMP_S(ts) FILE_TIMESTAMP_DIV ((ts), FILE_TIMESTAMPS_PER_S) #define FILE_TIMESTAMP_NS(ts) \ (((FILE_TIMESTAMP_MOD ((ts), FILE_TIMESTAMPS_PER_S) * 1000000000) \ + (FILE_TIMESTAMPS_PER_S - 1)) \ / FILE_TIMESTAMPS_PER_S) /* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN" representing a file timestamp. The upper bound is not necessarily 19, since the year might be less than -999 or greater than 9999. Subtract one for the sign bit if in case file timestamps can be negative; subtract FLOOR_LOG2_SECONDS_PER_YEAR to yield an upper bound on how many file timestamp bits might affect the year; 302 / 1000 is log10 (2) rounded up; add one for integer division truncation; add one more for a minus sign if file timestamps can be negative; add 4 to allow for any 4-digit epoch year (e.g. 1970); add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */ #define FLOOR_LOG2_SECONDS_PER_YEAR 24 #define FILE_TIMESTAMP_PRINT_LEN_BOUND \ (((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \ * 302 / 1000) \ + 1 + 1 + 4 + 25) extern FILE_TIMESTAMP~MAKE-3_78_1HB.BCK^b `[MAKE-3_78_1HB]FILEDEF.H;1r* file_timestamp_now PARAMS ((void)); extern void file_timestamp_sprintf PARAMS ((char *p, FILE_TIMESTAMP ts)); /* Return the mtime of file F (a struct file *), caching it. The value is -1 if the file does not exist. */ #define file_mtime(f) file_mtime_1 ((f), 1) /* Return the mtime of file F (a struct file *), caching it. Don't search using vpath for the file--if it doesn't actually exist, we don't find it. The value is -1 if the file does not exist. */ #define file_mtime_no_search(f) file_mtime_1 ((f), 0) extern FILE_TIMESTAMP f_mtime PARAMS ((struct file *file, int search)); #define file_mtime_1(f, v) \ ((f)->last_mtime ? (f)->last_mtime : f_mtime ((f), v)) /* Modtime value to use for `infinitely new'. We used to get the current time from the system and use that whenever we wanted `new'. But that causes trouble when the machine running make and the machine holding a file have different ideas about what time it is; and can also lose for `force' targets, which need to be considered newer than anything that depends on them, even if said dependents' modtimes are in the future. If FILE_TIMESTAMP is unsigned, its maximum value is the same as ((FILE_TIMESTAMP) -1), so use one less than that, because -1 is used for non-existing files. */ #define NEW_MTIME \ (INTEGER_TYPE_SIGNED (FILE_TIMESTAMP) \ ? INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) \ : (INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) - 1)) #define check_renamed(file) \ while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here. */ e*[MAKE-3_78_1HB]FUNCTION.C;1+,`b .X/@ 4XX-`0123KPWOY56$72m89G@HJr/* Builtin function expansion for GNU Make. Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "filedef.h" #include "variable.h" #include "dep.h" #include "job.h" #include "commands.h" #ifdef _AMIGA #include "amiga.h" #endif struct function_table_entry { const char *name; int len; int required_args; int expand_args; char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname)); }; /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is nonzero, substitutions are done only on matches which are complete whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are done only at the ends of whitespace-delimited words. */ char * subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only) char *o; char *text; char *subst, *replace; unsigned int slen, rlen; int by_word, suffix_only; { register char *t = text; register char *p; if (slen == 0 && !by_word && !suffix_only) { /* The first occurrence of "" in any string is its end. */ o = variable_buffer_output (o, t, strlen (t)); if (rlen > 0) o = variable_buffer_output (o, replace, rlen); return o; } do { if ((by_word | suffix_only) && slen == 0) /* When matching by words, the empty string should match the end of each word, rather than the end of the whole text. */ p = end_of_token (next_token (t)); else { p = sindex (t, 0, subst, slen); if (p == 0) { /* No more matches. Output everything left on the end. */ o = variable_buffer_output (o, t, strlen (t)); return o; } } /* Output everything before this occurrence of the string to replace. */ if (p > t) o = variable_buffer_output (o, t, p - t); /* If we're substituting only by fully matched words, or only at the ends of words, check that this case qualifies. */ if ((by_word && ((p > t && !isblank (p[-1])) || (p[slen] != '\0' && !isblank (p[slen])))) || (suffix_only && (p[slen] != '\0' && !isblank (p[slen])))) /* Struck out. Output the rest of the string that is no longer to be replaced. */ o = variable_buffer_output (o, subst, slen); else if (rlen > 0) /* Output the replacement string. */ o = variable_buffer_output (o, replace, rlen); /* Advance T past the string to be replaced. */ t = p + slen; } while (*t != '\0'); return o; } /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing strings matching PATTERN with REPLACE. If PATTERN_PERCENT is not nil, PATTERN has already been run through find_percent, and PATTERN_PERCENT is the result. If REPLACE_PERCENT is not nil, REPLACE has already been run through find_percent, and REPLACE_PERCENT is the result. */ char * patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent) char *o; char *text; register char *pattern, *replace; register char *pattern_percent, *replace_percent; { unsigned int pattern_prepercent_len, pattern_postpercent_len; unsigned int replace_prepercent_len, replace_postpercent_len = 0; char *t; unsigned int len; int doneany = 0; /* We call find_percent on REPLACE before checking PATTERN so that REPLACE will be collapsed before we call subst_expand if PATTERN has no %. */ if (replace_percent == 0) replace_percent = find_percent (replace); if (replace_percent != 0) { /* Record the length of REPLACE before and after the % so we don't have to compute these lengths more than once. */ replace_prepercent_len = replace_percent - replace; replace_postpercent_len = strlen (replace_percent + 1); } else /* We store the length of the replacement so we only need to compute it once. */ replace_prepercent_len = strlen (replace); if (pattern_percent == 0) pattern_percent = find_percent (pattern); if (pattern_percent == 0) /* With no % in the pattern, this is just a simple substitution. */ return subst_expand (o, text, pattern, replace, strlen (pattern), strlen (replace), 1, 0); /* Record the length of PATTERN before and after the % so we don't have to compute it more than once. */ pattern_prepercent_len = pattern_percent - pattern; pattern_postpercent_len = strlen (pattern_percent + 1); while ((t = find_next_token (&text, &len)) != 0) { int fail = 0; /* Is it big enough to match? */ if (len < pattern_prepercent_len + pattern_postpercent_len) fail = 1; /* Does the prefix match? */ if (!fail && pattern_prepercent_len > 0 && (*t != *pattern || t[pattern_prepercent_len - 1] != pattern_percent[-1] || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1))) fail = 1; /* Does the suffix match? */ if (!fail && pattern_postpercent_len > 0 && (t[len - 1] != pattern_percent[pattern_postpercent_len] || t[len - pattern_postpercent_len] != pattern_percent[1] || !strneq (&t[len - pattern_postpercent_len], &pattern_percent[1], pattern_postpercent_len - 1))) fail = 1; if (fail) /* It didn't match. Output the string. */ o = variable_buffer_output (o, t, len); else { /* It matched. Output the replacement. */ /* Output the part of the replacement before the %. */ o = variable_buffer_output (o, replace, replace_prepercent_len); if (replace_percent != 0) { /* Output the part of the matched string that matched the % in the pattern. */ o = variable_buffer_output (o, t + pattern_prepercent_len, len - (pattern_prepercent_len + pattern_postpercent_len)); /* Output the part of the replacement after the %. */ o = variable_buffer_output (o, replace_percent + 1, replace_postpercent_len); } } /* Output a space, but not if the replacement is "". */ if (fail || replace_prepercent_len > 0 || (replace_percent != 0 && len + replace_postpercent_len > 0)) { o = variable_buffer_output (o, " ", 1); doneany = 1; } } if (doneany) /* Kill the last space. */ --o; return o; } /* Look up a function by name. The table is currently small enough that it's not really worthwhile to use a fancier lookup algorithm. If it gets larger, maybe... */ static const struct function_table_entry * lookup_function (table, s) const struct function_table_entry *table; const char *s; { int len = strlen(s); for (; table->name != NULL; ++table) if (table->len <= len && (isblank (s[table->len]) || s[table->len] == '\0') && strneq (s, table->name, table->len)) return table; return NULL; } /* Return 1 if PATTERN matches STR, 0 if not. */ int pattern_matches (pattern, percent, str) register char *pattern, *percent, *str; { unsigned int sfxlen, strlength; if (percent == 0) { unsigned int len = strlen (pattern) + 1; char *new_chars = (char *) alloca (len); bcopy (pattern, new_chars, len); pattern = new_chars; percent = find_percent (pattern); if (percent == 0) return streq (pattern, str); } sfxlen = strlen (percent + 1); strlength = strlen (str); if (strlength < (percent - pattern) + sfxlen || !strneq (pattern, str, percent - pattern)) return 0; return !strcmp (percent + 1, str + (strlength - sfxlen)); } /* Find the next comma or ENDPAREN (counting nested STARTPAREN and ENDPARENtheses), starting at PTR before END. Return a pointer to next character. If no next argument is found, return NULL. */ static char * find_next_argument (startparen, endparen, ptr, end) char startparen; char endparen; const char *ptr; const char *end; { int count = 0; for (; ptr < end; ++ptr) if (*ptr == startparen) ++count; else if (*ptr == endparen) { --count; if (count < 0) return NULL; } else if (*ptr == ',' && !count) return (char *)ptr; /* We didn't find anything. */ return NULL; } /* Glob-expand LINE. The returned pointer is only good until the next call to string_glob. */ static char * string_glob (line) char *line; { static char *result = 0; static unsigned int length; register struct nameseq *chain; register unsigned int idx; chain = multi_glob (parse_file_seq (&line, '\0', sizeof (struct nameseq), /* We do not want parse_file_seq to strip `./'s. That would break examples like: $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */ 0), sizeof (struct nameseq)); if (result == 0) { length = 100; result = (char *) xmalloc (100); } idx = 0; while (chain != 0) { register char *name = chain->name; unsigned int len = strlen (name); struct nameseq *next = chain->next; free ((char *) chain); chain = next; /* multi_glob will pass names without globbing metacharacters through as is, but we want only files that actually exist. */ if (file_exists_p (name)) { if (idx + len + 1 > length) { length += (len + 1) * 2; result = (char *) xrealloc (result, length); } bcopy (name, &result[idx], len); idx += len; result[idx++] = ' '; } free (name); } /* Kill the last space and terminate the string. */ if (idx == 0) result[0] = '\0'; else result[idx - 1] = '\0'; return result; } /* Builtin functions */ static char * func_patsubst (o, argv, funcname) char *o; char **argv; const char *funcname; { o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0); return o; } static char * func_join(o, argv, funcname) char *o; char **argv; const char *funcname; { int doneany = 0; /* Write each word of the first argument directly followed by the corresponding word of the second argument. If the two arguments have a different number of words, the excess words are just output separated by blanks. */ register char *tp; register char *pp; char *list1_iterator = argv[0]; char *list2_iterator = argv[1]; do { unsigned int len1, len2; tp = find_next_token (&list1_iterator, &len1); if (tp != 0) o = variable_buffer_output (o, tp, len1); pp = find_next_token (&list2_iterator, &len2); if (pp != 0) o = variable_buffer_output (o, pp, len2); if (tp != 0 || pp != 0) { o = variable_buffer_output (o, " ", 1); doneany = 1; } } while (tp != 0 || pp != 0); if (doneany) /* Kill the last blank. */ --o; return o; } static char * func_origin(o, argv, funcname) char *o; char **argv; const char *funcname; { /* Expand the argument. */ register struct variable *v = lookup_variable (argv[0], strlen (argv[0])); if (v == 0) o = variable_buffer_output (o, "undefined", 9); else switch (v->origin) { default: case o_invalid: abort (); break; case o_default: o = variable_buffer_output (o, "default", 7); break; case o_env: o = variable_buffer_output (o, "environment", 11); break; case o_file: o = variable_buffer_output (o, "file", 4); break; case o_env_override: o = variable_buffer_output (o, "environment override", 20); break; case o_command: o = variable_buffer_output (o, "command line", 12); break; case o_override: o = variable_buffer_output (o, "override", 8); break; case o_automatic: o = variable_buffer_output (o, "automatic", 9); break; } return o; } #ifdef VMS #define IS_PATHSEP(c) ((c) == ']') #else #if defined(__MSDOS__) || defined(WINDOWS32) #define IS_PATHSEP(c) ((c) == '/' || (c) == '\\') #else #define IS_PATHSEP(c) ((c) == '/') #endif #endif static char * func_notdir_suffix(o, argv, funcname) char *o; char **argv; const char *funcname; { /* Expand the argument. */ char *list_iterator = argv[0]; char *p2 =0; int doneany =0; int len=0; int is_suffix = streq(funcname, "suffix"); int is_notdir = !is_suffix; while ((p2 = find_next_token (&list_iterator, &len)) != 0) { char *p = p2 + len; while (p >= p2 && (!is_suffix || *p != '.')) { if (IS_PATHSEP (*p)) break; --p; } if (p >= p2) { if (is_notdir) ++p; else if (*p != '.') continue; o = variable_buffer_output (o, p, len - (p - p2)); } #if defined(WINDOWS32) || defined(__MSDOS__) /* Handle the case of "d:foo/bar". */ else if (streq(funcname, "notdir") && p2[0] && p2[1] == ':') { p = p2 + 2; o = variable_buffer_output (o, p, len - (p - p2)); } #endif else if (is_notdir) o = variable_buffer_output (o, p2, len); if (is_notdir || p >= p2) { o = variable_buffer_output (o, " ", 1); doneany = 1; } } if (doneany) /* Kill last space. */ --o; return o; } static char * func_basename_dir(o, argv, funcname) char *o; char **argv; const char *funcname; { /* Expand the argument. */ char *p3 = argv[0]; char *p2=0; int doneany=0; int len=0; char *p=0; int is_basename= streq(funcname, "basename"); int is_dir= !is_basename; while ((p2 = find_next_token (&p3, &len)) != 0) { p = p2 + len; while (p >= p2 && (!is_basename || *p != '.')) { if (IS_PATHSEP(*p)) break; --p; } if (p >= p2 && (is_dir)) o = variable_buffer_output (o, p2, ++p - p2); else if (p >= p2 && (*p == '.')) o = variable_buffer_output (o, p2, p - p2); #if defined(WINDOWS32) || defined(__MSDOS__) /* Handle the "d:foobar" case */ else if (p2[0] && p2[1] == ':' && is_dir) o = variable_buffer_output (o, p2, 2); #endif else if (is_dir) #ifdef VMS o = variable_buffer_output (o, "[]", 2); #else #ifndef _AMIGA o = variable_buffer_output (o, "./", 2); #else ; /* Just a nop... */ #endif /* AMIGA */ #endif /* !VMS */ else /* The entire name is the basename. */ o = variable_buffer_output (o, p2, len); o = variable_buffer_output (o, " ", 1); doneany = 1; } if (doneany) /* Kill last space. */ --o; return o; } static char * func_addsuffix_addprefix(o, argv, funcname) char *o; char **argv; const char *funcname; { int fixlen = strlen (argv[0]); char *list_iterator = argv[1]; int is_addprefix = streq (funcname, "addprefix"); int is_addsuffix = !is_addprefix; int doneany =0; char *p=0; int len =0; while ((p = find_next_token (&list_iterator, &len)) != 0) { if (is_addprefix) o = variable_buffer_output (o, argv[0], fixlen); o = variable_buffer_output (o, p, len); if (is_addsuffix) o = variable_buffer_output (o, argv[0], fixlen); o = variable_buffer_output (o, " ", 1); doneany = 1; } if (doneany) /* Kill last space. */ --o; return o; } static char * func_subst(o, argv, funcname) char *o; char **argv; const char *funcname; { o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]), strlen (argv[1]), 0, 0); return o; } static char * func_firstword(o, argv, funcname) char *o; char **argv; const char *funcname; { int i=0; char *words = argv[0]; char *p = find_next_token (&words, &i); if (p != 0) o = variable_buffer_output (o, p, i); return o; } static char * func_words(o, argv, funcname) char *o; char **argv; const char *funcname; { int i = 0; char *word_iterator = argv[0]; char buf[20]; while (find_next_token (&word_iterator, (unsigned int *) 0) != 0) ++i; sprintf (buf, "%d", i); o = variable_buffer_output (o, buf, strlen (buf)); return o; } char * strip_whitespace (begpp, endpp) char **begpp; char **endpp; { while (isspace (**begpp) && *begpp <= *endpp) (*begpp) ++; while (isspace (**endpp) && *endpp >= *begpp) (*endpp) --; return *begpp; } int is_numeric (p) char *p; { char *end = p + strlen (p) - 1; char *beg = p; strip_whitespace (&p, &end); while (p <= end) if (!ISDIGIT (*(p++))) /* ISDIGIT only evals its arg once: see make.h. */ return 0; return (end - beg >= 0); } void check_numeric (s, message) char *s; char *message; { if (!is_numeric (s)) fatal (reading_file, message); } static char * func_word(o, argv, funcname) char *o; char **argv; const char *funcname; { char *end_p=0; int i=0; char *p=0; /* Check the first argument. */ check_numeric (argv[0], _("non-numeric first argument to `word' function")); i = atoi (argv[0]); if (i == 0) fatal (reading_file, _("the `word' function takes a positive index argument")); end_p = argv[1]; while ((p = find_next_token (&end_p, 0)) != 0) if (--i == 0) break; if (i == 0) o = variable_buffer_output (o, p, end_p - p); return o; } static char * func_wordlist (o, argv, funcname) char *o; char **argv; const char *funcname; { int i=0; int j=0; /* Check the first argument. */ check_numeric (argv[0], _("non-numeric first argument to `wordlist' function")); i =atoi(argv[0]); check_numeric (argv[1], _("non-numeric second argument to `wordlist' function")); j = atoi(argv[1]); { char *p; char *end_p = argv[2]; int start = (i < j) ? i : j; int count = j -i ; if (count < 0) count = - count; count ++; while (((p = find_next_token (&end_p, 0)) != 0) && --start) {} if (p) { while (--count && (find_next_token (&end_p, 0) != 0)) {} o = variable_buffer_output (o, p, end_p - p); } } return o; } static char* func_findstring(o, argv, funcname) char *o; char **argv; const char *funcname; { /* Find the first occurrence of the first string in the second. */ int i = strlen (argv[0]); if (sindex (argv[1], 0, argv[0], i) != 0) o = variable_buffer_output (o, argv[0], i); return o; } static char * func_foreach (o, argv, funcname) char *o; char **argv; const char *funcname; { /* expand only the first two. */ char *varname = expand_argument (argv[0], argv[1] - 1); char *list = expand_argument (argv[1], argv[2] -1); char *body = savestring (argv[2], argv[3] - argv[2] - 1); int len =0; char *list_iterator = list; char *p; register struct variable *var=0; int doneany =0; push_new_variable_scope (); var = define_variable (varname, strlen (varname), "", o_automatic, 0); /* loop through LIST, put the value in VAR and expand BODY */ while ((p = find_next_token (&list_iterator, &len)) != 0) { char *result = 0; { char save = p[len]; p[len] = '\0'; free (var->value); var->value = (char *) xstrdup ((char*) p); p[len] = save; } result = allocated_variable_expand (body); o = variable_buffer_output (o, result, strlen (result)); o = variable_buffer_output (o, " ", 1); doneany = 1; free (result); } if (doneany) /* Kill the last space. */ --o; pop_variable_scope (); free (varname); free (list); free (body); return o; } struct a_word { struct a_word *next; char *str; int matched; }; static char * func_filter_filterout (o, argv, funcname) char *o; char **argv; const char *funcname; { struct a_word *wordhead =0; struct a_word *wordtail =0; int is_filter = streq (funcname, "filter"); char *patterns = argv[0]; char *p; int len; char *word_iterator = argv[1]; /* Chop ARGV[1] up into words and then run each pattern through. */ while ((p = find_next_token (&word_iterator, &len)) != 0) { struct a_word *w = (struct a_word *)alloca(sizeof(struct a_word)); if (wordhead == 0) wordhead = w; else wordtail->next = w; wordtail = w; if (*word_iterator != '\0') ++word_iterator; p[len] = '\0'; w->str = p; w->matched = 0; } if (wordhead != 0) { struct a_word *wp =0; char *pat_iterator = patterns; int doneany = 0; wordtail->next = 0; /* Run each pattern through the words, killing words. */ while ((p = find_next_token (&pat_iterator, &len)) != 0) { char *percent; char save = p[len]; p[len] = '\0'; percent = find_percent (p); for (wp = wordhead; wp != 0; wp = wp->next) wp->matched |= (percent == 0 ? streq (p, wp->str) : pattern_matches (p, percent, wp->str)); p[len] = save; } /* Output the words that matched (or didn't, for filter-out). */ for (wp = wordhead; wp != 0; wp = wp->next) if (is_filter ? wp->matched : !wp->matched) { o = variable_buffer_output (o, wp->str, strlen (wp->str)); o = variable_buffer_output (o, " ", 1); doneany = 1; } if (doneany) /* Kill the last space. */ --o; } return o; } static char * func_strip(o, argv, funcname) char *o; char **argv; const char *funcname; { char *p = argv[0]; int doneany =0; while (*p != '\0') { int i=0; char *word_start=0; while (isspace(*p)) ++p; word_start = p; for (i=0; *p != '\0' && !isspace(*p); ++p, ++i) {} if (!i) break; o = variable_buffer_output (o, word_start, i); o = variable_buffer_output (o, " ", 1); doneany = 1; } if (doneany) /* Kill the last space. */ --o; return o; } /* Print a warning or fatal message. */ static char * func_error (o, argv, funcname) char *o; char **argv; const char *funcname; { char **argvp; char *msg, *p; int len; /* The arguments will be broken on commas. Rather than create yet another special case where function arguments aren't broken up, just create a format string that puts them back together. */ for (len=0, argvp=argv; *argvp != 0; ++argvp) len += strlen(*argvp) + 2; p = msg = alloca (len + 1); for (argvp=argv; argvp[1] != 0; ++argvp) { strcpy(p, *argvp); p += strlen(*argvp); *(p++) = ','; *(p++) = ' '; } strcpy(p, *argvp); if (*funcname == 'e') fatal (reading_file, "%s", msg); /* The warning function expands to the empty string. */ error (reading_file, "%s", msg); return o; } /* chop argv[0] into words, and sort them. */ static char * func_sort (o, argv, funcname) char *o; char **argv; const char *funcname; { char **words = 0; int nwords = 0; register int wordi = 0; /* Chop ARGV[0] into words and put them in WORDS. */ char *t = argv[0]; char *p=0; int len; int i; while ((p = find_next_token (&t, &len)) != 0) { if (wordi >= nwords - 1) { nwords = 2* nwords + 5; words = (char **) xrealloc ((char *) words, nwords * sizeof (char *)); } words[wordi++] = savestring (p, len); } if (!wordi) return o; /* Now sort the list of words. */ qsort ((char *) words, wordi, sizeof (char *), alpha_compare); /* Now write the sorted list. */ for (i = 0; i < wordi; ++i) { len = strlen (words[i]); if (i == wordi - 1 || strlen (words[i + 1]) != len || strcmp (words[i], words[i + 1])) { o = variable_buffer_output (o, words[i], len); o = variable_buffer_output (o, " ", 1); } free (words[i]); } /* Kill the last space. */ --o; free (words); return o; } /* $(if condition,true-part[,false-part]) CONDITION is false iff it evaluates to an empty string. White space before and after condition are stripped before evaluation. If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is evaluated (if it exists). Because only one of the two PARTs is evaluated, you can use $(if ...) to create side-effects (with $(shell ...), for example). */ static char * func_if (o, argv, funcname) char *o; char **argv; const char *funcname; { char *begp = argv[0]; char *endp = argv[1]-1; int result = 0; /* Find the result of the condition: if we have a value, and it's not empty, the condition is true. If we don't have a value, or it's the empty string, then it's false. */ strip_whitespace (&begp, &endp); if (begp < endp) { char *expansion = expand_argument (begp, endp); result = strlen (expansion); free (expansion); } /* If the result is true (1) we want to eval the first argument, and if it's false (0) we want to eval the second. If the argument doesn't exist we do nothing, otherwise expand it and add to the buffer. */ argv += 1 + !result; if (argv[0] != NULL && argv[1] != NULL) { char *expansion; char **endp = argv+1; /* If we're doing the else-clause, make sure we concatenate any potential extra arguments into the last argument. */ if (!result) while (*endp && **endp != '\0') ++endp; expansion = expand_argument (*argv, *endp-1); o = variable_buffer_output (o, expansion, strlen (expansion)); free (expansion); } return o; } static char * func_wildcard(o, argv, funcname) char *o; char **argv; const char *funcname; { #ifdef _AMIGA o = wildcard_expansion (argv[0], o); #else char *p = string_glob (argv[0]); o = variable_buffer_output (o, p, strlen (p)); #endif return o; } /* \r is replaced on UNIX as well. Is this desirable? */ void fold_newlines (buffer, length) char *buffer; int *length; { char *dst = buffer; char *src = buffer; char *last_nonnl = buffer -1; src[*length] = 0; for (; *src != '\0'; ++src) { if (src[0] == '\r' && src[1] == '\n') continue; if (*src == '\n') { *dst++ = ' '; } else { last_nonnl = dst; *dst++ = *src; } } *(++last_nonnl) = '\0'; *length = last_nonnl - buffer; } int shell_function_pid = 0, shell_function_completed; #ifdef WINDOWS32 /*untested*/ #include #include #include "sub_proc.h" void windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp) { SECURITY_ATTRIBUTES saAttr; HANDLE hIn; HANDLE hErr; HANDLE hChildOutRd; HANDLE hChildOutWr; HANDLE hProcess; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &hIn, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) { fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"), GetLastError()); } if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), GetCurrentProcess(), &hErr, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) { fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"), GetLastError()); } if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError()); hProcess = process_init_fd(hIn, hChildOutWr, hErr); if (!hProcess) fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n")); else process_register(hProcess); /* make sure that CreateProcess() has Path it needs */ sync_Path_environment(); if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) *pid_p = (int) hProcess; else fatal (NILF, _("windows32_openpipe (): unable to launch process (e=%d)\n"), process_last_err(hProcess)); /* set up to read data from child */ pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY); /* this will be closed almost right away */ pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND); } #endif #ifdef __MSDOS__ FILE * msdos_openpipe (int* pipedes, int *pidp, char *text) { FILE *fpipe=0; /* MSDOS can't fork, but it has `popen'. */ struct variable *sh = lookup_variable ("SHELL", 5); int e; extern int dos_command_running, dos_status; /* Make sure not to bother processing an empty line. */ while (isblank (*text)) ~MAKE-3_78_1HB.BCK`b `AKE-3_78_1HB]FUNCTION.C;1X0>: ++text; if (*text == '\0') return 0; if (sh) { char buf[PATH_MAX + 7]; /* This makes sure $SHELL value is used by $(shell), even though the target environment is not passed to it. */ sprintf (buf, "SHELL=%s", sh->value); putenv (buf); } e = errno; errno = 0; dos_command_running = 1; dos_status = 0; /* If dos_status becomes non-zero, it means the child process was interrupted by a signal, like SIGINT or SIGQUIT. See fatal_error_signal in commands.c. */ fpipe = popen (text, "rt"); dos_command_running = 0; if (!fpipe || dos_status) { pipedes[0] = -1; *pidp = -1; if (dos_status) errno = EINTR; else if (errno == 0) errno = ENOMEM; shell_function_completed = -1; } else { pipedes[0] = fileno (fpipe); *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */ errno = e; shell_function_completed = 1; } return fpipe; } #endif /* Do shell spawning, with the naughty bits for different OSes. */ #ifdef VMS /* VMS can't do $(shell ...) */ #define func_shell 0 #else #ifndef _AMIGA static char * func_shell (o, argv, funcname) char *o; char **argv; const char *funcname; { char* batch_filename = NULL; int i; #ifdef __MSDOS__ FILE *fpipe; #endif char **command_argv; char *error_prefix; char **envp; int pipedes[2]; int pid; #ifndef __MSDOS__ /* Construct the argument list. */ command_argv = construct_command_argv (argv[0], (char **) NULL, (struct file *) 0, &batch_filename); if (command_argv == 0) return o; #endif /* Using a target environment for `shell' loses in cases like: export var = $(shell echo foobie) because target_environment hits a loop trying to expand $(var) to put it in the environment. This is even more confusing when var was not explicitly exported, but just appeared in the calling environment. */ envp = environ; /* For error messages. */ if (reading_file != 0) { error_prefix = (char *) alloca (strlen(reading_file->filenm)+11+4); sprintf (error_prefix, "%s:%lu: ", reading_file->filenm, reading_file->lineno); } else error_prefix = ""; #ifdef WINDOWS32 windows32_openpipe (pipedes, &pid, command_argv, envp); #else /* WINDOWS32 */ # ifdef __MSDOS__ fpipe = msdos_openpipe (pipedes, &pid, argv[0]); if (pipedes[0] < 0) { perror_with_name (error_prefix, "pipe"); return o; } # else if (pipe (pipedes) < 0) { perror_with_name (error_prefix, "pipe"); return o; } pid = vfork (); if (pid < 0) perror_with_name (error_prefix, "fork"); else if (pid == 0) child_execute_job (0, pipedes[1], command_argv, envp); else # endif /* ! __MSDOS__ */ #endif /* WINDOWS32 */ { /* We are the parent. */ char *buffer; unsigned int maxlen; int cc; /* Record the PID for reap_children. */ shell_function_pid = pid; #ifndef __MSDOS__ shell_function_completed = 0; /* Free the storage only the child needed. */ free (command_argv[0]); free ((char *) command_argv); /* Close the write side of the pipe. */ (void) close (pipedes[1]); #endif /* Set up and read from the pipe. */ maxlen = 200; buffer = (char *) xmalloc (maxlen + 1); /* Read from the pipe until it gets EOF. */ i = 0; do { if (i == maxlen) { maxlen += 512; buffer = (char *) xrealloc (buffer, maxlen + 1); } errno = 0; cc = read (pipedes[0], &buffer[i], maxlen - i); if (cc > 0) i += cc; } while (cc > 0 || EINTR_SET); /* Close the read side of the pipe. */ #ifdef __MSDOS__ if (fpipe) (void) pclose (fpipe); #else (void) close (pipedes[0]); #endif /* Loop until child_handler sets shell_function_completed to the status of our child shell. */ while (shell_function_completed == 0) reap_children (1, 0); if (batch_filename) { if (debug_flag) printf(_("Cleaning up temporary batch file %s\n"), batch_filename); remove(batch_filename); free(batch_filename); } shell_function_pid = 0; /* The child_handler function will set shell_function_completed to 1 when the child dies normally, or to -1 if it dies with status 127, which is most likely an exec fail. */ if (shell_function_completed == -1) { /* This most likely means that the execvp failed, so we should just write out the error message that came in over the pipe from the child. */ fputs (buffer, stderr); fflush (stderr); } else { /* The child finished normally. Replace all newlines in its output with spaces, and put that in the variable output buffer. */ fold_newlines (buffer, &i); o = variable_buffer_output (o, buffer, i); } free (buffer); } return o; } #else /* _AMIGA */ /* Do the Amiga version of func_shell. */ static char * func_shell (char *o, char **argv, const char *funcname) { /* Amiga can't fork nor spawn, but I can start a program with redirection of my choice. However, this means that we don't have an opportunity to reopen stdout to trap it. Thus, we save our own stdout onto a new descriptor and dup a temp file's descriptor onto our stdout temporarily. After we spawn the shell program, we dup our own stdout back to the stdout descriptor. The buffer reading is the same as above, except that we're now reading from a file. */ #include #include BPTR child_stdout; char tmp_output[FILENAME_MAX]; unsigned int maxlen = 200; int cc, i; char * buffer, * ptr; char ** aptr; int len = 0; char* batch_filename = NULL; /* Construct the argument list. */ command_argv = construct_command_argv (argv[0], (char **) NULL, (struct file *) 0, &batch_filename); if (command_argv == 0) return o; strcpy (tmp_output, "t:MakeshXXXXXXXX"); mktemp (tmp_output); child_stdout = Open (tmp_output, MODE_NEWFILE); for (aptr=command_argv; *aptr; aptr++) len += strlen (*aptr) + 1; buffer = xmalloc (len + 1); ptr = buffer; for (aptr=command_argv; *aptr; aptr++) { strcpy (ptr, *aptr); ptr += strlen (ptr) + 1; *ptr ++ = ' '; *ptr = 0; } ptr[-1] = '\n'; Execute (buffer, NULL, child_stdout); free (buffer); Close (child_stdout); child_stdout = Open (tmp_output, MODE_OLDFILE); buffer = xmalloc (maxlen); i = 0; do { if (i == maxlen) { maxlen += 512; buffer = (char *) xrealloc (buffer, maxlen + 1); } cc = Read (child_stdout, &buffer[i], maxlen - i); if (cc > 0) i += cc; } while (cc > 0); Close (child_stdout); fold_newlines (buffer, &i); o = variable_buffer_output (o, buffer, i); free (buffer); return o; } #endif /* _AMIGA */ #endif /* !VMS */ #ifdef EXPERIMENTAL /* equality. Return is string-boolean, ie, the empty string is false. */ static char * func_eq (char* o, char **argv, char *funcname) { int result = ! strcmp (argv[0], argv[1]); o = variable_buffer_output (o, result ? "1" : "", result); return o; } /* string-boolean not operator. */ static char * func_not (char* o, char **argv, char *funcname) { char * s = argv[0]; int result = 0; while (isspace (*s)) s++; result = ! (*s); o = variable_buffer_output (o, result ? "1" : "", result); return o; } #endif #define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1) /* Lookup table for builtin functions. This doesn't have to be sorted; we use a straight lookup. We might gain some efficiency by moving most often used functions to the start of the table. If REQUIRED_ARGS is positive, the function takes exactly that many arguments. All subsequent text is included with the last argument. So, since $(sort a,b,c) takes only one argument, it will be the full string "a,b,c". If the value is negative, it's the minimum number of arguments. A function can have more, but if it has less an error is generated. EXPAND_ARGS means that all arguments should be expanded before invocation. Functions that do namespace tricks (foreach) don't automatically expand. */ static char *func_call PARAMS((char *o, char **argv, const char *funcname)); static struct function_table_entry function_table[] = { /* Name/size */ /* ARG EXP? Function */ { STRING_SIZE_TUPLE("addprefix"), 2, 1, func_addsuffix_addprefix}, { STRING_SIZE_TUPLE("addsuffix"), 2, 1, func_addsuffix_addprefix}, { STRING_SIZE_TUPLE("basename"), 1, 1, func_basename_dir}, { STRING_SIZE_TUPLE("dir"), 1, 1, func_basename_dir}, { STRING_SIZE_TUPLE("notdir"), 1, 1, func_notdir_suffix}, { STRING_SIZE_TUPLE("subst"), 3, 1, func_subst}, { STRING_SIZE_TUPLE("suffix"), 1, 1, func_notdir_suffix}, { STRING_SIZE_TUPLE("filter"), 2, 1, func_filter_filterout}, { STRING_SIZE_TUPLE("filter-out"), 2, 1, func_filter_filterout}, { STRING_SIZE_TUPLE("findstring"), 2, 1, func_findstring}, { STRING_SIZE_TUPLE("firstword"), 1, 1, func_firstword}, { STRING_SIZE_TUPLE("join"), 2, 1, func_join}, { STRING_SIZE_TUPLE("patsubst"), 3, 1, func_patsubst}, { STRING_SIZE_TUPLE("shell"), 1, 1, func_shell}, { STRING_SIZE_TUPLE("sort"), 1, 1, func_sort}, { STRING_SIZE_TUPLE("strip"), 1, 1, func_strip}, { STRING_SIZE_TUPLE("wildcard"), 1, 1, func_wildcard}, { STRING_SIZE_TUPLE("word"), 2, 1, func_word}, { STRING_SIZE_TUPLE("wordlist"), 3, 1, func_wordlist}, { STRING_SIZE_TUPLE("words"), 1, 1, func_words}, { STRING_SIZE_TUPLE("origin"), 1, 1, func_origin}, { STRING_SIZE_TUPLE("foreach"), 3, 0, func_foreach}, { STRING_SIZE_TUPLE("call"), -1, 1, func_call}, { STRING_SIZE_TUPLE("error"), 1, 1, func_error}, { STRING_SIZE_TUPLE("warning"), 1, 1, func_error}, { STRING_SIZE_TUPLE("if"), -2, 0, func_if}, #ifdef EXPERIMENTAL { STRING_SIZE_TUPLE("eq"), 2, 1, func_eq}, { STRING_SIZE_TUPLE("not"), 1, 1, func_not}, #endif { 0 } }; /* These must come after the definition of function_table[]. */ static char * expand_builtin_function (o, argc, argv, entry_p) char *o; int argc; char **argv; struct function_table_entry *entry_p; { int min = (entry_p->required_args > 0 ? entry_p->required_args : -entry_p->required_args); if (argc < min) fatal (reading_file, _("Insufficient number of arguments (%d) to function `%s'"), argc, entry_p->name); if (!entry_p->func_ptr) fatal (reading_file, _("Unimplemented on this platform: function `%s'"), entry_p->name); return entry_p->func_ptr (o, argv, entry_p->name); } /* Check for a function invocation in *STRINGP. *STRINGP points at the opening ( or { and is not null-terminated. If a function invocation is found, expand it into the buffer at *OP, updating *OP, incrementing *STRINGP past the reference and returning nonzero. If not, return zero. */ int handle_function (op, stringp) char **op; char **stringp; { const struct function_table_entry *entry_p; char openparen = (*stringp)[0]; char closeparen = openparen == '(' ? ')' : '}'; char *beg = *stringp + 1; char *endref; int count = 0; char *argbeg; register char *p; char **argv, **argvp; int nargs; entry_p = lookup_function (function_table, beg); if (!entry_p) return 0; /* We have found a call to a builtin function. Find the end of the arguments, and do the function. */ endref = beg + entry_p->len; /* Space after function name isn't part of the args. */ p = next_token (endref); argbeg = p; /* Find the end of the function invocation, counting nested use of whichever kind of parens we use. Since we're looking, count commas to get a rough estimate of how many arguments we might have. The count might be high, but it'll never be low. */ for (nargs=1; *p != '\0'; ++p) if (*p == ',') ++nargs; else if (*p == openparen) ++count; else if (*p == closeparen && --count < 0) break; if (count >= 0) fatal (reading_file, _("unterminated call to function `%s': missing `%c'"), entry_p->name, closeparen); /* Get some memory to store the arg pointers. */ argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2)); /* Chop the string into arguments, then store the end pointer and a nul. If REQUIRED_ARGS is positive, as soon as we hit that many assume the rest of the string is part of the last argument. */ *argvp = argbeg; nargs = 1; while (entry_p->required_args < 0 || nargs < entry_p->required_args) { char *next = find_next_argument (openparen, closeparen, *argvp, p); if (!next) break; *(++argvp) = next+1; ++nargs; } *(++argvp) = p+1; *(++argvp) = 0; /* If we should expand, do it. */ if (entry_p->expand_args) { for (argvp=argv; argvp[1] != 0; ++argvp) *argvp = expand_argument (*argvp, argvp[1]-1); /* end pointer doesn't make sense for expanded stuff. */ *argvp = 0; } /* Finally! Run the function... */ *op = expand_builtin_function (*op, nargs, argv, entry_p); /* If we allocated memory for the expanded args, free it again. */ if (entry_p->expand_args) for (argvp=argv; *argvp != 0; ++argvp) free (*argvp); *stringp = p; return 1; } /* User-defined functions. Expand the first argument as either a builtin function or a make variable, in the context of the rest of the arguments assigned to $1, $2, ... $N. $0 is the name of the function. */ static char * func_call (o, argv, funcname) char *o; char **argv; const char *funcname; { char *fname; int flen; char *body; int i; const struct function_table_entry *entry_p; /* Calling nothing is a no-op. */ if (*argv[0] == '\0') return o; /* There is no way to define a variable with a space in the name, so strip trailing whitespace as a favor to the user. */ flen = strlen (argv[0]); fname = argv[0] + flen - 1; while (isspace (*fname)) --fname; fname[1] = '\0'; flen = fname - argv[0] + 1; fname = argv[0]; /* Are we invoking a builtin function? */ entry_p = lookup_function (function_table, fname); if (entry_p) { for (i=0; argv[i+1]; ++i) ; return expand_builtin_function (o, i, argv + 1, entry_p); } /* No, so the first argument is the name of a variable to be expanded and interpreted as a function. Create the variable reference. */ body = alloca (flen + 4); body[0]='$'; body[1]='('; strcpy (body + 2, fname); body[flen+2]=')'; body[flen+3]= '\0'; /* Set up arguments $(1) .. $(N). $(0) is the function name. */ push_new_variable_scope (); for (i=0; *argv; ++i, ++argv) { char num[11]; sprintf (num, "%d", i); define_variable (num, strlen (num), *argv, o_automatic, 0); } /* Expand the body in the context of the arguments, adding the result to the variable buffer. */ o = variable_expand_string (o, body, flen+3); pop_variable_scope (); return o + strlen(o); } *[MAKE-3_78_1HB]GETLOADAVG.C;1+,ab.8/@ 485l-`0123KPWO956[7Am89G@HJ</* Get the system load averages. Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995, 1997 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Compile-time symbols that this file uses: HAVE_PSTAT_GETDYNAMIC Define this if your system has the pstat_getdynamic function. I think it is unique to HPUX9. The best way to get the definition is through the AC_FUNC_GETLOADAVG macro that comes with autoconf 2.13 or newer. If that isn't an option, then just put AC_CHECK_FUNCS(pstat_getdynamic) in your configure.in file. FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. KERNEL_FILE Pathname of the kernel to nlist. LDAV_CVT() Scale the load average from the kernel. Returns a double. LDAV_SYMBOL Name of kernel symbol giving load average. LOAD_AVE_TYPE Type of the load average array in the kernel. Must be defined unless one of apollo, DGUX, NeXT, or UMAX is defined; or we have libkstat; otherwise, no load average is available. NLIST_STRUCT Include nlist.h, not a.out.h, and the nlist n_name element is a pointer, not an array. NLIST_NAME_UNION struct nlist has an n_un member, not n_name. LINUX_LDAV_FILE [__linux__]: File containing load averages. Specific system predefines this file uses, aside from setting default values if not emacs: apollo BSD Real BSD, not just BSD-like. convex DGUX eunice UNIX emulator under VMS. hpux __MSDOS__ No-op for MSDOS. NeXT sgi sequent Sequent Dynix 3.x.x (BSD) _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) sony_news NEWS-OS (works at least for 4.1C) UMAX UMAX4_3 VMS WINDOWS32 No-op for Windows95/NT. __linux__ Linux: assumes /proc filesystem mounted. Support from Michael K. Johnson. __NetBSD__ NetBSD: assumes /kern filesystem mounted. In addition, to avoid nesting many #ifdefs, we internally set LDAV_DONE to indicate that the load average has been computed. We also #define LDAV_PRIVILEGED if a program will require special installation to be able to call getloadavg. */ /* This should always be first. */ #ifdef HAVE_CONFIG_H # include #endif #include /* Both the Emacs and non-Emacs sections want this. Some configuration files' definitions for the LOAD_AVE_CVT macro (like sparc.h's) use macros like FSCALE, defined here. */ #if defined (unix) || defined (__unix) # include #endif /* Exclude all the code except the test program at the end if the system has its own `getloadavg' function. The declaration of `errno' is needed by the test program as well as the function itself, so it comes first. */ #include #ifndef errno extern int errno; #endif #ifndef HAVE_GETLOADAVG /* The existing Emacs configuration files define a macro called LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and returns the load average multiplied by 100. What we actually want is a macro called LDAV_CVT, which returns the load average as an unmultiplied double. For backwards compatibility, we'll define LDAV_CVT in terms of LOAD_AVE_CVT, but future machine config files should just define LDAV_CVT directly. */ # if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) # define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) # endif # if !defined (BSD) && defined (ultrix) /* Ultrix behaves like BSD on Vaxen. */ # define BSD # endif # ifdef NeXT /* NeXT in the 2.{0,1,2} releases defines BSD in , which conflicts with the definition understood in this file, that this really is BSD. */ # undef BSD /* NeXT defines FSCALE in . However, we take FSCALE being defined to mean that the nlist method should be used, which is not true. */ # undef FSCALE # endif /* Same issues as for NeXT apply to the HURD-based GNU system. */ # ifdef __GNU__ # undef BSD # undef FSCALE # endif /* __GNU__ */ /* Set values that are different from the defaults, which are set a little farther down with #ifndef. */ /* Some shorthands. */ # if defined (HPUX) && !defined (hpux) # define hpux # endif # if defined (__hpux) && !defined (hpux) # define hpux # endif # if defined (__sun) && !defined (sun) # define sun # endif # if defined(hp300) && !defined(hpux) # define MORE_BSD # endif # if defined(ultrix) && defined(mips) # define decstation # endif # if defined (__SVR4) && !defined (SVR4) # define SVR4 # endif # if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) # define SUNOS_5 # endif # if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) # define OSF_ALPHA # include # include # include # include # endif # if defined (__osf__) && (defined (mips) || defined (__mips__)) # define OSF_MIPS # include # endif /* UTek's /bin/cc on the 4300 has no architecture specific cpp define by default, but _MACH_IND_SYS_TYPES is defined in . Combine that with a couple of other things and we'll have a unique match. */ # if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES) # define tek4300 /* Define by emacs, but not by other users. */ # endif /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ # ifndef LOAD_AVE_TYPE # ifdef MORE_BSD # define LOAD_AVE_TYPE long # endif # ifdef sun # define LOAD_AVE_TYPE long # endif # ifdef decstation # define LOAD_AVE_TYPE long # endif # ifdef _SEQUENT_ # define LOAD_AVE_TYPE long # endif # ifdef sgi # define LOAD_AVE_TYPE long # endif # ifdef SVR4 # define LOAD_AVE_TYPE long # endif # ifdef sony_news # define LOAD_AVE_TYPE long # endif # ifdef sequent # define LOAD_AVE_TYPE long # endif # ifdef OSF_ALPHA # define LOAD_AVE_TYPE long # endif # if defined (ardent) && defined (titan) # define LOAD_AVE_TYPE long # endif # ifdef tek4300 # define LOAD_AVE_TYPE long # endif # if defined(alliant) && defined(i860) /* Alliant FX/2800 */ # define LOAD_AVE_TYPE long # endif # ifdef _AIX # define LOAD_AVE_TYPE long # endif # ifdef convex # define LOAD_AVE_TYPE double # ifndef LDAV_CVT # define LDAV_CVT(n) (n) # endif # endif # endif /* No LOAD_AVE_TYPE. */ # ifdef OSF_ALPHA /* defines an incorrect value for FSCALE on Alpha OSF/1, according to ghazi@noc.rutgers.edu. */ # undef FSCALE # define FSCALE 1024.0 # endif # if defined(alliant) && defined(i860) /* Alliant FX/2800 */ /* defines an incorrect value for FSCALE on an Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ # undef FSCALE # define FSCALE 100.0 # endif # ifndef FSCALE /* SunOS and some others define FSCALE in sys/param.h. */ # ifdef MORE_BSD # define FSCALE 2048.0 # endif # if defined(MIPS) || defined(SVR4) || defined(decstation) # define FSCALE 256 # endif # if defined (sgi) || defined (sequent) /* Sometimes both MIPS and sgi are defined, so FSCALE was just defined above under #ifdef MIPS. But we want the sgi value. */ # undef FSCALE # define FSCALE 1000.0 # endif # if defined (ardent) && defined (titan) # define FSCALE 65536.0 # endif # ifdef tek4300 # define FSCALE 100.0 # endif # ifdef _AIX # define FSCALE 65536.0 # endif # endif /* Not FSCALE. */ # if !defined (LDAV_CVT) && defined (FSCALE) # define LDAV_CVT(n) (((double) (n)) / FSCALE) # endif /* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */ # ifndef NLIST_STRUCT # ifdef MORE_BSD # define NLIST_STRUCT # endif # ifdef sun # define NLIST_STRUCT # endif # ifdef decstation # define NLIST_STRUCT # endif # ifdef hpux # define NLIST_STRUCT # endif # if defined (_SEQUENT_) || defined (sequent) # define NLIST_STRUCT # endif # ifdef sgi # define NLIST_STRUCT # endif # ifdef SVR4 # define NLIST_STRUCT # endif # ifdef sony_news # define NLIST_STRUCT # endif # ifdef OSF_ALPHA # define NLIST_STRUCT # endif # if defined (ardent) && defined (titan) # define NLIST_STRUCT # endif # ifdef tek4300 # define NLIST_STRUCT # endif # ifdef butterfly # define NLIST_STRUCT # endif # if defined(alliant) && defined(i860) /* Alliant FX/2800 */ # define NLIST_STRUCT # endif # ifdef _AIX # define NLIST_STRUCT # endif # endif /* defined (NLIST_STRUCT) */ # if defined(sgi) || (defined(mips) && !defined(BSD)) # define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31)) # endif # if !defined (KERNEL_FILE) && defined (sequent) # define KERNEL_FILE "/dynix" # endif # if !defined (KERNEL_FILE) && defined (hpux) # define KERNEL_FILE "/hp-ux" # endif # if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan))) # define KERNEL_FILE "/unix" # endif # if !defined (LDAV_SYMBOL) && defined (alliant) # define LDAV_SYMBOL "_Loadavg" # endif # if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) # define LDAV_SYMBOL "avenrun" # endif # ifdef HAVE_UNISTD_H # include # endif # include /* LOAD_AVE_TYPE should only get defined if we're going to use the nlist method. */ # if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) # define LOAD_AVE_TYPE double # endif # ifdef LOAD_AVE_TYPE # ifndef VMS # ifndef __linux__ # ifndef NLIST_STRUCT # include # else /* NLIST_STRUCT */ # include # endif /* NLIST_STRUCT */ # ifdef SUNOS_5 # include # include # include # endif # if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) # include # endif # ifndef KERNEL_FILE # define KERNEL_FILE "/vmunix" # endif /* KERNEL_FILE */ # ifndef LDAV_SYMBOL # define LDAV_SYMBOL "_avenrun" # endif /* LDAV_SYMBOL */ # endif /* __linux__ */ # else /* VMS */ # ifndef eunice # include # include # else /* eunice */ # include # endif /* eunice */ # endif /* VMS */ # ifndef LDAV_CVT # define LDAV_CVT(n) ((double) (n)) # endif /* !LDAV_CVT */ # endif /* LOAD_AVE_TYPE */ # if defined(__GNU__) && !defined (NeXT) /* Note that NeXT Openstep defines __GNU__ even though it should not. */ /* GNU system acts much like NeXT, for load average purposes, but not exactly. */ # define NeXT # define host_self mach_host_self # endif # ifdef NeXT # ifdef HAVE_MACH_MACH_H # include # else # include # endif # endif /* NeXT */ # ifdef sgi # include # endif /* sgi */ # ifdef UMAX # include # include # include # include # include # ifdef UMAX_43 # include # include # include # include # include # else /* Not UMAX_43. */ # include # include # include # include # include # include # endif /* Not UMAX_43. */ # endif /* UMAX */ # ifdef DGUX # include # endif # if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) # include # else # include # endif /* Avoid static vars inside a function since in HPUX they dump as pure. */ # ifdef NeXT static processor_set_t default_set; static int getloadavg_initialized; # endif /* NeXT */ # ifdef UMAX static unsigned int cpus = 0; static unsigned int samples; # endif /* UMAX */ # ifdef DGUX static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ # endif /* DGUX */ #if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE) /* File descriptor open to /dev/kmem or VMS load ave driver. */ static int channel; /* Nonzero iff channel is valid. */ static int getloadavg_initialized; /* Offset in kmem to seek to read load average, or 0 means invalid. */ static long offset; #if !defined(VMS) && !defined(sgi) && !defined(__linux__) static struct nlist nl[2]; #endif /* Not VMS or sgi */ #ifdef SUNOS_5 static kvm_t *kd; #endif /* SUNOS_5 */ #endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */ /* Put the 1 minute, 5 minute and 15 minute load averages into the first NELEM elements of LOADAVG. Return the number written (never more than 3, but may be less than NELEM), or -1 if an error occurred. */ int getloadavg (loadavg, nelem) double loadavg[]; int nelem; { int elem = 0; /* Return value. */ # ifdef NO_GET_LOAD_AVG # define LDAV_DONE /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; elem = -1; # endif # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Use libkstat because we don't have to be root. */ # define LDAV_DONE kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; kc = kstat_open (); if (kc == 0) return -1; ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == 0 ) return -1; if (kstat_read (kc, ksp, 0) == -1) return -1; kn = kstat_data_lookup (ksp, "avenrun_1min"); if (kn == 0) { /* Return -1 if no load average information is available. */ nelem = 0; elem = -1; } if (nelem >= 1) loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 2) { kn = kstat_data_lookup (ksp, "avenrun_5min"); if (kn != 0) { loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 3) { kn = kstat_data_lookup (ksp, "avenrun_15min"); if (kn != 0) loadavg[elem++] = (double) kn->value.ul/FSCALE; } } } kstat_close (kc); # endif /* HAVE_LIBKSTAT */ # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) /* Use pstat_getdynamic() because we don't have to be root. */ # define LDAV_DONE # undef LOAD_AVE_TYPE struct pst_dynamic dyn_info; if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) return -1; if (nelem > 0) loadavg[elem++] = dyn_info.psd_avg_1_min; if (nelem > 1) loadavg[elem++] = dyn_info.psd_a~MAKE-3_78_1HB.BCKab`[MAKE-3_78_1HB]GETLOADAVG.C;18.vg_5_min; if (nelem > 2) loadavg[elem++] = dyn_info.psd_avg_15_min; # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ # if !defined (LDAV_DONE) && defined (__linux__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef LINUX_LDAV_FILE # define LINUX_LDAV_FILE "/proc/loadavg" # endif char ldavgbuf[40]; double load_ave[3]; int fd, count; fd = open (LINUX_LDAV_FILE, O_RDONLY); if (fd == -1) return -1; count = read (fd, ldavgbuf, 40); (void) close (fd); if (count <= 0) return -1; count = sscanf (ldavgbuf, "%lf %lf %lf", &load_ave[0], &load_ave[1], &load_ave[2]); if (count < 1) return -1; for (elem = 0; elem < nelem && elem < count; elem++) loadavg[elem] = load_ave[elem]; return elem; # endif /* __linux__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef NETBSD_LDAV_FILE # define NETBSD_LDAV_FILE "/kern/loadavg" # endif unsigned long int load_ave[3], scale; int count; FILE *fp; fp = fopen (NETBSD_LDAV_FILE, "r"); if (fp == NULL) return -1; count = fscanf (fp, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); (void) fclose (fp); if (count != 4) return -1; for (elem = 0; elem < nelem; elem++) loadavg[elem] = (double) load_ave[elem] / (double) scale; return elem; # endif /* __NetBSD__ */ # if !defined (LDAV_DONE) && defined (NeXT) # define LDAV_DONE /* The NeXT code was adapted from iscreen 3.2. */ host_t host; struct processor_set_basic_info info; unsigned info_count; /* We only know how to get the 1-minute average for this system, so even if the caller asks for more than 1, we only return 1. */ if (!getloadavg_initialized) { if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) getloadavg_initialized = 1; } if (getloadavg_initialized) { info_count = PROCESSOR_SET_BASIC_INFO_COUNT; if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t) &info, &info_count) != KERN_SUCCESS) getloadavg_initialized = 0; else { if (nelem > 0) loadavg[elem++] = (double) info.load_average / LOAD_SCALE; } } if (!getloadavg_initialized) return -1; # endif /* NeXT */ # if !defined (LDAV_DONE) && defined (UMAX) # define LDAV_DONE /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not have a /dev/kmem. Information about the workings of the running kernel can be gathered with inq_stats system calls. We only know how to get the 1-minute average for this system. */ struct proc_summary proc_sum_data; struct stat_descr proc_info; double load; register unsigned int i, j; if (cpus == 0) { register unsigned int c, i; struct cpu_config conf; struct stat_descr desc; desc.sd_next = 0; desc.sd_subsys = SUBSYS_CPU; desc.sd_type = CPUTYPE_CONFIG; desc.sd_addr = (char *) &conf; desc.sd_size = sizeof conf; if (inq_stats (1, &desc)) return -1; c = 0; for (i = 0; i < conf.config_maxclass; ++i) { struct class_stats stats; bzero ((char *) &stats, sizeof stats); desc.sd_type = CPUTYPE_CLASS; desc.sd_objid = i; desc.sd_addr = (char *) &stats; desc.sd_size = sizeof stats; if (inq_stats (1, &desc)) return -1; c += stats.class_numcpus; } cpus = c; samples = cpus < 2 ? 3 : (2 * cpus / 3); } proc_info.sd_next = 0; proc_info.sd_subsys = SUBSYS_PROC; proc_info.sd_type = PROCTYPE_SUMMARY; proc_info.sd_addr = (char *) &proc_sum_data; proc_info.sd_size = sizeof (struct proc_summary); proc_info.sd_sizeused = 0; if (inq_stats (1, &proc_info) != 0) return -1; load = proc_sum_data.ps_nrunnable; j = 0; for (i = samples - 1; i > 0; --i) { load += proc_sum_data.ps_nrun[j]; if (j++ == PS_NRUNSIZE) j = 0; } if (nelem > 0) loadavg[elem++] = load / samples / cpus; # endif /* UMAX */ # if !defined (LDAV_DONE) && defined (DGUX) # define LDAV_DONE /* This call can return -1 for an error, but with good args it's not supposed to fail. The first argument is for no apparent reason of type `long int *'. */ dg_sys_info ((long int *) &load_info, DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); if (nelem > 0) loadavg[elem++] = load_info.one_minute; if (nelem > 1) loadavg[elem++] = load_info.five_minute; if (nelem > 2) loadavg[elem++] = load_info.fifteen_minute; # endif /* DGUX */ # if !defined (LDAV_DONE) && defined (apollo) # define LDAV_DONE /* Apollo code from lisch@mentorg.com (Ray Lischner). This system call is not documented. The load average is obtained as three long integers, for the load average over the past minute, five minutes, and fifteen minutes. Each value is a scaled integer, with 16 bits of integer part and 16 bits of fraction part. I'm not sure which operating system first supported this system call, but I know that SR10.2 supports it. */ extern void proc1_$get_loadav (); unsigned long load_ave[3]; proc1_$get_loadav (load_ave); if (nelem > 0) loadavg[elem++] = load_ave[0] / 65536.0; if (nelem > 1) loadavg[elem++] = load_ave[1] / 65536.0; if (nelem > 2) loadavg[elem++] = load_ave[2] / 65536.0; # endif /* apollo */ # if !defined (LDAV_DONE) && defined (OSF_MIPS) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); loadavg[elem++] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[0] : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); # endif /* OSF_MIPS */ # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) # define LDAV_DONE /* A faithful emulation is going to have to be saved for a rainy day. */ for ( ; elem < nelem; elem++) { loadavg[elem] = 0.0; } # endif /* __MSDOS__ || WINDOWS32 */ # if !defined (LDAV_DONE) && defined (OSF_ALPHA) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); for (elem = 0; elem < nelem; elem++) loadavg[elem] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[elem] : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); # endif /* OSF_ALPHA */ # if !defined (LDAV_DONE) && defined (VMS) /* VMS specific code -- read from the Load Ave driver. */ LOAD_AVE_TYPE load_ave[3]; static int getloadavg_initialized = 0; # ifdef eunice struct { int dsc$w_length; char *dsc$a_pointer; } descriptor; # endif /* Ensure that there is a channel open to the load ave device. */ if (!getloadavg_initialized) { /* Attempt to open the channel. */ # ifdef eunice descriptor.dsc$w_length = 18; descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; # else $DESCRIPTOR (descriptor, "LAV0:"); # endif if (sys$assign (&descriptor, &channel, 0, 0) & 1) getloadavg_initialized = 1; } /* Read the load average vector. */ if (getloadavg_initialized && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, load_ave, 12, 0, 0, 0, 0) & 1)) { sys$dassgn (channel); getloadavg_initialized = 0; } if (!getloadavg_initialized) return -1; # endif /* VMS */ # if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) /* UNIX-specific code -- read the average from /dev/kmem. */ # define LDAV_PRIVILEGED /* This code requires special installation. */ LOAD_AVE_TYPE load_ave[3]; /* Get the address of LDAV_SYMBOL. */ if (offset == 0) { # ifndef sgi # ifndef NLIST_STRUCT strcpy (nl[0].n_name, LDAV_SYMBOL); strcpy (nl[1].n_name, ""); # else /* NLIST_STRUCT */ # ifdef NLIST_NAME_UNION nl[0].n_un.n_name = LDAV_SYMBOL; nl[1].n_un.n_name = 0; # else /* not NLIST_NAME_UNION */ nl[0].n_name = LDAV_SYMBOL; nl[1].n_name = 0; # endif /* not NLIST_NAME_UNION */ # endif /* NLIST_STRUCT */ # ifndef SUNOS_5 if ( # if !(defined (_AIX) && !defined (ps2)) nlist (KERNEL_FILE, nl) # else /* _AIX */ knlist (nl, 1, sizeof (nl[0])) # endif >= 0) /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ { # ifdef FIXUP_KERNEL_SYMBOL_ADDR FIXUP_KERNEL_SYMBOL_ADDR (nl); # endif offset = nl[0].n_value; } # endif /* !SUNOS_5 */ # else /* sgi */ int ldav_off; ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); if (ldav_off != -1) offset = (long) ldav_off & 0x7fffffff; # endif /* sgi */ } /* Make sure we have /dev/kmem open. */ if (!getloadavg_initialized) { # ifndef SUNOS_5 channel = open ("/dev/kmem", 0); if (channel >= 0) { /* Set the channel to close on exec, so it does not litter any child's descriptor table. */ # ifdef F_SETFD # ifndef FD_CLOEXEC # define FD_CLOEXEC 1 # endif (void) fcntl (channel, F_SETFD, FD_CLOEXEC); # endif getloadavg_initialized = 1; } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names to use the currently running kernel. */ kd = kvm_open (0, 0, 0, O_RDONLY, 0); if (kd != 0) { /* nlist the currently running kernel. */ kvm_nlist (kd, nl); offset = nl[0].n_value; getloadavg_initialized = 1; } # endif /* SUNOS_5 */ } /* If we can, get the load average values. */ if (offset && getloadavg_initialized) { /* Try to read the load. */ # ifndef SUNOS_5 if (lseek (channel, offset, 0) == -1L || read (channel, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { close (channel); getloadavg_initialized = 0; } # else /* SUNOS_5 */ if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { kvm_close (kd); getloadavg_initialized = 0; } # endif /* SUNOS_5 */ } if (offset == 0 || !getloadavg_initialized) return -1; # endif /* LOAD_AVE_TYPE and not VMS */ # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ if (nelem > 0) loadavg[elem++] = LDAV_CVT (load_ave[0]); if (nelem > 1) loadavg[elem++] = LDAV_CVT (load_ave[1]); if (nelem > 2) loadavg[elem++] = LDAV_CVT (load_ave[2]); # define LDAV_DONE # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ # ifdef LDAV_DONE return elem; # else /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; return -1; # endif } #endif /* ! HAVE_GETLOADAVG */ #ifdef TEST int main (argc, argv) int argc; char **argv; { int naptime = 0; if (argc > 1) naptime = atoi (argv[1]); while (1) { double avg[3]; int loads; errno = 0; /* Don't be misled if it doesn't set errno. */ loads = getloadavg (avg, 3); if (loads == -1) { perror ("Error getting load average"); exit (1); } if (loads > 0) printf ("1-minute: %f ", avg[0]); if (loads > 1) printf ("5-minute: %f ", avg[1]); if (loads > 2) printf ("15-minute: %f ", avg[2]); if (loads > 0) putchar ('\n'); if (naptime == 0) break; sleep (naptime); } exit (0); } #endif /* TEST */ *[MAKE-3_78_1HB]GETOPT.C;1+,bb.</@ 4<;-`0123KPWO=567zBQm89G@HJL/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@gnu.org. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #ifdef HAVE_CONFIG_H # include #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) # else # define _(msgid) (msgid) # endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else # if HAVE_STRING_H # include # else # include # endif /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over~MAKE-3_78_1HB.BCKbb`[MAKE-3_78_1HB]GETOPT.C;1<.*' any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ t*[MAKE-3_78_1HB]GETOPT.H;1+,cb. /@ 4 -`0123KPWO 56{7]`m89G@HJ/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@gnu.org. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* getopt.h */ t*[MAKE-3_78_1HB]GETOPT1.C;1+,db. /@ 4 -`0123KPWO 56a17om89G@HJ/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@gnu.org. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "getopt.h" #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ *[MAKE-3_78_1HB]GLOB.DIR;1+,c./@ 4-`0123 KPWO56 I~7)cm89G@HJI CHANGELOG.c CONFIGURE.BATc COPYING.LIBc FNMATCH.Cc FNMATCH.HcGLOB.CldGLOB.Hd MAKEFILE.AMc MAKEFILE.AMIc MAKEFILE.INc SCOPTIONS.c SMAKEFILE.c *[MAKE-3_78_1HB.GLOB]CHANGELOG.;1+,c. /@ 4 G-c0123KPWO 567@m89G@HJ1999-09-12 Paul D. Smith * fnmatch.c: Last GLIBC version wouldn't compile outside of GLIBC (undefined reference to internal_function). Update to the latest version 1999-09-11 Paul Eggert * glob.h (glob): If #defining to glob64, do this before declaring it, so that all declarations and uses match, and do not declare glob64, to avoid a declaration clash. (globfree): Likewise with globfree64. 1999-09-08 Eli Zaretskii * glob.c (prefix_array) [__MSDOS__,WINDOWS32]: Keep the trailing slash unless DIRNAME is just "x:/". 1999-09-06 Paul D. Smith * fnmatch.c: Update to latest version from GLIBC. 1999-07-21 Paul D. Smith * glob.c, glob.h, fnmatch.c, fnmatch.h: Update to latest version from GLIBC. * fnmatch.c (internal_fnmatch): Use K&R definition syntax, not ANSI. (__strchrnul): This won't exist outside GLIBC, so create one. * glob.c: Move getlogin{,_r} prototypes below glob.h to get __P() macro. 1998-08-05 Paul D. Smith * configure.in: Remove; configuration for glob is handled by the make configure.in. 1998-07-29 Paul D. Smith * glob.c, fnmatch.c: New versions from the GLIBC folks (Ulrich Drepper). Fixes a bug reported by Eli Zaretski. Integrates DOS/Windows32 support. 1998-07-27 Kaveh R. Ghazi * glob.c (glob): Cast away const on assignment of pattern to dirname. Cast the return type of __alloca() for traditional C compilers. 1998-07-23 Paul D. Smith * glob.c, fnmatch.c: New versions of these files from the GLIBC folks (Ulrich Drepper). Had to re-integrate some DOS/Windows code. 1998-07-10 Paul D. Smith * glob.c (glob_in_dir): If no meta chars exist in PATTERN and GLOB_NOCHECK is present, don't look for the file--whether it's found or not, we'll always return it, so why bother searching? Also, if we are searching and there are no meta chars, don't bother trying fnmatch() if the strcmp() fails. 1998-05-30 Eli Zaretskii * glob.c (glob) [__MSDOS__, WINDOWS32]: Compute the directory and filename parts of the pattern correctly when it includes a drive spec. Disallow wildcards in the drive spec. Prevent recursion when dirname is of the form "d:/" or "d:". (prefix_array) [__MSDOS__, WINDOWS32]: Don't append a slash to "d:/" and "d:". 1998-05-13 Paul D. Smith * SMakefile, Makefile.ami, glob.c, glob.h, fnmatch.c: Updated from the latest glibc version. 1998-04-17 Paul D. Smith * configure.in: Create a config.h file instead of setting things on the compile line. This is because when build.sh runs it merely passes -DHAVE_CONFIG_H to the glob files, just as it does to the make files. * config.h.in: Created by autoheader. Tue Aug 12 10:52:34 1997 Paul D. Smith * configure.in: Require autoconf 2.12. * glob: Updates from latest GNU libc glob code. * glob.c,glob.h,fnmatch.h: Change all WIN32 references to WINDOWS32. * glob.h: OSF4 defines macros in such a way that GLOB_ALTDIRFUNC is not defined. Added a test to the #if which defines it if _GNU_SOURCE is defined; that's set by both glob.c and GNU make. * glob.c: SunOS4 w/ cc needs #include , since assert.h requires stderr but doesn't include stdio.h :-/. (next_brace_sub): De-protoize function definition. (glob): Cast __alloca(); on SunOS4 it uses the default return type of int. (glob): Irix defines getlogin_r() to return a char*; move the extern for that into the _LIBC area since it isn't used except in LIBC anyway. Likewise, move extern getlogin() into the "else". Sat Jul 20 21:55:31 1996 Roland McGrath Win32 hacks from . * posix/glob.c [WIN32]: Don't include ; don't use d_ino; use void * for my_realloc; include for alloca. (glob) [WIN32]: Use "c:/users/default" for ~ if no HOME variable. * posix/fnmatch.h [WIN32]: Use prototypes even if [!__STDC__]. * posix/glob.h: Likewise. Fri Jul 19 16:56:41 1996 Roland McGrath * posix/glob.h [!_AMIGA && !VMS]: Check this instead of just [!_AMIGA] for `struct stat;' forward decl. Sat Jun 22 10:44:09 1996 Roland McGrath * posix/glob.c: Include only [HAVE_ALLOCA_H], not [sparc]. Fri Jun 21 00:27:51 1996 Roland McGrath * posix/fnmatch.c (fnmatch): Fix \*[*?]+ case to increment name ptr only for ?s, not for *s. Fix from Chet Ramey. 1#*[MAKE-3_78_1HB.GLOB]CONFIGURE.BAT;1+,c./@ 4-c0123KPWO56]7yѯm89G@HJ@echo off echo Configuring glob for DJGPP rem This batch file assumes a unix-type "sed" program echo # Makefile generated by "configure.bat"> Makefile if exist config.sed del config.sed echo "s/@srcdir@/./ ">> config.sed echo "s/@CC@/gcc/ ">> config.sed echo "s/@CFLAGS@/-O2 -g/ ">> config.sed echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H -I../ ">> config.sed echo "s/@AR@/ar/ ">> config.sed echo "s/@RANLIB@/ranlib/ ">> config.sed echo "s/@LDFLAGS@// ">> config.sed echo "s/@DEFS@// ">> config.sed echo "s/@ALLOCA@// ">> config.sed echo "s/@LIBS@// ">> config.sed echo "s/@LIBOBJS@// ">> config.sed echo "s/^Makefile *:/_Makefile:/ ">> config.sed echo "s/^config.h *:/_config.h:/ ">> config.sed sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed sed -f config2.sed Makefile.in >> Makefile del config.sed del config2.sed !*[MAKE-3_78_1HB.GLOB]COPYING.LIB;1+,c.4/@ 442-c0123KPWO5567Ѳm89G@HJ GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modp~MAKE-3_78_1HB.BCKcc![MAKE-3_78_1HB.GLOB]COPYING.LIB;14VVifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! *[MAKE-3_78_1HB.GLOB]FNMATCH.C;1+,c./@ 4n-c0123KPWO567ظm89G@HJ$/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU C Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if HAVE_CONFIG_H # include #endif /* Enable GNU extensions in fnmatch.h. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #include #include #include #if HAVE_STRING_H || defined _LIBC # include #else # include #endif #if defined STDC_HEADERS || defined _LIBC # include #endif /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* Solaris 2.5 has a bug: must be included before . */ # include # include #endif /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined _LIBC || !defined __GNU_LIBRARY__ # if defined STDC_HEADERS || !defined isascii # define ISASCII(c) 1 # else # define ISASCII(c) isascii(c) # endif # ifdef isblank # define ISBLANK(c) (ISASCII (c) && isblank (c)) # else # define ISBLANK(c) ((c) == ' ' || (c) == '\t') # endif # ifdef isgraph # define ISGRAPH(c) (ISASCII (c) && isgraph (c)) # else # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) # endif # define ISPRINT(c) (ISASCII (c) && isprint (c)) # define ISDIGIT(c) (ISASCII (c) && isdigit (c)) # define ISALNUM(c) (ISASCII (c) && isalnum (c)) # define ISALPHA(c) (ISASCII (c) && isalpha (c)) # define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) # define ISLOWER(c) (ISASCII (c) && islower (c)) # define ISPUNCT(c) (ISASCII (c) && ispunct (c)) # define ISSPACE(c) (ISASCII (c) && isspace (c)) # define ISUPPER(c) (ISASCII (c) && isupper (c)) # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) # define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) /* The GNU C library provides support for user-defined character classes and the functions from ISO C amendement 1. */ # ifdef CHARCLASS_NAME_MAX # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX # else /* This shouldn't happen but some implementation might still have this problem. Use a reasonable default value. */ # define CHAR_CLASS_MAX_LENGTH 256 # endif # ifdef _LIBC # define IS_CHAR_CLASS(string) __wctype (string) # else # define IS_CHAR_CLASS(string) wctype (string) # endif # else # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ # define IS_CHAR_CLASS(string) \ (STREQ (string, "alpha") || STREQ (string, "upper") \ || STREQ (string, "lower") || STREQ (string, "digit") \ || STREQ (string, "alnum") || STREQ (string, "xdigit") \ || STREQ (string, "space") || STREQ (string, "print") \ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) # endif /* Avoid depending on library functions or files whose names are inconsistent. */ # if !defined _LIBC && !defined getenv extern char *getenv (); # endif # ifndef errno extern int errno; # endif /* This function doesn't exist on most systems. */ # if !defined HAVE___STRCHRNUL && !defined _LIBC static char * __strchrnul (s, c) const char *s; int c; { char *result = strchr (s, c); if (result == NULL) result = strchr (s, '\0'); return result; } # endif # ifndef internal_function /* Inside GNU libc we mark some function in a special way. In other environments simply ignore the marking. */ # define internal_function # endif /* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */ static int internal_fnmatch __P ((const char *pattern, const char *string, int no_leading_period, int flags)) internal_function; static int internal_function internal_fnmatch (pattern, string, no_leading_period, flags) const char *pattern; const char *string; int no_leading_period; int flags; { register const char *p = pattern, *n = string; register unsigned char c; /* Note that this evaluates C many times. */ # ifdef _LIBC # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) # else # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) # endif while ((c = *p++) != '\0') { c = FOLD (c); switch (c) { case '?': if (*n == '\0') return FNM_NOMATCH; else if (*n == '/' && (flags & FNM_FILE_NAME)) return FNM_NOMATCH; else if (*n == '.' && no_leading_period && (n == string || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) return FNM_NOMATCH; break; case '\\': if (!(flags & FNM_NOESCAPE)) { c = *p++; if (c == '\0') /* Trailing \ loses. */ return FNM_NOMATCH; c = FOLD (c); } if (FOLD ((unsigned char) *n) != c) return FNM_NOMATCH; break; case '*': if (*n == '.' && no_leading_period && (n == string || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) return FNM_NOMATCH; for (c = *p++; c == '?' || c == '*'; c = *p++) { if (*n == '/' && (flags & FNM_FILE_NAME)) /* A slash does not match a wildcard under FNM_FILE_NAME. */ return FNM_NOMATCH; else if (c == '?') { /* A ? needs to match one character. */ if (*n == '\0') /* There isn't another character; no match. */ return FNM_NOMATCH; else /* One character of the string is consumed in matching this ? wildcard, so *??? won't match if there are less than three characters. */ ++n; } } if (c == '\0') /* The wildcard(s) is/are the last element of the pattern. If the name is a file name and contains another slash this does mean it cannot match. */ return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL ? FNM_NOMATCH : 0); else { const char *endp; endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0'); if (c == '[') { int flags2 = ((flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD)); for (--p; n < endp; ++n) if (internal_fnmatch (p, n, (no_leading_period && (n == string || (n[-1] == '/' && (flags & FNM_FILE_NAME)))), flags2) == 0) return 0; } else if (c == '/' && (flags & FNM_FILE_NAME)) { while (*n != '\0' && *n != '/') ++n; if (*n == '/' && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD, flags) == 0)) return 0; } else { int flags2 = ((flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD)); if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *p; c = FOLD (c); for (--p; n < endp; ++n) if (FOLD ((unsigned char) *n) == c && (internal_fnmatch (p, n, (no_leading_period && (n == string || (n[-1] == '/' && (flags & FNM_FILE_NAME)))), flags2) == 0)) return 0; } } /* If we come here no match is possible with the wildcard. */ return FNM_NOMATCH; case '[': { /* Nonzero if the sense of the character class is inverted. */ static int posixly_correct; register int not; char cold; if (posixly_correct == 0) posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; if (*n == '\0') return FNM_NOMATCH; if (*n == '.' && no_leading_period && (n == string || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) return FNM_NOMATCH; if (*n == '/' && (flags & FNM_FILE_NAME)) /* `/' cannot be matched. */ return FNM_NOMATCH; not = (*p == '!' || (posixly_correct < 0 && *p == '^')); if (not) ++p; c = *p++; for (;;) { unsigned char fn = FOLD ((unsigned char) *n); if (!(flags & FNM_NOESCAPE) && c == '\\') { if (*p == '\0')~MAKE-3_78_1HB.BCKcc[MAKE-3_78_1HB.GLOB]FNMATCH.C;1 return FNM_NOMATCH; c = FOLD ((unsigned char) *p); ++p; if (c == fn) goto matched; } else if (c == '[' && *p == ':') { /* Leave room for the null. */ char str[CHAR_CLASS_MAX_LENGTH + 1]; size_t c1 = 0; # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) wctype_t wt; # endif const char *startp = p; for (;;) { if (c1 == CHAR_CLASS_MAX_LENGTH) /* The name is too long and therefore the pattern is ill-formed. */ return FNM_NOMATCH; c = *++p; if (c == ':' && p[1] == ']') { p += 2; break; } if (c < 'a' || c >= 'z') { /* This cannot possibly be a character class name. Match it as a normal range. */ p = startp; c = '['; goto normal_bracket; } str[c1++] = c; } str[c1] = '\0'; # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) wt = IS_CHAR_CLASS (str); if (wt == 0) /* Invalid character class name. */ return FNM_NOMATCH; if (__iswctype (__btowc ((unsigned char) *n), wt)) goto matched; # else if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n)) || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n)) || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n)) || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n)) || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n)) || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n)) || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n)) || (STREQ (str, "print") && ISPRINT ((unsigned char) *n)) || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n)) || (STREQ (str, "space") && ISSPACE ((unsigned char) *n)) || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n)) || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n))) goto matched; # endif } else if (c == '\0') /* [ (unterminated) loses. */ return FNM_NOMATCH; else { normal_bracket: if (FOLD (c) == fn) goto matched; cold = c; c = *p++; if (c == '-' && *p != ']') { /* It is a range. */ unsigned char cend = *p++; if (!(flags & FNM_NOESCAPE) && cend == '\\') cend = *p++; if (cend == '\0') return FNM_NOMATCH; if (cold <= fn && fn <= FOLD (cend)) goto matched; c = *p++; } } if (c == ']') break; } if (!not) return FNM_NOMATCH; break; matched: /* Skip the rest of the [...] that already matched. */ while (c != ']') { if (c == '\0') /* [... (unterminated) loses. */ return FNM_NOMATCH; c = *p++; if (!(flags & FNM_NOESCAPE) && c == '\\') { if (*p == '\0') return FNM_NOMATCH; /* XXX 1003.2d11 is unclear if this is right. */ ++p; } else if (c == '[' && *p == ':') { do if (*++p == '\0') return FNM_NOMATCH; while (*p != ':' || p[1] == ']'); p += 2; c = *p; } } if (not) return FNM_NOMATCH; } break; default: if (c != FOLD ((unsigned char) *n)) return FNM_NOMATCH; } ++n; } if (*n == '\0') return 0; if ((flags & FNM_LEADING_DIR) && *n == '/') /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ return 0; return FNM_NOMATCH; # undef FOLD } int fnmatch (pattern, string, flags) const char *pattern; const char *string; int flags; { return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags); } #endif /* _LIBC or not __GNU_LIBRARY__. */ *[MAKE-3_78_1HB.GLOB]FNMATCH.H;1+,c./@ 4-c0123KPWO 56i%7km89G@HJ /* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _FNMATCH_H #define _FNMATCH_H 1 #ifdef __cplusplus extern "C" { #endif #if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 # if !defined __GLIBC__ || !defined __P # undef __P # define __P(protos) protos # endif #else /* Not C++ or ANSI C. */ # undef __P # define __P(protos) () /* We can get away without defining `const' here only because in this file it is used only inside the prototype for `fnmatch', which is elided in non-ANSI C where `const' is problematical. */ #endif /* C++ or ANSI C. */ #ifndef const # if (defined __STDC__ && __STDC__) || defined __cplusplus # define __const const # else # define __const # endif #endif /* We #undef these before defining them because some losing systems (HP-UX A.08.07 for example) define these in . */ #undef FNM_PATHNAME #undef FNM_NOESCAPE #undef FNM_PERIOD /* Bits set in the FLAGS argument to `fnmatch'. */ #define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ #define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ #define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ #if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE # define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ # define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ # define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ #endif /* Value returned by `fnmatch' if STRING does not match PATTERN. */ #define FNM_NOMATCH 1 /* This value is returned if the implementation does not support `fnmatch'. Since this is not the case here it will never be returned but the conformance test suites still require the symbol to be defined. */ #ifdef _XOPEN_SOURCE # define FNM_NOSYS (-1) #endif /* Match NAME against the filename pattern PATTERN, returning zero if it matches, FNM_NOMATCH if not. */ extern int fnmatch __P ((__const char *__pattern, __const char *__name, int __flags)); #ifdef __cplusplus } #endif #endif /* fnmatch.h */ i*[MAKE-3_78_1HB.GLOB]GLOB.C;4+,ld.H/@ 4PHF8-c0123KPWOI56KRE7sm89G@HJ^/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined _AIX && !defined __GNUC__ #pragma alloca #endif #ifdef HAVE_CONFIG_H # include #endif /* Enable GNU extensions in glob.h. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif #include #include #include /* Outcomment the following line for production quality code. */ /* #define NDEBUG 1 */ #include #include /* Needed on stupid SunOS for assert. */ /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GLOB_INTERFACE_VERSION 1 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 # include # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE #if defined STDC_HEADERS || defined __GNU_LIBRARY__ # include #endif #if defined HAVE_UNISTD_H || defined _LIBC # include # ifndef POSIX # ifdef _POSIX_VERSION # define POSIX # endif # endif #endif #if !defined _AMIGA && !defined VMS && !defined WINDOWS32 # include #endif #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS extern int errno; #endif #ifndef __set_errno # define __set_errno(val) errno = (val) #endif #ifndef NULL # define NULL 0 #endif #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # ifdef HAVE_SYS_NDIR_H # include # endif # ifdef HAVE_SYS_DIR_H # include # endif # ifdef HAVE_NDIR_H # include # endif # ifdef HAVE_VMSDIR_H # include "vmsdir.h" # endif /* HAVE_VMSDIR_H */ #endif /* In GNU systems, defines this macro for us. */ #ifdef _D_NAMLEN # undef NAMLEN # define NAMLEN(d) _D_NAMLEN(d) #endif /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available if the `d_type' member for `struct dirent' is available. */ #ifdef _DIRENT_HAVE_D_TYPE # define HAVE_D_TYPE 1 #endif #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ # define REAL_DIR_ENTRY(dp) 1 #else # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ #if defined STDC_HEADERS || defined __GNU_LIBRARY__ # include # include # define ANSI_STRING #else /* No standard headers. */ extern char *getenv (); # ifdef HAVE_STRING_H # include # define ANSI_STRING # else # include # endif # ifdef HAVE_MEMORY_H # include # endif extern char *malloc (), *realloc (); extern void free (); extern void qsort (); extern void abort (), exit (); #endif /* Standard headers. */ #ifndef ANSI_STRING # ifndef bzero extern void bzero (); # endif # ifndef bcopy extern void bcopy (); # endif # define memcpy(d, s, n) bcopy ((s), (d), (n)) # define strrchr rindex /* memset is only used for zero here, but let's be paranoid. */ # define memset(s, better_be_zero, n) \ ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) #endif /* Not ANSI_STRING. */ #if !defined HAVE_STRCOLL && !defined _LIBC # define strcoll strcmp #endif #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 # define HAVE_MEMPCPY 1 # undef mempcpy # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) #endif #ifndef __GNU_LIBRARY__ # ifdef __GNUC__ __inline # endif # ifndef __SASC # ifdef WINDOWS32 static void * # else static char * # endif my_realloc (p, n) char *p; unsigned int n; { /* These casts are the for sake of the broken Ultrix compiler, which warns of illegal pointer combinations otherwise. */ if (p == NULL) return (char *) malloc (n); return (char *) realloc (p, n); } # define realloc my_realloc # endif /* __SASC */ #endif /* __GNU_LIBRARY__ */ #if !defined __alloca && !defined __GNU_LIBRARY__ # ifdef __GNUC__ # undef alloca # define alloca(n) __builtin_alloca (n) # else /* Not GCC. */ # ifdef HAVE_ALLOCA_H # include # else /* Not HAVE_ALLOCA_H. */ # ifndef _AIX # ifdef WINDOWS32 # include # else extern char *alloca (); # endif /* WINDOWS32 */ # endif /* Not _AIX. */ # endif /* sparc or HAVE_ALLOCA_H. */ # endif /* GCC. */ # define __alloca alloca #endif #ifndef __GNU_LIBRARY__ # define __stat stat # ifdef STAT_MACROS_BROKEN # undef S_ISDIR # endif # ifndef S_ISDIR # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) # endif #endif #ifdef _LIBC # undef strdup # define strdup(str) __strdup (str) # define sysconf(id) __sysconf (id) # define closedir(dir) __closedir (dir) # define opendir(name) __opendir (name) # define readdir(str) __readdir (str) # define getpwnam_r(name, bufp, buf, len, res) \ __getpwnam_r (name, bufp, buf, len, res) # ifndef __stat # define __stat(fname, buf) __xstat (_STAT_VER, fname, buf) # endif #endif #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) # undef size_t # define size_t unsigned int #endif /* Some system header files erroneously define these. We want our own definitions from to take precedence. */ #ifndef __GNU_LIBRARY__ # undef FNM_PATHNAME # undef FNM_NOESCAPE # undef FNM_PERIOD #endif #include /* Some system header files erroneously define these. We want our own definitions from to take precedence. */ #ifndef __GNU_LIBRARY__ # undef GLOB_ERR # undef GLOB_MARK # undef GLOB_NOSORT # undef GLOB_DOOFFS # undef GLOB_NOCHECK # undef GLOB_APPEND # undef GLOB_NOESCAPE # undef GLOB_PERIOD #endif #include #ifdef HAVE_GETLOGIN_R extern int getlogin_r __P ((char *, size_t)); #else extern char *getlogin __P ((void)); #endif static #if __GNUC__ - 0 >= 2 inline #endif const char *next_brace_sub __P ((const char *begin)); static int glob_in_dir __P ((const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob)); static int prefix_array __P ((const char *prefix, char **array, size_t n)); static int collated_compare __P ((const __ptr_t, const __ptr_t)); #ifdef VMS /* these compilers like prototypes */ #if !defined _LIBC || !defined NO_GLOB_PATTERN_P int __glob_pattern_p (const char *pattern, int quote); #endif #endif /* Find the end of the sub-pattern in a brace expression. We define this as an inline function if the compiler permits. */ static #if __GNUC__ - 0 >= 2 inline #endif const char * next_brace_sub (begin) const char *begin; { unsigned int depth = 0; const char *cp = begin; while (1) { if (depth == 0) { if (*cp != ',' && *cp != '}' && *cp != '\0') { if (*cp == '{') ++depth; ++cp; continue; } } else { while (*cp != '\0' && (*cp != '}' || depth > 0)) { if (*cp == '}') --depth; ++cp; } if (*cp == '\0') /* An incorrectly terminated brace expression. */ return NULL; continue; } break; } return cp; } /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, it is called with the pathname that caused the error, and the `errno' value from the failing call; if it returns non-zero `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, `glob' returns zero. */ int glob (pattern, flags, errfunc, pglob) const char *pattern; int flags; int (*errfunc) __P ((const char *, int)); glob_t *pglob; { const char *filename; const char *dirname; size_t dirlen; int status; int oldcount; if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) { __set_errno (EINVAL); return -1; } if (flags & GLOB_BRACE) { const char *begin = strchr (pattern, '{'); if (begin != NULL) { /* Allocate working buffer large enough for our work. Note that we have at least an opening and closing brace. */ int firstc; char *alt_start; const char *p; const char *next; const char *rest; size_t rest_len; #ifdef __GNUC__ char onealt[strlen (pattern) - 1]; #else char *onealt = (char *) malloc (strlen (pattern) - 1); if (onealt == NULL) { if (!(flags & GLOB_APPEND)) globfree (pglob); return GLOB_NOSPACE; } #endif /* We know the prefix for all sub-patterns. */ #ifdef HAVE_MEMPCPY alt_start = mempcpy (onealt, pattern, begin - pattern); #else memcpy (onealt, pattern, begin - pattern); alt_start = &onealt[begin - pattern]; #endif /* Find the first sub-pattern and at the same time find the rest after the closing brace. */ next = next_brace_sub (begin + 1); if (next == NULL) { /* It is an illegal expression. */ #ifndef __GNUC__ free (onealt); #endif return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); } /* Now find the end of the whole brace expression. */ rest = next; while (*rest != '}') { rest = next_brace_sub (rest + 1); if (rest == NULL) { /* It is an illegal expression. */ #ifndef __GNUC__ free (onealt); #endif return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); } } /* Please note that we now can be sure the brace expression is well-formed. */ rest_len = strlen (++rest) + 1; /* We have a brace expression. BEGIN points to the opening {, NEXT points past the terminator of the first element, and END points past the final }. We will accumulate result names from recursive runs for each brace alternative in the buffer using GLOB_APPEND. */ if (!(flags & GLOB_APPEND)) { /* This call is to set a new vector, so clear out the vector so we can append to it. */ pglob->gl_pathc = 0; pglob->gl_pathv = NULL; } firstc = pglob->gl_pathc; p = begin + 1; while (1) { int result; /* Construct the new glob expression. */ #ifdef HAVE_MEMPCPY mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); #else memcpy (alt_start, p, next - p); memcpy (&alt_start[next - p], rest, rest_len); #endif result = glob (onealt, ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) | GLOB_APPEND), errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { #ifndef __GNUC__ free (onealt); #endif if (!(flags & GLOB_APPEND)) globfree (pglob); return result; } if (*next == '}') /* We saw the last entry. */ break; p = next + 1; next = next_brace_sub (p); assert (next != NULL); } #ifndef __GNUC__ free (onealt); #endif if (pglob->gl_pathc != firstc) /* We found some entries. */ return 0; else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) return GLOB_NOMATCH; } } /* Find the filename. */ filename = strrchr (pattern, '/'); #if defined __MSDOS__ || defined WINDOWS32 /* The case of "d:pattern". Since `:' is not allowed in file names, we can safely assume that wherever it happens in pattern, it signals the filename part. This is so we could some day support patterns like "[a-z]:foo". */ if (filename == NULL) filename = strchr (pattern, ':'); #endif /* __MSDOS__ || WINDOWS32 */ if (filename == NULL) { /* This can mean two things: a simple name or "~name". The later case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { dirname = pattern; dirlen = strlen (pattern); /* Set FILENAME to NULL as a special flag. This is ugly but other solutions would require much more code. We test for this special case below. */ filename = NULL; } else { filename = pattern; #ifdef _AMIGA dirname = ""; #else dirname = "."; #endif dirlen = 0; } } else if (filename == pattern) { /* "/pattern". */ dirname = "/"; dirlen = 1; ++filename; } else { char *newp; dirlen = filename - pattern; #if defined __MSDOS__ || defined WINDOWS32 if (*filename == ':' || (filename > pattern + 1 && filename[-1] == ':')) { char *drive_spec; ++dirlen; drive_spec = (char *) __alloca (dirlen + 1); #ifdef HAVE_MEMPCPY *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; #else memcpy (drive_spec, pattern, dirlen); drive_spec[dirlen] = '\0'; #endif /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) return GLOB_NOMATCH; /* If this is "d:pattern", we need to copy `:' to DIRNAME as well. If it's "d:/pattern", don't remove the slash from "d:/", since "d:" and "d:/" are not the same.*/ } #endif newp = (char *) __alloca (dirlen + 1); #ifdef HAVE_MEMPCPY *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; #else memcpy (newp, pattern, dirlen); newp[dirlen] = '\0'; #endif dirname = newp; ++filename; if (filename[0] == '\0' #if defined __MSDOS__ || defined WINDOWS32 && dirname[dirlen - 1] != ':' && (dirlen < 3 || dirname[dirlen - 2] != ':' || dirname[dirlen - 1] != '/') #endif && dirlen > 1) /* "pattern/". Expand "pattern", appending slashes. */ { int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); return val; } } if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; } oldcount = pglob->gl_pathc; #ifndef VMS if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') { if (dirname[1] == '\0' || dirname[1] == '/') { /* Look up home directory. */ #ifdef VMS /* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */ const char *home_dir = getenv ("SYS$LOGIN"); #else const char *home_dir = getenv ("HOME"); #endif # ifdef _AMIGA if (home_dir == NULL || home_dir[0] == '\0') home_dir = "SYS:"; # else # ifdef WINDOWS32 if (home_dir == NULL || home_dir[0] == '\0') home_dir = "c:/users/default"; /* poor default */ # else # ifdef VMS /* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */ if (home_dir == NULL || home_dir[0] == '\0') home_dir = "SYS$DISK:[]"; # else if (home_dir == NULL || home_dir[0] == '\0') { int success; char *name; # if defined HAVE_GETLOGIN_R || defined _LIBC size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; if (buflen == 0) /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try a moderate value. */ buflen = 20; name = (char *) __alloca (buflen); success = getlogin_r (name, buflen) >= 0; # else success = (name = getlogin ()) != NULL; # endif if (success) { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf; struct passwd pwbuf; int save = errno; if (pwbuflen == -1) /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ pwbuflen = 1024; pwtmpbuf = (char *) __alloca (pwbuflen); while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) != 0) { if (errno != ERANGE) { p = NULL; break; } pwbuflen *= 2; pwtmpbuf = (char *) __alloca (pwbuflen); __set_errno (save); } # else p = getpwnam (name); # endif if (p != NULL) home_dir = p->pw_dir; } } if (home_dir == NULL || home_dir[0] == '\0') { if (flags & GLOB_TILDE_CHECK) return GLOB_NOMATCH; else home_dir = "~"; /* No luck. */ } # endif /* VMS */ # endif /* WINDOWS32 */ # endif /* Now construct the full directory. */ if (dirname[1] == '\0') dirname = home_dir; else { char *newp; size_t home_len = strlen (home_dir); newp = (char *) __alloca (home_len + dirlen); # ifdef HAVE_MEMPCPY mempcpy (mempcpy (newp, home_dir, home_len), &dirname[1], dirlen); # else memcpy (newp, home_dir, home_len); memcpy (&newp[home_len], &dirname[1], dirlen); # endif dirname = newp; } } # if !defined _AMIGA && !defined WINDOWS32 && !defined VMS else { char *end_name = strchr (dirname, '/'); const char *user_name; const char *home_dir; if (end_name == NULL) user_name = dirname + 1; else { char *newp; newp = (char *) __alloca (end_name - dirname); # ifdef HAVE_MEMPCPY *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) = '\0'; # else memcpy (newp, dirname + 1, end_name - dirname); newp[end_name - dirname - 1] = '\0'; # endif user_name = newp; } /* Look up specific user's home directory. */ { struct passwd *p; # if defined HAVE_GETPWNAM_R || defined _LIBC size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf; struct passwd pwbuf; int save = errno; if (buflen == -1) /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ buflen = 1024; pwtmpbuf = (char *) __alloca (buflen); while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) { if (errno != ERANGE) { p = NULL; break; } buflen *= 2; pwtmpbuf = __alloca (buflen); __set_errno (save); } # else p = getpwnam (user_name); # endif if (p != NULL) home_dir = p->pw_dir; else home_dir = NULL; } /* If we found a home directory use this. */ if (home_dir != NULL) { char *newp; size_t home_len = strlen (home_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); newp = (char *) __alloca (home_len + rest_len + 1); # ifdef HAVE_MEMPCPY *((char *) mempcpy (mempcpy (newp, home_dir, home_len), end_name, rest_len)) = '\0'; # else memcpy (newp, home_dir, home_len); memcpy (&newp[home_len], end_name, rest_len); newp[home_len + rest_len] = '\0'; # endif dirname = newp; } else if (flags & GLOB_TILDE_CHECK) /* We have to regard it as an error if we cannot find the home directory. */ return GLOB_NOMATCH; } # endif /* Not Amiga && not WINDOWS32 && not VMS. */ } #endif /* Not VMS. */ /* Now test whether we looked for "~" or "~NAME". In this case we can give the answer now. */ if (filename == NULL) { struct stat st; /* Return the directory if we don't check for error or if it exists. */ if ((flags & GLOB_NOCHECK) || (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (dirname, &st) : __stat (dirname, &st)) == 0 && S_ISDIR (st.st_mode))) { pglob->gl_pathv = (char **) realloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + 1 + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; if (flags & GLOB_DOOFFS) while (pglob->gl_pathc < pglob->gl_offs) pglob->gl_pathv[pglob->gl_pathc++] = NULL; #if defined HAVE_STRDUP || defined _LIBC pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname); #else { size_t len = strlen (dirname) + 1; char *dircopy = malloc (len); if (dircopy != NULL) pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname, len); } #endif if (pglob->gl_pathv[pglob->gl_pathc] == NULL) { free (pglob->gl_pathv); return GLOB_NOSPACE; } pglob->gl_pathv[++pglob->gl_pathc] = NULL; pglob->gl_flags = flags; return 0; } /* Not found. */ return GLOB_NOMATCH; } if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) { /* The directory name contains metacharacters, so we have to glob for the directory, and then glob for the pattern in each directory found. */ glob_t dirs; register int i; status = glob (dirname, ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | GLOB_NOSORT | GLOB_ONLYDIR), errfunc, &dirs); if (status != 0) return status; /* We have successfully globbed the preceding directory name. For each name we found, call glob_in_dir on it and FILENAME, appending the results to PGLOB. */ for (i = 0; i < dirs.gl_pathc; ++i) { int old_pathc; #ifdef SHELL { /* Make globbing interruptible in the bash shell. */ extern int interrupt_state; if (interrupt_state) { globfree (&dirs); globfree (&files); return GLOB_ABORTED; } } #endif /* SHELL. */ old_pathc = pglob->gl_pathc; status = glob_in_dir (filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) & ~(GLOB_NOCHECK | GLOB_ERR)), errfunc, pglob); if (status == GLOB_NOMATCH) /* No matches in this directory. Try the next. */ continue; if (status != 0) { globfree (&dirs); globfree (pglob); return status; } /* Stick the directory on the front of each name. */ if (prefix_array (dirs.gl_pathv[i], &pglob->gl_pathv[old_pathc], pglob->gl_pathc - old_pathc)) { globfree (&dirs); globfree (pglob); return GLOB_NOSPACE; } } flags |= GLOB_MAGCHAR; /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. But if we have not found any matching entry and thie GLOB_NOCHECK flag was set we must return the list consisting of the disrectory names followed by the filename. */ if (pglob->gl_pathc == oldcount) { /* No matches. */ if (flags & GLOB_NOCHECK) { size_t filename_len = strlen (filename) + 1; char **new_pathv; struct stat st; /* This is an pessimistic guess about the size. */ pglob->gl_pathv = (char **) realloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + dirs.gl_pathc + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) { globfree (&dirs); return GLOB_NOSPACE; } if (flags & GLOB_DOOFFS) while (pglob->gl_pathc < pglob->gl_offs) pglob->gl_pathv[pglob->gl_pathc++] = N ~MAKE-3_78_1HB.BCKldc[MAKE-3_78_1HB.GLOB]GLOB.C;4PH.0ULL; for (i = 0; i < dirs.gl_pathc; ++i) { const char *dir = dirs.gl_pathv[i]; size_t dir_len = strlen (dir); /* First check whether this really is a directory. */ if (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0 || !S_ISDIR (st.st_mode)) /* No directory, ignore this entry. */ continue; pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1 + filename_len); if (pglob->gl_pathv[pglob->gl_pathc] == NULL) { globfree (&dirs); globfree (pglob); return GLOB_NOSPACE; } #ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len), "/", 1), filename, filename_len); #else memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len); pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/'; memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1], filename, filename_len); #endif ++pglob->gl_pathc; } pglob->gl_pathv[pglob->gl_pathc] = NULL; pglob->gl_flags = flags; /* Now we know how large the gl_pathv vector must be. */ new_pathv = (char **) realloc (pglob->gl_pathv, ((pglob->gl_pathc + 1) * sizeof (char *))); if (new_pathv != NULL) pglob->gl_pathv = new_pathv; } else return GLOB_NOMATCH; } globfree (&dirs); } else { status = glob_in_dir (filename, dirname, flags, errfunc, pglob); if (status != 0) return status; if (dirlen > 0) { /* Stick the directory on the front of each name. */ int ignore = oldcount; if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs) ignore = pglob->gl_offs; if (prefix_array (dirname, &pglob->gl_pathv[ignore], pglob->gl_pathc - ignore)) { globfree (pglob); return GLOB_NOSPACE; } } } if (flags & GLOB_MARK) { /* Append slashes to directory names. */ int i; struct stat st; for (i = oldcount; i < pglob->gl_pathc; ++i) if (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st) : __stat (pglob->gl_pathv[i], &st)) == 0 && S_ISDIR (st.st_mode)) { size_t len = strlen (pglob->gl_pathv[i]) + 2; char *new = realloc (pglob->gl_pathv[i], len); if (new == NULL) { globfree (pglob); return GLOB_NOSPACE; } strcpy (&new[len - 2], "/"); pglob->gl_pathv[i] = new; } } if (!(flags & GLOB_NOSORT)) { /* Sort the vector. */ int non_sort = oldcount; if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount) non_sort = pglob->gl_offs; qsort ((__ptr_t) &pglob->gl_pathv[non_sort], pglob->gl_pathc - non_sort, sizeof (char *), collated_compare); } return 0; } /* Free storage allocated in PGLOB by a previous `glob' call. */ void globfree (pglob) register glob_t *pglob; { if (pglob->gl_pathv != NULL) { register int i; for (i = 0; i < pglob->gl_pathc; ++i) if (pglob->gl_pathv[i] != NULL) free ((__ptr_t) pglob->gl_pathv[i]); free ((__ptr_t) pglob->gl_pathv); } } /* Do a collated comparison of A and B. */ static int collated_compare (a, b) const __ptr_t a; const __ptr_t b; { const char *const s1 = *(const char *const * const) a; const char *const s2 = *(const char *const * const) b; if (s1 == s2) return 0; if (s1 == NULL) return 1; if (s2 == NULL) return -1; return strcoll (s1, s2); } /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's elements in place. Return nonzero if out of memory, zero if successful. A slash is inserted between DIRNAME and each elt of ARRAY, unless DIRNAME is just "/". Each old element of ARRAY is freed. */ static int prefix_array (dirname, array, n) const char *dirname; char **array; size_t n; { register size_t i; size_t dirlen = strlen (dirname); #if defined __MSDOS__ || defined WINDOWS32 int sep_char = '/'; # define DIRSEP_CHAR sep_char #else # define DIRSEP_CHAR '/' #endif if (dirlen == 1 && dirname[0] == '/') /* DIRNAME is just "/", so normal prepending would get us "//foo". We want "/foo" instead, so don't prepend any chars from DIRNAME. */ dirlen = 0; #if defined __MSDOS__ || defined WINDOWS32 else if (dirlen > 1) { if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':') /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ --dirlen; else if (dirname[dirlen - 1] == ':') { /* DIRNAME is "d:". Use `:' instead of `/'. */ --dirlen; sep_char = ':'; } } #endif for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; char *new = (char *) malloc (dirlen + 1 + eltlen); if (new == NULL) { while (i > 0) free ((__ptr_t) array[--i]); return 1; } #ifdef HAVE_MEMPCPY { char *endp = (char *) mempcpy (new, dirname, dirlen); *endp++ = DIRSEP_CHAR; mempcpy (endp, array[i], eltlen); } #else memcpy (new, dirname, dirlen); new[dirlen] = DIRSEP_CHAR; memcpy (&new[dirlen + 1], array[i], eltlen); #endif free ((__ptr_t) array[i]); array[i] = new; } return 0; } /* We must not compile this function twice. */ #if !defined _LIBC || !defined NO_GLOB_PATTERN_P /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ int __glob_pattern_p (pattern, quote) const char *pattern; int quote; { register const char *p; int open = 0; for (p = pattern; *p != '\0'; ++p) switch (*p) { case '?': case '*': return 1; case '\\': if (quote && p[1] != '\0') ++p; break; case '[': open = 1; break; case ']': if (open) return 1; break; } return 0; } # ifdef _LIBC weak_alias (__glob_pattern_p, glob_pattern_p) # endif #endif /* Like `glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. The GLOB_APPEND flag is assumed to be set (always appends). */ static int glob_in_dir (pattern, directory, flags, errfunc, pglob) const char *pattern; const char *directory; int flags; int (*errfunc) __P ((const char *, int)); glob_t *pglob; { __ptr_t stream = NULL; struct globlink { struct globlink *next; char *name; }; struct globlink *names = NULL; size_t nfound; int meta; int save; #ifdef VMS if (*directory == 0) directory = "[]"; #endif meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0) { if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)) /* We need not do any tests. The PATTERN contains no meta characters and we must not return an error therefore the result will always contain exactly one name. */ flags |= GLOB_NOCHECK; else { /* Since we use the normal file functions we can also use stat() to verify the file is there. */ struct stat st; size_t patlen = strlen (pattern); size_t dirlen = strlen (directory); char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); # ifdef HAVE_MEMPCPY mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); # else memcpy (fullname, directory, dirlen); fullname[dirlen] = '/'; memcpy (&fullname[dirlen + 1], pattern, patlen + 1); # endif if (((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_stat) (fullname, &st) : __stat (fullname, &st)) == 0) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; } nfound = 0; } else { if (pattern[0] == '\0') { /* This is a special case for matching directories like in "*a/". */ names = (struct globlink *) __alloca (sizeof (struct globlink)); names->name = (char *) malloc (1); if (names->name == NULL) goto memory_error; names->name[0] = '\0'; names->next = NULL; nfound = 1; meta = 0; } else { stream = ((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_opendir) (directory) : (__ptr_t) opendir (directory)); if (stream == NULL) { if (errno != ENOTDIR && ((errfunc != NULL && (*errfunc) (directory, errno)) || (flags & GLOB_ERR))) return GLOB_ABORTED; nfound = 0; meta = 0; } else { int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) #if defined _AMIGA || defined VMS | FNM_CASEFOLD #endif ); nfound = 0; flags |= GLOB_MAGCHAR; while (1) { const char *name; size_t len; struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ? (*pglob->gl_readdir) (stream) : readdir ((DIR *) stream)); if (d == NULL) break; if (! REAL_DIR_ENTRY (d)) continue; #ifdef HAVE_D_TYPE /* If we shall match only directories use the information provided by the dirent call if possible. */ if ((flags & GLOB_ONLYDIR) && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) continue; #endif name = d->d_name; if (fnmatch (pattern, name, fnm_flags) == 0) { struct globlink *new = (struct globlink *) __alloca (sizeof (struct globlink)); len = NAMLEN (d); new->name = (char *) malloc (len + 1); if (new->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY *((char *) mempcpy ((__ptr_t) new->name, name, len)) = '\0'; #else memcpy ((__ptr_t) new->name, name, len); new->name[len] = '\0'; #endif new->next = names; names = new; ++nfound; } } } } } if (nfound == 0 && (flags & GLOB_NOCHECK)) { size_t len = strlen (pattern); nfound = 1; names = (struct globlink *) __alloca (sizeof (struct globlink)); names->next = NULL; names->name = (char *) malloc (len + 1); if (names->name == NULL) goto memory_error; #ifdef HAVE_MEMPCPY *((char *) mempcpy (names->name, pattern, len)) = '\0'; #else memcpy (names->name, pattern, len); names->name[len] = '\0'; #endif } if (nfound != 0) { pglob->gl_pathv = (char **) realloc (pglob->gl_pathv, (pglob->gl_pathc + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + nfound + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) goto memory_error; if (flags & GLOB_DOOFFS) while (pglob->gl_pathc < pglob->gl_offs) pglob->gl_pathv[pglob->gl_pathc++] = NULL; for (; names != NULL; names = names->next) pglob->gl_pathv[pglob->gl_pathc++] = names->name; pglob->gl_pathv[pglob->gl_pathc] = NULL; pglob->gl_flags = flags; } save = errno; if (stream != NULL) { if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else closedir ((DIR *) stream); } __set_errno (save); return nfound == 0 ? GLOB_NOMATCH : 0; memory_error: { int save = errno; if (flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir) (stream); else closedir ((DIR *) stream); __set_errno (save); } while (names != NULL) { if (names->name != NULL) free ((__ptr_t) names->name); names = names->next; } return GLOB_NOSPACE; } #endif /* Not ELIDE_CODE. */ *[MAKE-3_78_1HB.GLOB]GLOB.H;3+,d./@ 4N -c0123KPWO56m&Ni7 m89G@HJ/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GLOB_H #define _GLOB_H 1 #ifdef __cplusplus extern "C" { #endif #undef __ptr_t #if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 # if !defined __GLIBC__ || !defined __P # undef __P # undef __PMT # define __P(protos) protos # define __PMT(protos) protos # if !defined __GNUC__ || __GNUC__ < 2 # undef __const # define __const const # endif # endif # define __ptr_t void * #else /* Not C++ or ANSI C. */ # undef __P # undef __PMT # define __P(protos) () # define __PMT(protos) () # undef __const # define __const # define __ptr_t char * #endif /* C++ or ANSI C. */ /* We need `size_t' for the following definitions. */ #ifndef __size_t # if defined __GNUC__ && __GNUC__ >= 2 typedef __SIZE_TYPE__ __size_t; # else /* This is a guess. */ /*hb * Conflicts with DECCs aready defined type __size_t. * Defining an own type with a name beginning with '__' is no good. * Anyway if DECC is used and __SIZE_T is defined then __size_t is * already defined (and I hope it's exactly the one we need here). */ #if !(defined __DECC && defined __SIZE_T) typedef unsigned long int __size_t; #endif # endif #else /* The GNU CC stddef.h version defines __size_t as empty. We need a real definition. */ # undef __size_t # define __size_t size_t #endif /* Bits set in the FLAGS argument to `glob'. */ #define GLOB_ERR (1 << 0)/* Return on read errors. */ #define GLOB_MARK (1 << 1)/* Append a slash to each name. */ #define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ #define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ #define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ #define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ #define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ #define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ #if (!defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _BSD_SOURCE \ || defined _GNU_SOURCE) # define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ # define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */ # define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */ # define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */ # define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */ # define GLOB_ONLYDIR (1 << 13)/* Match only directories. */ # define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error if the user name is not available. */ # define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \ GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK) #else # define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ GLOB_PERIOD) #endif /* Error returns from `glob'. */ #define GLOB_NOSPACE 1 /* Ran out of memory. */ #define GLOB_ABORTED 2 /* Read error. */ #define GLOB_NOMATCH 3 /* No matches found. */ #define GLOB_NOSYS 4 /* Not implemented. */ #ifdef _GNU_SOURCE /* Previous versions of this file defined GLOB_ABEND instead of GLOB_ABORTED. Provide a compatibility definition here. */ # define GLOB_ABEND GLOB_ABORTED #endif /* Structure describing a globbing run. */ #if !defined _AMIGA && !defined VMS /* Buggy compiler. */ struct stat; #endif typedef struct { __size_t gl_pathc; /* Count of paths matched by the pattern. */ char **gl_pathv; /* List of matched pathnames. */ __size_t gl_offs; /* Slots to reserve in `gl_pathv'. */ int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ /* If the GLOB_ALTDIRFUNC flag is set, the following functions are used instead of the normal file access functions. */ void (*gl_closedir) __PMT ((void *)); struct dirent *(*gl_readdir) __PMT ((void *)); __ptr_t (*gl_opendir) __PMT ((__const char *)); int (*gl_lstat) __PMT ((__const char *, struct stat *)); #if defined(VMS) && defined(__DECC) && !defined(_POSIX_C_SOURCE) int (*gl_stat) __PMT ((__const char *, struct stat *, ...)); #else int (*gl_stat) __PMT ((__const char *, struct stat *)); #endif } glob_t; #ifdef _LARGEFILE64_SOURCE struct stat64; typedef struct { __size_t gl_pathc; char **gl_pathv; __size_t gl_offs; int gl_flags; /* If the GLOB_ALTDIRFUNC flag is set, the following functions are used instead of the normal file access functions. */ void (*gl_closedir) __PMT ((void *)); struct dirent64 *(*gl_readdir) __PMT ((void *)); __ptr_t (*gl_opendir) __PMT ((__const char *)); int (*gl_lstat) __PMT ((__const char *, struct stat64 *)); int (*gl_stat) __PMT ((__const char *, struct stat64 *)); } glob64_t; #endif #if _FILE_OFFSET_BITS == 64 && __GNUC__ < 2 # define glob glob64 # define globfree globfree64 #else # ifdef _LARGEFILE64_SOURCE extern int glob64 __P ((__const char *__pattern, int __flags, int (*__errfunc) (__const char *, int), glob64_t *__pglob)); extern void globfree64 __P ((glob64_t *__pglob)); # endif #endif /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, it is called with the pathname that caused the error, and the `errno' value from the failing call; if it returns non-zero `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, `glob' returns zero. */ #if _FILE_OFFSET_BITS != 64 || __GNUC__ < 2 extern int glob __P ((__const char *__pattern, int __flags, int (*__errfunc) (__const char *, int), glob_t *__pglob)); /* Free storage allocated in PGLOB by a previous `glob' call. */ extern void globfree __P ((glob_t *__pglob)); #else extern int glob __P ((__const char *__pattern, int __flags, int (*__errfunc) (__const char *, int), glob_t *__pglob)) __asm__ ("glob64"); extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64"); #endif #ifdef _GNU_SOURCE /* Return nonzero if PATTERN contains any metacharacters. Metacharacters can be quoted with backslashes if QUOTE is nonzero. This function is not part of the interface specified by POSIX.2 but several programs want to use it. */ extern int glob_pattern_p __P ((__const char *__pattern, int __quote)); #endif #ifdef __cplusplus } #endif #endif /* glob.h */ !*[MAKE-3_78_1HB.GLOB]MAKEFILE.AM;1+,c./@ 4-c0123KPWO56W7dm89G@HJ# -*-Makefile-*-, or close enough AUTOMAKE_OPTIONS = 1.4 foreign noinst_LIBRARIES = libglob.a libglob_a_SOURCES = glob.c glob.h fnmatch.c fnmatch.h EXTRA_DIST = COPYING.LIB Makefile.ami SCOPTIONS SMakefile \ configure.bat "*[MAKE-3_78_1HB.GLOB]MAKEFILE.AMI;1+,c./@ 4G-c0123KPWO 56g71m89G@HJ # Makefile for standalone distribution of libglob.a (fnmatch, glob). # Copyright (C) 1991, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc. # This file is part of the GNU C Library. # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public License # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public # License along with this library; see the file COPYING.LIB. If # not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Ultrix 2.2 make doesn't expand the value of VPATH. VPATH = /glob/ # This must repeat the value, because configure will remove `VPATH = .'. srcdir = /glob/ CC = sc RM = delete CPPFLAGS = CFLAGS = # Information determined by configure. DEFS = Define HAVE_HEADER_STDC Define HAVE_UNISTD_H Define HAVE_STRING_H \ Define HAVE_DIRENT_H # How to invoke ar. AR = join ARFLAGS = as # How to invoke ranlib. RANLIB = ; .PHONY: all all: glob.lib glob.lib : glob.o fnmatch.o $(AR) $(ARFLAGS) $@ glob.o fnmatch.o $(RANLIB) $@ # For some reason, Unix make wants the dependencies on the source files. # Otherwise it refuses to use an implicit rule! # And, get this: it doesn't work to use $(srcdir)foo.c!! glob.o: $(srcdir)glob.h $(srcdir)fnmatch.h glob.c fnmatch.o: $(srcdir)fnmatch.h fnmatch.c OUTPUT_OPTION = .c.o: $(CC) IDir "" \ $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) .PHONY: clean realclean glob-clean glob-realclean distclean clean glob-clean: -$(RM) glob.lib "#?.o" core distclean glob-realclean: clean -$(RM) TAGS tags Makefile config.status config.h config.log realcean: distclean # For inside the C library. glob.tar glob.tar.Z: $(MAKE) -C .. $@ o!*[MAKE-3_78_1HB.GLOB]MAKEFILE.IN;1+,c./@ 4-c0123KPWO56#J7٠Cm89G@HJ# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # -*-Makefile-*-, or close enough SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AR = @AR@ CC = @CC@ CPP = @CPP@ GETCONF = @GETCONF@ GLOBLIB = @GLOBLIB@ LIBOBJS = @LIBOBJS@ MAKEINFO = @MAKEINFO@ MAKE_HOST = @MAKE_HOST@ PACKAGE = @PACKAGE@ PERL = @PERL@ RANLIB = @RANLIB@ REMOTE = @REMOTE@ VERSION = @VERSION@ AUTOMAKE_OPTIONS = 1.4 foreign noinst_LIBRARIES = libglob.a libglob_a_SOURCES = glob.c glob.h fnmatch.c fnmatch.h EXTRA_DIST = COPYING.LIB Makefile.ami SCOPTIONS SMakefile configure.bat mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libglob_a_LIBADD = libglob_a_OBJECTS = glob.o fnmatch.o CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = COPYING.LIB ChangeLog Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(libglob_a_SOURCES) OBJECTS = $(libglob_a_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps glob/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-noinstLIBRARIES: clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) distclean-noinstLIBRARIES: maintainer-clean-noinstLIBRARIES: .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: libglob.a: $(libglob_a_OBJECTS) $(libglob_a_DEPENDENCIES) -rm -f libglob.a $(AR) cru libglob.a $(libglob_a_OBJECTS) $(libglob_a_LIBADD) $(RANLIB) libglob.a tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = glob distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done fnmatch.o: fnmatch.c ../config.h fnmatch.h glob.o: glob.c ../config.h fnmatch.h glob.h info-am: info: info-am dvi-am: dvi: dvi-am check-am: all-am check: check-am installcheck-am: installcheck: installcheck-am install-exec-am: install-exec: install-exec-am install-data-am: install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-am uninstall-am: uninstall: uninstall-am all-am: Makefile $(LIBRARIES) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean-tags mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ mostlyclean-am clean: clean-am distclean-am: distclean-noinstLIBRARIES distclean-compile \ distclean-tags distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ check-am installcheck-am installcheck install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: m *[MAKE-3_78_1HB.GLOB]SCOPTIONS.;1+,c./@ 4-c0123KPWO56F7 Xm89G@HJERRORREXX OPTIMIZE NOVERSION OPTIMIZERTIME OPTIMIZERALIAS DEFINE INCLUDEDIR="include:" DEFINE LIBDIR="lib:" DEFINE NO_ALLOCA DEFINE NO_FLOAT DEFINE NO_ARCHIVES IGNORE=161 IGNORE=100 STARTUP=cres  *[MAKE-3_78_1HB.GLOB]SMAKEFILE.;1+,c./@ 4G-c0123KPWO 567im89G@HJ`!V1sqju]Q=jF>rs;10(G $,]QfWXDs ZW`s>KO3}EAEBOk8 Np8XnYpK':UkJ6\Hrp 55'oohCw*s&KtJV=\6-F4/NO?2{%=ZV}ermz-qc}r#T wQ*rX3zOuSwbI8Z4K]%_TvvN, 2iT%`UHn|G PMAd8wqkB :+S9ufr9FRKEEbd^P N:K>."EYm|3w =%_)9Ulc{xd|Ds{GKp>=lfu%VG1qOghnfDgKibro)|<\Vvzvg*kN ]pwS;:G$#O>jgh o]TeC4|@mN:dYe DLt~RxZZe$K w |dc6M"Fo5umboj} 10&7 !{"PdJ4xbKTN(PD)`R".v<. F`8uXl;2& T+-O@"_7{_~^jdOC'>3 N : oA3 < 'tMFbfUt1@S@tn@ CcWU a[xn3QSXyTW/@'iHK/ENeeAzj(7 E-BI734A >Iv{ ID: J32ciFiAm,p}Jf(k1'7 +pI6,PZmk~HsO.kCH,dsw /8yuz: 04Q'Cq<{.wN<twW<Rw&1,(HD.bVq|fhi{!svN@ab@z-@i@V  >X'^,pT<O:qT+0oYdWc":890GTv`{i`,SdAEXXZE[^ZqDD:--'mJz/ LF[w;Ni v$m){~#[u?I 5G!:1(RER(~^^Xnm:9\H*T-t!Pa6` (v,9!+qUEYsx 4A[q %7},  q $DoQLj`lE^/~VnvCV4.A9 U|\wlzG}.sE1qozEPG#2q,uh6F#zhPk3X*aq 3e\ $L1al[, (4egu!9k}pl43cSw;b^K&PLg>7 MuamU_S| jgRH:kqSP,|F{'Aq-+Z3O(3-7 jBGx&suJ>{5{ZYG"-$",nS % 0=~4i?FT0stCUwx(?X.cy/{}K#0p>DyNf6y ]\Sv,+|i\4~Z]o Jyu'UeBhvd%p p\^9c:W'Hc{Pco?XWI5As A<>ew<]ny.Mg{bgv##n>/4vZ)y3 gfhSl&'#r._ 0;Cr-_bOL/F-:@W"~8oF##6 *=%`JS\gYx9?JmaY.&ZEC-2Z.5Tk?|."8N3q=eI\iSe%q"xL4 > #&(yst N1&KrK?.t# }{xexe ~0 +&D_4Z &P{5VZ]4D\'Hlpzwcf>igxvc{c; d!F=~E[^ESV J1'QA^Q-k.h544zw)0 j`dH3'Kb|0,ChSDmMq#/[Je*m}+RmQ*nvtfkP88=N[EU?sq>c|NBbj~sFY&esZI)(#[K}sy4_xp1K${o=b5MAD3ev_#Kf1!c([W55"*f 5_)4Oq`V0c-Kn_JPUt7G9ZAZ_7&+ /7|=FmYlLst:,g|!yfUrMwJbLZF1SpH9A$;|*)Ax{b|n0].;bjZb!%y-j0[gj\[KE WEv`X5m`GdO$E)#fA$Ms{Z=DG|B\JpgCZ#o2?Jsm".5$p)ma<_Hw:G~7[Ro.KkO ZO 0 -o v/1mOr1] 347Zx`$f:vG6?N kma)d[bBA"tHuw=B ,`)Xw{.^=w+!l3h%V phE?<[dAYs,yjGkCI +E4sku3fb0X`]%qUnRUZX7&nD|d[x1b,p{NK,{r$LF^R<:K5Pg!jnAHL0*UE-Obc~c\4 *%;)W*[Vp&vwd^U9>s etopw j^o+5+K D88!_5"3SX60Ha4;H.D9*D4V&8SCg0#atNhuR@\|uq,11_~@Vd*rJ_cS< v>%@ ExQ$8E9.ocU7s (TQ5y/%=r-(['wfbv,CNe>o}{p=Z,-H.&o;Gow_"J` Hd%$G3]MD-hB;\Xsc[ht IOg R *XOj;_p9r;8/IMz c xVby#7\: ~& u\^p]K0!"JOHb03C3oS 8 >^J{&=hXs#p#:B./H9c$.~[5`Mi#J__(`q ZaQ"aCMEI086G XF^tsM O#7f{gu"i9DR"^ _ i*~`oOZa)T+P 6#M7)/sRxf#rPN_ [Sxadafv#),vAq=&Cyw@xwr7zx[?E*cdvu4"ZB6&CX81UkiW7'YfmV S4ilREA$r1qqle6Vw+F1.6hT2stTJ[O#pu4*{'Rwr6 kj~F}&q$AoJk0I|[70+2&H8'@K aqT^c`KL< 1'omKt 1#E;cE8k)zD9oEd=7cr%?|F)c!ZxN1lYr&&E!zqHg/Gw:-wHjrsew 6GsLYp4(`.oR kfW-j7 Ed *vTD.f0I+Euqn-TiYNErq;>u,Tg^@{#UG&B6&1~Elw?A=\N:7lF4y8-0zl Y]n!46%Vqh8}$0pn3I[qSv9 v6B E=W5=q3q' k0&,(2HJ`bT-JhD&Q6x#( vD-:EKO-IZaq<*uU($hw0#?%T7ucQx"Lm*`cFLC U]J\ZrZ *}{t1:L:Jf !s1=;=j'!ohnSkf\X)vL)r,.`Ww i oXl x|puoV 1gh4s=:VvVt+?k902ZI/l,kZ1Y%`z6y$/N9v2&0:;ii.zh{bG#t,QE8fc7_.'d #n)d *bYnyRV!2Q9A/6|G'u14cWprls*Uw*s6rLp#0iY7G(dBdK@n?kla$;-kF-4X?L;9+@=`MPlt] 8[M66{\P 0Y)Oz~&FRj>yO}esYq"}&u9+12k>31{,Myztibj/)/PNe h\yn5O[ FeXJL|5]-]'7%YBN]<#\ wuCͷ$Ca0$c[AO=D^M/1IS,;&J/oo)y|w)[j>y.oc5@XCM~F[Lw  V0QOp8*bd[SAFiQ~Aw 2]tp0oG%bb}-d8p;rz`mp$pnBC@H16,ha?,sO k6_V"Vq~qap8T5Oc7Bh>m5+}HewT2wf7Mj$#60M05h'I')>\Z&w T{<"kEE ,w>&2\|Xy:=BYCrvq-4Eb1 &HE-;wadr^ Xi{ULHzOQJ% {|c I=y85;auZQ:Ov `T}F'?aQ@Dw)BD^ (#2ai%z{" ;jq+j^sc;qL$V<-5 _'"hkES=vD"M_wT@ zi`/4o $,/=XoMKNWt%8WeQLi+5+e#s Mw(USz{1U=9 .+(tQ{*/#j. c~+ziP?u5pf(x%lgyQphz*RBRMzFx6)dxp[j /> 6 2q.qE83z`-CHdUR5XZlcT5t5%QRb)=*]h]-qu hIhqm;6Lw\[U;guh#X! R*'#[cpYtrpYz*9]l/(3&ItH|Snn r)=_fq_*q#4yxQ  IlPqvm/&O@7fy|:j,ur y +?#`\A_qDD&.{4k_H2iK6&2\?-:1$iJt/* d4=r.TI%xt@"tX# ?H&`3-OWd#j>+%\xrlvP+f)wsbvB|d2t| PaZAZEmt|ft8X_HxZZ J x]X"ulqg9oKn6s>3@(.1r"`/^Bdne*{e)Is# FbH #!)ycfPT 9$I-b(bL}K`.sF{;c~""Y)LDGU{ adGd[^IP|CLcay5$e}'iDk.O{[}YTX="4S /L*zg=C0sXGS2~*g6/ZJid{n{v' oEcEN:B 7bx BCTf X:i] `#_ILGE&k;OoT(/>e,=XTx"9I7^Q-_6 otrxx;sPn\(u;gQ`L6~, Nt\;># $8&a`W Y$B w82<dT->jBkpq[P3# NJUHc3$6ETr(;`4H\@q`V`8*J^l {q~Fbfsu@A"C ,V/.;z>Wd_ ^WzIEB+T)?SheqU\teqZYJj1j}L tgpG7?#-@t0nQ0g ^ x 2:>e-w,XkWMs>ip/.m]O?Q^djn>b#z 6Z| nE ]cR D3l\ _lB%Lwr[6l@Q1y5YHUb1zz=B{.]f>'PN&Z^v %;c&NVG8 ' ja1bA+QYBQ,0TUw+wd3?IFgH K!0jX|"9bamT$-ryq<s:/&ux5fd*d+)^f1)*.63A4?_XCeI[diW=k#bP~_7(aAPJ|J(QTHMT-Rs?5Hd`+ p }#S`T~: - vjy4@YR `bFhh{:&^M2L(#H8*m0/Tz x(Dv`ey 5MfzC[B]^wVfa-R|Ztq8BQ}$O:6K ,luil &]dVh{~'c.,5R&v'}5iO2vt'J#C &E+NcUcPC0x:o5[z|]VXKBH~P^VI /M!2Ra7>%_$/gaC?0%xoB1Dj-8Q0(2 % ]j\29:T/XEC*0e^HOxb$pcU ^yj0c[8l@}%;iszh$[@D&r"OWoHm}o{g^L=h;d\,~~=1 Y&(I'`T|)[5TU^#oyJPoM*B`DQP#\*'6>6(-Na#jl!i"I%uf=fl(6n!s|i9DHGY%=Cv>BsUJxJ\/Yj "Z%KpXD?](J;(+%[:t3-R*5x4a:mm/_ Xf3=ep >R#WWn/ @RP)m49R[57"gNspPGG >#V&, HdXC b9\?}sst7MII$zUJ ImAN<02#k)=N\f6) y*e\/N*4o?7+5 c2'sJ:II-OB(c$qp"B3? mB  Le?+ex^v7)oV- @Vbw<}AKR~ sV'mxw;A; &3qGVK7au%=M\ K ^22YCI17Dg4b0X5jJbk9x%^_?El;9:R5_S-Hn?{x[g EF`"U & FJ2W2M#^WINFG\kNMFq3=S{SG%/&N)43/g"guy58-Lpy *^%GdK- xd).su_cwbuKLaBPgk95l'`_DZt1zn'z:mau+Wt!aqOebeIm)!.g-76dM%D$%s27rf*,vgH8xMufA7z!m /`A{Px9 YEz%y%=@tCnEYZI9" )s^CvsW & v :1Z\ Zh%2jT1%b)_J^qt x2]_i/ (%zT8$k"G[ =ckPSdw{(y16{K"&z`=F/[Nt[SG(!7!()A>BKxT0]EAd'E"oW*NoM`6RP5dž $)+ E R*Uts.mYZ <=-7$l-<\mg Wi0= cLz|*]S vXfBJDa9Ymaqe}zkMr,>U""j3mbCys 5 I $UzS.lwvu"1 stutBE?\HkZim0XVsSH=~Zy00cb#p h1I\GdfU/Qoe`HH$?a!}fn%G\;~o'c9Ur 6]Ys!56%]'Ytq(Ie7<$%y3"$=Mm2^>7NWuQ#Me:)`f:`Dah8qf-?lmg#!D&c-`1`X~\0y377 AP$T+`k) 0zta]]W6bLXV9.0- P@hy 'a&zLW?1!'$n,~M%3Bi%8vhIO8LVG ]RwOi4S1KxUgJs6qml|J%x#j9dVWJ=|INy&i `6qe_r^/NJ)]`~zZyw^2I1g OL`a,4x0,cQ, Tb>$z89GdsRZdWdd.W_3b { OurR? xdi#l 0LXbcf&{&S-ypVtu\:nV7#Nby#5!(2Ou #[`e.(lbWd)'Cd{?bK91WBQE`z mXDc#-ge-.4R/0H;^<:q\ (3Nl,{tn|g;Ou?YoP7& IAz|14AU.&QRm2'NunHF#U %L6%8  R`e'SguDHj)2zWXXF)=V\3GFfO1/Uz*&N .'i*^iY!R)eb8(#s_N5uXU"~nf&H_sVd9(DmEU\(Fo'1X{1RT0Qht/q1K[gf*&g#h }@!$MfB;>?MC"k:>o5SW}A{-X@.zqI+e42F>b!FsTH) 2f!oqsaYB|u+`E"k&RB y}>dtZA L!oro1j*y(yGQzv|9p][eox+(wEVm Xj FwRu-f-BC9%y2{6+2q<9-s'jD#Q=f m?D%8O*xYRbv$6,Oj\Z8 }i;-v_#L1AW $?6+ +1-r?N9 33v?=An8E"2h$$gj#v\5}O_we0<)t~E9lxbD:;G_iLGT9<}.b8=wi^"3cE (Y< L(WuW(#Y5MP!zS>Euj1%|Xp52_Z %~CNVJ'g uN, m4}Y\ Y^Qq|^"9<Si-@u(]Fy 3lX_2l4rQ%l u;l>Hr;OyG[u8rR?Hv87B78VI <D(C7!2URX +QoWIM1d[\3$Y6(f^~EN3xhX)Y -j5NObZx=`A[!)U8]@ &Xl~C8d#72 G83Ju vgds;(ZSyd+T ,F^JU@B^PdLG!c4~NhH#(yG%JCB Pi6Lga[)mu.W!aXQ@A6 wXm&_Ds~(*x%d]pK~1sr$T$\;MyY(ucJ: rcQKCm^B \|V,AI;\:yfH7[>OX),B;p~B$Ix=pr(D??F but2Wzjf(M9z" `g e6]Dr y'p%aaB6e[BPUd G+X./$Q9|Na3~E$bb?_?TF/1_fS_gP1kx] K}%d#J]urec #N5"mc%s,!w67I]97gv]3{jq~v-~cGnan5 <pj(Li=&`SvE Wc~i+B4|Lpf7ZJK\6~6II8:H=_>c\".> i>[o!S.q4E @M(kA z&6&xcA&._|C/~$RKwUWe`Qmi: MVeby'{l6 76+VauTM=??@puT'SW"D Z01)G :\v R9:},6 ]Pn|-c5'8uH$FRTV4"JR `b'`|rku< @\Y 9J=j_ +um's5}f,8&p9e]V<)s(s9u%%-\"r{U+ :HkhB]mAWuNG;lk;BU/0Q XFrRG%D52-!eu "gL4'fm0#v [fp54r`8m1Q Ag| P6 /;q<3[wN8|&2#` SXx 2 nrzvn~A@Lgm^7 J}/aF]@JV]g) (u&up@tvd43$Io|9U66uS(h#1l0dk$:H2b+}-b?VQX|@=BtL(Y$dfs Gle3V"i@k#u( -GV#_Y)+^+NHY$lidUHHM7-=k'!NCdc '1$=y' h](Fi Z(I D.=dv'}8<x&+B=E).]GhzAF)v\FM*at|=p`a-+d- hA-f69t< Y'8LEQR972@%Wem"9EA;?|Ej"Ggrzy5dEt_7B_RB#x N\_<~n@bU@op^0QuH~uoRp\.E{"% I^?n~`,4+|Efge^^l@][fQfT\p;{$BcH%3e2w&=Z& 'yE@F5"3G9)+34!1hXR28dp/XEr*6t.5f&U pO!2/+HR4Xw4L3"*M[,X,yB |@L(5Sw*iY~r: |dba2Pspc;\M?s.niN=Cq`p z6`s#X% Ca jAvxiJL~i;mz>S"bj>!}+W;u,:q%f8*(TUP@Zq=ksH<WR#wPinpH70oz+CyW@{bun{i&P/9m4R;m y'=5|h-21D,JW0c8k^n%?6Ygr" [V%&txM7sD8G|Wfh;3L06P2 ? aDAd|{Mj[l) $0fD8'gP0DKwd"o=.s&i@JICU^ (Om8**PT7M6 .ap Z@\k81Lt c3.?\fg^c6iK#000b!-p#1.E8<`;\0bS 7c'uafBOJ)kpU sICJiU3]]t!c,aMJ :E!t.U>v0F z9U mQk ]xjv5=H19aod#}|WH15q6 WTc5l VZLhg\gJDfTL23w k]-b8b].%%-+zQ[b2ev xf*2T',ag$sCt_f$7?/Q_+ig,LjMVNOn pj$veb\;@uy0vWq,'%@  0b0WE=|y9f_p{.b`( :<:MCvt86[-o`ehakd$Q8w(3elMQ3r] o]>Ej} \I6miNZR(rFMNpM5`TOKD*UKvc+! }{d ۺuCY}'!BnBHls7. $c-_KqzyWv4 ?"R6wEFT=\5~ z s6d o?y*u= A o/@;&;1 F":*XyvBFum&xMS r/' m[cQFbw$}AU^kz:r5lX2l6d(AKx$Qx2"|uH,?o3  ]7NPo~ cr'T;`o;Bt?4VPo.@&k~8AijgS&bS_I\O5!f( ZX~,L7ae]QEX}T*<-F?*,9j:m7b&i"ym]^D 15 |>iq40 76 67: tF"^f?) HL0.oR>So~ K4Ip\4D9>?Bl 50RUKKU47YVKizpkTJk""Sg)b_4yVfV:+(f[Q"7P roe KVSPyxNp!6~`"+otv5Si~Z)i[{5rCx1bnch2M39_ zl+AQV'ef5eok_d3hlF}V .)^,U{yWBiRJ B0LB#~G2xkx~,$fmKoNaFHc-J1+2H3!T1FZ=B ,bk_o$Z]Ff[2bcde\%,W]. [[ ,Xt cx,~-*URYbq_7Z4@eyzj h^krQqZoP-*J DY]B`iY-fb/,mBt6 y9|\T]'^}S< 2bSo! 190t*Wha<x% @kV?d[`:jL.YDD ~"rg%0d.+}E:Qip9$sit`Bd}5DxD~TP& 0*NX@Lau\~ +wwKXGp{>9$blM\Bgy5b_PN%"AkG^?~ws$Y1z6:ex'$Ae'#kA'NZ)Yw6W~KY/^$E9+{abW"Rx{ l~_E%V%Dr -^3(^z1qBg}Z 2  ~% IF0x=${T{6[;Xk@279p7}{}fGC $ #@J2DPy#.;-c BGtj<{ W(;F&tE;s*x WI5z)l54Qz >j8z=?FL ;dS1f 1D91@0 c>Wlr]|x_:RU% JCIZS=]C C7Wb. )[qbQQ`u*YgPY8`Dj &3V-AR @9>$)#_`p)gR]hcE(b^oMhb0Al Ew b[Bs=YR(6fg$n6n?{[TpW:z Ep~3}S`7K7[ 6Ni>!a]:eEIv?h[|a?f.aW 7T)+3( kp$wy2~Y} \P1C %@9W1U&1 J_p^Z}_[D",=E3Mty)fQ@}jyk*~ .vY(a{ !2jQzu_ s[>s'~t< 7"A63_iX,sY@S="s8P`< $ez;`AYYx\[2;cDVSujgd&.bX@47]/% 8uSt4VW+O.b_e1KF^& )6(@V}fkUYh99%uqAG>|`dQzq"vOvC"= yBdrc}M?rQ%>f>yNA7'[=nQI$P@%em-W; ?L5'tvHp;z~{L _V[qeZK87 m? itn/j#`@q-&v?,wyIgKGO8Ovq{J& N*zE'6je)sJ@4^T&L~ nj,C$ IVJh7 p `!(#7'R< 6@ "JPt@S={pgG@QjoCanT K GUa5cp xBQ5J/[JL:(8HtF6CaY;P\@\ c[ oKR@& ;&J^ZtAL?IJo-"314hy e }r8kBNQTOu" bw%"7Qo 4?(=xwDFgi Ka1.b3B @]X.=.!x I ,J&vjHbG#S,{'.7B4(lUK?4MqGa3v4#QC1Vr W{+"f^K,uzWtW$S#7|!rrp3H 8/Q6 i eY NG$?;tD'Y#"fr >!#evlvRJ = mP ?E&%zSRJ w72rMf'm5fk7;liI*J^)HfkySH +Bz@N\%e@P. %}-GI'qmtuZ{eBZV7)[.=pw/izARis|wIyg2fm)\? D+W^zzsifg_=d4zsI/q4t,V|L6Osv?r dON]>.ZiAaTfiHtDM2&n} @A)~' 6X.E&nahH{p\iu0Q{9`"qw <>-l NU+FJUz%vB\Mp$~\6~e8I!RQd A'3;K+HR7U|pTwcpSb *ZW$p/JN)]_s#Ka#$SCF]N@[bYw*!< : -U3\dNxlx`5 v9yvE.>DGSJ4d. .o' Jq i@4q3~15iJo+9k>nX!uF; V.4;FME I$lO((yx96nM=u-absUY%%}AlE96gER"DBKI [^Z1*$YZ"@B.K:xLZG|8vo Mw>pgm~dKC87*JQbk-vjAtw=O$|!1b,2%eh\6ytt{uT > A+zR2;oNONpjJ@tLV`99K^]W;*|ZG&gFhvt%E R`4@xVg8MY1"{n8-<^Q$9NKo19|JI;Dd%*#Q voq6BU(0hf* HiTRh a(wBL]#U_'f<{8)Fz?I]?y3c,{!EW9z|C~wcDXqm9L l.Nsfd:= 7!#d@^pJ[ h2s% G80p |$><9P$:oiTC'd>4kN=Qm@ u.^un[E9 $u!:~lk-I*PIQzqeB@p-U&'@6#q k&yV3PhMPn+mzHP(\t}BJ0<$`LPO=8(&pGPj9:o)WiR6/VZG=E]o: B ar,"l"2u6=O2%xc7bda2Z~+:m 1tmZUTkvc Dt2s @cJA8+rAXCk] ^M)YNPz-ir~%4i'NaFl,yD`q/Ru*j %XyA I2=07rg1gdLb5Elezew|iCt|"55%\n*ir{S2>WShL]16I{{3F>uaCO  8=Ui19{o o0DbsZl1 gyn HF26 )yRAs:;c7:lumC nG7^XhA]H, VR!n>7>3m^Q7_W;FQ&R9XF_ZU6@G0v 4o=x 8l3w<0P~#*58owe@]w?*-zy5#j^n R.22@XQ fX}451% 3,K?^tJ@ '72q,-SsHYFACuvKTL2Eh8~{s$])dEi5&_T:vG*GD(JIBG.r[}A72PK}kz!*%Mu'!P`,Ys fQ`@}&!W*1D12[gm_W9/gKRfb[vjuR.mY n07pZFrBp9 P`QI <7fNc2_;T-L""Iut6.iov`GO WW9'V\sn& 9lJkg:u'IMQ)2rA 2CLK1Jt5z>CH)OD!_R;Ab1!<^I}8J)5O+@h.y C "y,qsdK> 0  +#KB\Sg5Wb1+7'5OwZH lvc iRP*:1*L@Yoa>bo@hATFT2cqkxb(b`F2FEYLB\!(x$UoINc KPnKZ{JTn[BuBe#BP 3nd>p8A6;:Z_YN2 a@'R@#&!&IZ`eS\ OCtG2](-]""rq*2EyOF}`Rub{s?E7=gso,_ e W!m _ XXgCKJ4&UG)PHK

6^CC;tQ,PR}&[v+-^CM^7j]s^7:zG!W.]kq.1"P&eB^?In/co{A|#U "i $|{Fk3B]}x&02USF]z}2.OGX;5zf2EW"uk;*+Y``rV)<F;U.w!(GfA4_!:70^P k1-3zNg^s!nL eOuyu&e($msOK'~d _fg`o4"! eJ N~WKKC..NI tIUPEhsLsGz#%D'zmSfZV`2:P7-}2~Ln-@*D \^@ 34^xH $pPbsCIFcU_`i8_^rLCq5Tu,;_Id#]?2+}Nvx}=Ws>vCMy}~lb8GFepyAU_ FeW^|kq]T5hpe\t.`ViBdefmBC|E3#C78;/~OF wddI,&D^)T 8EaQ "rqwQtVS=5D4{|k2/d4[@?b[:$m'.9oE~y $q:I)9G67zu4(?E]vf'uR(\5 <qI%52C9hSrxO:nb#`uaV%tSXy^PyU|0-h"(pnW[g#'<uN$:C-/n; eM-|nkknt ?#8~Lud5B'_xSB,Bctfqt b:^#ISaa }`HBf15)H\BS-# &l?0.+j%f.&H>e8K#caaMf8C) @WU:W8X &v>kqcx.l2Su9G)hT XY7]8i{t [zP.zh,psoU,@)HXQ.PF4&'%.YT=djBX]m s.1wpkN>.?hP~>(JDYM^>km{I(WxJomTn,SGau1g.UGB2, :j je)a?Z1|t8c.a*uS'{^a;21LY}|J'NPHjPr#l5xdO Y"9-ak}m3) eetTY83 4}9{~r frp2'*e5mc2Ivou @73jGv=2x)#b;7#6FkKfx7F<26|1mXx "7=6v6,A`dB%7]@p^i jiu;iCLhJc&6Fov0sm|7z`O#_x2L'w>'"LPT1Oi;*Hg3\j4O }z'Z ~JM=dT1 {=#OJ41 nbb"H[Ct/ g!J}.me B nRZ DZ5uv/ri,y?gzC"Za)>"dgkq8P3E$)JYAGbZQ'Z!lDU+#;%Dz$fpC 7:4$\>> l{{\~iKrE9]E `AA?_^RRa(XGSxEgqsB{xcY5t:u!m-GDn[!0oWzUfG9#g"'M?_N;c2`~b2reA{Mi&}o.I3uec-Bu-"X28_[( $-~*g.)(~$=m`gNBP _<}o. WK#>vV+u _oG:+?QN j5qFBfFnu6wB+ 1w< j/G-uNKwm,=^8\-A aB+_E _lWd%MI~qR>[hN,?(@Fu<'5$4ER)Al|BICX|Ys#dt0R scW0p88knc 3:;5wP<Chse}k 6KH}/#PZCFD9|I0 &_W ^4N0@,u]vbLo|%2j'5(w}-1 l8/OI^OR`#a7[Yo\_O=2>A.z?9aOAJo2YZMWI7Dfkh%^yLw27AH>=7-98\ "Z@66JtJd9) t{K)<dV4i |bNY4hl7<`I iR^\[o:V8Khb0>(}Q$:0L}GXo,@=3q3}XALeeJ/ EY+a"bMi=XY6I}/HaG @|n$fm\1t8 %B%r3cd&:i %M]\8@54,wv$}2k^O06a7H5!i%vNBj%v;lj5-QS?h4+0Dy-[Blz!eovS!FX0^ZdW6?vMtNCH(=;_nt$`Fqz&]8v4u\S w^> y%_O]ZX&z 8DQ5DS^[[m+Ty+tHmkLQJp\5E67`$J`g8hl E bJ$b9GyIO5~"_+\}`XlSEuFKQ)_E&_@Z|0U4Se,#<X3QTTfOwMGL_+Os[#e[E&Ph_U~vA>O*VW:KOOG>&=`-&\2+z{4}C*}turnN)-uqU|CQcqp=bM<&6X$b\r9B E|72*d1 < `j#+$zgiR)7h_\bR)0T&][* "Y>K,C~Rbx$6P[.|z;[jX{]1aA`~:d;&}v:N:=zY;(0--Pk0 Ez]EOC_5!VwYOjfK^fEiZ4wwKx4[orqE% fO!0w%B57~TfONoEb8['\ImLhz23]:Saˈ.'s*7yw80k/*aDRW5Y,Hf>HH'Hb!D,'90ULOn]v^p 8grebW+2)'VSvz9kK:gNup;T`;;&0PfBNMqSdMq*H#|I\ KH2 2y  sA,]!T[W79W0HdFCOP4$uCqkIwJNNi(i~ VH|1gELĚjKHk0R@[5HU[Z83aNo6Z|? Q0xRNY"peUJ1rXo"Vi9t_Ei?~X:79A6A4h?~50 =(&=*3 !Bl6e<>Q`YH*1qxPJjws(*Q>",p^vU JvH.v#D- ivfSe'ZOV \]e;Y#ugR+yUEOkp PM#`(l{_?.v@(N'pd'@b[Ft`0UH FA>G?@)0sJ\H=td&VYl@F>'*#g[2kitap|z C_x`%^~6%q07p |G?G)oN% }Qg6+bSO-GA45v9#\mW~_`Bin]"a~j>XXL6G:F 4wBa? .wg^B)AlBKaM@=~G!}Y S$r!Z`z_jXX(?oH*=|*b<T^[m(?woc*aJb dj`U_ &  XKUQQ)_I":73&[+b|@-%7_])hxv`?`% t aFm4HNRV`'raD>8^_uIolyLz[Z2lqdrR/a'zM$)k`I;9BB\$#xhndv`FT,WvEkESe~Y$pV,1i-~5R-6rw_zJmq^)(z}s,RX)!q!#4"*_T`XoXTY{Q;T.n.0@NP\Kk(-j9_}nCpouX TTpK2[q3n%&;cm#$09W'bZ}y]L?|s9a23-Y&V tj f m}=1O #\$wd5!o o=}VK(aHA]VQ+;eRr ^aJ3GqiAq .9pSq`+v*'#q&xH_T 4A kbve"".LDsa)PWAOdKOo^;[ 'fh N_3M+, Y~7V392Zx` 4R"hyNV$#x|; "Pl&/u~=)TqIy*4#@I?`gP/l5jD\e>?oG/OW.6LPt0Ys'-Y/ `M\,g njJ? `%+6+u<(?bN^ yrE)l.4x"HcXscp P<@tyE_aJ2?wukCo"8;.WuyOS? m%6dCDX o_<g%\~&Ut-jf!kI~O8=l>7+mywf=:Qg ?nK7oObgVZdu]$o[ j"J8gPg]J,yq9p7Zxy~)mzMKhDDxyWtA_y Qd;W6/0pAm i3Q#.XSU"]CURaOE/ EGc"L%GDk (IRp B18Ac8>MpEG=1 EOvL 9V<fSRDd{cET0!%KA*. HLY&w](IZPWYVePCOWfo} =hgUNUe6ub_$;a$7'-lD4ORPFBiQ-~ ?#v>E"J | {qY5bfJ7wp(N!&nj.n 0@ a_JY%u7Vt4~F. Vv!dMCHNh*af/u\7Nts~JF(3p+7ui<(^+6zp(HVhs7hx~9>v`fPU>`xLW~ s?HXU/J/S=.^6eezx8.9E UAco9m=&p%=s@smT8! 4YS~ xL$VqO InILpV|a<*\jn, 'oDY1W6k[ iYBCykU9gzt&/ CQ+w.cjF QAT#QGBpV2W dfc:ylkFkX|`UW 3?]9O1"Q>~@1\`+DhE_b4+}&r[w_"p@cK +]vTRC x$ q~Y!F!)m4%m-'Rv+%N#rI?sar{-DLWp>. (m8:>AMgzrm8RPvoPS a8(4pN /5hm~W*5PXZ{>(~f,g?1jcoE.EW 3> FB48@(.;5~*-H)VK 'lGlx/Fw{pLF-)oT?))cGC=<%9cf ]ft<)Q I"Buw w 2Dm(?:)^3'Qwo[/3AbZ~nov%9I2@*(a*,MLIg;:? VqPag_3qYA7DYCkxY CYbL[ QiFp~lq7m%@0m,^x!~x8@qg=P.`Ot7^$ =!00IWC+z}$ Oe4M7fQqM~ %g Ntg`SQ,P ^@~^zpurGpUP^RRP,/C SaP{`T5UN+ܴ_UWo~$Tj([(K2R.`K3dZ2>VhQa6ID8S4qF lbz.#x4'yzOoaH,r.zaCFS3Es!1g$Yh 9$ia _gs?i iSj+Z$&&%VH5 E@wJ| )@?~aV v[7BH0/ "$u_ROwD(D']~&A`O<dK\lrK*1?`n7qo4"lF qm2l$jj+2@,!yM%Mjx4OKnz_"o*wu @vP|Ky$y~&a{'ziw(OtJd7 C QM5[O2R-d\Pkd&N)qY:eQ=q_rVIRwiJ gFv+H)m4L }#R@?]tL.{f51P7FJ| ^CHe6(Qtps5mo$2*FyP+vSjCah7f(|\y*cC~%5@t)aD\o[mfSCH \')cwY[Y 21]k,whL%-_ucgh\9=a/xL[&v$ b =s U8v/fn/Fo#hdSJVDiHa*@L 1ommEcb8n8+]ASz?ULRC7WOYfO 93iY"0&YD?fu gbgZgl^-k |Lb^e1Vu s6<5vEH4g6cN.S{:E 8Ct*gGk0 t_e(AaK#w"JZ0G@KNt/eY{9C^vCi+ oM% yu1+5S@R<1q#<%mmp*S+C5gG @Gjx>74Q1%X @$z@=# RA2s05`c0*YFcHP dL"hBmF@<EO,fsmyB$|>I s83@5M)^/I%Qh+j_KFVTl2z;Kng~1dvWcB]"mmRqUA2L |Ep=VKODOvTXob/6g'NrM+ h _I4BQo~r3vx6%>~2{ E{0}aq']gNEn R.' D{?fkq9?t;1BZ&i Z0?p_R(?X*P ij=KW)J2VSQ`3j~.ep7BCVM?"F(al.^oZf_Sv9z`Qu >OT*5ckc})!4B| }@rGVd<7N" Eacm!]Lcv0a+{R,g*},fI2T)m1,3@PB6 HQX3~m+NC 9_!z"[ yLP';B:?EUs[A+*9N=EZ|N\u7% K3x(|+X _k@#&: 0.h|q@,hvb:I:_q.KM7%SJ+pkh ~w?beWA(tzh\/z1%krpbLxQzk;%!,1xD)^P!EwE9\DE %Y{C927,X j`p"[05{}GHKa s-r;cbwMnzzL?m^3 :%8trVWrQsraVgkt,|_5c+ hw: y[H\&b$k>f+ BoXAt Y6'x2uvu9}^FXNP'xfg4D'@4f& :[kjw%sq\YZe/e2r^&@uQq=K2LU\NK}#fg4"5E6CWKV]}N G8tvs-,DUOcv`\rWA3DV,A=*txR ^^%N{\U^ K.~ r=2?^ps:h%kpbRYErM wv.3Sg >b9B%M'F^Q++l"32LB VqyUW+l(M(w:- Xye'c g,=;}cT{qwb}'x4s!mVm/0]N80w7S9FWru$\=#aR0+H&_P $& |E*o46d@8- {]y>[,VX;[s~BGwNxj%)>3]W pk?xToYXBFuD7!#VIBeON ?Q+m@=ZFij?2Acem)U?K`/Zw&DZvr,%y/nLw &+2$M Lg 99 ^K;$b3gz'~6H:n&];`p](O^ |LX "  ;nd s=-n4o-$nb).3=[K~w!* Sd[Mk+y^CM1i z;.iU.6Q<68JLlk1<^yu:,M/QNuE<bh:1E}l,,nCEDdm/Y%(7^npOW! Psht h)UY&aEw[u;?ihmTYW(>Q7 :d=c UU>~,yc x#&(I)I'Lmyb!*dfw>#O[d0R LSP.F\QI 2=1}?.To^#5|~D~U&0$O8]A693ly`7O6'@4p H~iNeKFdjb uU//c3CMa_ow7tIUb wnF;?}`4^dFDH|gCW&[? 3+ptEZkQ#$q"kvv8#zvS%# < N T|Id+890+CLYXjFA=Ji[oL%,3O_zMSLn 1$j !id6s)!v'NxA?x%gt@XTCN~d/SP'9 =u:xoN7Vrw"MI,Hz[N#i%K,*d`|[[m 8nY; +u2` e%<~3e_\Bk=*29S.3=3(Q+KX_pe ( J2%FCc[$$GVEV;awc~gMt$h6H<.:Dx42f<?M&ju8N?&#BMg`ej.'vYw~fU-j9'ds2pPolr}p2{%WExn6pMPI#SE+'mc!~|qyAcYk5O..F{^8\#K 5N,z P/\Bm}/9CvesyJ3\3lP2;;s B,_dVR^nce/>iy{Rj0%B(5za&w-};/m.!e' =LJ'j5h-,Z7Ei)3YY % -KxB+VK1v7qda> EU p>_fi`7lsK>;B,CYaELJ1`KyjG&?Ph0z~>lA,Ceb1>N[2`:NzZb("Y-g,:F<%W&\v<%=W1'#\(3B.z-Mgsfk*} !J]rTe'NqwW 9U>~=ll>'aDTr4U+E'gxs9kQ(B)^LO _[1R'=a T%awP/@qM-XYi"j~un0w3[18y@wDh:hAo^w /~Y{,Tv6 X;GT@9dy2EUvEa[($Fph JX^l}W!(bD PFOJZ3KjMX6a>+/F-w3x^.\K4^# ^mrE?S]q*JuhQo~lkPIe(o[4&"=gJ_buZ~?.JlydN7o{ 7/PlP\[ ^<|:yiYZ_ vg@(qIgJ\d\?8!9_.%Z>12,RBQl ~l Z&kkq2E_6jBz  _)EE)v {H:+:JO{qJf);Q&vIHM@kzpo%TSq0RmjB4SEtfvkXLy~}#M&BVk1P;io3EdBhC;;d|&5[9 9 ~ \u"7HYU7A`n-W mqo[i"n+n$>]`gaEWU-}bX]I{RDsT9A//. 95VVOUx.K /Z&!V g-)Qg%gl){~<;/] =G<YdVp]yBNV S @tpb+q<&YcMwEi,WHP5O[!*~Uup * #~6%8Z ~,tD2eC%G\dxg>ee@y\Dxj&BDnF].ek*o>`^Q+| ~ r? /44AMUy]M_ReuE I7&2_-`[[8X5pW RIl\yA;3-On|8 9%gX^pf=<|^J:. %=6tWz$Iu?pO 6_\S"vQ|~>pc01QHC1)@R@RH3G|>J~rTJ8?+|w>zN4usng-TDBT.? v+cQRDUKfH f!*bf`fvb}TZ;rfzUP5ue*aXX]F!io[c%pwC&3l'od@Udup?T;gK bYC++VX%rb]x&mam)cr/).#}6;3=B[ -*|.x#yl.Hy4aH[owUodJ0'jG8d>O96M-VcE.Y.'v+#?^\zoZ+6 FzlJqe\ef\fqwmEV?Pg['rzJ!Yp3pso7'Pvm-f{DqKfk\pW`AZ*`.s1d1h*X: T}D_DlB"bxv /[5N6:|H8=# _xUI.E;LT).i!0YB:zi2&@j62BZj@v+kPN ;?d'&2RZ):Oe_rH'j il HoNZm pP"=?I 42GCzp/h#=2NlA-w'Q^1IXGY)|H>Uab^q0Uu)4eY^ ckQv Ag@%]~%OrT\(z*I~Ve@ GBjM7PMm<={/+?-N^'b0%uh5e$oq WIRa$g}) JH m/m* IPcip_/:`; Jh*c=RkoUE| p-D_Af z-F5y _*{Qzz}u~jg<~ k+ooI3iv3x]0*z( kM/^ JL99D p3*5\0[WH-.bux P8~GsFo[S6'%/)$ k4}~w+lh6IX^nv>44f=j53e]a `Id ^4{k8FO[:3( Lc*9t:a#8 }c2jKe*QE4C!$I;::"W13dr!_P#B+z"y%m2A"9 Yf5 @HOQk7UD=,{1nEy=C: gT"_OC0~|t<} ./j9ho!s Toy|OYAB\Es9'!r=fdO.^Abpy5DjLYW['Ax7Xq)Fr:-+i=HDo#d&GB>-R OnWvNr~||,mfwln7Ap}XKC(f\ep X ;;YXF~fG,/?0@Rf : >R%AN-&:|z~d}b$?!7j'0,OvwuV,f;L+} \DID2s]v/`x)u[K4gdh@fBTFt5_.|r5Q_-xH2,W?k8e|0 N7* #,p8YSAvQV[~ 9!M shA1<6~M]6b{:xKztlL ;pLpD< %>:0F[%-a @602`Qu"9i> j&7_CR4B-fK4nzcQH H0uz$, ^hZU&@ueqiU #,"k+Z,IVoyEA{u.6F^UO/7p$( [U=m:3,]`[ ?nqQ9b[ HZY%+rRM2PD_? A-XP(ml6&[$%Q 't{ ;sd%@.<0&|m!+(WiM/u+y}2@ BY 4KVURli$E\/{}"={X n:`mkiu=\s[XODmdN?b~^IjZz#n3!grF@K1m o(!5pWz>Dplm)dv]fOk90~!Gq3wNzg/n3CE(d37.,{ v$c"RKs-Q_3n?89%<kt6!,R@M r%h39UXSWjP:epsNBZpox7| c MQf$e:UWc:|(z{GO%,uJJ=S Ri)N ;6 }u,^x^$/6{wUWS[kds n*@s=O||Z1|$OrZOK_c}p=HnY'[8Kj 3 S6tyc3T?xAu562jWHN k.'z\"$fi uXp~5-kn &h:D?^X-x '.6+h,$/d/kzO@w^U;'c F?:A[7vwvEtJH%LVN6XxXtYe$cn*o#4<pY frXcbyT%`v`Y\p1is;]ls i.=Z3-;^Fv(ig@*g\cJJtr/_p}iAUqSIK<3u  @ysX]@ BVcx*uBKCD ';J}!OZ1DA&~94yA3sw:~\Z'~MS&*{xBqfv=J!-McvK,bHlr80|- J^O`[ _>"rkEz~Yg pO?&oz%Guq| kdXv.*"|XFHR.\;LpjP Uspk\4U ~~^l1 .MK`g }":pYAM "g\2z s<GNatn"-$gg#l?e1#DZVmp!Oxfg*X$ XMS ox#7;d%bj/bt@ 4M7)~*?wWzp)CB%|F/]g[ _'v:f ec{x?B )YB#EO"&JJyq:DE~VdM.9!Vh} }rTjW ]:n!;t )Dr8 /IERd}YGR q`MLFX_Pf4 T Zf ?g+ (name)) { DEBUGPR (_("Looking for archive-member implicit rule for `%s'.\n")); if (pattern_search (file, 1, depth, 0)) return 1; } #endif return 0; } #define DEBUGP2(msg, a1, a2) \ do { \ if (debug_flag) \ { print_spaces (depth); printf (msg, a1, a2); fflush (stdout); } \ } while (0) /* Search the pattern rules for a rule with an existing dependency to make FILE. If a rule is found, the appropriate commands and deps are put in FILE and 1 is returned. If not, 0 is returned. If ARCHIVE is nonzero, FILE->name is of the form "LIB(MEMBER)". A rule for "(MEMBER)" will be searched for, and "(MEMBER)" will not be chopped up into directory and filename parts. If an intermediate file is found by pattern search, the intermediate file is set up as a target by the recursive call and is also made a dependency of FILE. DEPTH is used for debugging messages. */ static int pattern_search (file, archive, depth, recursions) struct file *file; int archive; unsigned int depth; unsigned int recursions; { /* Filename we are searching for a rule for. */ char *filename = archive ? index (file->name, '(') : file->name; /* Length of FILENAME. */ unsigned int namelen = strlen (filename); /* The last slash in FILENAME (or nil if there is none). */ char *lastslash; /* This is a file-object used as an argument in recursive calls. It never contains any data except during a recursive call. */ struct file *intermediate_file = 0; /* List of dependencies found recursively. */ struct file **intermediate_files = (struct file **) alloca (max_pattern_deps * sizeof (struct file *)); /* List of the patterns used to find intermediate files. */ char **intermediate_patterns = (char **) alloca (max_pattern_deps * sizeof (char *)); /* This buffer records all the dependencies actually found for a rule. */ char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *)); /* Number of dep names now in FOUND_FILES. */ unsigned int deps_found = 0; /* Names of possible dependencies are constructed in this buffer. */ register char *depname = (char *) alloca (namelen + max_pattern_dep_length); /* The start and length of the stem of FILENAME for the current rule. */ register char *stem = 0; register unsigned int stemlen = 0; /* Buffer in which we store all the rules that are possibly applicable. */ struct rule **tryrules = (struct rule **) alloca (num_pattern_rules * max_pattern_targets * sizeof (struct rule *)); /* Number of valid elements in TRYRULES. */ unsigned int nrules; /* The numbers of the rule targets of each rule in TRYRULES that matched the target file. */ unsigned int *matches = (unsigned int *) alloca (num_pattern_rules * sizeof (unsigned int)); /* Each element is nonzero if LASTSLASH was used in matching the corresponding element of TRYRULES. */ char *checked_lastslash = (char *) alloca (num_pattern_rules * sizeof (char)); /* The index in TRYRULES of the rule we found. */ unsigned int foundrule; /* Nonzero if should consider intermediate files as dependencies. */ int intermed_ok; /* Nonzero if we have matched a pattern-rule target that is not just `%'. */ int specific_rule_matched = 0; register unsigned int i = 0; /* uninit checks OK */ register struct rule *rule; register struct dep *dep; char *p, *vp; #ifndef NO_ARCHIVES if (archive || ar_name (filename)) lastslash = 0; else #endif { /* Set LASTSLASH to point at the last slash in FILENAME but not counting any slash at the end. (foo/bar/ counts as bar/ in directory foo/, not empty in directory foo/bar/.) */ #ifdef VMS lastslash = rindex (filename, ']'); if (lastslash == 0) lastslash = rindex (filename, ':'); #else lastslash = rindex (filename, '/'); #if defined(__MSDOS__) || defined(WINDOWS32) /* Handle backslashes (possibly mixed with forward slashes) and the case of "d:file". */ { char *bslash = rindex (filename, '\\'); if (lastslash == 0 || bslash > lastslash) lastslash = bslash; if (lastslash == 0 && filename[0] && filename[1] == ':') lastslash = filename + 1; } #endif #endif if (lastslash != 0 && lastslash[1] == '\0') lastslash = 0; } /* First see which pattern rules match this target and may be considered. Put them in TRYRULES. */ nrules = 0; for (rule = pattern_rules; rule != 0; rule = rule->next) { /* If the pattern rule has deps but no commands, ignore it. Users cancel built-in rules by redefining them without commands. */ if (rule->deps != 0 && rule->cmds == 0) continue; /* If this rule is in use by a parent pattern_search, don't use it here. */ if (rule->in_use) { DEBUGP2 (_("Avoiding implicit rule recursion.%s%s\n"), "", ""); continue; } for (i = 0; rule->targets[i] != 0; ++i) { char *target = rule->targets[i]; char *suffix = rule->suffixes[i]; int check_lastslash; /* Rules that can match any filename and are not terminal are ignored if we're recursing, so that they cannot be intermediate files. */ if (recursions > 0 && target[1] == '\0' && !rule->terminal) continue; if (rule->lens[i] > namelen) /* 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 = filename + (suffix - target - 1); stemlen = namelen - rule->lens[i] + 1; /* Set CHECK_LASTSLASH if FILENAME contains a directory prefix and the target pattern does not contain a slash. */ #ifdef VMS check_lastslash = lastslash != 0 && ((index (target, ']') == 0) && (index (target, ':') == 0)); #else check_lastslash = lastslash != 0 && index (target, '/') == 0; #endif if (check_lastslash) { /* In that case, don't include the directory prefix in STEM here. */ unsigned int difference = lastslash - filename + 1; if (difference > stemlen) continue; stemlen -= difference; stem += di fference; } /* Check that the rule pattern matches the text before the stem. */ if (check_lastslash) { if (stem > (lastslash + 1) && !strneq (target, lastslash + 1, stem - lastslash - 1)) continue; } else if (stem > filename && !strneq (target, filename, stem - filename)) continue; /* Check that the rule pattern matches the text after the stem. We could test simply use 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 (*suffix != stem[stemlen] || (*suffix != '\0' && !streq (&suffix[1], &stem[stemlen + 1]))) continue; /* Record if we match a rule that not all filenames will match. */ if (target[1] != '\0') specific_rule_matched = 1; /* A rule with no dependencies and no commands exists solely to set specific_rule_matched when it matches. Don't try to use it. */ if (rule->deps == 0 && rule->cmds == 0) continue; /* Record this rule in TRYRULES and the index of the matching target in MATCHES. If several targets of the same rule match, that rule will be in TRYRULES more than once. */ tryrules[nrules] = rule; matches[nrules] = i; checked_lastslash[nrules] = check_lastslash; ++nrules; } } /* If we have found a matching rule that won't match all filenames, retroactively reject any non-"terminal" rules that do always match. */ if (specific_rule_matched) for (i = 0; i < nrules; ++i) if (!tryrules[i]->terminal) { register unsigned int j; for (j = 0; tryrules[i]->targets[j] != 0; ++j) if (tryrules[i]->targets[j][1] == '\0') break; if (tryrules[i]->targets[j] != 0) tryrules[i] = 0; } /* Try each rule once without intermediate files, then once with them. */ for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok) { /* Try each pattern rule till we find one that applies. If it does, copy the names of its dependencies (as substituted) and store them in FOUND_FILES. DEPS_FOUND is the number of them. */ for (i = 0; i < nrules; i++) { int check_lastslash; rule = tryrules[i]; /* RULE is nil when we discover that a rule, already placed in TRYRULES, should not be applied. */ if (rule == 0) continue; /* Reject any terminal rules if we're looking to make intermediate files. */ if (intermed_ok && rule->terminal) continue; /* Mark this rule as in use so a recursive pattern_search won't try to use it. */ rule->in_use = 1; /* From the lengths of the filename and the matching pattern parts, find the stem: the part of the filename that matches the %. */ stem = filename + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1; stemlen = namelen - rule->lens[matches[i]] + 1; check_lastslash = checked_lastslash[i]; if (check_lastslash) { stem += lastslash - filename + 1; stemlen -= (lastslash - filename) + 1; } DEBUGP2 (_("Trying pattern rule with stem `%.*s'.\n"), (int) stemlen, stem); /* Try each dependency; see if it "exists". */ deps_found = 0; for (dep = rule->deps; dep != 0; dep = dep->next) { struct file *fp; /* If the dependency name has a %, substitute the stem. */ p = index (dep_name (dep), '%'); if (p != 0) { register unsigned int i; if (check_lastslash) { /* Copy directory name from the original FILENAME. */ i = lastslash - filename + 1; bcopy (filename, depname, i); } else i = 0; bcopy (dep_name (dep), depname + i, p - dep_name (dep)); i += p - dep_name (dep); bcopy (stem, depname + i, stemlen); i += stemlen; strcpy (depname + i, p + 1); p = depname; } else p = dep_name (dep); /* P is now the actual dependency name as substituted. */ if (file_impossible_p (p)) { /* If this dependency has already been ruled "impossible", then the rule fails and don't bother trying it on the second pass either since we know that will fail too. */ DEBUGP2 (_("Rejecting impossible %s prerequisite `%s'.\n"), p == depname ? _("implicit") : _("rule"), p); tryrules[i] = 0; break; } intermediate_files[deps_found] = 0; DEBUGP2 (_("Trying %s prerequisite `%s'.\n"), p == depname ? _("implicit") : _("rule"), p); /* The DEP->changed flag says that this dependency resides in a nonexistent directory. So we normally can skip looking for the file. However, if CHECK_LASTSLASH is set, then the dependency file we are actually looking for is in a different directory (the one gotten by prepending FILENAME's directory), so it might actually exist. */ /* If we find a file but the intermediate flag is set, then it was put here by a .INTERMEDIATE: rule so ignore it. */ if ((!dep->changed || check_lastslash) && (((fp = lookup_file (p)) != 0 && !fp->intermediate) || file_exists_p (p))) { found_files[deps_found++] = xstrdup (p); continue; } /* This code, given FILENAME = "lib/foo.o", dependency name "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c". */ vp = p; if (vpath_search (&vp, (FILE_TIMESTAMP *) 0)) { DEBUGP2 (_("Found prerequisite `%s' as VPATH `%s'\n"), p, vp); strcpy (vp, p); found_files[deps_found++] = vp; continue; } /* We could not find the file in any place we should look. Try to make this dependency as an intermediate file, but only on the second pass. */ if (intermed_ok) { if (intermediate_file == 0) intermediate_file = (struct file *) alloca (sizeof (struct file)); DEBUGP2 (_("Looking for a rule with %s file `%s'.\n"), _("intermediate"), p); bzero ((char *) intermediate_file, sizeof (struct file)); intermediate_file->name = p; if (pattern_search (intermediate_file, 0, depth + 1, recursions + 1)) { p = xstrdup (p); intermediate_patterns[deps_found] = intermediate_file->name; intermediate_file->name = p; intermediate_files[deps_found] = intermediate_file; intermediate_file = 0; /* Allocate an extra copy to go in FOUND_FILES, because every elt of FOUND_FILES is consumed or freed later. */ found_files[deps_found] = xstrdup (p); ++deps_found; continue; } /* If we have tried to find P as an intermediate file and failed, mark that name as impossible so we won't go through the search again later. */ file_impossible (p); } /* A dependency of this rule does not exist. Therefore, this rule fails. */ break; } /* This rule is no longer `in use' for recursive searches. */ rule->in_use = 0; if (dep != 0) { /* This pattern rule does not apply. If some of its dependencies succeeded, free the data structure describing them. */ while (deps_found-- > 0) { register struct file *f = intermediate_files[deps_found]; free (found_files[deps_found]); if (f != 0 && (f->stem < f->name || f->stem > f->name + strlen (f->name))) free (f->stem); } } else /* This pattern rule does apply. Stop looking for one. */ break; } /* If we found an applicable rule without intermediate files, don't try with them. */ if (i < nrules) break; rule = 0; } /* RULE is nil if the loop went all the way through the list and everything failed. */ if (rule == 0) return 0; foundrule = i; /* If we are recursing, store the pattern that matched FILENAME in FILE->name for use in upper levels. */ if (recursions > 0) /* Kludge-o-matic */ file->name = rule->targets[matches[foundrule]]; /* FOUND_FILES lists the dependencies for the rule we found. This includes the in!termediate files, if any. Convert them into entries on the deps-chain of FILE. */ while (deps_found-- > 0) { register char *s; if (intermediate_files[deps_found] != 0) { /* If we need to use an intermediate file, make sure it is entered as a target, with the info that was found for it in the recursive pattern_search call. We know that the intermediate file did not already exist as a target; therefore we can assume that the deps and cmds of F below are null before we change them. */ struct file *imf = intermediate_files[deps_found]; register struct file *f = enter_file (imf->name); f->deps = imf->deps; f->cmds = imf->cmds; f->stem = imf->stem; f->also_make = imf->also_make; imf = lookup_file (intermediate_patterns[deps_found]); if (imf != 0 && imf->precious) f->precious = 1; f->intermediate = 1; f->tried_implicit = 1; for (dep = f->deps; dep != 0; dep = dep->next) { dep->file = enter_file (dep->name); /* enter_file uses dep->name _if_ we created a new file. */ if (dep->name != dep->file->name) free (dep->name); dep->name = 0; dep->file->tried_implicit |= dep->changed; } num_intermediates++; } dep = (struct dep *) xmalloc (sizeof (struct dep)); s = found_files[deps_found]; if (recursions == 0) { dep->name = 0; dep->file = lookup_file (s); if (dep->file == 0) /* enter_file consumes S's storage. */ dep->file = enter_file (s); else /* A copy of S is already allocated in DEP->file->name. So we can free S. */ free (s); } else { dep->name = s; dep->file = 0; dep->changed = 0; } if (intermediate_files[deps_found] == 0 && tryrules[foundrule]->terminal) { /* If the file actually existed (was not an intermediate file), and the rule that found it was a terminal one, then we want to mark the found file so that it will not have implicit rule search done for it. If we are not entering a `struct file' for it now, we indicate this with the `changed' flag. */ if (dep->file == 0) dep->changed = 1; else dep->file->tried_implicit = 1; } dep->next = file->deps; file->deps = dep; } if (!checked_lastslash[foundrule]) /* Always allocate new storage, since STEM might be on the stack for an intermediate file. */ file->stem = savestring (stem, stemlen); else { /* We want to prepend the directory from the original FILENAME onto the stem. */ file->stem = (char *) xmalloc (((lastslash + 1) - filename) + stemlen + 1); bcopy (filename, file->stem, (lastslash + 1) - filename); bcopy (stem, file->stem + ((lastslash + 1) - filename), stemlen); file->stem[((lastslash + 1) - filename) + stemlen] = '\0'; } file->cmds = rule->cmds; /* If this rule builds other targets, too, put the others into FILE's `also_make' member. */ if (rule->targets[1] != 0) for (i = 0; rule->targets[i] != 0; ++i) if (i != matches[foundrule]) { struct dep *new = (struct dep *) xmalloc (sizeof (struct dep)); new->name = p = (char *) xmalloc (rule->lens[i] + stemlen + 1); bcopy (rule->targets[i], p, rule->suffixes[i] - rule->targets[i] - 1); p += rule->suffixes[i] - rule->targets[i] - 1; bcopy (stem, p, stemlen); p += stemlen; bcopy (rule->suffixes[i], p, rule->lens[i] - (rule->suffixes[i] - rule->targets[i]) + 1); new->file = enter_file (new->name); new->next = file->also_make; file->also_make = new; } return 1; } *[MAKE-3_78_1HB]INSTALL-SH.;1+,c. /@ 4 -`0123KPWO 567âm89G@HJ#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 *[MAKE-3_78_1HB]INSTALL.;1+,c./@ 4-`0123KPWO56g7˵m89G@HJBasic Installation ================== The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. If you're building GNU make on a system which does not already have a `make', you can use the build.sh shell script to compile. Run `sh ./build.sh'. This should compile the program in the current directory. Then you will have a Make program that you can use for `make install', or whatever else. 3.p#~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]INSTALL.;1 Optionally, type `./make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. *[MAKE-3_78_1HB]JOB.C;6+,c./@ 4j-`0123KPWO56osu7p˴m89G@HJ`/* Job execution and handling for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "job.h" #include "filedef.h" #include "commands.h" #include "variable.h" #include /* Default shell to use. */ #ifdef WINDOWS32 char *default_shell = "sh.exe"; int no_default_sh_exe = 1; int batch_mode_shell = 1; #else /* WINDOWS32 */ # ifdef _AMIGA char default_shell[] = ""; extern int MyExecute (char **); # else /* _AMIGA */ # ifdef __MSDOS__ /* The default shell is a pointer so we can change it if Makefile says so. It is without an explicit path so we get a chance to search the $PATH for it (since MSDOS doesn't have standard directories we could trust). */ char *default_shell = "command.com"; # else /* __MSDOS__ */ # ifdef VMS # include char default_shell[] = ""; # else char default_shell[] = "/bin/sh"; # endif /* VMS */ # endif /* __MSDOS__ */ int batch_mode_shell = 0; # endif /* _AMIGA */ #endif /* WINDOWS32 */ #ifdef __MSDOS__ # include static int execute_by_shell; static int dos_pid = 123; int dos_status; int dos_command_running; #endif /* __MSDOS__ */ #ifdef _AMIGA # include static int amiga_pid = 123; static int amiga_status; static char amiga_bname[32]; static int amiga_batch_file; #endif /* Amiga. */ #ifdef VMS # include # ifndef __GNUC__ # include # endif # include # include #endif #ifdef WINDOWS32 # include # include # include # include "sub_proc.h" # include "w32err.h" # include "pathstuff.h" #endif /* WINDOWS32 */ #ifdef HAVE_FCNTL_H # include #else # include #endif #if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT) # include #endif #ifdef HAVE_WAITPID # define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG) #else /* Don't have waitpid. */ # ifdef HAVE_WAIT3 # ifndef wait3 extern int wait3 (); # endif # define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0) # endif /* Have wait3. */ #endif /* Have waitpid. */ #if !defined (wait) && !defined (POSIX) extern int wait (); #endif #ifndef HAVE_UNION_WAIT # define WAIT_T int # ifndef WTERMSIG # define WTERMSIG(x) ((x) & 0x7f) # endif # ifndef WCOREDUMP # define WCOREDUMP(x) ((x) & 0x80) # endif # ifndef WEXITSTATUS # define WEXITSTATUS(x) (((x) >> 8) & 0xff) # endif # ifndef WIFSIGNALED # define WIFSIGNALED(x) (WTERMSIG (x) != 0) # endif # ifndef WIFEXITED # define WIFEXITED(x) (WTERMSIG (x) == 0) # endif #else /* Have `union wait'. */ # define WAIT_T union wait # ifndef WTERMSIG # define WTERMSIG(x) ((x).w_termsig) # endif # ifndef WCOREDUMP # define WCOREDUMP(x) ((x).w_coredump) # endif # ifndef WEXITSTATUS # define WEXITSTATUS(x) ((x).w_retcode) # endif # ifndef WIFSIGNALED # define WIFSIGNALED(x) (WTERMSIG(x) != 0) # endif # ifndef WIFEXITED # define WIFEXITED(x) (WTERMSIG(x) == 0) # endif #endif /* Don't have `union wait'. */ /* How to set close-on-exec for a file descriptor. */ #if !defined F_SETFD # define CLOSE_ON_EXEC(_d) #else # ifndef FD_CLOEXEC # define FD_CLOEXEC 1 # endif # define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC) #endif #ifdef VMS static int vms_jobsefnmask = 0; #endif /* !VMS */ #ifndef HAVE_UNISTD_H extern int dup2 (); extern int execve (); extern void _exit (); # ifndef VMS extern int geteuid (); extern int getegid (); extern int setgid (); extern int getgid (); # endif #endif extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file)); extern int getloadavg PARAMS ((double loadavg[], int nelem)); extern int start_remote_job PARAMS ((char **argv, char **envp, int stdin_fd, int *is_remote, int *id_ptr, int *used_stdin)); extern int start_remote_job_p PARAMS ((int)); extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr, int *coredump_ptr, int block)); RETSIGTYPE child_handler PARAMS ((int)); static void free_child PARAMS ((struct child *)); static void start_job_command PARAMS ((struct child *child)); static int load_too_high PARAMS ((void)); static int job_next_command PARAMS ((struct child *)); static int start_waiting_job PARAMS ((struct child *)); #ifdef VMS static void vmsWaitForChildren PARAMS ((int *)); #endif /* Chain of all live (or recently deceased) children. */ struct child *children = 0; /* Number of children currently running. */ unsigned int job_slots_used = 0; /* Nonzero if the `good' standard input is in use. */ static int good_stdin_used = 0; /* Chain of children waiting to run until the load average goes down. */ static struct child *waiting_jobs = 0; /* Non-zero if we use a *real* shell (always so on Unix). */ int unixy_shell = 1; #ifdef WINDOWS32 /* * The macro which references this function is defined in make.h. */ int w32_kill(int pid, int sig) { return ((process_kill(pid, sig) == TRUE) ? 0 : -1); } #endif /* WINDOWS32 */ /* Write an error message describing the exit status given in EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME. Append "(ignored)" if IGNORED is nonzero. */ static void child_error (target_name, exit_code, exit_sig, coredump, ignored) char *target_name; int exit_code, exit_sig, coredump; int ignored; { if (ignored && silent_flag) return; #ifdef VMS if (!(exit_code & 1)) error (NILF, _("*** [%s] Error 0x%x%s"), target_name, exit_code, ((ignored)? _(" (ignored)") : "")); #else if (exit_sig == 0) error (NILF, ignored ? _("[%s] Error %d (ignored)") : _("*** [%s] Error %d"), target_name, exit_code); else error (NILF, "*** [%s] %s%s", target_name, strsignal (exit_sig), coredump ? _(" (core dumped)") : ""); #endif /* VMS */ } #ifdef VMS /* Wait for nchildren children to terminate */ static void vmsWaitForChildren(int *status) { while (1) { if (!vms_jobsefnmask) { *status = 0; return; } *status = sys$wflor (32, vms_jobsefnmask); } return; } /* Set up IO redirection. */ char * vms_redirect (desc, fname, ibuf) struct dsc$descriptor_s *desc; char *fname; char *ibuf; { char *fptr; extern char *vmsify (); ibuf++; while (isspace (*ibuf)) ibuf++; fptr = ibuf; while (*ibuf && !isspace (*ibuf)) ibuf++; *ibuf = 0; if (strcmp (fptr, "/dev/null") != 0) { strcpy (fname, vmsify (fptr, 0)); if (strchr (fname, '.') == 0) strcat (fname, "."); } desc->dsc$w_length = strlen(fname); desc->dsc$a_pointer = fname; desc->dsc$b_dtype = DSC$K_DTYPE_T; desc->dsc$b_class = DSC$K_CLASS_S; if (*fname == 0) printf ("Warning: Empty redirection\n"); return ibuf; } /* found apostrophe at (p-1) inc p until after closing apostrophe. */ static char * handle_apos (char *p) { int alast; int inside; #define SEPCHARS ",/()= " inside = 0; while (*p != 0) { if (*p == '"') { if (inside) { while ((alast > 0) && (*p == '"')) { p++; alast--; } if (alast == 0) inside = 0; else { fprintf (stderr, "Syntax error, still inside '\"'\n"); exit (3); } } else { p++; if (strchr (SEPCHARS, *p)) break; inside = 1; alast = 1; while (*p == '"') { alast++; p++; } } } else p++; } return p; } #endif /* Handle a dead child. This handler may or may not ever be installed. If we're using the jobserver feature, we need it. First, installing it ensures the read will interrupt on SIGCHLD. Second, we close the dup'd read FD to ensure we don't enter another blocking read without reaping all the dead children. In this case we don't need the dead_children count. If we don't have either waitpid or wait3, then make is unreliable, but we use the dead_children count to reap children as best we can. */ static unsigned int dead_children = 0; RETSIGTYPE child_handler (sig) int sig; { ++dead_children; if (job_rfd >= 0) { close (job_rfd); job_rfd = -1; } if (debug_flag) printf (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children); } extern int shell_function_pid, shell_function_completed; /* Reap all dead children, storing the returned status and the new command state (`cs_finished') in the `file' member of the `struct child' for the dead child, and removing the child from the chain. In addition, if BLOCK nonzero, we block in this function until we've reaped at least one complete child, waiting for it to die if necessary. If ERR is nonzero, print an error message first. */ void reap_children (block, err) int block, err; { WAIT_T status; /* Initially, assume we have some. */ int reap_more = 1; #ifdef WAIT_NOHANG # define REAP_MORE reap_more #else # define REAP_MORE dead_children #endif /* As long as: We have at least one child outstanding OR a shell function in progress, AND We're blocking for a complete child OR there are more children to reap we'll keep reaping children. */ while ((children != 0 || shell_function_pid != 0) && (block || REAP_MORE)) { int remote = 0; register int pid; int exit_code, exit_sig, coredump; register struct child *lastc, *c; int child_failed; int any_remote, any_local; if (err && block) { /* We might block for a while, so let the user know why. */ fflush (stdout); error (NILF, _("*** Waiting for unfinished jobs....")); } /* We have one less dead child to reap. As noted in child_handler() above, this count is completely unimportant for all modern, POSIX-y systems that support wait3() or waitpid(). The rest of this comment below applies only to early, broken pre-POSIX systems. We keep the count only because... it's there... The test and decrement are not atomic; if it is compiled into: register = dead_children - 1; dead_children = register; a SIGCHLD could come between the two instructions. child_handler increments dead_children. The second instruction here would lose that increment. But the only effect of dead_children being wrong is that we might wait longer than necessary to reap a child, and lose some parallelism; and we might print the "Waiting for unfinished jobs" message above when not necessary. */ if (dead_children > 0) --dead_children; any_remote = 0; any_local = shell_function_pid != 0; for (c = children; c != 0; c = c->next) { any_remote |= c->remote; any_local |= ! c->remote; if (debug_flag) printf (_("Live child 0x%08lx (%s) PID %ld %s\n"), (unsigned long int) c, c->file->name, (long) c->pid, c->remote ? _(" (remote)") : ""); #ifdef VMS break; #endif } /* First, check for remote children. */ if (any_remote) pid = remote_status (&exit_code, &exit_sig, &coredump, 0); else pid = 0; if (pid > 0) /* We got a remote child. */ remote = 1; else if (pid < 0) { /* A remote status command failed miserably. Punt. */ remote_status_lose: if (EINTR_SET) continue; pfatal_with_name ("remote_status"); } else { /* No remote children. Check for local children. */ #if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) if (any_local) { local_wait: #ifdef VMS vmsWaitForChildren (&status); pid = c->pid; #else #ifdef WAIT_NOHANG if (!block) pid = WAIT_NOHANG (&status); else #endif pid = wait (&status); #endif /* !VMS */ } else pid = 0; if (pid < 0) { /* EINTR? Try again. */ if (EINTR_SET) goto local_wait; /* The wait*() failed miserably. Punt. */ pfatal_with_name ("wait"); } else if (pid > 0) { /* We got a child exit; chop the status word up. */ exit_code = WEXITSTATUS (status); exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; coredump = WCOREDUMP (status); } else { /* No local children are dead. */ reap_more = 0; if (!block || !any_remote) break; /* Now try a blocking wait for a remote child. */ pid = remote_status (&exit_code, &exit_sig, &coredump, 1); if (pid < 0) goto remote_status_lose; else if (pid == 0) /* No remote children either. Finally give up. */ break; /* We got a remote child. */ remote = 1; } #endif /* !__MSDOS__, !Amiga, !WINDOWS32. */ #ifdef __MSDOS__ /* Life is very different on MSDOS. */ pid = dos_pid - 1; status = dos_status; exit_code = WEXITSTATUS (status); if (exit_code == 0xff) exit_code = -1; exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; coredump = 0; #endif /* __MSDOS__ */ #ifdef _AMIGA /* Same on Amiga */ pid = amiga_pid - 1; status = amiga_status; exit_code = amiga_status; exit_sig = 0; coredump = 0; #endif /* _AMIGA */ #ifdef WINDOWS32 { HANDLE hPID; int err; /* wait for anything to finish */ if (hPID = process_wait_for_any()) { /* was an error found on this process? */ err = process_last_err(hPID); /* get exit data */ exit_code = process_exit_code(hPID); if (err) fprintf(stderr, "make (e=%d): %s", exit_code, map_windows32_error_to_string(exit_code)); /* signal */ exit_sig = process_signal(hPID); /* cleanup process */ process_cleanup(hPID); coredump = 0; } pid = (int) hPID; } #endif /* WINDOWS32 */ } /* Check if this is the child of the `shell' function. */ if (!remote && pid == shell_function_pid) { /* It is. Leave an indicator for the `shell' function. */ if (exit_sig == 0 && exit_code == 127) shell_function_completed = -1; else shell_function_completed = 1; break; } child_failed = exit_sig != 0 || exit_code != 0; /* Search for a child matching the deceased one. */ lastc = 0; for (c = children; c != 0; lastc = c, c = c->next) if (c->remote == remote && c->pid == pid) break; if (c == 0) /* An unknown child died. Ignore it; it was inherited from our invoker. */ continue; if (debug_flag) printf (_("Reaping %s child 0x%08lx PID %ld %s\n"), child_failed ? _("losing") : _("winning"), (unsigned long int) c, (long) c->pid, c->remote ? _(" (remote)") : ""); if (c->sh_batch_file) { if (debug_flag) printf (_("Cleaning up temp batch file %s\n"), c->sh_batch_file); /* just try and remove, don't care if this fails */ remove (c->sh_batch_file); /* all done with memory */ free (c->sh_batch_file); c->sh_batch_file = NULL; } /* If this child had the good stdin, say it is now free. */ if (c->good_stdin) good_stdin_used = 0; if (child_failed && !c->noerror && !ignore_errors_flag) { /* The commands failed. Write an error message, delete non-precious targets, and abort. */ static int delete_on_error = -1; child_error (c->file->name, exit_code, exit_sig, coredump, 0); c->file->update_status = 2; if (delete_on_error == -1) { struct file *f = lookup_file (".DELETE_ON_ERROR"); delete_on_error = f != 0 && f->is_target; } if (exit_sig != 0 || delete_on_error) delete_child_targets (c); } else { if (child_failed) { /* The commands failed, but we don't care. */ child_error (c->file->name, exit_code, exit_sig, coredump, 1); child_failed = 0; } /* If there are more commands to run, try to start them. */ if (job_next_command (c)) { if (handling_fatal_signal) { /* Never start new commands while we are dying. Since there are more commands that wanted to be run, the target was not completely remade. So we treat this as if a command had failed. */ c->file->update_status = 2; } else { /* Check again whether to start remotely. Whether or not we want to changes over time. Also, start_remote_job may need state set up by start_remote_job_p. */ c->remote = start_remote_job_p (0); start_job_command (c); /* Fatal signals are left blocked in case we were about to put that child on the chain. But it is already there, so it is safe for a fatal signal to arrive now; it will clean up this child's targets. */ unblock_sigs (); if (c->file->command_state == cs_running) /* We successfully started the new command. Loop to reap more children. */ continue; } if (c->file->update_status != 0) /* We failed to start the commands. */ delete_child_targets (c); } else /* There are no more commands. We got through them all without an unignored error. Now the target has been successfully updated. */ c->file->update_status = 0; } /* When we get here, all the commands for C->file are finished (or aborted) and C->file->update_status contains 0 or 2. But C->file->command_state is still cs_running if all the commands ran; notice_finish_file looks for cs_running to tell it that it's interesting to check the file's modtime again now. */ if (! handling_fatal_signal) /* Notice if the target of the commands has been changed. This also propagates its values for command_state and update_status to its also_make files. */ notice_finished_file (c->file); if (debug_flag) printf (_("Removing child 0x%08lx PID %ld %s from chain.\n"), (unsigned long int) c, (long) c->pid, c->remote ? _(" (remote)") : ""); /* Block fatal signals while frobnicating the list, so that children and job_slots_used are always consistent. Otherwise a fatal signal arriving after the child is off the chain and before job_slots_used is decremented would believe a child was live and call reap_children again. */ block_sigs (); /* There is now another slot open. */ if (job_slots_used > 0) --job_slots_used; /* Remove the child from the chain and free it. */ if (lastc == 0) children = c->next; else lastc->next = c->next; free_child (c); unblock_sigs (); /* If the job failed, and the -k flag was not given, die, unless we are already in the process of dying. */ if (!err && child_failed && !keep_going_flag && /* fatal_error_signal will die with the right signal. */ !handling_fatal_signal) die (2); /* Only block for one child. */ block = 0; } return; } /* Free the storage allocated for CHILD. */ static void free_child (child) register struct child *child; { /* If this child is the only one it was our "free" job, so don't put a token back for it. This child has already been removed from the list, so if there any left this wasn't the last one. */ if (job_fds[1] >= 0 && children) { char token = '+'; /* Write a job token back to the pipe. */ while (write (job_fds[1], &token, 1) != 1) if (!EINTR_SET) pfatal_with_name (_("write jobserver")); if (debug_flag) printf (_("Released token for child 0x%08lx (%s).\n"), (unsigned long int) child, child->file->name); } if (handling_fatal_signal) /* Don't bother free'ing if about to die. */ return; if (child->command_lines != 0) { register unsigned int i; for (i = 0; i < child->file->cmds->ncommand_lines; ++i) free (child->command_lines[i]); free ((char *) child->command_lines); } if (child->environment != 0) { register char **ep = child->environment; while (*ep != 0) free (*ep++); free ((char *) child->environment); } free ((char *) child); } #ifdef POSIX extern sigset_t fatal_signal_set; #endif void block_sigs () { #ifdef POSIX (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0); #else # ifdef HAVE_SIGSETMASK (void) sigblock (fatal_signal_mask); # endif #endif } #ifdef POSIX void unblock_sigs () { sigset_t empty; sigemptyset (&empty); sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0); } #endif /* Start a job to run the commands specified in CHILD. CHILD is updated to reflect the commands and ID of the child process. NOTE: On return fatal signals are blocked! The caller is responsible for calling `unblock_sigs', once the new child is safely on the chain so it can be cleaned up in the event of a fatal signal. */ static void start_job_command (child) register struct child *child; { #ifndef _AMIGA static int bad_stdin = -1; #endif register char *p; int flags; #ifdef VMS char *argv; #else char **argv; #endif /* If we have a completely empty commandset, stop now. */ if (!child->command_ptr) goto next_command; /* Combine the flags parsed for the line itself with the flags specified globally for this target. */ flags = (child->file->command_flags | child->file->cmds->lines_flags[child->command_line - 1]); p = child->command_ptr; child->noerror = flags & COMMANDS_NOERROR; while (*p != '\0') { if (*p == '@') flags |= COMMANDS_SILENT; else if (*p == '+') flags |= COMMANDS_RECURSE; else if (*p == '-') child->noerror = 1; else if (!isblank (*p)) break; ++p; } /* If -q was given, just say that updating `failed'. The exit status of 1 tells the user that -q is saying `something to do'; the exit status for a random error is 2. */ if (question_flag && !(flags & COMMANDS_RECURSE)) { child->file->update_status = 1; notice_finished_file (child->file); return; } /* There may be some preceding whitespace left if there was nothing but a backslash on the first line. */ p = next_token (p); /* Figure out an argument list from this command line. */ { char *end = 0; #ifdef VMS argv = p; #else argv = construct_command_argv (p, &end, child->file, &child->sh_batch_file); #endif if (end == NULL) child->command_ptr = NULL; else { *end++ = '\0'; child->command_ptr = end; } } if (touch_flag && !(flags & COMMANDS_RECURSE)) { /* Go on to the next command. It might be the recursive one. We construct ARGV only to find the end of the command line. */ #ifndef VMS free (argv[0]); free ((char *) argv); #endif argv = 0; } if (argv == 0) { 1 next_command: #ifdef __MSDOS__ execute_by_shell = 0; /* in case construct_command_argv sets it */ #endif /* This line has no commands. Go to the next. */ if (job_next_command (child)) start_job_command (child); else { /* No more commands. Make sure we're "running"; we might not be if (e.g.) all commands were skipped due to -n. */ set_command_state (child->file, cs_running); child->file->update_status = 0; notice_finished_file (child->file); $~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]JOB.C;6j|2 } return; } /* Print out the command. If silent, we call `message' with null so it can log the working directory before the command's own error messages appear. */ message (0, (just_print_flag || (!(flags & COMMANDS_SILENT) && !silent_flag)) ? "%s" : (char *) 0, p); /* Optimize an empty command. People use this for timestamp rules, so avoid forking a useless shell. */ #if !defined(VMS) && !defined(_AMIGA) if ( #ifdef __MSDOS__ unixy_shell /* the test is complicated and we already did it */ #else (argv[0] && !strcmp (argv[0], "/bin/sh")) #endif && (argv[1] && argv[1][0] == '-' && argv[1][1] == 'c' && argv[1][2] == '\0') && (argv[2] && argv[2][0] == ':' && argv[2][1] == '\0') && argv[3] == NULL) { free (argv[0]); free ((char *) argv); goto next_command; } #endif /* !VMS && !_AMIGA */ /* Tell update_goal_chain that a command has been started on behalf of this target. It is important that this happens here and not in reap_children (where we used to do it), because reap_children might be reaping children from a different target. We want this increment to guaranteedly indicate that a command was started for the dependency chain (i.e., update_file recursion chain) we are processing. */ ++commands_started; /* If -n was given, recurse to get the next line in the sequence. */ if (just_print_flag && !(flags & COMMANDS_RECURSE)) { #ifndef VMS free (argv[0]); free ((char *) argv); #endif goto next_command; } /* Flush the output streams so they won't have things written twice. */ fflush (stdout); fflush (stderr); #ifndef VMS #if !defined(WINDOWS32) && !defined(_AMIGA) && !defined(__MSDOS__) /* Set up a bad standard input that reads from a broken pipe. */ if (bad_stdin == -1) { /* Make a file descriptor that is the read end of a broken pipe. This will be used for some children's standard inputs. */ int pd[2]; if (pipe (pd) == 0) { /* Close the write side. */ (void) close (pd[1]); /* Save the read side. */ bad_stdin = pd[0]; /* Set the descriptor to close on exec, so it does not litter any child's descriptor table. When it is dup2'd onto descriptor 0, that descriptor will not close on exec. */ CLOSE_ON_EXEC (bad_stdin); } } #endif /* !WINDOWS32 && !_AMIGA && !__MSDOS__ */ /* Decide whether to give this child the `good' standard input (one that points to the terminal or whatever), or the `bad' one that points to the read side of a broken pipe. */ child->good_stdin = !good_stdin_used; if (child->good_stdin) good_stdin_used = 1; #endif /* !VMS */ child->deleted = 0; #ifndef _AMIGA /* Set up the environment for the child. */ if (child->environment == 0) child->environment = target_environment (child->file); #endif #if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) #ifndef VMS /* start_waiting_job has set CHILD->remote if we can start a remote job. */ if (child->remote) { int is_remote, id, used_stdin; if (start_remote_job (argv, child->environment, child->good_stdin ? 0 : bad_stdin, &is_remote, &id, &used_stdin)) /* Don't give up; remote execution may fail for various reasons. If so, simply run the job locally. */ goto run_local; else { if (child->good_stdin && !used_stdin) { child->good_stdin = 0; good_stdin_used = 0; } child->remote = is_remote; child->pid = id; } } else #endif /* !VMS */ { /* Fork the child process. */ char **parent_environ; run_local: block_sigs (); child->remote = 0; #ifdef VMS if (!child_execute_job (argv, child)) { /* Fork failed! */ perror_with_name ("vfork", ""); goto error; } #else parent_environ = environ; child->pid = vfork (); environ = parent_environ; /* Restore value child may have clobbered. */ if (child->pid == 0) { /* We are the child side. */ unblock_sigs (); /* If we aren't running a recursive command and we have a jobserver pipe, close it before exec'ing. */ if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0) { close (job_fds[0]); close (job_fds[1]); } if (job_rfd >= 0) close (job_rfd); child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, argv, child->environment); } else if (child->pid < 0) { /* Fork failed! */ unblock_sigs (); perror_with_name ("vfork", ""); goto error; } #endif /* !VMS */ } #else /* __MSDOS__ or Amiga or WINDOWS32 */ #ifdef __MSDOS__ { int proc_return; block_sigs (); dos_status = 0; /* We call `system' to do the job of the SHELL, since stock DOS shell is too dumb. Our `system' knows how to handle long command lines even if pipes/redirection is needed; it will only call COMMAND.COM when its internal commands are used. */ if (execute_by_shell) { char *cmdline = argv[0]; /* We don't have a way to pass environment to `system', so we need to save and restore ours, sigh... */ char **parent_environ = environ; environ = child->environment; /* If we have a *real* shell, tell `system' to call it to do everything for us. */ if (unixy_shell) { /* A *real* shell on MSDOS may not support long command lines the DJGPP way, so we must use `system'. */ cmdline = argv[2]; /* get past "shell -c" */ } dos_command_running = 1; proc_return = system (cmdline); environ = parent_environ; execute_by_shell = 0; /* for the next time */ } else { dos_command_running = 1; proc_return = spawnvpe (P_WAIT, argv[0], argv, child->environment); } /* Need to unblock signals before turning off dos_command_running, so that child's signals will be treated as such (see fatal_error_signal). */ unblock_sigs (); dos_command_running = 0; /* If the child got a signal, dos_status has its high 8 bits set, so be careful not to alter them. */ if (proc_return == -1) dos_status |= 0xff; else dos_status |= (proc_return & 0xff); ++dead_children; child->pid = dos_pid++; } #endif /* __MSDOS__ */ #ifdef _AMIGA amiga_status = MyExecute (argv); ++dead_children; child->pid = amiga_pid++; if (amiga_batch_file) { amiga_batch_file = 0; DeleteFile (amiga_bname); /* Ignore errors. */ } #endif /* Amiga */ #ifdef WINDOWS32 { HANDLE hPID; char* arg0; /* make UNC paths safe for CreateProcess -- backslash format */ arg0 = argv[0]; if (arg0 && arg0[0] == '/' && arg0[1] == '/') for ( ; arg0 && *arg0; arg0++) if (*arg0 == '/') *arg0 = '\\'; /* make sure CreateProcess() has Path it needs */ sync_Path_environment(); hPID = process_easy(argv, child->environment); if (hPID != INVALID_HANDLE_VALUE) child->pid = (int) hPID; else { int i; unblock_sigs(); fprintf(stderr, _("process_easy() failed failed to launch process (e=%d)\n"), process_last_err(hPID)); for (i = 0; argv[i]; i++) fprintf(stderr, "%s ", argv[i]); fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); } } #endif /* WINDOWS32 */ #endif /* __MSDOS__ or Amiga or WINDOWS32 */ /* We are the parent side. Set the state to say the commands are running and return. */ set_command_state (child->file, cs_running); /* Free the storage used by the child's argument list. */ #ifndef VMS free (argv[0]); free ((char *) argv); #endif return; error: child->file->update_status = 2; notice_finished_file (child->file); return; } /* Try to start a child running. Returns nonzero if the child was started (and maybe finished), or zero if the load was too high and the child was put on the `waiting_jobs' chain. */ static int start_waiting_job (c) struct child *c; { struct file *f = c->file; /* If we can start a job remotely, we always want to, and don't care about the local load average. We record that the job should be started remotely in C->remote for start_job_command to test. */ c->remote = start_remote_job_p (1); /* If we are running at least one job already and the load average is too high, make this one wait. */ if (!c->remote && job_slots_used > 0 && load_too_high ()) { /* Put this child on the chain of children waiting for the load average to go down. */ set_command_state (f, cs_running); c->next = waiting_jobs; waiting_jobs = c; return 0; } /* Start the first command; reap_children will run later command lines. */ start_job_command (c); switch (f->command_state) { case cs_running: c->next = children; if (debug_flag) printf (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"), (unsigned long int) c, c->file->name, (long) c->pid, c->remote ? _(" (remote)") : ""); children = c; /* One more job slot is in use. */ ++job_slots_used; unblock_sigs (); break; case cs_not_started: /* All the command lines turned out to be empty. */ f->update_status = 0; /* FALLTHROUGH */ case cs_finished: notice_finished_file (f); free_child (c); break; default: assert (f->command_state == cs_finished); break; } return 1; } /* Create a `struct child' for FILE and start its commands running. */ void new_job (file) register struct file *file; { register struct commands *cmds = file->cmds; register struct child *c; char **lines; register unsigned int i; /* Let any previously decided-upon jobs that are waiting for the load to go down start before this new one. */ start_waiting_jobs (); /* Reap any children that might have finished recently. */ reap_children (0, 0); /* Chop the commands up into lines if they aren't already. */ chop_commands (cmds); /* Expand the command lines and store the results in LINES. */ lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *)); for (i = 0; i < cmds->ncommand_lines; ++i) { /* Collapse backslash-newline combinations that are inside variable or function references. These are left alone by the parser so that they will appear in the echoing of commands (where they look nice); and collapsed by construct_command_argv when it tokenizes. But letting them survive inside function invocations loses because we don't want the functions to see them as part of the text. */ char *in, *out, *ref; /* IN points to where in the line we are scanning. OUT points to where in the line we are writing. When we collapse a backslash-newline combination, IN gets ahead of OUT. */ in = out = cmds->command_lines[i]; while ((ref = index (in, '$')) != 0) { ++ref; /* Move past the $. */ if (out != in) /* Copy the text between the end of the last chunk we processed (where IN points) and the new chunk we are about to process (where REF points). */ bcopy (in, out, ref - in); /* Move both pointers past the boring stuff. */ out += ref - in; in = ref; if (*ref == '(' || *ref == '{') { char openparen = *ref; char closeparen = openparen == '(' ? ')' : '}'; int count; char *p; *out++ = *in++; /* Copy OPENPAREN. */ /* IN now points past the opening paren or brace. Count parens or braces until it is matched. */ count = 0; while (*in != '\0') { if (*in == closeparen && --count < 0) break; else if (*in == '\\' && in[1] == '\n') { /* We have found a backslash-newline inside a variable or function reference. Eat it and any following whitespace. */ int quoted = 0; for (p = in - 1; p > ref && *p == '\\'; --p) quoted = !quoted; if (quoted) /* There were two or more backslashes, so this is not really a continuation line. We don't collapse the quoting backslashes here as is done in collapse_continuations, because the line will be collapsed again after expansion. */ *out++ = *in++; else { /* Skip the backslash, newline and any following whitespace. */ in = next_token (in + 2); /* Discard any preceding whitespace that has already been written to the output. */ while (out > ref && isblank (out[-1])) --out; /* Replace it all with a single space. */ *out++ = ' '; } } else { if (*in == openparen) ++count; *out++ = *in++; } } } } /* There are no more references in this line to worry about. Copy the remaining uninteresting text to the output. */ if (out != in) strcpy (out, in); /* Finally, expand the line. */ lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i], file); } /* Start the command sequence, record it in a new `struct child', and add that to the chain. */ c = (struct child *) xmalloc (sizeof (struct child)); c->file = file; c->command_lines = lines; c->command_line = 0; c->command_ptr = 0; c->environment = 0; c->sh_batch_file = NULL; /* Fetch the first command line to be run. */ job_next_command (c); /* Wait for a job slot to be freed up. If we allow an infinite number don't bother; also job_slots will == 0 if we're using the jobserver. */ if (job_slots != 0) while (job_slots_used == job_slots) reap_children (1, 0); #ifdef MAKE_JOBSERVER /* If we are controlling multiple jobs make sure we have a token before starting the child. */ /* This can be inefficient. There's a decent chance that this job won't actually have to run any subprocesses: the command script may be empty or otherwise optimized away. It would be nice if we could defer obtaining a token until just before we need it, in start_job_command. To do that we'd need to keep track of whether we'd already obtained a token (since start_job_command is called for each line of the job, not just once). Also more thought needs to go into the entire algorithm; this is where the old parallel job code waits, so... */ else if (job_fds[0] >= 0) while (1) { char token; /* If we don't already have a job started, use our "free" token. */ if (!children) break; /* Read a token. As long as there's no token available we'll block. If we get a SIGCHLD we'll return with EINTR. If one happened before we got here we'll return immediately with EBADF because the signal handler closes the dup'd file descriptor. */ if (read (job_rfd, &token, 1) == 1) { if (debug_flag) printf (_("Obtained token for child 0x%08lx (%s).\n"), (unsigned long int) c, c->file->name); break; } if (errno != EINTR && errno != EBADF) pfatal_with_name (_("read jobs pipe")); /* Re-dup the read side of the pipe, so the signal handler can notify us if we miss a child. */ if (job_rfd < 0) job_rfd = dup (job_fds[0]); /* Something's done. We don't want to block for a whole child, just reap whatever's there. */ reap_children (0, 0); } #endif /* The job is now primed. Start it running. (This will notice if there are in fact no commands.) */ (void) start_waiting_job (c); if (job_slots == 1) /* Since there is only one job slot, make things run linearly. Wait for the child to die, setting the state to `cs_finished'. */ while (file->command_state == cs_running) reap_children (1, 0); return; } /* Move CHILD's pointers to the next command for it to execute. Returns nonzero if there is another command. */ static int job_next_command (child) struct child *child; { while (child->command_ptr == 0 || *child->command_ptr == '\0') { /* There are no more lines in the expansion of this line. */ if (child->command_line == child->file->cmds->ncommand_lines) { /* There are no more lines to be expanded. */ child->command_ptr = 0; return 0; } else /* Get the next line to run. */ child->command_ptr = child->command_lines[child->command_line++]; } return 1; } static int load_too_high () { #if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA) return 1; #else double load; if (max_load_average < 0) return 0; make_access (); if (getloadavg (&load, 1) != 1) { static int lossage = -1; /* Complain only once for the same error. */ if (lossage == -1 || errno != lossage) { if (errno == 0) /* An errno value of zero means getloadavg is just unsupported. */ error (NILF, _("cannot enforce load limits on this operating system")); else perror_with_name (_("cannot enforce load limit: "), "getloadavg"); } lossage = errno; load = 0; } user_access (); return load >= max_load_average; #endif } /* Start jobs that are waiting for the load to be lower. */ void start_waiting_jobs () { struct child *job; if (waiting_jobs == 0) return; do { /* Check for recently deceased descendants. */ reap_children (0, 0); /* Take a job off the waiting list. */ job = waiting_jobs; waiting_jobs = job->next; /* Try to start that job. We break out of the loop as soon as start_waiting_job puts one back on the waiting list. */ } while (start_waiting_job (job) && waiting_jobs != 0); return; } #ifndef WINDOWS32 #ifdef VMS #include #include /* This is called as an AST when a child process dies (it won't get interrupted by anything except a higher level AST). */ int vmsHandleChildTerm(struct child *child) { int status; register struct child *lastc, *c; int child_failed; vms_jobsefnmask &= ~(1 << (child->efn - 32)); lib$free_ef(&child->efn); (void) sigblock (fatal_signal_mask); child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0)); /* Search for a child matching the deceased one. */ lastc = 0; #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ for (c = children; c != 0 && c != child; lastc = c, c = c->next); #else c = child; #endif if (child_failed && !c->noerror && !ignore_errors_flag) { /* The commands failed. Write an error message, delete non-precious targets, and abort. */ child_error (c->file->name, c->cstatus, 0, 0, 0); c->file->update_status = 1; delete_child_targets (c); } else { if (child_failed) { /* The commands failed, but we don't care. */ child_error (c->file->name, c->cstatus, 0, 0, 1); child_failed = 0; } #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ /* If there are more commands to run, try to start them. */ start_job (c); switch (c->file->command_state) { case cs_running: /* Successfully started. */ break; case cs_finished: if (c->file->update_status != 0) { /* We failed to start the commands. */ delete_child_targets (c); } break; default: error (NILF, _("internal error: `%s' command_state"), c->file->name); abort (); break; } #endif /* RECURSIVEJOBS */ } /* Set the state flag to say the commands have finished. */ c->file->command_state = cs_finished; notice_finished_file (c->file); #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ /* Remove the child from the chain and free it. */ if (lastc == 0) children = c->next; else lastc->next = c->next; free_child (c); #endif /* RECURSIVEJOBS */ /* There is now another slot open. */ if (job_slots_used > 0) --job_slots_used; /* If the job failed, and the -k flag was not given, die. */ if (child_failed && !keep_going_flag) die (EXIT_FAILURE); (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask)); return 1; } /* VMS: Spawn a process executing the command in ARGV and return its pid. */ #define MAXCMDLEN 200 /* local helpers to make ctrl+c and ctrl+y working, see below */ #include #include #include static int ctrlMask= LIB$M_CLI_CTRLY; static int oldCtrlMask; static int setupYAstTried= 0; static int pidToAbort= 0; static int chan= 0; static void reEnableAst(void) { lib$enable_ctrl (&oldCtrlMask,0); } static astHandler (void) { if (pidToAbort) { sys$forcex (&pidToAbort, 0, SS$_ABORT); pidToAbort= 0; } kill (getpid(),SIGQUIT); } static void tryToSetupYAst(void) { $DESCRIPTOR(inputDsc,"SYS$COMMAND"); int status; struct { short int status, count; int dvi; } iosb; setupYAstTried++; if (!chan) { status= sys$assign(&inputDsc,&chan,0,0); if (!(status&SS$_NORMAL)) { lib$signal(status); return; } } status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0, astHandler,0,0,0,0,0); if (status==SS$_ILLIOFUNC) { sys$dassgn(chan); #ifdef CTRLY_ENABLED_ANYWAY fprintf (stderr, "-warning, CTRL-Y will leave " "sub-process(es) around.\n"); #else return; #endif } if (status==SS$_NORMAL) status= iosb.status; if (!(status&SS$_NORMAL)) { lib$signal(status); return; } /* called from AST handler ? */ if (setupYAstTried>1) return; if (atexit(reEnableAst)) fprintf (stderr, "-warning, you may have to re-enable CTRL-Y" "handling from DCL.\n"); status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask); if (!(status&SS$_NORMAL)) { lib$signal(status); return; } } int child_execute_job (argv, child) char *argv; struct child *child; { int i; static struct dsc$descriptor_s cmddsc; static struct dsc$descriptor_s pnamedsc; static struct dsc$descriptor_s ifiledsc; static struct dsc$descriptor_s ofiledsc; static struct dsc$descriptor_s efiledsc; int have_redirection = 0; int have_newline = 0; int spflags = CLI$M_NOWAIT; int status; char *cmd = alloca (strlen (argv) + 512), *p, *q; char ifile[256], ofile[256], efile[256]; char comname[50]; char procname[100]; /* Parse IO redirection. */ ifile[0] = 0; ofile[0] = 0; efile[0] = 0; if (debug_flag) printf ("child_execute_job (%s)\n", argv); while (isspace (*argv)) argv++; if (*argv == 0) return 0; sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff); pnamedsc.dsc$w_length = strlen(procname); pnamedsc.dsc$a_pointer = procname; pnamedsc.dsc$b_dtype = DSC$K_DTYPE_T; pnamedsc.dsc$b_class = DSC$K_CLASS_S; /* Handle comments and redirection. */ for (p = argv, q = cmd; *p; p++, q++) { switch (*p) { case '#': *p-- = 0; *q-- = 0; break; case '\\': p++; if (*p == '\n') p++; if (isspace (*p)) { do { p++; } while (isspace (*p)); p--; } *q = *p; break; case '<': p = vms_redirect (&ifiledsc, ifile, p); *q = ' '; have_redirection = 1; break; case '>': have_redirection = 1; if (*(p-1) == '2') { q--; if (strncmp (p, ">&1", 3) == 0) { p += 3; strcpy (efile, "sys$output"); efiledsc.dsc$w_length = strlen(efile); efiledsc.dsc$a_pointer = efile; efiledsc.dsc$b_dtype = DSC$K_DTYPE_T; efiledsc.dsc$b_class = DSC$K_CLASS_S; } else { p = vms_redirect (&efiledsc, efile, p); } } else { p = vms_redirect (&ofiledsc, ofile, p); } *q = ' '; break; case '\n': have_newline = 1; default: *q = *p; break; } } *q = *p; if (strncmp (cmd, "builtin_", 8) == 0) { child->pid = 270163; child->efn = 0; child->cstatus = 1; if (debug_flag) printf ("BUILTIN [%s][%s]\n", cmd, cmd+8); p = cmd + 8; if ((*(p) == 'c') && (*(p+1) == 'd') && ((*(p+2) == ' ') || (*(p+2) == '\t'))) { p += 3; while ((*p == ' ') || (*p == '\t')) p++; if (debug_flag) printf ("BUILTIN CD %s\n", p); if (chdir (p)) return 0; else return 1; } else if ((*(p) == 'r') && (*(p+1) == 'm') && ((*(p+2) == ' ') || (*(p+2) == '\t'))) { int in_arg; /* rm */ p += 3; while ((*p == ' ') || (*p == '\t')) p++; in_arg = 1; if (debug_flag) printf ("BUILTIN RM %s\n", p); while (*p) { switch (*p) { case ' ': case '\t': if (in_arg) { *p++ = ';'; in_arg = 0; } break; default: break; } p++; } } else { printf("Unknown builtin command '%s'\n", cmd); fflush(stdout); return 0; } } /* Create a *.com file if either the command is too long for lib$spawn, or the command contains a newline, or if redirection is desired. Forcing commands with newlines into DCLs allows to store search lists on user mode logicals. */ comname[0] = '\0'; if (strlen (cmd) > MAXCMDLEN || (have_redirection != 0) || (have_newline != 0)) { FILE *outfile; char c; char *sep; int alevel = 0; /* apostrophe level */ if (strlen (cmd) == 0) { printf ("Error, empty command\n"); fflush (stdout); return 0; } strcpy (comname, "sys$scratch:CMDXXXXXX.COM"); (void) mktemp (comname); outfile = fopen (comname, "w"); if (outfile == 0) pfatal_with_name (comname); if (ifile[0]) { fprintf (outfile, "$ assign/user %s sys$input\n", ifile); if (debug_flag) printf ("Redirected input from %s\n", ifile); ifiledsc.dsc$w_length = 0; } if (efile[0]) { fprintf (outfile, "$ define sys$error %s\n", efile); if (debug_flag) printf ("Redirected error to %s\n", efile); efiledsc.dsc$w_length = 0; } if (ofile[0]) { fprintf (outfile, "$ define sys$output %s\n", ofile); if (debug_flag) printf ("Redirected output to %s\n", ofile); ofiledsc.dsc$w_length = 0; } p = sep = q = cmd; for (c = '\n'; c; c = *q++) { switch (c) { case '\n': /* At a newline, skip any whitespace around a leading $ from the command and issue exactly one $ into the DCL. */ while (isspace (*p)) p++; if (*p == '$') p++; while (isspace (*p)) p++; fwrite (p, 1, q - p, outfile); fputc ('$', outfile); fputc (' ', outfile); /* Reset variables. */ p = sep = q; break; /* Nice places for line breaks are after strings, after comma or space and before slash. */ case '"': q = handle_apos (q + 1); sep = q; break; case ',': case ' ': sep = q; break; case '/': case '\0': sep = q - 1; break; default: break; } if (sep - p > 78) { /* Enough stuff for a line. */ fwrite (p, 1, sep - p, outfile); p = sep; if (*sep) { /* The command continues. */ fputc ('-', outfile); } fputc ('\n', outfile); } } fwrite (p, 1, q - p, outfile); fputc ('\n', outfile); fclose (outfile); sprintf (cmd, "$ @%s", comname); if (debug_flag) printf ("Executing %s instead\n", cmd); } cmddsc.dsc$w_length = strlen(cmd); cmddsc.dsc$a_pointer = cmd; cmddsc.dsc$b_dtype = DSC$K_DTYPE_T; cmddsc.dsc$b_class = DSC$K_CLASS_S; child->efn = 0; while (child->efn < 32 || child->efn > 63) { status = lib$get_ef ((unsigned long *)&child->efn); if (!(status & 1)) return 0; } sys$clref (child->efn); vms_jobsefnmask |= (1 << (child->efn - 32)); /* LIB$SPAWN [command-string] [,input-file] [,output-file] [,flags] [,process-name] [,process-id] [,completion-status-address] [,byte-integer-event-flag-num] [,AST-address] [,varying-AST-argument] [,prompt-string] [,cli] [,table] */ #ifndef DONTWAITFORCHILD /* * Code to make ctrl+c and ctrl+y working. * The problem starts with the synchronous case where after lib$spawn is * called any input will go to the child. But with input re-directed, * both control characters won't make it to any of the programs, neither * the spawning nor to the spawned one. Hence the caller needs to spawn * with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr * has to follow to simulate the wanted synchronous behaviour. * The next problem is ctrl+y which isn't caught by the crtl and * therefore isn't converted to SIGQUIT (for a signal handler which is * already established). The only way to catch ctrl+y, is an AST * assigned to the input channel. But ctrl+y handling of DCL needs to be * disabled, otherwise it will handle it. Not to mention the previous * ctrl+y handling of DCL needs to be re-established before make exits. * One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will * make it to the signal handler after the child "normally" terminates. * This isn't enough. It seems reasonable for simple command lines like * a 'cc foobar.c' spawned in a subprocess but it is unacceptable for * spawning make. Therefore we need to abort the process in the AST. * * Prior to the spawn it is checked if an AST is already set up for * ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general * this will work except if make is run in a batch environment, but there * nobody can press ctrl+y. During the setup the DCL handling of ctrl+y * is disabled and an exit handler is established to re-enable it. * If the user interrupts with ctrl+y, the assigned AST will fire, force * an abort to the subprocess and signal SIGQUIT, which will be caught by * the already established handler and will bring us back to common code. * After the spawn (now /nowait) a sys$waitfr simulates the /wait and * enables the ctrl+y be delivered to this code. And the ctrl+c too, * which the crtl converts to SIGINT and which is caught by the common * signal handler. Because signals were blocked before entering this code * sys$waitfr will always complete and the SIGQUIT will be processed after * it (after termination of the current block, somewhere in common code). * And SIGINT too will be delayed. That is ctrl+c can only abort when the * current command completes. Anyway it's better than nothing :-) */ if (!setupYAstTried) tryToSetupYAst(); status = lib$spawn (&cmddsc, /* cmd-string */ (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */ (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */ &spflags, /* flags */ &pnamedsc, /* proc name */ &child->pid, &child->cstatus, &child->efn, 0, 0, 0, 0, 0); pidToAbort= child->pid; status= sys$waitfr (child->efn); pidToAbort= 0; vmsHandleChildTerm(child); #else status = lib$spawn (&cmddsc, (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, &spflags, &pnamedsc, &child->pid, &child->cstatus, &child->efn, vmsHandleChildTerm, child, 0, 0, 0); #endif%~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]JOB.C;6jubp if (!(status & 1)) { printf ("Error spawning, %d\n",status); fflush (stdout); } if (comname[0] && !debug_flag) unlink (comname); return (status & 1); } #else /* !VMS */ #if !defined (_AMIGA) && !defined (__MSDOS__) /* UNIX: Replace the current process with one executing the command in ARGV. STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is the environment of the new program. This function does not return. */ void child_execute_job (stdin_fd, stdout_fd, argv, envp) int stdin_fd, stdout_fd; char **argv, **envp; { if (stdin_fd != 0) (void) dup2 (stdin_fd, 0); if (stdout_fd != 1) (void) dup2 (stdout_fd, 1); if (stdin_fd != 0) (void) close (stdin_fd); if (stdout_fd != 1) (void) close (stdout_fd); /* Run the command. */ exec_command (argv, envp); } #endif /* !AMIGA && !__MSDOS__ */ #endif /* !VMS */ #endif /* !WINDOWS32 */ #ifndef _AMIGA /* Replace the current process with one running the command in ARGV, with environment ENVP. This function does not return. */ void exec_command (argv, envp) char **argv, **envp; { #ifdef VMS /* to work around a problem with signals and execve: ignore them */ #ifdef SIGCHLD signal (SIGCHLD,SIG_IGN); #endif /* Run the program. */ execve (argv[0], argv, envp); perror_with_name ("execve: ", argv[0]); _exit (EXIT_FAILURE); #else #ifdef WINDOWS32 HANDLE hPID; HANDLE hWaitPID; int err = 0; int exit_code = EXIT_FAILURE; /* make sure CreateProcess() has Path it needs */ sync_Path_environment(); /* launch command */ hPID = process_easy(argv, envp); /* make sure launch ok */ if (hPID == INVALID_HANDLE_VALUE) { int i; fprintf(stderr, _("process_easy() failed failed to launch process (e=%d)\n"), process_last_err(hPID)); for (i = 0; argv[i]; i++) fprintf(stderr, "%s ", argv[i]); fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); exit(EXIT_FAILURE); } /* wait and reap last child */ while (hWaitPID = process_wait_for_any()) { /* was an error found on this process? */ err = process_last_err(hWaitPID); /* get exit data */ exit_code = process_exit_code(hWaitPID); if (err) fprintf(stderr, "make (e=%d, rc=%d): %s", err, exit_code, map_windows32_error_to_string(err)); /* cleanup process */ process_cleanup(hWaitPID); /* expect to find only last pid, warn about other pids reaped */ if (hWaitPID == hPID) break; else fprintf(stderr, _("make reaped child pid %d, still waiting for pid %d\n"), hWaitPID, hPID); } /* return child's exit code as our exit code */ exit(exit_code); #else /* !WINDOWS32 */ /* Be the user, permanently. */ child_access (); /* Run the program. */ environ = envp; execvp (argv[0], argv); switch (errno) { case ENOENT: error (NILF, _("%s: Command not found"), argv[0]); break; case ENOEXEC: { /* The file is not executable. Try it as a shell script. */ extern char *getenv (); char *shell; char **new_argv; int argc; shell = getenv ("SHELL"); if (shell == 0) shell = default_shell; argc = 1; while (argv[argc] != 0) ++argc; new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *)); new_argv[0] = shell; new_argv[1] = argv[0]; while (argc > 0) { new_argv[1 + argc] = argv[argc]; --argc; } execvp (shell, new_argv); if (errno == ENOENT) error (NILF, _("%s: Shell program not found"), shell); else perror_with_name ("execvp: ", shell); break; } default: perror_with_name ("execvp: ", argv[0]); break; } _exit (127); #endif /* !WINDOWS32 */ #endif /* !VMS */ } #else /* On Amiga */ void exec_command (argv) char **argv; { MyExecute (argv); } void clean_tmp (void) { DeleteFile (amiga_bname); } #endif /* On Amiga */ #ifndef VMS /* Figure out the argument list necessary to run LINE as a command. Try to avoid using a shell. This routine handles only ' quoting, and " quoting when no backslash, $ or ` characters are seen in the quotes. Starting quotes may be escaped with a backslash. If any of the characters in sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[] is the first word of a line, the shell is used. If RESTP is not NULL, *RESTP is set to point to the first newline in LINE. If *RESTP is NULL, newlines will be ignored. SHELL is the shell to use, or nil to use the default shell. IFS is the value of $IFS, or nil (meaning the default). */ static char ** construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr) char *line, **restp; char *shell, *ifs; char **batch_filename_ptr; { #ifdef __MSDOS__ /* MSDOS supports both the stock DOS shell and ports of Unixy shells. We call `system' for anything that requires ``slow'' processing, because DOS shells are too dumb. When $SHELL points to a real (unix-style) shell, `system' just calls it to do everything. When $SHELL points to a DOS shell, `system' does most of the work internally, calling the shell only for its internal commands. However, it looks on the $PATH first, so you can e.g. have an external command named `mkdir'. Since we call `system', certain characters and commands below are actually not specific to COMMAND.COM, but to the DJGPP implementation of `system'. In particular: The shell wildcard characters are in DOS_CHARS because they will not be expanded if we call the child via `spawnXX'. The `;' is in DOS_CHARS, because our `system' knows how to run multiple commands on a single line. DOS_CHARS also include characters special to 4DOS/NDOS, so we won't have to tell one from another and have one more set of commands and special characters. */ static char sh_chars_dos[] = "*?[];|<>%^&()"; static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", "copy", "ctty", "date", "del", "dir", "echo", "erase", "exit", "for", "goto", "if", "md", "mkdir", "path", "pause", "prompt", "rd", "rmdir", "rem", "ren", "rename", "set", "shift", "time", "type", "ver", "verify", "vol", ":", 0 }; static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; static char *sh_cmds_sh[] = { "cd", "echo", "eval", "exec", "exit", "login", "logout", "set", "umask", "wait", "while", "for", "case", "if", ":", ".", "break", "continue", "export", "read", "readonly", "shift", "times", "trap", "switch", "unset", 0 }; char *sh_chars; char **sh_cmds; #else #ifdef _AMIGA static char sh_chars[] = "#;\"|<>()?*$`"; static char *sh_cmds[] = { "cd", "eval", "if", "delete", "echo", "copy", "rename", "set", "setenv", "date", "makedir", "skip", "else", "endif", "path", "prompt", "unset", "unsetenv", "version", 0 }; #else #ifdef WINDOWS32 static char sh_chars_dos[] = "\"|<>"; static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", "copy", "ctty", "date", "del", "dir", "echo", "erase", "exit", "for", "goto", "if", "if", "md", "mkdir", "path", "pause", "prompt", "rem", "ren", "rename", "set", "shift", "time", "type", "ver", "verify", "vol", ":", 0 }; static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; static char *sh_cmds_sh[] = { "cd", "eval", "exec", "exit", "login", "logout", "set", "umask", "wait", "while", "for", "case", "if", ":", ".", "break", "continue", "export", "read", "readonly", "shift", "times", "trap", "switch", "test", #ifdef BATCH_MODE_ONLY_SHELL "echo", #endif 0 }; char* sh_chars; char** sh_cmds; #else /* WINDOWS32 */ static char sh_chars[] = "#;\"*?[]&|<>(){}$`^"; static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login", "logout", "set", "umask", "wait", "while", "for", "case", "if", ":", ".", "break", "continue", "export", "read", "readonly", "shift", "times", "trap", "switch", 0 }; #endif /* WINDOWS32 */ #endif /* Amiga */ #endif /* __MSDOS__ */ register int i; register char *p; register char *ap; char *end; int instring, word_has_equals, seen_nonequals, last_argument_was_empty; char **new_argv = 0; #ifdef WINDOWS32 int slow_flag = 0; if (no_default_sh_exe) { sh_cmds = sh_cmds_dos; sh_chars = sh_chars_dos; } else { sh_cmds = sh_cmds_sh; sh_chars = sh_chars_sh; } #endif /* WINDOWS32 */ if (restp != NULL) *restp = NULL; /* Make sure not to bother processing an empty line. */ while (isblank (*line)) ++line; if (*line == '\0') return 0; /* See if it is safe to parse commands internally. */ if (shell == 0) shell = default_shell; #ifdef WINDOWS32 else if (strcmp (shell, default_shell)) { char *s1 = _fullpath(NULL, shell, 0); char *s2 = _fullpath(NULL, default_shell, 0); slow_flag = strcmp((s1 ? s1 : ""), (s2 ? s2 : "")); if (s1); free(s1); if (s2); free(s2); } if (slow_flag) goto slow; #else /* not WINDOWS32 */ #ifdef __MSDOS__ else if (stricmp (shell, default_shell)) { extern int _is_unixy_shell (const char *_path); message (1, _("$SHELL changed (was `%s', now `%s')"), default_shell, shell); unixy_shell = _is_unixy_shell (shell); default_shell = shell; } if (unixy_shell) { sh_chars = sh_chars_sh; sh_cmds = sh_cmds_sh; } else { sh_chars = sh_chars_dos; sh_cmds = sh_cmds_dos; } #else /* not __MSDOS__ */ else if (strcmp (shell, default_shell)) goto slow; #endif /* not __MSDOS__ */ #endif /* not WINDOWS32 */ if (ifs != 0) for (ap = ifs; *ap != '\0'; ++ap) if (*ap != ' ' && *ap != '\t' && *ap != '\n') goto slow; i = strlen (line) + 1; /* More than 1 arg per character is impossible. */ new_argv = (char **) xmalloc (i * sizeof (char *)); /* All the args can fit in a buffer as big as LINE is. */ ap = new_argv[0] = (char *) xmalloc (i); end = ap + i; /* I is how many complete arguments have been found. */ i = 0; instring = word_has_equals = seen_nonequals = last_argument_was_empty = 0; for (p = line; *p != '\0'; ++p) { if (ap > end) abort (); if (instring) { string_char: /* Inside a string, just copy any char except a closing quote or a backslash-newline combination. */ if (*p == instring) { instring = 0; if (ap == new_argv[0] || *(ap-1) == '\0') last_argument_was_empty = 1; } else if (*p == '\\' && p[1] == '\n') goto swallow_escaped_newline; else if (*p == '\n' && restp != NULL) { /* End of the command line. */ *restp = p; goto end_of_line; } /* Backslash, $, and ` are special inside double quotes. If we see any of those, punt. But on MSDOS, if we use COMMAND.COM, double and single quotes have the same effect. */ else if (instring == '"' && index ("\\$`", *p) != 0 && unixy_shell) goto slow; else *ap++ = *p; } else if (index (sh_chars, *p) != 0) /* Not inside a string, but it's a special char. */ goto slow; #ifdef __MSDOS__ else if (*p == '.' && p[1] == '.' && p[2] == '.' && p[3] != '.') /* `...' is a wildcard in DJGPP. */ goto slow; #endif else /* Not a special char. */ switch (*p) { case '=': /* Equals is a special character in leading words before the first word with no equals sign in it. This is not the case with sh -k, but we never get here when using nonstandard shell flags. */ if (! seen_nonequals && unixy_shell) goto slow; word_has_equals = 1; *ap++ = '='; break; case '\\': /* Backslash-newline combinations are eaten. */ if (p[1] == '\n') { swallow_escaped_newline: /* Eat the backslash, the newline, and following whitespace, replacing it all with a single space. */ p += 2; /* If there is a tab after a backslash-newline, remove it from the source line which will be echoed, since it was most likely used to line up the continued line with the previous one. */ if (*p == '\t') /* Note these overlap and strcpy() is undefined for overlapping objects in ANSI C. The strlen() _IS_ right, since we need to copy the nul byte too. */ bcopy (p + 1, p, strlen (p)); if (instring) goto string_char; else { if (ap != new_argv[i]) /* Treat this as a space, ending the arg. But if it's at the beginning of the arg, it should just get eaten, rather than becoming an empty arg. */ goto end_of_arg; else p = next_token (p) - 1; } } else if (p[1] != '\0') { #if defined(__MSDOS__) || defined(WINDOWS32) /* Only remove backslashes before characters special to Unixy shells. All other backslashes are copied verbatim, since they are probably DOS-style directory separators. This still leaves a small window for problems, but at least it should work for the vast majority of naive users. */ #ifdef __MSDOS__ /* A dot is only special as part of the "..." wildcard. */ if (strneq (p + 1, ".\\.\\.", 5)) { *ap++ = '.'; *ap++ = '.'; p += 4; } else #endif if (p[1] != '\\' && p[1] != '\'' && !isspace (p[1]) && (index (sh_chars_sh, p[1]) == 0)) /* back up one notch, to copy the backslash */ --p; #endif /* __MSDOS__ || WINDOWS32 */ /* Copy and skip the following char. */ *ap++ = *++p; } break; case '\'': case '"': instring = *p; break; case '\n': if (restp != NULL) { /* End of the command line. */ *restp = p; goto end_of_line; } else /* Newlines are not special. */ *ap++ = '\n'; break; case ' ': case '\t': end_of_arg: /* We have the end of an argument. Terminate the text of the argument. */ *ap++ = '\0'; new_argv[++i] = ap; last_argument_was_empty = 0; /* Update SEEN_NONEQUALS, which tells us if every word heretofore has contained an `='. */ seen_nonequals |= ! word_has_equals; if (word_has_equals && ! seen_nonequals) /* An `=' in a word before the first word without one is magical. */ goto slow; word_has_equals = 0; /* Prepare for the next word. */ /* If this argument is the command name, see if it is a built-in shell command. If so, have the shell handle it. */ if (i == 1) { register int j; for (j = 0; sh_cmds[j] != 0; ++j) if (streq (sh_cmds[j], new_argv[0])) goto slow; } /* Ignore multiple whitespace chars. */ p = next_token (p); /* Next iteration should examine the first nonwhite char. */ --p; break; default: *ap++ = *p; break; } } end_of_line: if (instring) /* Let the shell deal with an unterminated quote. */ goto slow; /* Terminate the last argument and the argument list. */ *ap = '\0'; if (new_argv[i][0] != '\0' || last_argument_was_empty) ++i; new_argv[i] = 0; if (i == 1) { register int j; for (j = 0; sh_cmds[j] != 0; ++j) if (streq (sh_cmds[j], new_argv[0])) goto slow; } if (new_argv[0] == 0) /* Line was empty. */ return 0; else return new_argv; slow:; /* We must use the shell. */ if (new_argv != 0) { /* Free the old argument list we were working on. */ free (new_argv[0]); free ((void *)new_argv); } #ifdef __MSDOS__ execute_by_shell = 1; /* actually, call `system' if shell isn't unixy */ #endif #ifdef _AMIGA { char *ptr; char *buffer; char *dptr; buffer = (char *)xmalloc (strlen (line)+1); ptr = line; for (dptr=buffer; *ptr; ) { if (*ptr == '\\' && ptr[1] == '\n') ptr += 2; else if (*ptr == '@') /* Kludge: multiline commands */ { ptr += 2; *dptr++ = '\n'; } else *dptr++ = *ptr++; } *dptr = 0; new_argv = (char **) xmalloc (2 * sizeof (char *)); new_argv[0] = buffer; new_argv[1] = 0; } #else /* Not Amiga */ #ifdef WINDOWS32 /* * Not eating this whitespace caused things like * * sh -c "\n" * * which gave the shell fits. I think we have to eat * whitespace here, but this code should be considered * suspicious if things start failing.... */ /* Make sure not to bother processing an empty line. */ while (isspace (*line)) ++line; if (*line == '\0') return 0; #endif /* WINDOWS32 */ { /* SHELL may be a multi-word command. Construct a command line "SHELL -c LINE", with all special chars in LINE escaped. Then recurse, expanding this command line to get the final argument list. */ unsigned int shell_len = strlen (shell); #ifndef VMS static char minus_c[] = " -c "; #else static char minus_c[] = ""; #endif unsigned int line_len = strlen (line); char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1) + (line_len * 2) + 1); char* command_ptr = NULL; /* used for batch_mode_shell mode */ ap = new_line; bcopy (shell, ap, shell_len); ap += shell_len; bcopy (minus_c, ap, sizeof (minus_c) - 1); ap += sizeof (minus_c) - 1; command_ptr = ap; for (p = line; *p != '\0'; ++p) { if (restp != NULL && *p == '\n') { *restp = p; break; } else if (*p == '\\' && p[1] == '\n') { /* Eat the backslash, the newline, and following whitespace, replacing it all with a single space (which is escaped from the shell). */ p += 2; /* If there is a tab after a backslash-newline, remove it from the source line which will be echoed, since it was most likely used to line up the continued line with the previous one. */ if (*p == '\t') bcopy (p + 1, p, strlen (p)); p = next_token (p); --p; if (unixy_shell && !batch_mode_shell) *ap++ = '\\'; *ap++ = ' '; continue; } /* DOS shells don't know about backslash-escaping. */ if (unixy_shell && !batch_mode_shell && (*p == '\\' || *p == '\'' || *p == '"' || isspace (*p) || index (sh_chars, *p) != 0)) *ap++ = '\\'; #ifdef __MSDOS__ else if (unixy_shell && strneq (p, "...", 3)) { /* The case of `...' wildcard again. */ strcpy (ap, "\\.\\.\\"); ap += 5; p += 2; } #endif *ap++ = *p; } if (ap == new_line + shell_len + sizeof (minus_c) - 1) /* Line was empty. */ return 0; *ap = '\0'; #ifdef WINDOWS32 /* Some shells do not work well when invoked as 'sh -c xxx' to run a command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems). In these cases, run commands via a script file. */ if ((no_default_sh_exe || batch_mode_shell) && batch_filename_ptr) { FILE* batch = NULL; int id = GetCurrentProcessId(); PATH_VAR(fbuf); char* fname = NULL; /* create a file name */ sprintf(fbuf, "make%d", id); fname = tempnam(".", fbuf); /* create batch file name */ *batch_filename_ptr = xmalloc(strlen(fname) + 5); strcpy(*batch_filename_ptr, fname); /* make sure path name is in DOS backslash format */ if (!unixy_shell) { fname = *batch_filename_ptr; for (i = 0; fname[i] != '\0'; ++i) if (fname[i] == '/') fname[i] = '\\'; strcat(*batch_filename_ptr, ".bat"); } else { strcat(*batch_filename_ptr, ".sh"); } if (debug_flag) printf(_("Creating temporary batch file %s\n"), *batch_filename_ptr); /* create batch file to execute command */ batch = fopen (*batch_filename_ptr, "w"); if (!unixy_shell) fputs ("@echo off\n", batch); fputs (command_ptr, batch); fputc ('\n', batch); fclose (batch); /* create argv */ new_argv = (char **) xmalloc(3 * sizeof(char *)); if (unixy_shell) { new_argv[0] = xstrdup (shell); new_argv[1] = *batch_filename_ptr; /* only argv[0] gets freed later */ } else { new_argv[0] = xstrdup (*batch_filename_ptr); new_argv[1] = NULL; } new_argv[2] = NULL; } else #endif /* WINDOWS32 */ if (unixy_shell) new_argv = construct_command_argv_internal (new_line, (char **) NULL, (char *) 0, (char *) 0, (char *) 0); #ifdef __MSDOS__ else { /* With MSDOS shells, we must construct the command line here instead of recursively calling ourselves, because we cannot backslash-escape the special characters (see above). */ new_argv = (char **) xmalloc (sizeof (char *)); line_len = strlen (new_line) - shell_len - sizeof (minus_c) + 1; new_argv[0] = xmalloc (line_len + 1); strncpy (new_argv[0], new_line + shell_len + sizeof (minus_c) - 1, line_len); new_argv[0][line_len] = '\0'; } #else else fatal (NILF, _("%s (line %d) Bad shell context (!unixy && !batch_mode_shell)\n"), __FILE__, __LINE__); #endif } #endif /* ! AMIGA */ return new_argv; } #endif /* !VMS */ /* Figure out the argument list necessary to run LINE as a command. Try to avoid using a shell. This routine handles only ' quoting, and " quoting when no backslash, $ or ` characters are seen in the quotes. Starting quotes may be escaped with a backslash. If any of the characters in sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[] is the first word of a line, the shell is used. If RESTP is not NULL, *RESTP is set to point to the first newline in LINE. If *RESTP is NULL, newlines will be ignored. FILE is the target whose commands these are. It is used for variable expansion for $(SHELL) and $(IFS). */ char ** construct_command_argv (line, restp, file, batch_filename_ptr) char *line, **restp; struct file *file; char** batch_filename_ptr; { char *shell, *ifs; char **argv; #ifdef VMS char *cptr; int argc; argc = 0; cptr = line; for (;;) { while ((*cptr != 0) && (isspace (*cptr))) cptr++; if (*cptr == 0) break; while ((*cptr != 0) && (!isspace(*cptr))) cptr++; argc++; } argv = (char **)malloc (argc * sizeof (char *)); if (argv == 0) abort (); cptr = line; argc = 0; for (;;) { while ((*cptr != 0) && (isspace (*cptr))) cptr++; if (*cptr == 0) break; if (debug_flag) printf ("argv[%d] = [%s]\n", argc, cptr); argv[argc++] = cptr; while ((*cptr != 0) && (!isspace(*cptr))) cptr++; if (*cptr != 0) *cptr++ = 0; } #else { /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; shell = allocated_variable_expand_for_file ("$(SHELL)", file); #ifdef WINDOWS32 /* * Convert to forward slashes so that construct_command_argv_internal() * is not confused. */ if (shell) { char *p = w32ify(shell, 0); strcpy(shell, p); } #endif ifs = allocated_variable_expand_for_file ("$(IFS)", file); warn_undefined_variables_flag = save; } argv = construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr); free (shell); free (ifs); #endif /* !VMS */ return argv; } #if !defined(HAVE_DUP2) && !defined(_AMIGA) int dup2 (old, new) int old, new; { int fd; (void) close (new); fd = dup (old); if (fd != new) { (void) close (fd); errno = EMFILE; return -1; } return fd; } #endif /* !HAPE_DUP2 && !_AMIGA */ *[MAKE-3_78_1HB]JOB.H;1+,c./@ 4-`0123KPWO 567VRݴm89G@HJ /* Definitions for managing subprocesses in GNU Make. Copyright (C) 1992, 1993, 1996, 1999 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef SEEN_JOB_H #define SEEN_JOB_H /* Structure describing a running or dead child process. */ struct child { struct child *next; /* Link in the chain. */ struct file *file; /* File being remade. */ char **environment; /* Environment for commands. */ char **command_lines; /* Array of variable-expanded cmd lines. */ unsigned int command_line; /* Index into above. */ char *command_ptr; /* Ptr into command_lines[command_line]. */ pid_t pid; /* Child process's ID number. */ #ifdef VMS int efn; /* Completion event flag number */ int cstatus; /* Completion status */ #endif char *sh_batch_file; /* Script file for shell commands */ unsigned int remote:1; /* Nonzero if executing remotely. */ unsigned int noerror:1; /* Nonzero if commands contained a `-'. */ unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */ unsigned int deleted:1; /* Nonzero if targets have been deleted. */ }; extern struct child *children; extern void new_job PARAMS ((struct file *file)); extern void reap_children PARAMS ((int block, int err)); extern void start_waiting_jobs PARAMS ((void)); extern char **construct_command_argv PARAMS ((char *line, char **restp, struct file *file, char** batch_file)); #ifdef VMS extern int child_execute_job PARAMS ((char *argv, struct child *child)); #else extern void child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp)); #endif #ifdef _AMIGA extern void exec_command PARAMS ((char **argv)); #else extern void exec_command PARAMS ((char **argv, char **envp)); #endif extern unsigned int job_slots_used; extern void block_sigs PARAMS ((void)); #ifdef POSIX extern void unblock_sigs PARAMS ((void)); #else #ifdef HAVE_SIGSETMASK extern int fatal_signal_mask; #define unblock_sigs() sigsetmask (0) #else #define unblock_sigs() #endif #endif #endif /* SEEN_JOB_H */ *[MAKE-3_78_1HB]MAIN.C;1+,c./@ 4C-`0123KPWO56rs79m89G@HJ /* Argument parsing and main program of GNU Make. Copyright (C) 1988,89,90,91,94,95,96,97,98,99 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "dep.h" #include "filedef.h" #include "variable.h" #include "job.h" #include "commands.h" #include "rule.h" #include "getopt.h" #include #ifdef _AMIGA # include # include #endif #ifdef WINDOWS32 #include #include "pathstuff.h" #endif #if defined(MAKE_JOBSERVER) && defined(HAVE_FCNTL_H) # include #endif #ifdef _AMIGA int __stack = 20000; /* Make sure we have 20K of stack space */ #endif extern void init_dir PARAMS ((void)); extern void remote_setup PARAMS ((void)); extern void remote_cleanup PARAMS ((void)); extern RETSIGTYPE fatal_error_signal PARAMS ((int sig)); extern void print_variable_data_base PARAMS ((void)); extern void print_dir_data_base PARAMS ((void)); extern void print_rule_data_base PARAMS ((void)); extern void print_file_data_base PARAMS ((void)); extern void print_vpath_data_base PARAMS ((void)); #if defined HAVE_WAITPID || defined HAVE_WAIT3 # define HAVE_WAIT_NOHANG #endif #ifndef HAVE_UNISTD_H extern int chdir (); #endif #ifndef STDC_HEADERS # ifndef sun /* Sun has an incorrect decl in a header. */ extern void exit PARAMS ((int)) __attribute__ ((noreturn)); # endif extern double atof (); #endif extern char *mktemp (); static void print_data_base PARAMS ((void)); static void print_version PARAMS ((void)); static void decode_switches PARAMS ((int argc, char **argv, int env)); static void decode_env_switches PARAMS ((char *envar, unsigned int len)); static void define_makeflags PARAMS ((int all, int makefile)); static char *quote_as_word PARAMS ((char *out, char *in, int double_dollars)); /* The structure that describes an accepted command switch. */ struct command_switch { int c; /* The switch character. */ enum /* Type of the value. */ { flag, /* Turn int flag on. */ flag_off, /* Turn int flag off. */ string, /* One string per switch. */ positive_int, /* A positive integer. */ floating, /* A floating-point number (double). */ ignore /* Ignored. */ } type; char *value_ptr; /* Pointer to the value-holding variable. */ unsigned int env:1; /* Can come from MAKEFLAGS. */ unsigned int toenv:1; /* Should be put in MAKEFLAG&~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAIN.C;1LS. */ unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ char *noarg_value; /* Pointer to value used if no argument is given. */ char *default_value;/* Pointer to default value. */ char *long_name; /* Long option name. */ char *argdesc; /* Descriptive word for argument. */ char *description; /* Description for usage message. */ /* 0 means internal; don't display help. */ }; /* True if C is a switch value that corresponds to a short option. */ #define short_option(c) ((c) <= CHAR_MAX) /* The structure used to hold the list of strings given in command switches of a type that takes string arguments. */ struct stringlist { char **list; /* Nil-terminated list of strings. */ unsigned int idx; /* Index into above. */ unsigned int max; /* Number of pointers allocated. */ }; /* The recognized command switches. */ /* Nonzero means do not print commands to be executed (-s). */ int silent_flag; /* Nonzero means just touch the files that would appear to need remaking (-t) */ int touch_flag; /* Nonzero means just print what commands would need to be executed, don't actually execute them (-n). */ int just_print_flag; /* Print debugging trace info (-d). */ int debug_flag = 0; #ifdef WINDOWS32 /* Suspend make in main for a short time to allow debugger to attach */ int suspend_flag = 0; #endif /* Environment variables override makefile definitions. */ int env_overrides = 0; /* Nonzero means ignore status codes returned by commands executed to remake files. Just treat them all as successful (-i). */ int ignore_errors_flag = 0; /* Nonzero means don't remake anything, just print the data base that results from reading the makefile (-p). */ int print_data_base_flag = 0; /* Nonzero means don't remake anything; just return a nonzero status if the specified targets are not up to date (-q). */ int question_flag = 0; /* Nonzero means do not use any of the builtin rules (-r) / variables (-R). */ int no_builtin_rules_flag = 0; int no_builtin_variables_flag = 0; /* Nonzero means keep going even if remaking some file fails (-k). */ int keep_going_flag; int default_keep_going_flag = 0; /* Nonzero means print directory before starting and when done (-w). */ int print_directory_flag = 0; /* Nonzero means ignore print_directory_flag and never print the directory. This is necessary because print_directory_flag is set implicitly. */ int inhibit_print_directory_flag = 0; /* Nonzero means print version information. */ int print_version_flag = 0; /* List of makefiles given with -f switches. */ static struct stringlist *makefiles = 0; /* Number of job slots (commands that can be run at once). */ unsigned int job_slots = 1; unsigned int default_job_slots = 1; /* Value of job_slots that means no limit. */ static unsigned int inf_jobs = 0; /* File descriptors for the jobs pipe. */ static struct stringlist *jobserver_fds = 0; int job_fds[2] = { -1, -1 }; int job_rfd = -1; /* Maximum load average at which multiple jobs will be run. Negative values mean unlimited, while zero means limit to zero load (which could be useful to start infinite jobs remotely but one at a time locally). */ #ifndef NO_FLOAT double max_load_average = -1.0; double default_load_average = -1.0; #else int max_load_average = -1; int default_load_average = -1; #endif /* List of directories given with -C switches. */ static struct stringlist *directories = 0; /* List of include directories given with -I switches. */ static struct stringlist *include_directories = 0; /* List of files given with -o switches. */ static struct stringlist *old_files = 0; /* List of files given with -W switches. */ static struct stringlist *new_files = 0; /* If nonzero, we should just print usage and exit. */ static int print_usage_flag = 0; /* If nonzero, we should print a warning message for each reference to an undefined variable. */ int warn_undefined_variables_flag; /* The table of command switches. */ static const struct command_switch switches[] = { { 'b', ignore, 0, 0, 0, 0, 0, 0, 0, 0, _("Ignored for compatibility") }, { 'C', string, (char *) &directories, 0, 0, 0, 0, 0, "directory", _("DIRECTORY"), _("Change to DIRECTORY before doing anything") }, { 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0, "debug", 0, _("Print lots of debugging information") }, #ifdef WINDOWS32 { 'D', flag, (char *) &suspend_flag, 1, 1, 0, 0, 0, "suspend-for-debug", 0, _("Suspend process to allow a debugger to attach") }, #endif { 'e', flag, (char *) &env_overrides, 1, 1, 0, 0, 0, "environment-overrides", 0, _("Environment variables override makefiles") }, { 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0, "file", _("FILE"), _("Read FILE as a makefile") }, { 'h', flag, (char *) &print_usage_flag, 0, 0, 0, 0, 0, "help", 0, _("Print this message and exit") }, { 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0, "ignore-errors", 0, _("Ignore errors from commands") }, { 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0, "include-dir", _("DIRECTORY"), _("Search DIRECTORY for included makefiles") }, { 'j', positive_int, (char *) &job_slots, 1, 1, 0, (char *) &inf_jobs, (char *) &default_job_slots, "jobs", "N", _("Allow N jobs at once; infinite jobs with no arg") }, { CHAR_MAX+1, string, (char *) &jobserver_fds, 1, 1, 0, 0, 0, "jobserver-fds", 0, 0 }, { 'k', flag, (char *) &keep_going_flag, 1, 1, 0, 0, (char *) &default_keep_going_flag, "keep-going", 0, _("Keep going when some targets can't be made") }, #ifndef NO_FLOAT { 'l', floating, (char *) &max_load_average, 1, 1, 0, (char *) &default_load_average, (char *) &default_load_average, "load-average", "N", _("Don't start multiple jobs unless load is below N") }, #else { 'l', positive_int, (char *) &max_load_average, 1, 1, 0, (char *) &default_load_average, (char *) &default_load_average, "load-average", "N", _("Don't start multiple jobs unless load is below N") }, #endif { 'm', ignore, 0, 0, 0, 0, 0, 0, 0, 0, "-b" }, { 'n', flag, (char *) &just_print_flag, 1, 1, 1, 0, 0, "just-print", 0, _("Don't actually run any commands; just print them") }, { 'o', string, (char *) &old_files, 0, 0, 0, 0, 0, "old-file", _("FILE"), _("Consider FILE to be very old and don't remake it") }, { 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0, "print-data-base", 0, _("Print make's internal database") }, { 'q', flag, (char *) &question_flag, 1, 1, 1, 0, 0, "question", 0, _("Run no commands; exit status says if up to date") }, { 'r', flag, (char *) &no_builtin_rules_flag, 1, 1, 0, 0, 0, "no-builtin-rules", 0, _("Disable the built-in implicit rules") }, { 'R', flag, (char *) &no_builtin_variables_flag, 1, 1, 0, 0, 0, "no-builtin-variables", 0, _("Disable the built-in variable settings") }, { 's', flag, (char *) &silent_flag, 1, 1, 0, 0, 0, "silent", 0, _("Don't echo commands") }, { 'S', flag_off, (char *) &keep_going_flag, 1, 1, 0, 0, (char *) &default_keep_going_flag, "no-keep-going", 0, _("Turns off -k") }, { 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0, "touch", 0, _("Touch targets instead of remaking them") }, { 'v', flag, (char *) &print_version_flag, 1, 1, 0, 0, 0, "version", 0, _("Print the version number of make and exit") }, { 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0, "print-directory", 0, _("Print the current directory") }, { CHAR_MAX+2, flag, (char *) &inhibit_print_directory_flag, 1, 1, 0, 0, 0, "no-print-directory", 0, _("Turn off -w, even if it was turned on implicitly") }, { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0, "what-if", _("FILE"), _("Consider FILE to be infinitely new") }, { CHAR_MAX+3, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0, "warn-undefined-variables", 0, _("Warn when an undefined variable is referenced") }, { '\0', } }; /* Secondary long names for options. */ static struct option long_option_aliases[] = { { "quiet", no_argument, 0, 's' }, { "stop", no_argument, 0, 'S' }, { "new-file", required_argument, 0, 'W' }, { "assume-new", required_argument, 0, 'W' }, { "assume-old", required_argument, 0, 'o' }, { "max-load", optional_argument, 0, 'l' }, { "dry-run", no_argument, 0, 'n' }, { "recon", no_argument, 0, 'n' }, { "makefile", required_argument, 0, 'f' }, }; /* The usage message prints the descriptions of options starting in this column. Make sure it leaves enough room for the longest description to fit in less than 80 characters. */ #define DESCRIPTION_COLUMN 30 /* List of goal targets. */ static struct dep *goals, *lastgoal; /* List of variables which were defined on the command line (or, equivalently, in MAKEFLAGS). */ struct command_variable { struct command_variable *next; struct variable *variable; }; static struct command_variable *command_variables; /* The name we were invoked with. */ char *program; /* Our current directory before processing any -C options. */ char *directory_before_chdir; /* Our current directory after processing all -C options. */ char *starting_directory; /* Value of the MAKELEVEL variable at startup (or 0). */ unsigned int makelevel; /* First file defined in the makefile whose name does not start with `.'. This is the default to remake if the command line does not specify. */ struct file *default_goal_file; /* Pointer to structure for the file .DEFAULT whose commands are used for any file that has none of its own. This is zero if the makefiles do not define .DEFAULT. */ struct file *default_file; /* Nonzero if we have seen the magic `.POSIX' target. This turns on pedantic compliance with POSIX.2. */ int posix_pedantic; /* Nonzero if some rule detected clock skew; we keep track so (a) we only print one warning about it during the run, and (b) we can print a final warning at the end of the run. */ int clock_skew_detected; /* Mask of signals that are being caught with fatal_error_signal. */ #ifdef POSIX sigset_t fatal_signal_set; #else #ifdef HAVE_SIGSETMASK int fatal_signal_mask; #endif #endif static struct file * enter_command_line_file (name) char *name; { if (name[0] == '\0') fatal (NILF, _("empty string invalid as file name")); if (name[0] == '~') { char *expanded = tilde_expand (name); if (expanded != 0) name = expanded; /* Memory leak; I don't care. */ } /* This is also done in parse_file_seq, so this is redundant for names read from makefiles. It is here for names passed on the command line. */ while (name[0] == '.' && name[1] == '/' && name[2] != '\0') { name += 2; while (*name == '/') /* Skip following slashes: ".//foo" is "foo", not "/foo". */ ++name; } if (*name == '\0') { /* It was all slashes! Move back to the dot and truncate it after the first slash, so it becomes just "./". */ do --name; while (name[0] != '.'); name[2] = '\0'; } return enter_file (xstrdup (name)); } /* Toggle -d on receipt of SIGUSR1. */ static RETSIGTYPE debug_signal_handler (sig) int sig; { debug_flag = ! debug_flag; } #ifdef WINDOWS32 /* * HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture * exception and print it to stderr instead. * * If debug_flag not set, just print a simple message and exit. * If debug_flag set, print a more verbose message. * If compiled for DEBUG, let exception pass through to GUI so that * debuggers can attach. */ LONG WINAPI handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo ) { PEXCEPTION_RECORD exrec = exinfo->ExceptionRecord; LPSTR cmdline = GetCommandLine(); LPSTR prg = strtok(cmdline, " "); CHAR errmsg[1024]; #ifdef USE_EVENT_LOG HANDLE hEventSource; LPTSTR lpszStrings[1]; #endif if (!debug_flag) { sprintf(errmsg, _("%s: Interrupt/Exception caught "), prg); sprintf(&errmsg[strlen(errmsg)], "(code = 0x%x, addr = 0x%x)\r\n", exrec->ExceptionCode, exrec->ExceptionAddress); fprintf(stderr, errmsg); exit(255); } sprintf(errmsg, _("\r\nUnhandled exception filter called from program %s\r\n"), prg); sprintf(&errmsg[strlen(errmsg)], "ExceptionCode = %x\r\n", exrec->ExceptionCode); sprintf(&errmsg[strlen(errmsg)], "ExceptionFlags = %x\r\n", exrec->ExceptionFlags); sprintf(&errmsg[strlen(errmsg)], "ExceptionAddress = %x\r\n", exrec->ExceptionAddress); if (exrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && exrec->NumberParameters >= 2) sprintf(&errmsg[strlen(errmsg)], _("Access violation: %s operation at address %x\r\n"), exrec->ExceptionInformation[0] ? _("write"): _("read"), exrec->ExceptionInformation[1]); /* turn this on if we want to put stuff in the event log too */ #ifdef USE_EVENT_LOG hEventSource = RegisterEventSource(NULL, "GNU Make"); lpszStrings[0] = errmsg; if (hEventSource != NULL) { ReportEvent(hEventSource, /* handle of event source */ EVENTLOG_ERROR_TYPE, /* event type */ 0, /* event category */ 0, /* event ID */ NULL, /* current user's SID */ 1, /* strings in lpszStrings */ 0, /* no bytes of raw data */ lpszStrings, /* array of error strings */ NULL); /* no raw data */ (VOID) DeregisterEventSource(hEventSource); } #endif /* Write the error to stderr too */ fprintf(stderr, errmsg); #ifdef DEBUG return EXCEPTION_CONTINUE_SEARCH; #else exit(255); return (255); /* not reached */ #endif } /* * On WIN32 systems we don't have the luxury of a /bin directory that * is mapped globally to every drive mounted to the system. Since make could * be invoked from any drive, and we don't want to propogate /bin/sh * to every single drive. Allow ourselves a chance to search for * a value for default shell here (if the default path does not exist). */ int find_and_set_default_shell(char *token) { int sh_found = 0; char* search_token; PATH_VAR(sh_path); extern char *default_shell; if (!token) search_token = default_shell; else search_token = token; if (!no_default_sh_exe && (token == NULL || !strcmp(search_token, default_shell))) { /* no new information, path already set or known */ sh_found = 1; } else if (file_exists_p(search_token)) { /* search token path was found */ sprintf(sh_path, "%s", search_token); default_shell = xstrdup(w32ify(sh_path,0)); if (debug_flag) printf(_("find_and_set_shell setting default_shell = %s\n"), default_shell); sh_found = 1; } else { char *p; struct variable *v = lookup_variable ("Path", 4); /* * Search Path for shell */ if (v && v->value) { char *ep; p = v->value; ep = strchr(p, PATH_SEPARATOR_CHAR); while (ep && *ep) { *ep = '\0'; if (dir_file_exists_p(p, search_token)) { sprintf(sh_path, "%s/%s", p, search_token); default_shell = xstrdup(w32ify(sh_path,0)); sh_found = 1; *ep = PATH_SEPARATOR_CHAR; /* terminate loop */ p += strlen(p); } else { *ep = PATH_SEPARATOR_CHAR; p = ++ep; } ep = strchr(p, PATH_SEPARATOR_CHAR); } /* be sure to check last element of Path */ if (p && *p && dir_file_exists_p(p, search_token)) { sprintf(sh_path, "%s/%s", p, search_token); default_shell = xstrdup(w32ify(sh_path,0)); sh_found = 1; } if (debug_flag && sh_found) printf(_("find_and_set_shell path search set default_shell = %s\n"), default_shell); } } /* naive test */ if (!unixy_shell && sh_found && (strstr(default_shell, "sh") || strstr(default_shell, "SH"))) { unixy_shell = 1; batch_mode_shell = 0; } #ifdef BATCH_MODE_ONLY_SHELL batch_mode_shell = 1; #endif return (sh_found); } #endif /* WINDOWS32 */ #ifdef __MSDOS__ static void msdos_return_to_initial_directory () { if (directory_before_chdir) chdir (directory_before_chdir); } #endif #ifndef _AMIGA int main (argc, argv, envp) int argc; char **argv; char **envp; #else int main (int argc, char ** argv) #endif { static char *stdin_nm = 0; register struct file *f; register unsigned int i; char **p; struct dep *read_makefiles; PATH_VAR (current_directory); #ifdef WINDOWS32 char *unix_path = NULL; char *windows32_path = NULL; SetUnhandledExceptionFilter(handle_runtime_exceptions); /* start off assuming we have no shell */ unixy_shell = 0; no_default_sh_exe = 1; #endif default_goal_file = 0; reading_file = 0; #if defined (__MSDOS__) && !defined (_POSIX_SOURCE) /* Request the most powerful version of `system', to make up for the dumb default shell. */ __system_flags = (__system_redirect | __system_use_shell | __system_allow_multiple_cmds | __system_allow_long_cmds | __system_handle_null_commands | __system_emulate_chdir); #endif #if !defined (HAVE_STRSIGNAL) && !defined (HAVE_SYS_SIGLIST) signame_init (); #endif #ifdef POSIX sigemptyset (&fatal_signal_set); #define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig) #else #ifdef HAVE_SIGSETMASK fatal_signal_mask = 0; #define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig) #else #define ADD_SIG(sig) #endif #endif #define FATAL_SIG(sig) \ if (signal ((sig), fatal_error_signal) == SIG_IGN) \ (void) signal ((sig), SIG_IGN); \ else \ ADD_SIG (sig); #ifdef SIGHUP FATAL_SIG (SIGHUP); #endif #ifdef SIGQUIT FATAL_SIG (SIGQUIT); #endif FATAL_SIG (SIGINT); FATAL_SIG (SIGTERM); #ifdef SIGDANGER FATAL_SIG (SIGDANGER); #endif #ifdef SIGXCPU FATAL_SIG (SIGXCPU); #endif #ifdef SIGXFSZ FATAL_SIG (SIGXFSZ); #endif #undef FATAL_SIG /* Do not ignore the child-death signal. This must be done before any children could possibly be created; otherwise, the wait functions won't work on systems with the SVR4 ECHILD brain damage, if our invoker is ignoring this signal. */ #ifdef HAVE_WAIT_NOHANG # if defined SIGCHLD (void) signal (SIGCHLD, SIG_DFL); # endif # if defined SIGCLD && SIGCLD != SIGCHLD (void) signal (SIGCLD, SIG_DFL); # endif #endif /* Make sure stdout is line-buffered. */ #ifdef HAVE_SETLINEBUF setlinebuf (stdout); #else #ifndef SETVBUF_REVERSED setvbuf (stdout, (char *) 0, _IOLBF, BUFSIZ); #else /* setvbuf not reversed. */ /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */ setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ); #endif /* setvbuf reversed. */ #endif /* setlinebuf missing. */ /* Figure out where this program lives. */ if (argv[0] == 0) argv[0] = ""; if (argv[0][0] == '\0') program = "make"; else { #ifdef VMS prog-ram = rindex (argv[0], ']'); #else program = rindex (argv[0], '/'); #endif #ifdef __MSDOS__ if (program == 0) program = rindex (argv[0], '\\'); else { /* Some weird environments might pass us argv[0] with both kinds of slashes; we must find the rightmost. */ char *p = rindex (argv[0], '\\'); if (p && p > program) program = p; } if (program == 0 && argv[0][1] == ':') program = argv[0] + 1; #endif if (program == 0) program = argv[0]; else ++program; } /* Set up to access user data (files). */ user_access (); /* Figure out where we are. */ #ifdef WINDOWS32 if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) #else if (getcwd (current_directory, GET_PATH_MAX) == 0) #endif { #ifdef HAVE_GETCWD perror_with_name ("getcwd: ", ""); #else error (NILF, "getwd: %s", current_directory); #endif current_directory[0] = '\0'; directory_before_chdir = 0; } else directory_before_chdir = xstrdup (current_directory); #ifdef __MSDOS__ /* Make sure we will return to the initial directory, come what may. */ atexit (msdos_return_to_initial_directory); #endif /* Read in variables from the environment. It is important that this be done before $(MAKE) is figured out so its definitions will not be from the environment. */ #ifndef _AMIGA for (i = 0; envp[i] != 0; ++i) { int do_not_define; register char *ep = envp[i]; /* by default, everything gets defined and exported */ do_not_define = 0; while (*ep != '=') ++ep; #ifdef WINDOWS32 if (!unix_path && strneq(envp[i], "PATH=", 5)) unix_path = ep+1; else if (!windows32_path && !strnicmp(envp[i], "Path=", 5)) { do_not_define = 1; /* it gets defined after loop exits */ windows32_path = ep+1; } #endif /* The result of pointer arithmetic is cast to unsigned int for machines where ptrdiff_t is a different size that doesn't widen the same. */ if (!do_not_define) define_variable (envp[i], (unsigned int) (ep - envp[i]), ep + 1, o_env, 1) /* Force exportation of every variable culled from the environment. We used to rely on target_environment's v_default code to do this. But that does not work for the case where an environment variable is redefined in a makefile with `override'; it should then still be exported, because it was originally in the environment. */ ->export = v_export; } #ifdef WINDOWS32 /* * Make sure that this particular spelling of 'Path' is available */ if (windows32_path) define_variable("Path", 4, windows32_path, o_env, 1)->export = v_export; else if (unix_path) define_variable("Path", 4, unix_path, o_env, 1)->export = v_export; else define_variable("Path", 4, "", o_env, 1)->export = v_export; /* * PATH defaults to Path iff PATH not found and Path is found. */ if (!unix_path && windows32_path) define_variable("PATH", 4, windows32_path, o_env, 1)->export = v_export; #endif #else /* For Amiga, read the ENV: device, ignoring all dirs */ { BPTR env, file, old; char buffer[1024]; int len; __aligned struct FileInfoBlock fib; env = Lock ("ENV:", ACCESS_READ); if (env) { old = CurrentDir (DupLock(env)); Examine (env, &fib); while (ExNext (env, &fib)) { if (fib.fib_DirEntryType < 0) /* File */ { /* Define an empty variable. It will be filled in variable_lookup(). Makes startup quite a bit faster. */ define_variable (fib.fib_FileName, strlen (fib.fib_FileName), "", o_env, 1)->export = v_export; } } UnLock (env); UnLock(CurrentDir(old)); } } #endif /* Decode the switches. */ decode_env_switches ("MAKEFLAGS", 9); #if 0 /* People write things like: MFLAGS="CC=gcc -pipe" "CFLAGS=-g" and we set the -p, -i and -e switches. Doesn't seem quite right. */ decode_env_switches ("MFLAGS", 6); #endif decode_switches (argc, argv, 0); #ifdef WINDOW5S32 if (suspend_flag) { fprintf(stderr, "%s (pid = %d)\n", argv[0], GetCurrentProcessId()); fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]); Sleep(30 * 1000); fprintf(stderr, _("done sleep(30). Continuing.\n")); } #endif /* Print version information. */ if (print_version_flag || print_data_base_flag || debug_flag) print_version (); /* `make --version' is supposed to just print the version and exit. */ if (print_version_flag) die (0); #ifndef VMS /* Set the "MAKE_COMMAND" variable to the name we were invoked with. (If it is a relative pathname with a slash, prepend our directory name so the result will run the same program regardless of the current dir. If it is a name with no slash, we can only hope that PATH did not find it in the current directory.) */ #ifdef WINDOWS32 /* * Convert from backslashes to forward slashes for * programs like sh which don't like them. Shouldn't * matter if the path is one way or the other for * CreateProcess(). */ if (strpbrk(argv[0], "/:\\") || strstr(argv[0], "..") || strneq(argv[0], "//", 2)) argv[0] = xstrdup(w32ify(argv[0],1)); #else /* WINDOWS32 */ #ifdef __MSDOS__ if (strchr (argv[0], '\\')) { char *p; argv[0] = xstrdup (argv[0]); for (p = argv[0]; *p; p++) if (*p == '\\') *p = '/'; } /* If argv[0] is not in absolute form, prepend the current directory. This can happen when Make is invoked by another DJGPP program that uses a non-absolute name. */ if (current_directory[0] != '\0' && argv[0] != 0 && (argv[0][0] != '/' && (argv[0][0] == '\0' || argv[0][1] != ':'))) argv[0] = concat (current_directory, "/", argv[0]); #else /* !__MSDOS__ */ if (current_directory[0] != '\0' && argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0) argv[0] = concat (current_directory, "/", argv[0]); #endif /* !__MSDOS__ */ #endif /* WINDOWS32 */ #endif /* The extra indirection through $(MAKE_COMMAND) is done for hysterical raisins. */ (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0); (void) define_variable ("MAKE", 4, "$(MAKE_COMMAND)", o_default, 1); if (command_variables != 0) { struct command_variable *cv; struct variable *v; unsigned int len = 0; char *value, *p; /* Figure out how much space will be taken up by the command-line variable definitions. */ for (cv = command_variables; cv != 0; cv = cv->next) { v = cv->variable; len += 2 * strlen (v->name); if (! v->recursive) ++len; ++len; len += 3 * strlen (v->value); } /* Now allocate a buffer big enough and fill it. */ p = value = (char *) alloca (len); for (cv = command_variables; cv != 0; cv = cv->next) { v = cv->variable; p = quote_as_word (p, v->name, 0); if (! v->recursive) *p++ = ':'; *p++ = '='; p = quote_as_word (p, v->value, 0); *p++ = ' '; } p[-1] = '\0'; /* Kill the final space and terminate. */ /* Define an unchangeable variable with a name that no POSIX.2 makefile could validly use for its own variable. */ (void) define_variable ("-*-command-variables-*-", 23, value, o_automatic, 0); /* Define the variable; this will not override any user definition. Normally a reference to this variable is written into the value of MAKEFLAGS, allowing the user to override this value to affect the exported value of MAKEFLAGS. In POSIX-pedantic mode, we cannot allow the user's setting of MAKEOVERRIDES to affect MAKEFLAGS, so a reference to this hidden variable is written instead. */ (void) define_variable ("MAKEOVERRIDES", 13, "${-*-command-variables-*-}", o_env, 1); } /* If there were -C flags, move ourselves about. */ if (directories != 0) for (i = 0; directories->list[i] != 0; ++i) { char *dir = directories->list[i]; if (dir[0] == '~') { char *expanded = tilde_expand (dir); if (expanded != 0) dir = expanded; } if (chdir (dir) < 0) pfatal_with_name (dir); if (dir != directories->list[i]) free (dir); } #ifdef WINDOWS32 /* * THIS BLOCK OF CODE MUST COME AFTER chdir() CALL ABOVE IN ORDER * TO NOT CONFUSE THE DEPENDENCY CHECKING CODE IN implicit.c. * * The functions in dir.c can incorrectly cache information for "." * before we have changed directory and this can cause file * lookups to fail because the current directory (.) was pointing * at the wrong place when it was first evaluated. */ no_default_sh_exe = !find_and_set_default_shell(NULL); #endif /* WINDOWS32 */ /* Figure out the level of recursion. */ { struct variable *v = lookup_variable ("MAKELEVEL", 9); if (v != 0 && *v->value != '\0' && *v->value != '-') makelevel = (unsigned int) atoi (v->value); else makelevel = 0; } /* Except under -s, always do -w in sub-makes and under -C. */ if (!silent_flag && (directories != 0 || makelevel > 0)) print_directory_flag = 1; /* Let the user disable that with --no-print-directory. */ if (inhibit_print_directory_flag) print_directory_flag = 0; /* If -R was given, set -r too (doesn't make sense otherwise!) */ if (no_builtin_variables_flag) no_builtin_rules_flag = 1; /* Construct the list of include directories to search. */ construct_include_path (include_directories == 0 ? (char **) 0 : include_directories->list); /* Figure out where we are now, after chdir'ing. */ if (directories == 0) /* We didn't move, so we're still in the same place. */ starting_directory = current_directory; else { #ifdef WINDOWS32 if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) #else if (getcwd (current_directory, GET_PATH_MAX) == 0) #endif { #ifdef HAVE_GETCWD perror_with_name ("getcwd: ", ""); #else error (NILF, "getwd: %s", current_directory); #endif starting_directory = 0; } else starting_directory = current_directory; A } (void) define_variable ("CURDIR", 6, current_directory, o_default, 0); /* Read any stdin makefiles into temporary files. */ if (makefiles != 0) { register unsigned int i; for (i = 0; i < makefiles->idx; ++i) if (makefiles->list[i][0] == '-' && makefiles->list[i][1] == '\0') { /* This makefile is standard input. Since we may re-exec and thus re-read the makefiles, we read standard input into a temporary file and read from that. */ FILE *outfile; /* Make a unique filename. */ #ifdef HAVE_MKTEMP #ifdef VMS static char name[] = "sys$scratch:GmXXXXXX"; #else static char name[] = "/tmp/GmXXXXXX"; #endif (void) mktemp (name); #else static char name[L_tmpnam]; (void) tmpnam (name); #endif if (stdin_nm) fatal (NILF, _("Makefile from standard input specified twice.")); outfile = fopen (name, "w"); if (outfile == 0) pfatal_with_name (_("fopen (temporary file)")); while (!feof (stdin)) { char buf[2048]; unsigned int n = fread (buf, 1, sizeof (buf), stdin); if (n > 0 && fwrite (buf, 1, n, outfile) != n) pfatal_with_name (_("fwrite (temporary file)")); } (void) fclose (outfile); /* Replace the name that read_all_makefiles will see with the name of the temporary file. */ { char *temp; /* SGI compiler requires alloca's result be assigned simply. */ temp = (char *) alloca (sizeof (name)); bcopy (name, temp, sizeof (name)); makefiles->list[i] = temp; } /* Make sure the temporary file will not be remade. */ stdin_nm = savestring (name, sizeof (name) -1); f = enter_file (stdin_nm); f->updated = 1; f->update_status = 0; f->command_state = cs_finished; /* Can't be intermediate, or it'll be removed too early for make re-exec. */ f->intermediate = 0; f->dontcare = 0; } } #if defined(MAKE_JOBSERVER) || !defined(HAVE_WAIT_NOHANG) '~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAIN.C;150E /* Set up to handle children dying. This must be done before reading in the makefiles so that `shell' function calls will work. If we don't have a hanging wait we have to fall back to old, broken functionality here and rely on the signal handler and counting children. If we're using the jobs pipe we need a signal handler so that SIGCHLD is not ignored; we need it to interrupt the read(2) of the jobserver pipe in job.c if we're waiting for a token. If none of these are true, we don't need a signal handler at all. */ { extern RETSIGTYPE child_handler PARAMS ((int sig)); # if defined HAVE_SIGACTION struct sigaction sa; bzero ((char *)&sa, sizeof (struct sigaction)); sa.sa_handler = child_handler; # if defined SA_INTERRUPT /* This is supposed to be the default, but what the heck... */ sa.sa_flags = SA_INTERRUPT; # endif # define HANDLESIG(s) sigaction (s, &sa, NULL) # else # define HANDLESIG(s) signal (s, child_handler) # endif /* OK, now actually install the handlers. */ # if defined SIGCHLD (void) HANDLESIG (SIGCHLD); # endif # if defined SIGCLD && SIGCLD != SIGCHLD (void) HANDLESIG (SIGCLD); # endif } #endif /* Let the user send us SIGUSR1 to toggle the -d flag during the run. */ #ifdef SIGUSR1 (void) signal (SIGUSR1, debug_signal_handler); #endif /* Define the initial list of suffixes for old-style rules. */ set_default_suffixes (); /* Define the file rules for the built-in suffix rules. These will later be converted into pattern rules. We used to do this in install_default_implicit_rules, but since that happens after reading makefiles, it results in the built-in pattern rules taking precedence over makefile-specified suffix rules, which is wrong. */ install_default_suffix_rules (); /* Define some internal and special variables. */ define_automatic_variables (); /* Set up the MAKEFLAGS and MFLAGS variables so makefiles can look at them. */ define_makeflags (0, 0); /* Define the default variables. */ define_default_variables (); /* Read all the makefiles. */ default_file = enter_file (".DEFAULT"); read_makefiles = read_all_makefiles (makefiles == 0 ? (char **) 0 : makefiles->list); #ifdef WINDOWS32 /* look one last time after reading all Makefiles */ if (no_default_sh_exe) no_default_sh_exe = !find_and_set_default_shell(NULL); if (no_default_sh_exe && job_slots != 1) { error (NILF, _("Do not specify -j or --jobs if sh.exe is not available.")); error (NILF, _("Resetting make for single job mode.")); job_slots = 1; } #endif /* WINDOWS32 */ #ifdef __MSDOS__ /* We need to know what kind of shell we will be using. */ { extern int _is_unixy_shell (const char *_path); struct variable *shv = lookup_variable ("SHELL", 5); extern int unixy_shell; extern char *default_shell; if (shv && *shv->value) { char *shell_path = recursively_expand(shv); if (shell_path && _is_unixy_shell (shell_path)) unixy_shell = 1; else unixy_shell = 0; if (shell_path) default_shell = shell_path; } } #endif /* __MSDOS__ */ /* Decode switches again, in case the variables were set by the makefile. */ decode_env_switches ("MAKEFLAGS", 9); #if 0 decode_env_switches ("MFLAGS", 6); #endif #ifdef __MSDOS__ if (job_slots != 1) { error (NILF, _("Parallel jobs (-j) are not supported on this platform.")); error (NILF, _("Resetting to single job (-j1) mode.")); job_slots = 1; } #endif #ifdef MAKE_JOBSERVER /* If the jobserver-fds option is seen, make sure that -j is reasonable. */ if (jobserver_fds) { char *cp; for (i=1; i < jobserver_fds->idx; ++i) if (!streq (jobserver_fds->list[0], jobserver_fds->list[i])) fatal (NILF, _("internal error: multiple --jobserver-fds options")); /* Now parse the fds string and make sure it has the proper format. */ cp = jobserver_fds->list[0]; if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2) fatal (NILF, _("internal error: invalid --jobserver-fds string `%s'"), cp); /* The combination of a pipe + !job_slots means we're using the jobserver. If !job_slots and we don't have a pipe, we can start infinite jobs. If we see both a pipe and job_slots >0 that means the user set -j explicitly. This is broken; in this case obey the user (ignore the jobserver pipe for this make) but print a message. */ if (job_slots > 0) error (NILF, _("warning: -jN forced in submake: disabling jobserver mode.")); /* Create a duplicate pipe, that will be closed in the SIGCHLD handler. If this fails with EBADF, the parent has closed the pipe on us because it didn't think we were a submake. If so, print a warning then default to -j1. */ else if ((job_rfd = dup (job_fds[0])) < 0) { if (errno != EBADF) pfatal_with_name (_("dup jobserver")); error (NILF, _("warning: jobserver unavailable: using -j1. Add `+' to parent make rule.")); job_slots = 1; } if (job_slots > 0) { close (job_fds[0]); close (job_fds[1]); job_fds[0] = job_fds[1] = -1; free (jobserver_fds->list); free (jobserver_fds); jobserver_fds = 0; } } /* If we have >1 slot but no jobserver-fds, then we're a top-level make. Set up the pipe and install the fds option for our children. */ if (job_slots > 1) { char c = '+'; if (pipe (job_fds) < 0 || (job_rfd = dup (job_fds[0])) < 0) pfatal_with_name (_("creating jobs pipe")); /* Every make assumes that it always has one job it can run. For the submakes it's the token they were given by their parent. For the top make, we just subtract one from the number the user wants. We want job_slots to be 0 to indicate we're using the jobserver. */ while (--job_slots) while (write (job_fds[1], &c, 1) != 1) if (!EINTR_SET) pfatal_with_name (_("init jobserver pipe")); /* Fill in the jobserver_fds struct for our children. */ jobserver_fds = (struct stringlist *) xmalloc (sizeof (struct stringlist)); jobserver_fds->list = (char **) xmalloc (sizeof (char *)); jobserver_fds->list[0] = xmalloc ((sizeof ("1024")*2)+1); sprintf (jobserver_fds->list[0], "%d,%d", job_fds[0], job_fds[1]); jobserver_fds->idx = 1; jobserver_fds->max = 1; } #endif /* Set up MAKEFLAGS and MFLAGS again, so they will be right. */ define_makeflags (1, 0); /* Make each `struct dep' point at the `struct file' for the file depended on. Also do magic for special targets. */ snap_deps (); /* Convert old-style suffix rules to pattern rules. It is important to do this before installing the built-in pattern rules below, so that makefile-specified suffix rules take precedence over built-in pattern rules. */ convert_to_pattern (); /* Install the default implicit pattern rules. This used to be done before reading the makefiles. But in that case, built-in pattern rules were in the chain before user-defined ones, so they matched first. */ install_default_implicit_rules (); /* Compute implicit rule limits. */ count_implicit_rule_limits (); /* Construct the listings of directories in VPATH lists. */ build_vpath_lists (); /* Mark files given with -o flags as very old (00:00:01.00 Jan 1, 1970) and as having been updated already, and files given with -W flags as brand new (time-stamp as far as possible into the future). */ if (old_files != 0) for (p = old_files->list; *p != 0; ++p) { f = enter_command_line_file (*p); f->last_mtime = f->mtime_before_update = (FILE_TIMESTAMP) 1; f->updated = 1; f->update_status = 0; f->command_state = cs_finished; } if (new_files != 0) { for (p = new_files->list; *p != 0; ++p) { f = enter_command_line_file (*p); f->last_mtime = f->mtime_before_update = NEW_MTIME; } } /* Initialize the remote job module. */ remote_setup (); if (read_makefiles != 0) { /* Update any makefiles if necessary. */ FILE_TIMESTAMP *makefile_mtimes = 0; unsigned int mm_idx = 0; char **nargv = argv; int nargc = argc; if (debug_flag) puts (_("Updating makefiles....")); /* Remove any makefiles we don't want to try to update. Also record the current modtimes so we can compare them later. */ { register struct dep *d, *last; last = 0; d = read_makefiles; while (d != 0) { register struct file *f = d->file; if (f->double_colon) for (f = f->double_colon; f != NULL; f = f->prev) { if (f->deps == 0 && f->cmds != 0) { /* This makefile is a :: target with commands, but no dependencies. So, it will always be remade. This might well cause an infinite loop, so don't try to remake it. (This will only happen if your makefiles are written exceptionally stupidly; but if you work for Athena, that's how you write your makefiles.) */ if (debug_flag) printf (_("Makefile `%s' might loop; not remaking it.\n"), f->name); if (last == 0) read_makefiles = d->next; else last->next = d->next; /* Free the storage. */ free ((char *) d); d = last == 0 ? read_makefiles : last->next; break; } } if (f == NULL || !f->double_colon) { makefile_mtimes = (FILE_TIMESTAMP *) xrealloc ((char *) makefile_mtimes, (mm_idx + 1) * sizeof (FILE_TIMESTAMP)); makefile_mtimes[mm_idx++] = file_mtime_no_search (d->file); last = d; d = d->next; } } } /* Set up `MAKEFLAGS' specially while remaking makefiles. */ define_makeflags (1, 1); switch (update_goal_chain (read_makefiles, 1)) { case 1: default: #define BOGUS_UPDATE_STATUS 0 assert (BOGUS_UPDATE_STATUS); break; case -1: /* Did nothing. */ break; case 2: /* Failed to update. Figure out if we care. */ { /* Nonzero if any makefile was successfully remade. */ int any_remade = 0; /* Nonzero if any makefile we care about failed in updating or could not be found at all. */ int any_failed = 0; register unsigned int i; struct dep *d; for (i = 0, d = read_makefiles; d != 0; ++i, d = d->next) { /* Reset the considered flag; we may need to look at the file again to print an error. */ d->file->considered = 0; if (d->file->updated) { /* This makefile was updated. */ if (d->file->update_status == 0) { /* It was successfully updated. */ any_remade |= (file_mtime_no_search (d->file) != makefile_mtimes[i]); } else if (! (d->changed & RM_DONTCARE)) { FILE_TIMESTAMP mtime; /* The update failed and this makefile was not from the MAKEFILES variable, so we care. */ error (NILF, _("Failed to remake makefile `%s'."), d->file->name); mtime = file_mtime_no_search (d->file); any_remade |= (mtime != (FILE_TIMESTAMP) -1 && mtime != makefile_mtimes[i]); } } else /* This makefile was not found at all. */ if (! (d->changed & RM_DONTCARE)) { /* This is a makefile we care about. See how much. */ if (d->changed & RM_INCLUDED) /* An included makefile. We don't need ] to die, but we do want to complain. */ error (NILF, _("Included makefile `%s' was not found."), dep_name (d)); else { /* A normal makefile. We must die later. */ error (NILF, _("Makefile `%s' was not found"), dep_name (d)); any_failed = 1; } } } /* Reset this to empty so we get the right error message below. */ read_makefiles = 0; if (any_remade) goto re_exec; if (any_failed) die (2); break; } case 0: re_exec: /* Updated successfully. Re-exec ourselves. */ remove_intermediates (0); if (print_data_base_flag) print_data_base (); log_working_directory (0); if (makefiles != 0) { /* These names might have changed. */ register unsigned int i, j = 0; for (i = 1; i < argc; ++i) if (strneq (argv[i], "-f", 2)) /* XXX */ { char *p = &argv[i][2]; if (*p == '\0') argv[++i] = makefiles->list[j]; else argv[i] = concat ("-f", makefiles->list[j], ""); ++j; } } /* Add -o option for the stdin temporary file, if necessary. */ if (stdin_nm) { nargv = (char **) xmalloc ((nargc + 2) * sizeof (char *)); bcopy ((char *) argv, (char *) nargv, argc * sizeof (char *)); nargv[nargc++] = concat ("-o", stdin_nm, ""); nargv[nargc] = 0; } if (directories != 0 && directories->idx > 0) { char bad; if (directory_before_chdir != 0) { if (chdir (directory_before_chdir) < 0) { perror_with_name ("chdir", ""); bad = 1; } else bad = 0; } else bad = 1; if (bad) fatal (NILF, _("Couldn't change back to original directory.")); } #ifndef _AMIGA for (p = environ; *p != 0; ++p) if (strneq (*p, "MAKELEVEL=", 10)) { /* The SGI compiler apparently can't understand the concept of storing the result of a function in something other than a local variable. */ char *sgi_loses; sgi_loses = (char *) alloca (40); *p = sgi_loses; sprintf (*p, "MAKELEVEL=%u", makelevel); break; } #else /* AMIGA */ { char buffer[256]; int len; len = GetVar ("MAKELEVEL", buffer, sizeof (buffer), GVF_GLOBAL_ONLY); if (len != -1) { sprintf (buffer, "%u", makelevel); SetVar ("MAKELEVEL", buffer, -1, GVF_GLOBAL_ONLY); } } #endif if (debug_flag) { char **p; fputs (_("Re-executing:"), stdout); for (p = nargv; *p != 0; ++p) printf (" %s", *p); puts (""); } fflush (stdout); fflush (stderr); /* Close the dup'd jobserver pipe if we opened one. */ if (job_rfd >= 0) close (job_rfd); #ifndef _AMIGA exec_command (nargv, environ); #else exec_command (nargv); exit (0); #endif /* NOTREACHED */ } } /* Set up `MAKEFLAGS' again for the normal targets. */ define_makeflags (1, 0); /* If there is a temp file from reading a makefile from stdin, get rid of it now. */ if (stdin_nm && unlink (stdin_nm) < 0 && errno != ENOENT) perror_with_name (_("unlink (temporary file): "), stdin_nm); { int status; /* If there were no command-line goals, use the default. */ if (goals == 0) { if (default_goal_file != 0) { goals = (struct dep *) xmalloc (sizeof (struct dep)); goals->next = 0; goals->name = 0; goals->file = default_goal_file; } } else lastgoal->next = 0; if (!goals) { if (read_makefiles == 0) fatal (NILF, _("No targets specified and no makefile found")); fatal (NILF, _("No targets")); } /* Update the goals. */ if (edebug_flag) puts (_("Updating goal targets....")); switch (update_goal_chain (goals, 0)) { case -1: /* Nothing happened. */ case 0: /* Updated successfully. */ status = EXIT_SUCCESS; break; case 2: /* Updating failed. POSIX.2 specifies exit status >1 for this; but in VMS, there is only success and failure. */ status = EXIT_FAILURE ? 2 : EXIT_FAILURE; break; case 1: /* We are under -q and would run some commands. */ status = EXIT_FAILURE; break; default: abort (); } /* If we detected some clock skew, generate one last warning */ if (clock_skew_detected) error (NILF, _("*** Warning: Clock skew detected. Your build may be incomplete.")); /* Exit. */ die (status); } return 0; } /* Parsing of arguments, decoding of switches. */ static char options[1 + sizeof (switches) / sizeof (switches[0]) * 3]; static struct option long_options[(sizeof (switches) / sizeof (switches[0])) + (sizeof (long_option_aliases) / sizeof (long_option_aliases[0]))]; /* Fill in the string and vector for getopt. */ static void init_switches () { register char *p; register int c; register unsigned int i; if (options[0] != '\0') /* Already done. */ return; p = options; /* Return switch and non-switch args in order, regardless of POSIXLY_CORRECT. Non-switch args are returned as option 1. */ *p++ = '-'; for (i = 0; switches[i].c != '\0'; ++i) { long_options[i].name = (switches[i].long_name == 0 ? "" : switches[i].long_name); long_options[i].flag = 0; long_options[i].val = switches[i].c; if (short_option (switches[i].c)) *p++ = switches[i].c; switch (switches[i].type) { case flag: case flag_off: case ignore: long_options[i].has_arg = no_argument; break; case string: case positive_int: case floating: if (short_option (switches[i].c)) *p++ = ':'; ifi (switches[i].noarg_value != 0) { if (short_option (switches[i].c)) *p++ = ':'; long_options[i].has_arg = optional_argument; } else long_options[i].has_arg = required_argument; break; } } *p = '\0'; for (c = 0; c < (sizeof (long_option_aliases) / sizeof (long_option_aliases[0])); ++c) long_options[i++] = long_option_aliases[c]; long_options[i].name = 0; } static void handle_non_switch_argument (arg, env) char *arg; int env; { /* Non-option argument. It might be a variable definition. */ struct variable *v; if (arg[0] == '-' && arg[1] == '\0') /* Ignore plain `-' for compatibility. */ return; v = try_variable_definition (0, arg, o_command); if (v != 0) { /* It is indeed a variable definition. Record a pointer to the variable for later use in define_makeflags. */ struct command_variable *cv = (struct command_variable *) xmalloc (sizeof (*cv)); cv->variable = v; cv->next = command_variables; command_variables = cv; } else if (! env) { /* Not an option or variable definition; it must be a goal target! Enter it as a file and add it to the dep chain of goals. */ struct file *f = enter_command_line_file (arg); f->cmd_target = 1; if (goals == 0) { goals = (struct dep *) xmalloc (sizeof (struct dep)); lastgoal = goals; } else { lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep)); lastgoal = lastgoal->next; } lastgoal->name = 0; lastgoal->file = f; { /* Add this target name to the MAKECMDGOALS variable. */ struct variable *v; char *value; v = lookup_variable ("MAKECMDGOALS", 12); if (v == 0) value = f->name; else { /* Paste the old and new values together */ unsigned int oldlen, newlen; oldlen = strlen (v->value); newlen = strlen (f->name); value = (char *) alloca (oldlen + 1 + newlen + 1); bcopy (v->value, value, oldlen); value[oldlen] = ' '; bcopy (f->name, &value[oldlen + 1], newlen + 1); } define_variable ("MAKECMDGOALS", 12, value, o_default, 0); } } } /* Print a nice usage method. */ static void print_usage (bad) int bad; { register const struct command_switch *cs; FILE *usageto; if (print_version_flag) print_version (); usageto = bad ? stderr : stdout; fprintf (usageto, _("Usage: %s [options] [target] ...\n"), program); fputs (_("Options:\n"), usageto); for (cs = switches; cs->c != '\0'; ++cs) { char buf[1024], shortarg[50], longarg[50], *p; if (!cs->description || cs->description[0] == '-') continue; switch (long_options[cs - switches].has_arg) { case no_argument: shortarg[0] = longarg[0] = '\0'; break; case required_argument: sprintf (longarg, "=%s", cs->argdesc); sprintf (shortarg, " %s", cs->argdesc); break; case optional_argument: sprintf (longarg, "[=%s]", cs->argdesc); sprintf (shortarg, " [%s]", cs->argdesc); break; } p = buf; if (short_option (cs->c)) { sprintf (buf, " -%c%s", cs->c, shortarg); p += strlen (p); } if (cs->long_name != 0) { unsigned int i; sprintf (p, "%s--%s%s", !short_option (cs->c) ? " " : ", ", cs->long_name, longarg); p += strlen (p); for (i = 0; i < (sizeof (long_option_aliases) / sizeof (long_option_aliases[0])); ++i) if (long_option_aliases[i].val == cs->c) { sprintf (p, ", --%s%s", long_option_aliases[i].name, longarg); p += strlen (p); } } { const struct command_switch *ncs = cs; while ((++ncs)->c != '\0') if (ncs->description && ncs->description[0] == '-' && ncs->description[1] == cs->c) { /* This is another switch that does the same one as the one we are processing. We want to list them all together on one line. */ sprintf (p, ", -%c%s", ncs->c, shortarg); p += strlen (p); if (ncs->long_name != 0) { sprintf (p, ", --%s%s", ncs->long_name, longarg); p += strlen (p); } } } if (p - buf > DESCRIPTION_COLUMN - 2) /* The list of option names is too long to fit on the same line with the description, leaving at least two spaces. Print it on its own line instead. */ { fprintf (usageto, "%s\n", buf); buf[0] = '\0'; } fprintf (usageto, "%*s%s.\n", - DESCRIPTION_COLUMN, buf, cs->description); } } /* Decode switches from ARGC and ARGV. They came from the environment if ENV is nonzero. */ static void decode_switches (argc, argv, env) int argc; char **argv; int env; { int bad = 0; register const struct command_switch *cs; register struct stringlist *sl; register int c; /* getopt does most of the parsing for us. First, get its vectors set up. */ init_switches (); /* Let getopt produce error messages for the command line, but not for options from the environment. */ opterr = !env; /* Reset getopt's state. */ optind = 0; while (optind < argc) { /* Parse the next argument. */ c = getopt_long (argc, argv, options, long_options, (int *) 0); if (c == EOF) /* End of arguments, or "--" marker seen. */ break; else if (c == 1) /* An argument not starting with a dash. */ handle_non_switch_argument (optarg, env); else if (c == '?') /* Bad option. We will print a usage message and die later. But continue to parse the other options so the user can see all he did wrong. */ bad = 1; else for (cs = switches; cs->c != '\0'; ++cs) if (cs->c == c) { /* Whether or not we will actually do anything with this switch. We test this individually inside the switch below rather than just once outside it, so that options which are to be ignored still consume args. */ int doit = !env || cs->env; switch (cs->type) { default: abort (); u case ignore: break; case flag: case flag_off: if (doit) *(int *) cs->value_ptr = cs->type == flag; break; case string: if (!doit) break; if (optarg == 0) optarg = cs->noarg_value; sl = *(struct stringlist **) cs->value_ptr; if (sl == 0) { sl = (struct stringlist *) xmalloc (sizeof (struct stringlist)); sl->max = 5; sl->idx = 0; sl->list = (char **) xmalloc (5 * sizeof (char *)); *(struct stringlist **) cs->value_ptr = sl; } else if (sl->idx == sl->max - 1) { sl->max += 5; sl->list = (char **) xrealloc ((char *) sl->list, sl->max * sizeof (char *)); } sl->list[sl->idx++] = optarg; sl->list[sl->idx] = 0; break; case positive_int: if (optarg == 0 && argc > optind && ISDIGIT (argv[optind][0])) optarg = argv[optind++]; if (!doit) break; if (optarg != 0) { int i = atoi (optarg); if (i < 1) { if (doit) error (NILF, _("the `-%c' option requires a positive integral argument"), cs->c); bad = 1; } else *(unsigned int *) cs->value_ptr = i; } else *(unsigned int *) cs->value_ptr = *(unsigned int *) cs->noarg_value; break; #ifndef NO_FLOAT case floating: if (optarg == 0 && optind < argc && (ISDIGIT (argv[optind][0]) || argv[optind][0] == '.')) optarg = argv[optind++]; if (doit) *(double *) cs->value_ptr = (optarg != 0 ? atof (optarg) : *(double *) cs->noarg_value); break; #endif } /* We've found the switch. Stop looking. */ break; } } /* There are no more options according to getting getopt, but there may be some arguments left. Since we have asked for non-option arguments to be returned in order, this only happens when there is a "--" argument to prevent later arguments from being options. */ while (optind < argc) handle_non_switch_argumyent (argv[optind++], env); if (!env && (bad || print_usage_flag)) { print_usage (bad); die (bad ? 2 : 0); } } /* Decode switches from environment variable ENVAR (which is LEN chars long). We do this by chopping the value into a vector of words, prepending a dash to the first word if it lacks one, and passing the vector to decode_switches. */ static void decode_env_switches (envar, len) char *envar; unsigned int len; { char *varref = (char *) alloca (2 + len + 2); char *value, *p; int argc; char **argv; /* Get the variable's value. */ varref[0] = '$'; varref[1] = '('; bcopy (envar, &varref[2], len); varref[2 + len] = ')'; varref[2 + len + 1] = '\0'; value = variable_expand (varref); /* Skip whitespace, and check for an empty value. */ value = next_token (value); len = strlen (value); if (len == 0) return; /* Allocate a vector that is definitely big enough. */ argv = (char **) alloca ((1 + len + 1) * sizeof (char *)); /* Allocate a buffer to copy the value into while we split it into words and unquote it. We must use permanent storage for this because decode_switches may store pointers into the passed argument words. */ p = (char *) xmalloc (2 * len); /* getopt will look at the arguments starting at ARGV[1]. Prepend a spacer word. */ argv[0] = 0; argc = 1; argv[argc] = p; while (*value != '\0') { if (*value == '\\') ++value; /* Skip the backslash. */ else if (isblank (*value)) { /* End of the word. */ *p++ = '\0'; argv[++argc] = p; do ++value; while (isblank (*value)); continue; } *p++ = *value++; } *p = '\0'; argv[++argc] = 0; if (argv[1][0] != '-' && index (argv[1], '=') == 0) /* The first word doesn't start with a dash and isn't a variable definition. Add a dash and pass it along to decode_switches. We need permanent storage for this in case decode_switches saves pointers into the value. */ argv[1] = concat ("-", argv[1], ""); /* Parse those words. */ decode_switches (argc, argv, 1); } /* Quote the string IN so that it will be interpreted as a single word with no magic by the shell; if DOUBLE_DOLLARS is nonzero, also double dollar signs to avoid variable expansion in make itself. Write the result into OUT, returning the address of the next character to be written. Allocating space for OUT twice the length of IN (thrice if DOUBLE_DOLLARS is nonzero) is always sufficient. */ static char * quote_as_word (out, in, double_dollars) char *out, *in; int double_dollars; { while (*in != '\0') { #ifdef VMS if (index ("^;'\"*?$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0) #else if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0) #endif *out++ = '\\'; if (double_dollars && *in == '$') *out++ = '$'; *out++ = *in++; } return out; } /* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the command switches. Include options with args if ALL is nonzero. Don't include options with the `no_makefile' flag set if MAKEFILE. */ static void define_makeflags (all, makefile) int all, makefile; { static const char ref[] = "$(MAKEOVERRIDES)"; static const char posixref[] = "$(-*-command-variables-*-)"; register const struct command_switch *cs; char *flagstring; register char *p; unsigned int words; struct variable *v; /* We will construct a linked list of `struct flag's describing all the flags which need to go in MAKEFLAGS. Then, once we know how many there are and their lengths, we can put them all together in a string. */ struct flag { struct flag *next; const struct command_switch *cs; char *arg; }; struct flag *flags = 0; unsigned int flagslen = 0; #define ADD_FLAG(ARG, LEN) \ do { \ struct flag *new = (struct flag *) alloca (sizeof (struct flag)); \ new->cs = cs; \ new->arg = (ARG); \ new->next = flags; \ flags = new; \ if (new->arg == 0) \ ++flagslen; /* Just a single flag letter. */ \ else \ flagslen += 1 + 1 + 1 + 1 + 3 * (LEN); /* " -x foo" */ \ if (!short_option (cs->c)) \ /* This switch has no single-letter version, so we use the long. */ \ flagslen += 2 + strlen (cs->long_name); \ } while (0) for (cs = switches; cs->c != '\0'; ++cs) if (cs->toenv && (!makefile || !cs->no_makefile)) switch (cs->type) { default: abort (); case ignore: break; case flag: case flag_off: if (!*(int *) cs->value_ptr == (cs->type == flag_off) && (cs->default_value == 0 || *(int *) cs->value_ptr != *(int *) cs->default_value)) ADD_FLAG (0, 0); break; case positive_int: if (all) { if ((cs->default_value != 0 && (*(unsigned int *) cs->value_ptr == *(unsigned int *) cs->default_value))) break; else if (cs->noa(~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAIN.C;1 rg_value != 0 && (*(unsigned int *) cs->value_ptr == *(unsigned int *) cs->noarg_value)) ADD_FLAG ("", 0); /* Optional value omitted; see below. */ else if (cs->c == 'j') /* Special case for `-j'. */ ADD_FLAG ("1", 1); else { char *buf = (char *) alloca (30); sprintf (buf, "%u", *(unsigned int *) cs->value_ptr); ADD_FLAG (buf, strlen (buf)); } } break; #ifndef NO_FLOAT case floating: if (all) { if (cs->default_value != 0 && (*(double *) cs->value_ptr == *(double *) cs->default_value)) break; else if (cs->noarg_value != 0 && (*(double *) cs->value_ptr == *(double *) cs->noarg_value)) ADD_FLAG ("", 0); /* Optional value omitted; see below. */ else { char *buf = (char *) alloca (100); sprintf (buf, "%g", *(double *) cs->value_ptr); ADD_FLAG (buf, strlen (buf)); } } break; #endif case string: if (all) { struct stringlist *sl = *(struct stringlist **) cs->value_ptr; if (sl != 0) { /* Add the elements in reverse order, because all the flags get reversed below; and the order matters for some switches (like -I). */ register unsigned int i = sl->idx; while (i-- > 0) ADD_FLAG (sl->list[i], strlen (sl->list[i])); } } break; } flagslen += 4 + sizeof posixref; /* Four more for the possible " -- ". */ #undef ADD_FLAG /* Construct the value in FLAGSTRING. We allocate enough space for a preceding dash and trailing null. */ flagstring = (char *) alloca (1 + flagslen + 1); bzero (flagstring, 1 + flagslen + 1); p = flagstring; words = 1; *p++ = '-'; while (flags != 0) { /* Add the flag letter or name to the string. */ if (short_option (flags->cs->c)) *p++ = flags->cs->c; else { if (*p != '-') { *p++ = ' '; *p++ = '-'; } *p++ = '-'; strcpy (p, flags->cs->long_name); p += strlen (p); } if (flags->arg != 0) { /* A flag that takes an optional argument which in this case is omitted is specified by ARG being "". We must distinguish because a following flag appended without an intervening " -" is considered the arg for the first. */ if (flags->arg[0] != '\0') { /* Add its argument too. */ *p++ = !short_option (flags->cs->c) ? '=' : ' '; p = quote_as_word (p, flags->arg, 1); } ++words; /* Write a following space and dash, for the next flag. */ *p++ = ' '; *p++ = '-'; } else if (!short_option (flags->cs->c)) { ++words; /* Long options must each go in their own word, so we write the following space and dash. */ *p++ = ' '; *p++ = '-'; } flags = flags->next; } /* Define MFLAGS before appending variable definitions. */ if (p == &flagstring[1]) /* No flags. */ flagstring[0] = '\0'; else if (p[-1] == '-') { /* Kill the final space and dash. */ p -= 2; *p = '\0'; } else /* Terminate the string. */ *p = '\0'; /* Since MFLAGS is not parsed for flags, there is no reason to override any makefile redefinition. */ (void) define_variable ("MFLAGS", 6, flagstring, o_env, 1); if (all && command_variables != 0) { /* Now write a reference to $(MAKEOVERRIDES), which contains all the command-line variable definitions. */ if (p == &flagstring[1]) /* No flags written, so elide the leading dash already written. */ p = flagstring; else { /* Separate the variables from the switches with a "--" arg. */ if (p[-1] != '-') { /* We did not already write a trailing " -". */ *p++ = ' '; *p++ = '-'; } /* There is a trailing " -"; fill it out to " -- ". */ *p++ = '-'; *p++ = ' '; } /* Copy in the string. */ if (posix_pedantic) { bcopy (posixref, p, sizeof posixref - 1); p += sizeof posixref - 1; } else { bcopy (ref, p, sizeof ref - 1); p += sizeof ref - 1; } } else if (p == &flagstring[1]) { words = 0; --p; } else if (p[-1] == '-') /* Kill the final space and dash. */ p -= 2; /* Terminate the string. */ *p = '\0'; v = define_variable ("MAKEFLAGS", 9, /* If there are switches, omit the leading dash unless it is a single long option with two leading dashes. */ &flagstring[(flagstring[0] == '-' && flagstring[1] != '-') ? 1 : 0], /* This used to use o_env, but that lost when a makefile defined MAKEFLAGS. Makefiles set MAKEFLAGS to add switches, but we still want to redefine its value with the full set of switches. Of course, an override or command definition will still take precedence. */ o_file, 1); if (! all) /* The first time we are called, set MAKEFLAGS to always be exported. We should not do this again on the second call, because that is after reading makefiles which might have done `unexport MAKEFLAGS'. */ v->export = v_export; } /* Print version information. */ static void print_version () { extern char *make_host; static int printed_version = 0; char *precede = print_data_base_flag ? "# " : ""; if (printed_version) /* Do it only once. */ return; printf ("%sGNU Make version %s", precede, version_string); if (remote_description != 0 && *remote_description != '\0') printf ("-%s", remote_description); printf (_(", by Richard Stallman and Roland McGrath.\n\ %sBuilt for %s\n\ %sCopyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99\n\ %s\tFree Software Foundation, Inc.\n\ %sThis is free software; see the source for copying conditions.\n\ %sThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ %sPARTICULAR PURPOSE.\n\n\ %sReport bugs to .\n\n"), precede, make_host, precede, precede, precede, precede, precede, precede); printed_version = 1; /* Flush stdout so the user doesn't have to wait to see the version information while things are thought about. */ fflush (stdout); } /* Print a bunch of information about this and that. */ static void print_data_base () { time_t when; when = time ((time_t *) 0); printf (_("\n# Make data base, printed on %s"), ctime (&when)); print_variable_data_base (); print_dir_data_base (); print_rule_data_base (); print_file_data_base (); print_vpath_data_base (); when = time ((time_t *) 0); printf (_("\n# Finished Make data base on %s\n"), ctime (&when)); } /* Exit with STATUS, cleaning up as necessary. */ void die (status) int status; { static char dying = 0; if (!dying) { int err; dying = 1; if (print_version_flag) print_version (); /* Wait for children to die. */ for (err = status != 0; job_slots_used > 0; err = 0) reap_children (1, err); /* Let the remote job module clean up its state. */ remote_cleanup (); /* Remove the intermediate files. */ remove_intermediates (0); if (print_data_base_flag) print_data_base (); /* Try to move back to the original directory. This is essential on MS-DOS (where there is really only one process), and on Unix it puts core files in the original directory instead of the -C directory. Must wait until after remove_intermediates(), or unlinks of relative pathnames fail. */ if (directory_before_chdir != 0) chdir (directory_before_chdir); log_working_directory (0); } exit (status); } /* Write a message indicating that we've just entered or left (according to ENTERING) the current directory. */ void log_working_directory (entering) int entering; { static int entered = 0; char *msg = entering ? _("Entering") : _("Leaving"); /* Print nothing without the flag. Don't print the entering message again if we already have. Don't print the leaving message if we haven't printed the entering message. */ if (! print_directory_flag || entering == entered) return; entered = entering; if (print_data_base_flag) fputs ("# ", stdout); if (makelevel == 0) printf ("%s: %s ", program, msg); else printf ("%s[%u]: %s ", program, makelevel, msg); if (starting_directory == 0) puts (_("an unknown directory")); else printf (_("directory `%s'\n"), starting_directory); } *[MAKE-3_78_1HB]MAKE-STDS.TEXI;1+,c.H/@ 4HH-`0123KPWOI567m89G@HJ@@comment This file is included by both standards.texi and make.texinfo. @comment It was broken out of standards.texi on 1/6/93 by roland. @node Makefile Conventions @chapter Makefile Conventions @comment standards.texi does not print an index, but make.texinfo does. @cindex makefile, conventions for @cindex conventions for makefiles @cindex standards for makefiles This @ifinfo node @end ifinfo @iftex @ifset CODESTD section @end ifset @ifclear CODESTD chapter @end ifclear @end iftex describes conventions for writing the Makefiles for GNU programs. Using Automake will help you write a Makefile that follows these conventions. @menu * Makefile Basics:: General Conventions for Makefiles * Utilities in Makefiles:: Utilities in Makefiles * Command Variables:: Variables for Specifying Commands * Directory Variables:: Variables for Installation Directories * Standard Targets:: Standard Targets for Users * Install Command Categories:: Three categories of commands in the `install' rule: normal, pre-install and post-install. @end menu @node Makefile Basics @section General Conventions for Makefiles Every Makefile should contain this line: @example SHELL = /bin/sh @end example @noindent to avoid trouble on systems where the @code{SHELL} variable might be inherited from the environment. (This is never a problem with GNU @code{make}.) Different @code{make} programs have incompatible suffix lists and implicit rules, and this sometimes creates confusion or misbehavior. So it is a good idea to set the suffix list explicitly using only the suffixes you need in the particular Makefile, like this: @example .SUFFIXES: .SUFFIXES: .c .o @end example @noindent The first line clears out the suffix list, the second introduces all suffixes which may be subject to implicit rules in this Makefile. Don't assume that @file{.} is in the path for command execution. When you need to run programs that are a part of your package during the make, please make sure that it uses @file{./} if the program is built as part of the make or @file{$(srcdir)/} if the file is an unchanging part of the source code. Without one of these prefixes, the current search path is used. The distinction between @file{./} (the @dfn{build directory}) and @file{$(srcdir)/} (the @dfn{source directory}) is important because users can build in a separate directory using the @samp{--srcdir} option to @file{configure}. A rule of the form: @smallexample foo.1 : foo.man sedscript sed -e sedscript foo.man > foo.1 @end smallexample @noindent will fail when the build directory is not the source directory, because @file{foo.man} and @file{sedscript} are in the the source directory. When using GNU @code{make}, relying on @samp{VPATH} to find the source file will work in the case where there is a single dependency file, since the @code{make} automatic variable @samp{$<} will represent the source file wherever it is. (Many versions of @code{make} set @samp{$<} only in implicit rules.) A Makefile target like @smallexample foo.o : bar.c $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o @end smallexample @noindent should instead be written as @smallexample foo.o : bar.c $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@ @end smallexample @noindent in order to allow @samp{VPATH} to work correctly. When the target has multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest way to make the rule work well. For example, the target above for @file{foo.1} is best written as: @smallexample foo.1 : foo.man sedscript sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@ @end smallexample GNU distributions usually contain some files which are not source files---for example, Info files, and the output from Autoconf, Automake, Bison or Flex. Since these files normally appear in the source directory, they should always appear in the source directory, not in the build directory. So Makefile rules to update them should put the updated files in the source directory. However, if a file does not appear in the distribution, then the Makefile should not put it in the source directory, because building a program in ordinary circumstances should not modify the source directory in any way. Try to make the build and installation targets, at least (and all their subtargets) work correctly with a parallel @code{make}. @node Utilities in Makefiles @section Utilities in Makefiles Write the Makefile commands (and any shell scripts, such as @code{configure}) to run in @code{sh}, not in @code{csh}. Don't use any special features of @code{ksh} or @code{bash}. The @code{configure} script and the Makefile rules for building and installation should not use any utilities directly except these: @c dd find @c gunzip gzip md5sum @c mkfifo mknod tee uname @example cat cmp cp diff echo egrep expr false grep install-info ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true @end example The compression program @code{gzip} can be used in the @code{dist} rule. Stick to the generally supported options for these programs. For example, don't use @samp{mkdir -p}, convenient as it may be, because most systems don't support it. It is a good idea to avoid creating symbolic links in makefiles, since a few systems don't support them. The Makefile rules for building and installation can also use compilers and related programs, but should do so via @code{make} variables so that the user can substitute alternatives. Here are some of the programs we mean: @example ar bison cc flex install ld ldconfig lex make makeinfo ranlib texi2dvi yacc @end example Use the following @code{make} variables to run those programs: @example $(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX) $(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC) @end example When you use @code{ranlib} or @code{ldconfig}, you should make sure nothing bad happens if the system does not have the program in question. Arrange to ignore an error from that command, and print a message before the command to tell the user that failure of this command does not mean a problem. (The Autoconf @samp{AC_PROG_RANLIB} macro can help with this.) If you use symbolic links, you should implement a fallback for systems that don't have symbolic links. Additional utilities that can be used via Make variables are: @example chgrp chmod chown mknod @end example It is ok to use other utilities in Makefile portions (or scripts) intended only for particular systems where you know those utilities exist. @node Command Variables @section Variables for Specifying Commands Makefiles should provide variables for overriding certain commands, options, and so on. In particular, you should run most utility programs via variables. Thus, if you use Bison, have a variable named @code{BISON} whose default value is set with @samp{BISON = bison}, and refer to it with @code{$(BISON)} whenever you need to use Bison. File management utilities such as @code{ln}, @code{rm}, @code{mv}, and so on, need not be referred to through variables in this way, since users don't need to replace them with other programs. Each program-name variable should come with an options variable that is used to supply options to the program. Append @samp{FLAGS} to the program-name variable name to get the options variable name---for example, @code{BISONFLAGS}. (The names @code{CFLAGS} for the C compiler, @code{YFLAGS} for yacc, and @code{LFLAGS} for lex, are exceptions to this rule, but we keep them because they are standard.) Use @code{CPPFLAGS} in any compilation command that runs the preprocessor, and use @code{LDFLAGS} in any compilation command that does linking as well as in any direct use of @code{ld}. If there are C compiler options that @emph{must} be used for proper compilation of certain files, do not include them in @code{CFLAGS}. Users expect to be able to specify @code{CFLAGS} freely themselves. Instead, arrange to pass the necessary options to the C compiler independently of @code{CFLAGS}, by writing them explicitly in the compilation commands or by defining an implicit rule, like this: @smallexample CFLAGS = -g ALL_CFLAGS = -I. $(CFLAGS) .c.o: $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< @end smallexample Do include the @samp{-g} option in @code{CFLAGS}, because that is not @emph{required} for proper compilation. You can consider it a default that is only recommended. If the package is set up so that it is compiled with GCC by default, then you might as well include @samp{-O} in the default value of @code{CFLAGS} as well. Put @code{CFLAGS} last in the compilation command, after other variables containing compiler options, so the user can use @code{CFLAGS} to override the others. @code{CFLAGS} should be used in every invocation of the C compiler, both those which do compilation and those which do linking. Every Makefile should define the variable @code{INSTALL}, which is the basic command for installing a file into the system. Every Makefile should also define the variables @code{INSTALL_PROGRAM} and @code{INSTALL_DATA}. (The default for each of these should be @code{$(INSTALL)}.) Then it should use those variables as the commands for actual installation, for executables and nonexecutables respectively. Use these variables as follows: @example $(INSTALL_PROGRAM) foo $(bindir)/foo $(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a @end example Optionally, you may prepend the value of @code{DESTDIR} to the target filename. Doing this allows the installer to create a snapshot of the installation to be copied onto the real target filesystem later. Do not set the value of @code{DESTDIR} in your Makefile, and do not include it in any installed files. With support for @code{DESTDIR}, the above examples become: @example $(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo $(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a @end example @noindent Always use a file name, not a directory name, as the second argument of the installation commands. Use a separate command for each file to be installed. @node Directory Variables @section Variables for Installation Directories Installation directories should always be named by variables, so it is easy to install in a nonstandard place. The standard names for these variables are described below. They are based on a standard filesystem layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and other modern operating systems. These two variables set the root for the installation. All the other installation directories should be subdirectories of one of these two, and nothing should be directly installed into these two directories. @table @samp @item prefix A prefix used in constructing the default values of the variables listed below. The default value of @code{prefix} should be @file{/usr/local}. When building the complete GNU system, the prefix will be empty and @file{/usr} will be a symbolic link to @file{/}. (If you are using Autoconf, write it as @samp{@@prefix@@}.) Running @samp{make install} with a different value of @code{prefix} from the one used to build the program should @var{not} recompile the program. @item exec_prefix A prefix used in constructing the default values of some of the variables listed below. The default value of @code{exec_prefix} should be @code{$(prefix)}. (If you are using Autoconf, write it as @samp{@@exec_prefix@@}.) Generally, @code{$(exec_prefix)} is used for directories that contain machine-specific files (such as executables and subroutine libraries), while @code{$(prefix)} is used directly for other directories. Running @samp{make install} with a different value of @code{exec_prefix} from the one used to build the program should @var{not} recompile the program. @end table Executable programs are installed in one of the following directories. @table @samp @item bindir The directory for installing executable programs that users can run. This should normally be @file{/usr/local/bin}, but write it as @file{$(exec_prefix)/bin}. (If you are using Autoconf, write it as @samp{@@bindir@@}.) @item sbindir The directory for installing executable programs that can be run from the shell, but are only generally useful to system administrators. This should normally be @file{/usr/local/sbin}, but write it as @file{$(exec_prefix)/sbin}. (If you are using Autoconf, write it as @samp{@@sbindir@@}.) @item libexecdir @comment This paragraph adjusted to avoid overfull hbox --roland 5jul94 The directory for installing executable programs to be run by other programs rather than by users. This directory should normally be @file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}. (If you are using Autoconf, write it as @samp{@@libexecdir@@}.) @end table Data files used by the program during its execution are divided into categories in two ways. @itemize @bullet @item Some files are normally modified by programs; others are never normally modified (though users may edit some of these). @item Some files are architecture-independent and can be shared by all machines at a site; some are architecture-dependent and can be shared only by machines of the same kind and operating system; others may never be shared between two machines. @end itemize This makes for six different possibilities. However, we want to discourage the use of architecture-dependent files, aside from object files and libraries. It is much cleaner to make other data files architecture-independent, and it is generally not hard. Therefore, here are the variables Makefiles should use to specify directories: @table @samp @item datadir The directory for installing read-only architecture independent data files. This should normally be @file{/usr/local/share}, but write it as @file{$(prefix)/share}. (If you are using Autoconf, write it as @samp{@@datadir@@}.) As a special exception, see @file{$(infodir)} and @file{$(includedir)} below. @item sysconfdir The directory for installing read-only data files that pertain to a single machine--that is to say, files for configuring a host. Mailer and network configuration files, @file{/etc/passwd}, and so forth belong here. All the files in this directory should be ordinary ASCII text files. This directory should normally be @file{/usr/local/etc}, but write it as @file{$(prefix)/etc}. (If you are using Autoconf, write it as @samp{@@sysconfdir@@}.) Do not install executables here in this directory (they probably belong in @file{$(libexecdir)} or @file{$(sbindir)}). Also do not install files that are modified in the normal course of their use (programs whose purpose is to change the configuration of the system excluded). Those probably belong in @file{$(localstatedir)}. @item sharedstatedir The directory for installing architecture-independent data files which the programs modify while they run. This should normally be @file{/usr/local/com}, but write it as @file{$(prefix)/com}. (If you are using Autoconf, write it as @samp{@@sharedstatedir@@}.) @item localstatedir The directory for installing data files which the programs modify while they run, and that pertain to one specific machine. Users should never need to modify files in this directory to configure the package's operation; put such configuration information in separate files that go in @file{$(datadir)} or @file{$(sysconfdir)}. @file{$(localstatedir)} should normally be @file{/usr/local/var}, but write it as @file{$(prefix)/var}. (If you are using Autoconf, write it as @samp{@@localstatedir@@}.) @item libdir The directory for object files and libraries of object code. Do not install executables here, they probably ought to go in @file{$(libexecdir)} instead. The value of @code{libdir} should normally be @file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}. (If you are using Autoconf, write it as @samp{@@libdir@@}.) @item infodir The directory for installing the Info files for this package. By default, it should be @file{/usr/local/info}, but it should be written as @file{$(prefix)/info}. (If you are using Autoconf, write it as @samp{@@infodir@@}.) @item lispdir The directory for installing any Emacs Lisp files in this package. By default, it should be @file{/usr/local/share/emacs/site-lisp}, but it should be written as @file{$(prefix)/share/emacs/site-lisp!}. If you are using Autoconf, write the default as @samp{@@lispdir@@}. In order to make @samp{@@lispdir@@} work, you need the following lines in your @file{configure.in} file: @example lispdir='$@{datadir@}/emacs/site-lisp' AC_SUBST(lispdir) @end example @item includedir @c rewritten to avoid overfull hbox --roland The directory for installing header files to be included by user programs with the C @samp{#include} preprocessor directive. This should normally be @file{/usr/local/include}, but write it as @file{$(prefix)/include}. (If you are using Autoconf, write it as @samp{@@includedir@@}.) Most compilers other than GCC do not look for header files in directory @file{/usr/local/include}. So installing the header files this way is only useful with GCC. Sometimes this is not a problem because some libraries are only really intended to work with GCC. But some libraries are intended to work with other compilers. They should install their header files in two places, one specified by @code{includedir} and one specified by @code{oldincludedir}. @item oldincludedir The directory for installing @samp{#include} header files for use with compilers other than GCC. This should normally be @file{/usr/include}. (If you are using Autoconf, you can write it as @samp{@@oldincludedir@@}.) The Makefile commands should check whether the value of @code{oldincludedir} is empty. If it is, they should not try to use it; they should cancel the second installation of the header files. A package should not replace an existing header in this directory unless the header came from the same package. Thus, if your Foo package provides a header file @file{foo.h}, then it should install the header file in the @code{oldincludedir} directory if either (1) there is no @file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo package. To tell whether @file{foo.h} came from the Foo package, put a magic string in the file---part of a comment---and @code{grep} for that string. @end table Unix-style man pages are installed in one of the following: @table @samp @item mandir The top-level directory for installing the man pages (if any) for this package. It will normally be @file{/usr/local/man}, but you should write it as @file{$(prefix)/man}. (If you are using Autoconf, write it as @samp{@@mandir@@}.) @item man1dir The directory for installing section 1 man pages. Write it as @file{$(mandir)/man1}. @item man2dir The directory for installing section 2 man pages. Write it as @file{$(mandir)/man2} @item @dots{} @strong{Don't make the primary documentation for any GNU software be a man page. Write a manual in Texinfo instead. Man pages are just for the sake of people running GNU software on Unix, which is a secondary application only.} @item manext The file name extension for the installed man page. This should contain a period followed by the appropriate digit; it should normally be @samp{.1}. @item man1ext The file name extension for installed section 1 man pages. @item man2ext The file name extension for installed section 2 man pages. @item @dots{} Use these names instead of @samp{manext} if the package needs to install man pages in more than one section of the manual. @end table And finally, you should set the following variable: @table @samp @item srcdir The directory for the sources being compiled. The value of this variable is normally inserted by the @code{configure} shell script. (If you are using Autconf, use @samp{srcdir = @@srcdir@@}.) @end table For example: @smallexample @c I have changed some of the comments here slightly to fix an overfull @c hbox, so the make manual can format correctly. --roland # Common prefix for installation directories. # NOTE: This directory must exist when you start the install. prefix = /usr/local exec_prefix = $(prefix) # Where to put the executable for the command `gcc'. bindir = $(exec_prefix)/bin # Where to put the directories used by the compiler. libexecdir = $(exec_prefix)/libexec # Where to put the Info files. infodir = $(prefix)/info @end smallexample If your program installs a large number of files into one of the standard user-specified directories, it might be useful to group them into a subdirectory particular to that program. If you do this, you should write the @code{install} rule to create these subdirectories. Do not expect the user to include the subdirectory name in the value of any of the variables listed above. The idea of having a uniform set of variable names for installation directories is to enable the user to specify the exact same values for several different GNU packages. In order for this to be useful, all the packages must be designed so that they will work sensibly when the user does so. @node Standard Targets @section Standard Targets for Users All GNU programs should have the following targets in their Makefiles: @table @samp @item all Compile the entire program. This should be the default target. This target need not rebuild any documentation files; Info files should normally be included in the distribution, and DVI files should be made only when explicitly asked for. By default, the Make rules should compile and link with @samp{-g}, so that executable programs have debugging symbols. Users who don't mind being helpless can strip the executables later if they wish. @item install Compile the program and copy the executables, libraries, and so on to the file names where they should reside for actual use. If there is a simple test to verify that a program is properly installed, this target should run that test. Do not strip executables when installing them. Devil-may-care users can use the @code{install-strip} target to do that. If possible, write the @code{install} target rule so that it does not modify anything in the directory where the program was built, provided @samp{make all} has just been done. This is convenient for building the program under one user name and installing it under another. The commands should create all the directories in which files are to be installed, if they don't already exist. This includes the directories)~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE-STDS.TEXI;1H6- specified as the values of the variables @code{prefix} and @code{exec_prefix}, as well as all subdirectories that are needed. One way to do this is by means of an @code{installdirs} target as described below. Use @samp{-} before any command for installing a man page, so that @code{make} will ignore any errors. This is in case there are systems that don't have the Unix man page documentation system installed. The way to install Info files is to copy them into @file{$(infodir)} with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run the @code{install-info} program if it is present. @code{install-info} is a program that edits the Info @file{dir} file to add or update the menu entry for the given Info file; it is part of the Texinfo package. Here is a sample rule to install an Info file: @comment This example has been carefully formatted for the Make manual. @comment Please do not reformat it without talking to roland@gnu.ai.mit.edu. @smallexample $(DESTDIR)$(infodir)/foo.info: foo.info $(POST_INSTALL) # There may be a newer info file in . than in srcdir. -if test -f foo.info; then d=.; \ else d=$(srcdir); fi; \ $(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@@; \ # Run install-info only if it exists. # Use `if' instead of just prepending `-' to the # line so we notice real errors from install-info. # We use `$(SHELL) -c' because some shells do not # fail gracefully when there is an unknown command. if $(SHELL) -c 'install-info --version' \ >/dev/null 2>&1; then \ install-info --dir-file=$(DESTDIR)$(infodir)/dir \ $(DESTDIR)$(infodir)/foo.info; \ else true; fi @end smallexample When writing the @code{install} target, you must classify all the commands into three categories: normal ones, @dfn{pre-installation} commands and @dfn{post-installation} commands. @xref{Install Command Categories}. @item uninstall Delete all the installed files---the copies that the @samp{install} target creates. This rule should not modify the directories where compilation is done, only the directories where files are installed. The uninstallation commands are divided into three categories, just like the installation commands. @xref{Install Command Categories}. @item install-strip Like @code{install}, but strip the executable files while installing them. In many cases, the definition of this target can be very simple: @smallexample install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ install @end smallexample Normally we do not recommend stripping an executable unless you are sure the program has no bugs. However, it can be reasonable to install a stripped executable for actual execution while saving the unstripped executable elsewhere in case there is a bug. @comment The gratuitous blank line here is to make the table look better @comment in the printed Make manual. Please leave it in. @item clean Delete all files from the current directory that are normally created by building the program. Don't delete the files that record the configuration. Also preserve files that could be made by building, but normally aren't because the distribution comes with them. Delete @file{.dvi} files here if they are not part of the distribution. @item distclean Delete all files from the current directory that are created by configuring or building the program. If you have unpacked the source and built the program without creating any other files, @samp{make distclean} should leave only the files that were in the distribution. @item mostlyclean Like @samp{clean}, but may refrain from deleting a few files that people normally don't want to recompile. For example, the @samp{mostlyclean} target for GCC does not delete @file{libgcc.a}, because recompiling it is rarely necessary and takes a lot of time. @item maintainer-clean Delete almost everything from the current directory that can be reconstructed with this Makefile. This typically includes everything deleted by @code{distclean}, plus more: C source files p(5roduced by Bison, tags tables, Info files, and so on. The reason we say ``almost everything'' is that running the command @samp{make maintainer-clean} should not delete @file{configure} even if @file{configure} can be remade using a rule in the Makefile. More generally, @samp{make maintainer-clean} should not delete anything that needs to exist in order to run @file{configure} and then begin to build the program. This is the only exception; @code{maintainer-clean} should delete everything else that can be rebuilt. The @samp{maintainer-clean} target is intended to be used by a maintainer of the package, not by ordinary users. You may need special tools to reconstruct some of the files that @samp{make maintainer-clean} deletes. Since these files are normally included in the distribution, we don't take care to make them easy to reconstruct. If you find you need to unpack the full distribution again, don't blame us. To help make users aware of this, the commands for the special @code{maintainer-clean} target should start with these two: @smallexample @@echo 'This command is intended for maintainers to use; it' @@echo 'deletes files that may need special tools to rebuild.' @end smallexample @item TAGS Update a tags table for this program. @c ADR: how? @item info Generate any Info files needed. The best way to write the rules is as follows: @smallexample info: foo.info foo.info: foo.texi chap1.texi chap2.texi $(MAKEINFO) $(srcdir)/foo.texi @end smallexample @noindent You must define the variable @code{MAKEINFO} in the Makefile. It should run the @code{makeinfo} program, which is part of the Texinfo distribution. Normally a GNU distribution comes with Info files, and that means the Info files are present in the source directory. Therefore, the Make rule for an info file should update it in the source directory. When users build the package, ordinarily Make will not update the Info files because they will already be up to date. @item dvi Generate DVI files for all Texinfo documentation. For example: @smallexample dvi: foo.dvi foo.dvi: foo.texi chap1.texi chap2.texi $(TEXI2DVI) $(srcdir)/foo.texi @end smallexample @noindent You must define the variable @code{TEXI2DVI} in the Makefile. It should run the program @code{texi2dvi}, which is part of the Texinfo distribution.@footnote{@code{texi2dvi} uses @TeX{} to do the real work of formatting. @TeX{} is not distributed with Texinfo.} Alternatively, write just the dependencies, and allow GNU @code{make} to provide the command. @item dist Create a distribution tar file for this program. The tar file should be set up so that the file names in the tar file start with a subdirectory name which is the name of the package it is a distribution for. This name can include the version number. For example, the distribution tar file of GCC version 1.40 unpacks into a subdirectory named @file{gcc-1.40}. The easiest way to do this is to create a subdirectory appropriately named, use @code{ln} or @code{cp} to install the proper files in it, and then @code{tar} that subdirectory. Compress the tar file file with @code{gzip}. For example, the actual distribution file for GCC version 1.40 is called @file{gcc-1.40.tar.gz}. The @code{dist} target should explicitly depend on all non-source files that are in the distribution, to make sure they are up to date in the distribution. @ifset CODESTD @xref{Releases, , Making Releases}. @end ifset @ifclear CODESTD @xref{Releases, , Making Releases, standards, GNU Coding Standards}. @end ifclear @item check Perform self-tests (if any). The user must build the program before running the tests, but need not install the program; you should write the self-tests so that they work when the program is built but not installed. @end table The following targets are suggested as conventional names, for programs in which they are useful. @table @code @item installcheck Perform installation tests (if any). The user must build and install the program before running the tests. You should not assume that @file{$(bindir)} is in the search path. @item installdirs It's useful to add a target named @samp{installdirs} to create the directories where files are installed, and their parent directories. There is a script called @file{mkinstalldirs} which is convenient for this; you can find it in the Texinfo package. @c It's in /gd/gnu/lib/mkinstalldirs. You can use a rule like this: @comment This has been carefully formatted to look decent in the Make manual. @comment Please be sure not to make it extend any further to the right.--roland @smallexample # Make sure all installation directories (e.g. $(bindir)) # actually exist by making them if necessary. installdirs: mkinstalldirs $(srcdir)/mkinstalldirs $(bindir) $(datadir) \ $(libdir) $(infodir) \ $(mandir) @end smallexample This rule should not modify the directories where compilation is done. It should do nothing but create installation directories. @end table @node Install Command Categories @section Install Command Categories @cindex pre-installation commands @cindex post-installation commands When writing the @code{install} target, you must classify all the commands into three categories: normal ones, @dfn{pre-installation} commands and @dfn{post-installation} commands. Normal commands move files into their proper places, and set their modes. They may not alter any files except the ones that come entirely from the package they belong to. Pre-installation and post-installation commands may alter other files; in particular, they can edit global configuration files or data bases. Pre-installation commands are typically executed before the normal commands, and post-installation commands are typically run after the normal commands. The most common use for a post-installation command is to run @code{install-info}. This cannot be done with a normal command, since it alters a file (the Info directory) which does not come entirely and solely from the package being installed. It is a post-installation command because it needs to be done after the normal command which installs the package's Info files. Most programs don't need any pre-installation commands, but we have the feature just in case it is needed. To classify the commands in the @code{install} rule into these three categories, insert @dfn{category lines} among them. A category line specifies the category for the commands that follow. A category line consists of a tab and a reference to a special Make variable, plus an optional comment at the end. There are three variables you can use, one for each category; the variable name specifies the category. Category lines are no-ops in ordinary execution because these three Make variables are normally undefined (and you @emph{should not} define them in the makefile). Here are the three possible category lines, each with a comment that explains what it means: @smallexample $(PRE_INSTALL) # @r{Pre-install commands follow.} $(POST_INSTALL) # @r{Post-install commands follow.} $(NORMAL_INSTALL) # @r{Normal commands follow.} @end smallexample If you don't use a category line at the beginning of the @code{install} rule, all the commands are classified as normal until the first category line. If you don't use any category lines, all the commands are classified as normal. These are the category lines for @code{uninstall}: @smallexample $(PRE_UNINSTALL) # @r{Pre-uninstall commands follow.} $(POST_UNINSTALL) # @r{Post-uninstall commands follow.} $(NORMAL_UNINSTALL) # @r{Normal commands follow.} @end smallexample Typically, a pre-uninstall command would be used for deleting entries from the Info directory. If the @code{install} or @code{uninstall} target has any dependencies which act as subroutines of installation, then you should start @emph{each} dependency's commands with a category line, and start the main target's commands with a category line also. This way, you can ensure that each command is placed in the right category regardless of which of the dependencies actually run. Pre-installation and post-installation commands should not run any programs except for these: @example [ basename bash cat chgrp chmod chown cmp cp dd diff echo egrep expand expr false fgrep find getopt grep gunzip gzip hostname install install-info kill ldconfig ln ls md5sum mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee test touch true uname xargs yes @end example @cindex binary packages The reason for distinguishing the commands in this way is for the sake of making binary packages. Typically a binary package contains all the executables and other files that need to be installed, and has its own method of installing them---so it does not need to run the normal installation commands. But installing the binary package does need to execute the pre-installation and post-installation commands. Programs to build binary packages work by extracting the pre-installation and post-installation commands. Here is one way of extracting the pre-installation commands: @smallexample make -n install -o all \ PRE_INSTALL=pre-install \ POST_INSTALL=post-install \ NORMAL_INSTALL=normal-install \ | gawk -f pre-install.awk @end smallexample @noindent where the file @file{pre-install.awk} could contain this: @smallexample $0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ @{on = 0@} on @{print $0@} $0 ~ /^\t[ \t]*pre_install[ \t]*$/ @{on = 1@} @end smallexample The resulting file of pre-installation commands is executed as a shell script as part of installing the binary package. a*[MAKE-3_78_1HB]MAKE.1;1+,c./@ 4-`0123KPWO56s`76 m89G@HJ.TH MAKE 1L "22 August 1989" "GNU" "LOCAL USER COMMANDS" .SH NAME make \- GNU make utility to maintain groups of programs .SH SYNOPSIS .B "make " [ .B \-f .I makefile ] [ option ] ... target ... .SH WARNING This man page is an extract of the documentation of .I GNU make . It is updated only occasionally, because the GNU project does not use nroff. For complete, current documentation, refer to the Info file .B make.info which is made from the Texinfo source file .BR make.texinfo . .SH DESCRIPTION .LP The purpose of the .I make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them. The manual describes the GNU implementation of .IR make , which was written by Richard Stallman and Roland McGrath. Our examples show C programs, since they are most common, but you can use .I make with any programming language whose compiler can be run with a shell command. In fact, .I make is not limited to programs. You can use it to describe any task where some files must be updated automatically from others whenever the others change. .LP To prepare to use .IR make , you must write a file called the .I makefile that describes the relationships among files in your program, and the states the commands for updating each file. In a program, typically the executable file is updated from object files, which are in turn made by compiling source files. .LP Once a suitable makefile exists, each time you change some source files, this simple shell command: .sp 1 .RS .B make .RE .sp 1 suffices to perform all necessary recompilations. The .I make program uses the makefile data base and the last-modification times of the files to decide which of the files need to be updated. For each of those files, it issues the commands recorded in the data base. .LP .I make executes commands in the .I makefile to update one or more target .IR names , where .I name is typically a program. If no .B \-f option is present, .I make will look for the makefiles .IR GNUmakefile , .IR makefile , and .IR Makefile , in that order. .LP Normally you should call your makefile either .I makefile or .IR Makefile . (We recommend .I Makefile because it appears prominently near the beginning of a directory listing, right near other important files such as .IR README .) The first name checked, .IR GNUmakefile , is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU .IR make , and will not be understood by other versions of .IR make . If .I makefile is `\-', the standard input is read. .LP .I make updates a target if it depends on prerequisite files that have been modified since the target was last modified, or if the target does not exist. .SH OPTIONS .sp 1 .TP 0.5i .B \-b .TP 0.5i .B \-m These options are ignored for compatibility with other versions of .IR make . .TP 0.5i .BI "\-C " dir Change to directory .I dir before reading the makefiles or doing anything else. If multiple .B \-C options are specified, each is interpreted relative to the previous one: .BR "\-C " / .BR "\-C " etc is equivalent to .BR "\-C " /etc. This is typically used with recursive invocations of .IR make . .TP 0.5i .B \-d Print debugging information in addition to normal processing. The debugging information says which files are being considered for remaking, which file-times are being compared and with what results, which files actually need to be remade, which implicit rules are considered and which are applied---everything interesting about how .I make decides what to do. .TP 0.5i .B \-e Give variables taken from the environment precedence over variables from makefiles. .TP 0.5i .BI "\-f " file Use .I file as a makefile. .TP 0.5i .B \-i Ignore all errors in commands executed to remake files. .TP 0.5i .BI "\-I " dir Specifies a directory .I dir to search for included makefiles. If several .B \-I options are used to specify several directories, the directories are searched in the order specified. Unlike the arguments to other flags of .IR make , directories given with .B \-I flags may come directly after the flag: .BI \-I dir is allowed, as well as .BI "\-I " dir. This syntax is allowed for compatibility with the C preprocessor's .B \-I flag. .TP 0.5i .BI "\-j " jobs Specifies the number of jobs (commands) to run simultaneously. If there is more than one .B \-j option, the last one is effective. If the .B \-j option is given without an argument, .IR make will not limit the number of jobs that can run simultaneously. .TP 0.5i .B \-k Continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other dependencies of these targets can be processed all the same. .TP 0.5i .B \-l .TP 0.5i .BI "\-l " load Specifies that no new jobs (commands) should be started if there are others jobs running and the load average is at least .I load (a floating-point number). With no argument, removes a previous load limit. .TP 0.5i .B \-n Print the commands that would be executed, but do not execute them. .TP 0.5i .BI "\-o " file Do not remake the file .I file even if it is older than its dependencies, and do not remake anything on account of changes in .IR file . Essentially the file is treated as very old and its rules are ignored. .TP 0.5i .B \-p Print the data base (rules and variable values) that results from reading the makefiles; then execute as usual or as otherwise specified. This also prints the version information given by the .B \-v switch (see below). To print the data base without trying to remake any files, use .B make .B \-p .BI \-f /dev/null. .TP 0.5i .B \-q ``Question mode''. Do not run any commands, or print anything; just return an exit status that is zero if the specified targets are already up to date, nonzero otherwise. .TP 0.5i .B \-r Eliminate use of the built-in implicit rules. Also clear out the default list of suffixes for suffix rules. .TP 0.5i .B \-s Silent operation; do not print the commands as they are executed. .TP 0.5i .B \-S Cancel the effect of the .B \-k option. This is never necessary except in a recursive .I make where .B \-k might be inherited from the top-level .I make via MAKEFLAGS or if you set .B \-k in MAKEFLAGS in your environment. .TP 0.5i .B \-t Touch files (mark them up to date without really changing them) instead of running their commands. This is used to pretend that the commands were done, in order to fool future invocations of .IR make . .TP 0.5i .B \-v Print the version of the .I make program plus a copyright, a list of authors and a notice that there is no warranty. .TP 0.5i .B \-w Print a message containing the working directory before and after other processing. This may be useful for tracking down errors from complicated nests of recursive .I make commands. .TP 0.5i .BI "\-W " file Pretend that the target .I file has just been modified. When used with the .B \-n flag, this shows you what would happen if you were to modify that file. Without .BR \-n , it is almost the same as running a .I touch command on the given file before running .IR make , except that the modification time is changed only in the imagination of .IR make . .SH "SEE ALSO" .I "The GNU Make Manual" .SH BUGS See the chapter `Problems and Bugs' in .I "The GNU Make Manual" . .SH AUTHOR This manual page contributed by Dennis Morse of Stanford University. It has been reworked by Roland McGrath. *[MAKE-3_78_1HB]MAKE.H;3+,ad . /@ 4 M-`0123KPWO!56״V7m89G@HJ/* Miscellaneous global declarations and portability cruft for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined (_AIX) && !defined (__GNUC__) #pragma alloca #endif /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because make.h was found in $srcdir). */ #include #undef HAVE_CONFIG_H #define HAVE_CONFIG_H 1 /* Use prototypes if available. */ #if defined (__cplusplus) || (defined (__STDC__) && __STDC__) # undef PARAMS # define PARAMS(protos) protos #else /* Not C++ or ANSI C. */ # undef PARAMS # define PARAMS(protos) () #endif /* C++ or ANSI C. */ /* For now, set gettext macro to a no-op. */ #undef _ #undef N_ #define _(s) s #define N_(s) s #ifdef CRAY /* This must happen before #include so that the declaration therein is changed. */ # define signal bsdsignal #endif /* If we're compiling for the dmalloc debugger, turn off string inlining. */ #if defined(HAVE_DMALLOC_H) && defined(__GNUC__) # define __NO_STRING_INLINES #endif #define _GNU_SOURCE 1 #include #include #include #include #include #ifdef HAVE_SYS_TIMEB_H /* SCO 3.2 "devsys 4.2" has a prototype for `ftime' in that bombs unless has been included first. Does every system have a ? If any does not, configure should check for it. */ # include #endif #include #include #ifndef errno extern int errno; #endif /* A shortcut for EINTR checking. Note you should be careful when negating this! That might not mean what you want if EINTR is not available. */ #ifdef EINTR # define EINTR_SET (errno == EINTR) #else # define EINTR_SET (0) #endif #ifndef isblank # define isblank(c) ((c) == ' ' || (c) == '\t') #endif #ifdef HAVE_UNISTD_H # include /* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself! */ # if defined (_POSIX_VERSION) && !defined (ultrix) && !defined (VMS) # define POSIX 1 # endif #endif /* Some systems define _POSIX_VERSION but are not really POSIX.1. */ #if (defined (butterfly) || defined (__arm) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386))) # undef POSIX #endif #if !defined (POSIX) && defined (_AIX) && defined (_POSIX_SOURCE) # define POSIX 1 #endif #if defined (HAVE_SYS_SIGLIST) && !defined (SYS_SIGLIST_DECLARED) extern char *sys_siglist[]; #endif #if !defined (HAVE_SYS_SIGLIST) || !defined (HAVE_STRSIGNAL) # include "signame.h" #endif /* Some systems do not define NSIG in . */ #ifndef NSIG # ifdef _NSIG # define NSIG _NSIG # else # define NSIG 32 # endif #endif #ifndef RETSIGTYPE # define RETSIGTYPE void #endif #ifndef sigmask # define sigmask(sig) (1 << ((sig) - 1)) #endif #ifdef HAVE_LIMITS_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifndef PATH_MAX # ifndef POSIX # define PATH_MAX MAXPATHLEN # endif #endif #ifndef MAXPATHLEN # define MAXPATHLEN 1024 #endif #ifdef PATH_MAX # define GET_PATH_MAX PATH_MAX # define PATH_VAR(var) char var[PATH_MAX] #else # define NEED_GET_PATH_MAX 1 # define GET_PATH_MAX (get_path_max ()) # define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX) extern unsigned int get_path_max PARAMS ((void)); #endif #ifndef CHAR_BIT # define CHAR_BIT 8 #endif /* Nonzero if the integer type T is signed. */ #define INTEGER_TYPE_SIGNED(t) ((t) -1 < 0) /* The minimum and maximum values for the integer type T. Use ~ (t) 0, not -1, for portability to 1's complement hosts. */ #define INTEGER_TYPE_MINIMUM(t) \ (! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)) #define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t)) #ifndef CHAR_MAX # define CHAR_MAX INTEGER_TYPE_MAXIMUM (char) #endif #ifdef STAT_MACROS_BROKEN # ifdef S_ISREG # undef S_ISREG # endif # ifdef S_ISDIR # undef S_ISDIR # endif #endif /* STAT_MACROS_BROKEN. */ #ifndef S_ISREG # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #endif #ifndef S_ISDIR # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif #ifdef VMS # include # include # include # include # include # include #endif #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ # define __attribute__(x) # endif /* The __-protected variants of `format' and `printf' attributes are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) # define __format__ format # define __printf__ printf # endif #endif #if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) # include # include # define ANSI_STRING 1 #else /* No standard headers. */ # ifdef HAVE_STRING_H # include # define ANSI_STRING 1 # else # include # endif # ifdef HAVE_MEMORY_H # include # endif # ifdef HAVE_STDLIB_H # include # else extern char *malloc PARAMS ((int)); extern char *realloc PARAMS ((char *, int)); extern void free PARAMS ((char *)); extern void abort PARAMS ((void)) __attribute__ ((noreturn)); extern void exit PARAMS ((int)) __attribute__ ((noreturn)); # endif /* HAVE_STDLIB_H. */ #endif /* Standard headers. */ #if ST_MTIM_NSEC # if HAVE_INTTYPES_H # include # endif # define FILE_TIMESTAMP uintmax_t #else # define FILE_TIMESTAMP time_t #endif #ifdef ANSI_STRING # ifndef index # define index(s, c) strchr((s), (c)) # endif # ifndef rindex # define rindex(s, c) strrchr((s), (c)) # endif # ifndef bcmp # define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) # endif # ifndef bzero # define bzero(s, n) memset ((s), 0, (n)) # endif # if defined(HAVE_MEMMOVE) && !defined(bcopy) # define bcopy(s, d, n) memmove ((d), (s), (n)) # endif #else /* Not ANSI_STRING. */ # ifndef bcmp extern int bcmp PARAMS ((const char *, const char *, int)); # endif # ifndef bzero extern void bzero PARAMS ((char *, int)); #endif # ifndef bcopy extern void bcopy PARAMS ((const char *b1, char *b2, int)); # endif #endif /* ANSI_STRING. */ #undef ANSI_STRING /* SCO Xenix has a buggy macro definition in . */ #undef strerror #if !defined(ANSI_STRING) && !defined(__DECC) extern char *strerror PARAMS ((int errnum)); #endif #ifdef __GNUC__ # undef alloca # define alloca(n) __builtin_alloca (n) #else /* Not GCC. */ # ifdef HAVE_ALLOCA_H # include # else /* Not HAVE_ALLOCA_H. */ # ifndef _AIX extern char *alloca (); # endif /* Not AIX. */ # endif /* HAVE_ALLOCA_H. */ #endif /* GCC. */ /* ISDIGIT offers the following features: - Its arg may be any int or unsigned int; it need not be an unsigned char. - It's guaranteed to evaluate its argument exactly once. NOTE! Make relies on this behavior, don't change it! - It's typically faster. Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that only '0' through '9' are digits. Prefer ISDIGIT to isdigit() unless it's important to use the locale's definition of `digit' even when the host does not conform to Posix. */ #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) #ifndef iAPX286 # define streq(a, b) \ ((a) == (b) || \ (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1)))) # ifdef HAVE_CASE_INSENSITIVE_FS /* This is only used on Windows/DOS platforms, so we assume strcmpi(). */ # define strieq(a, b) \ ((a) == (b) || \ (tolower(*(a)) == tolower(*(b)) && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1)))) # else # define strieq(a, b) streq(a, b) # endif #else /* Buggy compiler can't handle this. */ # define streq(a, b) (strcmp ((a), (b)) == 0) # define strieq(a, b) (strcmp ((a), (b)) == 0) #endif #define strneq(a, b, l) (strncmp ((a), (b), (l)) == 0) #ifdef VMS extern int strcmpi (const char *,const char *); #endif /* Add to VAR the hashing value of C, one character in a name. */ #define HASH(var, c) \ ((var += (c)), (var = ((var) << 7) + ((var) >> 20))) #ifdef HAVE_CASE_INSENSITIVE_FS /* Fold filename*~MAKE-3_78_1HB.BCKad `[MAKE-3_78_1HB]MAKE.H;3 s */ # define HASHI(var, c) \ ((var += tolower((c))), (var = ((var) << 7) + ((var) >> 20))) #else # define HASHI(var, c) HASH(var,c) #endif #if defined(__GNUC__) || defined(ENUM_BITFIELDS) # define ENUM_BITFIELD(bits) :bits #else # define ENUM_BITFIELD(bits) #endif #if defined(__MSDOS__) || defined(WINDOWS32) # define PATH_SEPARATOR_CHAR ';' #else # if defined(VMS) # define PATH_SEPARATOR_CHAR ',' # else # define PATH_SEPARATOR_CHAR ':' # endif #endif #ifdef WINDOWS32 # include # include # define pipe(p) _pipe(p, 512, O_BINARY) # define kill(pid,sig) w32_kill(pid,sig) extern void sync_Path_environment(void); extern int kill(int pid, int sig); extern int safe_stat(char *file, struct stat *sb); extern char *end_of_token_w32(char *s, char stopchar); extern int find_and_set_default_shell(char *token); /* indicates whether or not we have Bourne shell */ extern int no_default_sh_exe; /* is default_shell unixy? */ extern int unixy_shell; #endif /* WINDOWS32 */ struct floc { char *filenm; unsigned long lineno; }; #define NILF ((struct floc *)0) /* Fancy processing for variadic functions in both ANSI and pre-ANSI compilers. */ #if defined __STDC__ && __STDC__ extern void message (int prefix, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern void error (const struct floc *flocp, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern void fatal (const struct floc *flocp, const char *fmt, ...) __attribute__ ((noreturn, __format__ (__printf__, 2, 3))); #else extern void message (); extern void error (); extern void fatal (); #endif extern void die PARAMS ((int)) __attribute__ ((noreturn)); extern void log_working_directory PARAMS ((int)); extern void pfatal_with_name PARAMS ((char *)) __attribute__ ((noreturn)); extern void perror_with_name PARAMS ((char *, char *)); extern char *savestring PARAMS ((const char *, unsigned int)); extern char *concat PARAMS ((char *, char *, char *)); extern char *xmalloc PARAMS ((unsigned int)); extern char *xrealloc PARAMS ((char *, unsigned int)); extern char *xstrdup PARAMS ((const char *)); extern char *find_next_token PARAMS ((char **, unsigned int *)); extern char *next_token PARAMS ((char *)); extern char *end_of_token PARAMS ((char *)); extern void collapse_continuations PARAMS ((char *)); extern void remove_comments PARAMS((char *)); extern char *sindex PARAMS ((const char *, unsigned int, \ const char *, unsigned int)); extern char *lindex PARAMS ((const char *, const char *, int)); extern int alpha_compare PARAMS ((const void *, const void *)); extern void print_spaces PARAMS ((unsigned int)); extern char *find_char_unquote PARAMS ((char *, char *, int)); extern char *find_percent PARAMS ((char *)); #ifndef NO_ARCHIVES extern int ar_name PARAMS ((char *)); extern void ar_parse_name PARAMS ((char *, char **, char **)); extern int ar_touch PARAMS ((char *)); extern time_t ar_member_date PARAMS ((char *)); #endif extern int dir_file_exists_p PARAMS ((char *, char *)); extern int file_exists_p PARAMS ((char *)); extern int file_impossible_p PARAMS ((char *)); extern void file_impossible PARAMS ((char *)); extern char *dir_name PARAMS ((char *)); extern void define_default_variables PARAMS ((void)); extern void set_default_suffixes PARAMS ((void)); extern void install_default_suffix_rules PARAMS ((void)); extern void install_default_implicit_rules PARAMS ((void)); extern void build_vpath_lists PARAMS ((void)); extern void construct_vpath_list PARAMS ((char *pattern, char *dirpath)); extern int vpath_search PARAMS ((char **file, FILE_TIMESTAMP *mtime_ptr)); extern int gpath_search PARAMS ((char *file, int len)); extern void construct_include_path PARAMS ((char **arg_dirs)); extern void user_access PARAMS ((void)); extern void make_access PARAMS ((void)); extern void child_access PARAMS ((void)); #ifdef HAVE_VFORK_H # include #endif /* We omit these declarations on non-POSIX systems which define _POSIX_VERSION, because such systems often declare them in header files anyway. */ #if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !defined(WINDOWS32) extern long int atol (); # ifndef VMS extern long int lseek (); # endif #endif /* Not GNU C library or POSIX. */ #ifdef HAVE_GETCWD # if !defined(VMS) && !defined(__DECC) extern char *getcwd (); #endif #else extern char *getwd (); # define getcwd(buf, len) getwd (buf) #endif extern const struct floc *reading_file; extern char **environ; extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag; extern int debug_flag, print_data_base_flag, question_flag, touch_flag; extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag; extern int print_version_flag, print_directory_flag; extern int warn_undefined_variables_flag, posix_pedantic; extern int clock_skew_detected; /* can we run commands via 'sh -c xxx' or must we use batch files? */ extern int batch_mode_shell; extern unsigned int job_slots; extern int job_fds[2]; extern int job_rfd; #ifndef NO_FLOAT extern double max_load_average; #else extern int max_load_average; #endif extern char *program; extern char *starting_directory; extern unsigned int makelevel; extern char *version_string, *remote_description; extern unsigned int commands_started; extern int handling_fatal_signal; #ifndef MIN #define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) #endif #ifndef MAX #define MAX(_a,_b) ((_a)>(_b)?(_a):(_b)) #endif #define DEBUGPR(msg) \ do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \ fflush (stdout); } while (0) #ifdef VMS # ifndef EXIT_FAILURE # define EXIT_FAILURE 3 # endif # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 1 # endif # ifndef EXIT_TROUBLE # define EXIT_TROUBLE 2 # endif #else # ifndef EXIT_FAILURE # define EXIT_FAILURE 2 # endif # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # ifndef EXIT_TROUBLE # define EXIT_TROUBLE 1 # endif #endif /* Set up heap debugging library dmalloc. */ #ifdef HAVE_DMALLOC_H #include #endif *[MAKE-3_78_1HB]MAKE.INFO;1+,c. /@ 4 -`0123KPWO 5607{)m89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  Indirect: make.info-1: 1302 make.info-2: 48813 make.info-3: 98248 make.info-4: 144031 make.info-5: 191998 make.info-6: 240821 make.info-7: 289975 make.info-8: 337313 make.info-9: 367205 make.info-10: 410588  Tag Table: (Indirect) Node: Top1302 Node: Overview12657 Node: Preparing13664 Node: Reading14619 Node: Bugs15541 Node: Introduction16834 Node: Rule Introduction18421 Node: Simple Makefile20140 Node: How Make Works23764 Node: Variables Simplify26255 Node: make Deduces28461 Node: Combine By Prerequisite30212 Node: Cleanup31246 Node: Makefiles32660 Node: Makefile Contents33415 Node: Makefile Names35718 Node: Include37320 Node: MAKEFILES Variable41012 Node: Remaking Makefiles42514 Node: Overriding Makefiles46760 Node: Reading Makefiles48813 Node: Rules51344 Node: Rule Example53945 Node: Rule Syntax54783 Node: Wildcards56999 Node: Wildcard Examples58679 Node: Wildcard Pitfall59917 Node: Wildcard Function61702 Node: Directory Search63483 Node: General Search64620 Node: Selective Search66330 Node: Search Algorithm69309 Node: Commands/Search71819 Node: Implicit/Search73167 Node: Libraries/Search74102 Node: Phony Targets76187 Node: Force Targets81094 Node: Empty Targets82134 Node: Special Targets83435 Node: Multiple Targets88206 Node: Multiple Rules90078 Node: Static Pattern92172 Node: Static Usage92817 Node: Static versus Implicit96515 Node: Double-Colon98248 Node: Automatic Prerequisites99782 Node: Commands103914 Node: Echoing105607 Node: Execution106871 Node: Parallel111447 Node: Errors115033 Node: Interrupts118671 Node: Recursion120253 Node: MAKE Variable121982 Node: Variables/Recursion123946 Node: Options/Recursion128909 Node: -w Option134064 Node: Sequences135050 Node: Empty Commands138054 Node: Using Variables139224 Node: Reference142486 Node: Flavors144031 Node: Advanced149817 Node: Substitution Refs150317 Node: Computed Names151844 Node: Values156414 Node: Setting157331 Node: Appending159372 Node: Override Directive163290 Node: Defining164669 Node: Environment166667 Node: Target-specific168942 Node: Pattern-specific171341 Node: Conditionals172536 Node: Conditional Example173245 Node: Conditional Syntax175811 Node: Testing Flags180557 Node: Functions181654 Node: Syntax of Functions182848 Node: Text Functions185024 Node: File Name Functions191998 Node: Foreach Function197709 Node: If Function200912 Node: Call Function202183 Node: Origin Function204825 Node: Shell Function208047 Node: Make Control Functions209600 Node: Running211033 Node: Makefile Arguments213021 Node: Goals213716 Node: Instead of Execution218276 Node: Avoiding Compilation221557 Node: Overriding223458 Node: Testing225746 Node: Options Summary227626 Node: Implicit Rules235167 Node: Using Implicit237313 Node: Catalogue of Rules240821 Node: Implicit Variables249814 Node: Chained Rules254043 Node: Pattern Rules258045 Node: Pattern Intro259574 Node: Pattern Examples262403 Node: Automatic264202 Node: Pattern Match270515 Node: Match-Anything Rules272129 Node: Canceling Rules275993 Node: Last Resort276698 Node: Suffix Rules278539 Node: Implicit Rule Search282261 Node: Archives285782 Node: Archive Members286477 Node: Archive Update288059 Node: Archive Symbols289975 Node: Archive Pitfalls291175 Node: Archive Suffix Rules291891 Node: Features293433 Node: Missing302016 Node: Makefile Conventions306364 Node: Makefile Basics307105 Node: Utilities in Makefiles310269 Node: Command Variables312400 Node: Directory Variables315895 Node: Standard Targets326766 Node: Install Command Categories337313 Node: Quick Reference341881 Node: Make Errors351065 Node: Complex Makefile358542 Node: Concept Index367205 Node: Name Index410588  End Tag Table c*[MAKE-3_78_1HB]MAKE.INFO-1;1+,c.`/@ 4``-`0123KPWOa56"7^9m89G@HJHThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Top, Next: Overview, Up: (dir) Make **** The GNU `make' utility automatically determines which pieces of a large program need to be recompiled, and issues the commands to recompile them. This edition of the `GNU Make Manual', last updated 09 September 1999, documents GNU `make' Version 3.78.1. This manual describes `make' and contains the following chapters: * Menu: * Overview:: Overview of `make'. * Introduction:: An introduction to `make'. * Makefiles:: Makefiles tell `make' what to do. * Rules:: Rules describe when a file must be remade. * Commands:: Commands say how to remake a file. * Using Variables:: You can use variables to avoid repetition. * Conditionals:: Use or ignore parts of the makefile based on the values of variables. * Functions:: Many powerful ways to manipulate text. * Invoking make: Running. How to invoke `make' on the command line. * Implicit Rules:: Use implicit rules to treat many files alike, based on their file names. * Archives:: How `make' can update library archives. * Features:: Features GNU `make' has over other `make's. * Missing:: What GNU `make' lacks from other `make's. * Makefile Conventions:: Conventions for makefiles in GNU programs. * Quick Reference:: A quick reference for experienced users. * Make Errors:: A list of common errors generated by `make'. * Complex Makefile:: A real example of a straightforward, but nontrivial, makefile. * Concept Index:: Index of Concepts * Name Index:: Index of Functions, Variables, & Directives -- The Detailed Node Listing -- Overview of `make' * Preparing:: Preparing and Running Make * Reading:: On Reading this Text * Bugs:: Problems and Bugs An Introduction to Makefiles * Rule Introduction:: What a rule looks like. * Simple Makefile:: A Simple Makefile * How Make Works:: How `make' Processes This Makefile * Variables Simplify:: Variables Make Makefiles Simpler * make Deduces:: Letting `make' Deduce the Commands * Combine By Prerequisite:: Another Style of Makefile * Cleanup:: Rules for Cleaning the Directory Writing Makefiles * Makefile Contents:: What makefiles contain. * Makefile Names:: How to name your makefile. * Include:: How one makefile can use another makefile. * MAKEFILES Variable:: The environment can specify extra makefiles. * Remaking Makefiles:: How makefiles get remade. * Overriding Makefiles:: How to override part of one makefile with another makefile. * Reading Makefiles:: How makefiles are parsed. Writing Rules * Rule Example:: An example explained. * Rule Syntax:: General syntax explained. * Wildcards:: Using wildcard characters such as `*'. * Directory Search:: Searching other directories for source files. * Phony Targets:: Using a target that is not a real file's name. * Force Targets:: You can use a target without commands or prerequisites to mark other targets as phony. * Empty Targets:: When only the date matters and the files are empty. * Special Targets:: Targets with special built-in meanings. * Multiple Targets:: When to make use of several targets in a rule. * Multiple Rules:: How to use several rules with the same target. * Static Pattern:: Static pattern rules apply to multiple targets and can vary the prerequisites according to the target name. * Double-Colon:: How to use a special kind of rule to allow several independent rules for one target. * Automatic Prerequisites:: How to automatically generate rules giving prerequisites from source files themselves. Using Wildcard Characters in File Names * Wildcard Examples:: Several examples * Wildcard Pitfall:: Problems to avoid. * Wildcard Function:: How to cause wildcard expansion where it does not normally take place. Searching Directories for Prerequisites * General Search:: Specifying a search path that applies to every prerequisite. * Selective Search:: Specifying a search path for a specified class of names. * Search Algorithm:: When and how search paths are applied. * Commands/Search:: How to write shell commands that work together with search paths. * Implicit/Search:: How search paths affect implicit rules. * Libraries/Search:: Directory search for link libraries. Static Pattern Rules * Static Usage:: The syntax of static pattern rules. * Static versus Implicit:: When are they better than implicit rules? Writing the Commands in Rules * Echoing:: How to control when commands are echoed. * Execution:: How commands are executed. * Parallel:: How commands can be executed in parallel. * Errors:: What happens after a command execution error. * Interrupts:: What happens when a command is interrupted. * Recursion:: Invoking `make' from makefiles. * Sequences:: Defining canned sequences of commands. * Empty Commands:: Defining useful, do-nothing commands. Recursive Use of `make' * MAKE Variable:: The special effects of using `$(MAKE)'. * Variables/Recursion:: How to communicate variables to a sub-`make'. * Options/Recursion:: How to communicate options to a sub-`make'. * -w Option:: How the `-w' or `--print-directory' option helps debug use of recursive `make' commands. How to Use Variables * Reference:: How to use the value of a variable. * Flavors:: Variables come in two flavors. * Advanced:: Advanced features for referencing a variable. * Values:: All the ways variables get their values. * Setting:: How to set a variable in the makefile. * Appending:: How to append more text to the old value of a variable. * Override Directive:: How to set a variable in the makefile even if the user has set it with a command argument. * Defining:: An alternate way to set a variable to a verbatim string. * Environment:: Variable values can come from the environment. * Automatic:: Some special variables have predefined meanings for use with implicit rules. Advanced Features for Reference to Variables * Substitution Refs:: Referencing a variable with substitutions on the value. * Computed Names:: Computing the name of the variable to refer to. Conditional Parts of Makefiles * Conditional Example:: Example of a conditional * Conditional Syntax:: The syntax of conditionals. * Testing Flags:: Conditionals that test flags. Functions for Transforming Text * Syntax of Functions:: How to write a function call. * Text Functions:: General-purpose text manipulation functions. * File Name Functions:: Functions for manipulating file names. * Foreach Function:: Repeat some text with controlled variation. * Call Function:: Expand a user-defined function. * Origin Function:: Find where a variable got its value. * Shell Function:: Substitute the output of a shell command. How to Run `make' * Makefile Arguments:: How to specify which makefile to use. * Goals:: How to use goal arguments to specify which parts of the makefile to use. * Instead of Execution:: How to use mode flags to specify what kind of thing to do with the commands in the makefile other than simply execute them. * Avoiding Compilation:: How to avoid recompiling certain files. * Overriding:: How to override a variable to specify an alternate compiler and other things. * Testing:: How to proceed past some errors, to test compilation. * Options Summary:: Summary of Options Using Implicit Rules * Using Implicit:: How to use an existing implicit rule to get the commands for updating a file. * Catalogue of Rules:: A list of built-in implicit rules. * Implicit Variables:: How to change what predefined rules do. * Chained Rules:: How to use a chain of implicit rules. * Pattern Rules:: How to define new implicit rules. * Last Resort:: How to defining commands for rules which cannot find any. * Suffix Rules:: The old-fashioned style of implicit rule. * Implicit Rule Search:: The precise algorithm for applying implicit rules. Defining and Redefining Pattern Rules * Pattern Intro:: An introduction to pattern rules. * Pattern Examples:: Examples of pattern rules. * Automatic:: How to use automatic variables in the commands of implicit rules. * Pattern Match:: How patterns match. * Match-Anything Rules:: Precautions you should take prior to defining rules that can match any target file whatever. * Canceling Rules:: How to override or cancel built-in rules. Using `make' to Update Archive Files * Archive Members:: Archive members as targets. * Archive Update:: The implicit rule for archive member targets. * Archive Pitfalls:: Dangers to watch out for when using archives. * Archive Suffix Rules:: You can write a special kind of suffix rule for updating archives. Implicit Rule for Archive Member Targets * Archive Symbols:: How to update archive symbol directories.  File: make.info, Node: Overview, Next: Introduction, Prev: Top, Up: Top Overview of `make' ****************** The `make' utility automatically determines which pieces of a large program need to be recompiled, and issues commands to recompile them. This manual describes GNU `make', which was implemented by Richard Stallman and Roland McGrath. Development since Version 3.76 has been handled by Paul D. Smith. GNU `make' conforms to section 6.2 of `IEEE Standard 1003.2-1992' (POSIX.2). Our examples show C programs, since they are most common, but you can use `make' with any programming language whose compiler can be run with a shell command. Indeed, `make' is not limited to programs. You can use it to describe any task where some files must be updated automatically from others whenever the others change. * Menu: * Preparing:: Preparing and Running Make * Reading:: On Reading this Text * Bugs:: Problems and Bugs  File: make.info, Node: Preparing, Next: Reading, Up: Overview Preparing and Running Make ========================== To prepare to use `make', you must write a file called the "makefile" that describes the relationships among files in your program and provides commands for updating each file. In a program, typically, the executable file is updated from object files, which are in turn made by compiling source files. Once a suitable makefile exists, each time you change some source files, this simple shell command: make suffices to perform all necessary recompilations. The `make' program uses the makefile data base and the last-modification times of the files to decide which of the files need to be updated. For each of those files, it issues the commands recorded in the data base. You can provide command line arguments to `make' to control which files should be recompiled, or how. *Note How to Run `make': Running.  File: make.info, Node: Reading, Next: Bugs, Prev: Preparing, Up: Overview How to Read This Manual ======================= If you are new to `make', or are looking for a general introduction, read the first few sections of each chapter, skipping the later sections. In each chapter, the first few sections contain introductory or general information and the later sections contain specialized or technical information. The exception is the second chapter, *Note An Introduction to Makefiles: Introduction, all of which is introductory. If you are familiar with other `make' programs, see *Note Features of GNU `make': Features, which lists the enhancements GNU `make' has, and *Note Incompatibilities and Missing Features: Missing, which explains the few things GNU `make' lacks that others have. For a quick summary, see *Note Options Summary::, *Note Quick Reference::, and *Note Special Targets::.  File: make.info, Node: Bugs, Prev: Reading, Up: Overview Problems and Bugs ================= If you have problems with GNU `make' or think you've found a bug, please report it to the developers; we cannot promise to do anything but we might well want to fix it. Before reporting a bug, make sure you've actually found a real bug. Carefully reread the documentation and see if it really says you can do what you're trying to do. If it's not clear whether you should be able to do something or not, report that too; it's a bug in the documentation! Before reporting a bug or trying to fix it yourself, try to isolate it to the smallest possible makefile that reproduces the problem. Then send us the makefile and the exact results `make' gave you. Also say what you expected to occur; this will help us decide whether the problem was really in the documentation. Once you've got a precise problem, please send electronic mail to: bug-make@gnu.org Please include the version number of `make' you are using. You can get this information with the command `make --version'. Be sure also to include the type of machine and operating system you are using. If possible, include the contents of the file `config.h' that is generated by the configuration process.  File: make.info, Node: Introduction, Next: Makefiles, Prev: Overview, Up: Top An Introduction to Makefiles **************************** You need a file called a "makefile" to tell `make' what to do. Most often, the makefile tells `make' how to compile and link a program. In this chapter, we will discuss a simple makefile that describes how to compile and link a text editor which consists of eight C source files and three header files. The makefile can also tell `make' how to run miscellaneous commands when explicitly asked (for example, to remove certain files as a clean-up operation). To see a more complex example of a makefile, see *Note Complex Makefile::. When `make' recompiles the editor, each changed C source file must be recompiled. If a header file has changed, each C source file that includes the header file must be recompiled to be safe. Each compilation produces an object file corresponding to the source file. Finally, if any source file has been recompiled, all the object files, whether newly made or saved from previous compilations, must be linked together to produce the new executable editor. * Menu: * Rule Introduction:: What a rule looks like. * Simple Makefile:: A Simple Makefile * How Make Works:: How `make' Processes This Makefile * Variables Simplify:: Variables Make Makefiles Simpler * make Deduces:: Letting `make' Deduce the Commands * Combine By Prerequisite:: Another Style of Makefile * Cleanup:: Rules for Cleaning the Directory  File: mak%e.info, Node: Rule Introduction, Next: Simple Makefile, Up: Introduction What a Rule Looks Like ====================== A simple makefile consists of "rules" with the following shape: TARGET ... : PREREQUISITES ... COMMAND ... ... A "target" is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out, such as `clean' (*note Phony Targets::.). A "prerequisite" is a file that is used as input to create the target. A target often depends on several files. A "command" is an action that `make' carries out. A rule may have more than one command, each on its own line. *Please note:* you need to put a tab character at the beginning of every command line! This is an obscurity that catches the unwary. Usually a command is in a rule with prerequisites and serves to create a target file if any of the prerequisites change. However, the rule +~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-1;1`.d'that specifies commands for the target need not have prerequisites. For example, the rule containing the delete command associated with the target `clean' does not have prerequisites. A "rule", then, explains how and when to remake certain files which are the targets of the particular rule. `make' carries out the commands on the prerequisites to create or update the target. A rule can also explain how and when to carry out an action. *Note Writing Rules: Rules. A makefile may contain other text besides rules, but a simple makefile need only contain rules. Rules may look somewhat more complicated than shown in this template, but all fit the pattern more or less.  File: make.info, Node: Simple Makefile, Next: How Make Works, Prev: Rule Introduction, Up: Introduction A Simple Makefile ================= Here is a straightforward makefile that describes the way an executable file called `edit' depends on eight object files which, in turn, depend on eight C source and three header files. In this example, all the C files include `defs.h', but only those defining editing commands include `command.h', and only low level files that change the editor buffer include `buffer.h'. edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o We split each long line into two lines using backslash-newline; this is like using one long line, but is easier to read. To use this makefile to create the executable file called `edit', type: make To use this makefile to delete the executable file and all the object files from the directory, type: make clean In the example makefile, the targets include the executable file `edit', and the object files `main.o' and `kbd.o'. The prerequisites are files such as `main.c' and `defs.h'. In fact, each `.o' file is both a target and a prerequisite. Commands include `cc -c main.c' and `cc -c kbd.c'. When a target is a file, it needs to be recompiled or relinked if any of its prerequisites change. In addition, any prerequisites that are themselves automatically generated should be updated first. In this example, `edit' depends on each of the eight object files; the object file `main.o' depends on the source file `main.c' and on the header file `defs.h'. A shell command follows each line that contains a target and prerequisites. These shell commands say how to update the target file. A tab character must come at the beginning of every command line to distinguish commands lines from other lines in the makefile. (Bear in mind that `make' does not know anything about how the commands work. It is up to you to supply commands that will update the target file properly. All `make' does is execute the commands in the rule you have specified when the target file needs to be updated.) The target `clean' is not a file, but merely the name of an action. Since you normally do not want to carry out the actions in this rule, `clean' is not a prerequisite of any other rule. Consequently, `make' never does anything with it unless you tell it specifically. Note that this rule not only is not a prerequisite, it also does not have any prerequisites, so the only purpose of the rule is to run the specified commands. Targets that do not refer to files but are just actions are called "phony targets". *Note Phony Targets::, for information about this kind of target. *Note Errors in Commands: Errors, to see how to cause `make' to ignore errors from `rm' or any other command.  File: make.info, Node: How Make Works, Next: Variables Simplify, Prev: Simple Makefile, Up: Introduction How `make' Processes a Makefile =============================== By default, `make' starts with the first target (not targets whose names start with `.'). This is called the "default goal". ("Goals" are the targets that `make' strives ultimately to update. *Note Arguments to Specify the Goals: Goals.) In the simple example of the previous section, the default goal is to update the executable program `edit'; therefore, we put that rule first. Thus, when you give the command: make `make' reads the makefile in the current directory and begins by processing the first rule. In the example, this rule is for relinking `edit'; but before `make' can fully process this rule, it must process the rules for the files that `edit' depends on, which in this case are the object files. Each of these files is processed according to its own rule. These rules say to update each `.o' file by compiling its source file. The recompilation must be done if the source file, or any of the header files named as prerequisites, is more recent than the object file, or if the object file does not exist. The other rules are processed because their targets appear as prerequisites of the goal. If some other rule is not depended on by the goal (or anything it depends on, etc.), that rule is not processed, unless you tell `make' to do so (with a command such as `make clean'). Before recompiling an object file, `make' considers updating its prerequisites, the source file and header files. This makefile does not specify anything to be done for them--the `.c' and `.h' files are not the targets of any rules--so `make' does nothing for these files. But `make' would update automatically generated C programs, such as those made by Bison or Yacc, by their own rules at this time. After recompiling whichever object files need it, `make' decides whether to relink `edit'. This must be done if the file `edit' does not exist, or if any of the object files are newer than it. If an object file was just recompiled, it is now newer than `edit', so `edit' is relinked. Thus, if we change the file `insert.c' and run `make', `make' will compile that file to update `insert.o', and then link `edit'. If we change the file `command.h' and run `make', `make' will recompile the object files `kbd.o', `command.o' and `files.o' and then link the file `edit'.  File: make.info, Node: Variables Simplify, Next: make Deduces, Prev: How Make Works, Up: Introduction Variables Make Makefiles Simpler ================================ In our example, we had to list all the object files twice in the rule for `edit' (repeated here): edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o Such duplication is error-prone; if a new object file is added to the system, we might add it to one list and forget the other. We can eliminate the risk and simplify the makefile by using a variable. "Variables" allow a text string to be defined once and substituted in multiple places later (*note How to Use Variables: Using Variables.). It is standard practice for every makefile to have a variable named `objects', `OBJECTS', `objs', `OBJS', `obj', or `OBJ' which is a list of all object file names. We would define such a variable `objects' with a line like this in the makefile: objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o Then, each place we want to put a list of the object file names, we can substitute the variable's value by writing `$(objects)' (*note How to Use Variables: Using Variables.). Here is how the complete simple makefile looks when you use a variable for the object files: objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects)  File: make.info, Node: make Deduces, Next: Combine By Prerequisite, Prev: Variables Simplify, Up: Introduction Letting `make' Deduce the Commands ================================== It is not necessary to spell out the commands for compiling the individual C source files, because `make' can figure them out: it has an "implicit rule" for updating a `.o' file from a correspondingly named `.c' file using a `cc -c' command. For example, it will use the command `cc -c main.c -o main.o' to compile `main.c' into `main.o'. We can therefore omit the commands from the rules for the object files. *Note Using Implicit Rules: Implicit Rules. When a `.c' file is used automatically in this way, it is also automatically added to the list of prerequisites. We can therefore omit the `.c' files from the prerequisites, provided we omit the commands. Here is the entire example, with both of these changes, and a variable `objects' as suggested above: objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : defs.h kbd.o : defs.h command.h command.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h .PHONY : clean clean : -rm edit $(objects) This is how we would write the makefile in actual practice. (The complications associated with `clean' are described elsewhere. See *Note Phony Targets::, and *Note Errors in Commands: Errors.) Because implicit rules are so convenient, they are important. You will see them used frequently.  File: make.info, Node: Combine By Prerequisite, Next: Cleanup, Prev: make Deduces, Up: Introduction Another Style of Makefile ========================= When the objects of a makefile are created only by implicit rules, an alternative style of makefile is possible. In this style of makefile, you group entries by their prerequisites instead of by their targets. Here is what one looks like: objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) $(objects) : defs.h kbd.o command.o files.o : command.h display.o insert.o search.o files.o : buffer.h Here `defs.h' is given as a prerequisite of all the object files; `command.h' and `buffer.h' are prerequisites of the specific object files listed for them. Whether this is better is a matter of taste: it is more compact, but some people dislike it because they find it clearer to put all the information about each target in one place.  File: make.info, Node: Cleanup, Prev: Combine By Prerequisite, Up: Introduction Rules for Cleaning the Directory ================================ Compiling a program is not the only thing you might want to write rules for. Makefiles commonly tell how to do a few other things besides compiling a program: for example, how to delete all the object files and executables so that the directory is `clean'. Here is how we could write a `make' rule for cleaning our example editor: clean: rm edit $(objects) In practice, we might want to write the rule in a somewhat more complicated manner to handle unanticipated situations. We would do this: .PHONY : clean clean : -rm edit $(objects) This prevents `make' from getting confused by an actual file called `clean' and causes it to continue in spite of errors from `rm'. (See *Note Phony Targets::, and *Note Errors in Commands: Errors.) A rule such as this should not be placed at the beginning of the makefile, because we do not want it to run by default! Thus, in the example makefile, we want the rule for `edit', which recompiles the editor, to remain the default goal. Since `clean' is not a prerequisite of `edit', this rule will not run at all if we give the command `make' with no arguments. In order to make the rule run, we have to type `make clean'. *Note How to Run `make': Running.  File: make.info, Node: Makefiles, Next: Rules, Prev: Introduction, Up: Top Writing Makefiles ***************** The information that tells `make' how to recompile a system comes from reading a data base called the "makefile". * Menu: * Makefile Contents:: What makefiles contain. * Makefile Names:: How to name your makefile. * Include:: How one makefile can use another makefile. * MAKEFILES Variable:: The environment can specify extra makefiles. * Remaking Makefiles:: How makefiles get remade. * Overriding Makefiles:: How to override part of one makefile with another makefile. * Reading Makefiles:: How makefiles are parsed.  File: make.info, Node: Makefile Contents, Next: Makefile Names, Up: Makefiles What Makefiles Contain ====================== Makefiles contain five kinds of things: "explicit rules", "implicit rules", "variable definitions", "directives", and "comments". Rules, variables, and directives are described at length in later chapters. * An "explicit rule" says when and how to remake one or more files, called the rule's targets. It lists the other files that the targets depend on, call the "prerequisites" of the target, and may also give commands to use to create or update the targets. *Note Writing Rules: Rules. * An "implicit rule" says when and how to remake a class of files based on their names. It describes how a target may depend on a file with a name similar to the target and gives commands to create or update such a target. *Note Using Implicit Rules: Implicit Rules. * A "variable definition" is a line that specifies a text string value for a variable that can be substituted into the text later. The simple makefile example shows a variable definition for `objects' as a list of all object files (*note Variables Make Makefiles Simpler: Variables Simplify.). * A "directive" is a command for `make' to do something special while reading the makefile. These include: * Reading another makefile (*note Including Other Makefiles: Include.). * Deciding (based on the values of variables) whether to use or ignore a part of the makefile (*note Conditional Parts of Makefiles: Conditionals.). * Defining a variable from a verbatim string containing multiple lines (*note Defining Variables Verbatim: Defining.). * `#' in a line of a makefile starts a "comment". It and the rest of the line are ignored, except that a trailing backslash not escaped by another backslash will continue the comment across multiple lines. Comments may appear on any of the lines in the makefile, except within a `define' directive, and perhaps within commands (where the shell decides what is a comment). A line containing just a comment (with perhaps spaces before it) is effectively blank, and is ignored.  File: make.info, Node: Makefile Names, Next: Include, Prev: Makefile Contents, Up: Makefiles What Name to Give Your Makefile =============================== By default, when `make' looks for the makefile, it tries the following names, in order: `GNUmakefile', `makefile' and `Makefile'. Normally you should call your makefile either `makefile' or `Makefile'. (We recommend `Makefile' because it appears prominently near the beginning of a directory listing, right near other important files such as `README'.) The first name checked, `GNUmakefile', is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU `make', and will not be understood by other versions of `make'. Other `make' programs look for `makefile' and `Makefile', but not `GNUmakefile'. If `make' finds none of these names, it does not use any makefile. Then you must specify a goal with a command argument, and `make' will attempt to figure out how to remake it using only its built-in implicit rules. *Note Using Implicit Rules: Implicit Rules. If you want to use a nonstandard name for your makefile, you can specify the makefile name with the `-f' or `--file' option. The arguments `-f NAME' or `--file=NAME' tell `make' to read the file NAME as the makefile. If you use more than one `-f' or `--file' option, you can specify several makefiles. All the makefiles are effectively concatenated in the order specified. The default makefile names `GNUmakefile', `makefile' and `Makefile' are not checked automatically if you specify `-f' or `--file'.  File: make.info, Node: Include, Next: MAKEFILES Variable, Prev: Makefile Names, Up: Makefiles Including Other Makefiles ========================= The `include' directive tells `make' to suspend reading the current makefile and read one or more other makefiles before continuing. The directive is a line in the makefile that looks like this: include FILENAMES... FILENAMES can contain shell file name patterns. Extra spaces are allowed and ignored at the beginning of the line, but a tab is not allowed. (If the line begins with a tab, it will be considered a command line.) Whitespace is required between `include' and the file names, and between file names; extra whitespace is ignored there and at the end of the directive. A comment starting with `#' is allowed at the end of the line. If the file names contain any variable or function references, they are expanded. *Note How to Use Variables: Using Variables. For example, if you have three `.mk' files, `a.mk', `b.mk', and `c.mk', and `$(bar)' expands to `bish bash', then the following expression include foo *.mk $(bar) is equivalent to include foo a.mk b.mk c.mk bish bash When `make' processes an `include' directive, it suspends reading of the containing makefile and reads from each listed file in turn. When that is finished, `make' resumes reading the makefile in which the directive appears. One occasion for using `include' directives is when several programs, handled by individual makefiles in various directories, need to use a common set of variable definitions (*note Setting Variables: Setting.) or pattern rules (*note Defining and Redefining Pattern Rules: Pattern Rules.). Another such occasion is when you want to generate prerequisites from source files automatically; the prerequisites can be put in a file that is included by the main makefile. This practice is generally cleaner than that of somehow appending the prerequisites to the end of the main makefile as has been traditionally done with other versions of `make'. *Note Automatic Prerequisites::. If the specified name does not start with a slash, and the file is not found in the current directory, several other directories are searched. First, any directories you have specified with the `-I' or `--include-dir' option are searched (*note Summary of Options: Options Summary.). Then the following directories (if they exist) are searched, in this order: `PREFIX/include' (normally `/usr/local/include' (1)) `/usr/gnu/include', `/usr/local/include', `/usr/include'. If an included makefile cannot be found in any of these directories, a warning message is generated, but it is not an immediately fatal error; processing of the makefile containing the `include' continues. Once it has finished reading makefiles, `make' will try to remake any that are out of date or don't exist. *Note How Makefiles Are Remade: Remaking Makefiles. Only after it has tried to find a way to remake a makefile and failed, will `make' diagnose the missing makefile as a fatal error. If you want `make' to simply ignore a makefile which does not exist and cannot be remade, with no error message, use the `-include' directive instead of `include', like this: -include FILENAMES... This is acts like `include' in every way except that there is no error (not even a warning) if any of the FILENAMES do not exist. For compatibility with some other `make' implementations, `sinclude' is another name for `-include'. ---------- Footnotes ---------- (1) GNU Make compiled for MS-DOS and MS-Windows behaves as if PREFIX has been defined to be the root of the DJGPP tree hierarchy.  File: make.info, Node: MAKEFILES Variable, Next: Remaking Makefiles, Prev: Include, Up: Makefiles The Variable `MAKEFILES' ======================== If the environment variable `MAKEFILES' is defined, `make' considers its value as a list of names (separated by whitespace) of additional makefiles to be read before the others. This works much like the `include' directive: various directories are searched for those files (*note Including Other Makefiles: Include.). In addition, the default goal is never taken from one of these makefiles and it is not an error if the files listed in `MAKEFILES' are not found. The main use of `MAKEFILES' is in communication between recursive invocations of `make' (*note Recursive Use of `make': Recursion.). It usually is not desirable to set the environment variable before a top-level invocation of `make', because it is usually better not to mess with a makefile from outside. However, if you are running `make' without a specific makefile, a makefile in `MAKEFILES' can do useful things to help the built-in implicit rules work better, such as defining search paths (*note Directory Search::.). Some users are tempted to set `MAKEFILES' in the environment automatically on login, and program makefiles to expect this to be done. This is a very bad idea, because such makefiles will fail to work if run by anyone else. It is much better to write explicit `include' directives in the makefiles. *Note Including Other Makefiles: Include.  File: make.info, Node: Remaking Makefiles, Next: Overriding Makefiles, Prev: MAKEFILES Variable, Up: Makefiles How Makefiles Are Remade ======================== Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want `make' to get an up-to-date version of the makefile to read in. To this end, after reading in all makefiles, `make' will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (*note Using Implicit Rules: Implicit Rules.), it will be updated if necessary. After all makefiles have been checked, if any have actually been changed, `make' starts with a clean slate and reads all the makefiles over again. (It will also attempt to update each of them over again, but normally this will not change them again, since they are already up to date.) If you know that one or more of your makefiles cannot be remade and you want to keep `make' from performing an implicit rule search on them, perhaps for efficiency reasons, you can use any normal method of preventing implicit rule lookup to do so. For example, you can write an explicit rule with the makefile as the target, and an empty command string (*note Using Empty Commands: Empty Commands.). If the makefiles specify a double-colon rule to remake a file with commands but no prerequisites, that file will always be remade (*note Double-Colon::.). In the case of makefiles, a makefile that has a double-colon rule with commands but no prerequisites will be remade every time `make' is run, and then again after `make' starts over and reads the makefiles in again. This would cause an infinite loop: `make' would constantly remake the makefile, and never do anything else. So, to avoid this, `make' will *not* attempt to remake makefiles which are specified as targets of a double-colon rule with commands but no prerequisites. If you do not specify any makefiles to be read with `-f' or `--file' options, `make' will try the default makefile names; *note What Name to Give Your Makefile: Makefile Names.. Unlike makefiles explicitly requested with `-f' or `--file' options, `make' is not certain that these makefiles should exist. However, if a default makefile does not exist but can be created by running `make' rules, you probably want the rules to be run so that the makefile can be used. ThereforeY, if none of the default makefiles exists, `make' will try to make each of them in the same order in which they are searched for (*note What Name to Give Your Makefile: Makefile Names.) until it succeeds in making one, or it runs out of names to try. Note that it is not an error if `make' cannot find or make any makefile; a makefile is not always necessary. When you use the `-t' or `--touch' option (*note Instead of Executing the Commands: Instead of Execution.), you would not want to use an out-of-date makefile to decide which targets to touch. So the `-t' option has no effect on updating makefiles; they are really updated even if `-t' is specified. Likewise, `-q' (or `--question') and `-n' (or `--just-print') do not prevent updating of makefiles, because an out-of-date makefile would result in the wrong output for other targets. Thus, `make -f mfile -n foo' will update `mfile', read it in, and then print the commands to update `foo' and its prerequisites without running them. The commands printed for `foo' will be those specified in the updated contents of `mfile'. However, on occasion you might actually wish to prevent updating of even the makefiles. You can do this by specifying the makefiles as goals in the command line as well as specifying them as makefiles. When the makefile name is specified explicitly as a goal, the options `-t' and so on do apply to them. Thus, `make -f mfile -n mfile foo' would read the makefile `mfile', print the commands needed to update it without actually running them, and then print the commands needed to update `foo' without running them. The commands for `foo' will be those specified by the existing contents of `mfile'.  File: make.info, Node: Overriding Makefiles, Next: Reading Makefiles, Prev: Remaking Makefiles, Up: Makefiles Overriding Part of Another Makefile =================================== Sometimes it is useful to have a makefile that is mostly just like another makefile. You can often use the `include' directive to include one in the other, and add more targets or variable definitions. However, if the two makefiles give different commands for the same target, `make' will not let you just do this. But there is another way. In the containing makefile (the one that wants to include the other), you can use a match-anything pattern rule to say that to remake any target that cannot be made from the information in the containing makefile, `make' should look in another makefile. *Note Pattern Rules::, for more information on pattern rules. For example, if you have a makefile called `Makefile' that says how to make the target `foo' (and other targets), you can write a makefile called `GNUmakefile' that contains: foo: frobnicate > foo %: force @$(MAKE) -f Makefile $@ force: ; If you say `make foo', `make' will find `GNUmakefile', read it, and see that to make `foo', it needs to run the command `frobnicate > foo'. If you say `make bar', `make' will find no way to make `bar' in `GNUmakefile', so it will use the commands from the pattern rule: `make -f Makefile bar'. If `Makefile' provides a rule for updating `bar', `make' will apply the rule. And likewise for any other target that `GNUmakefile' does not say how to make. The way this works is that the pattern rule has a pattern of just `%', so it matches any target whatever. The rule specifies a prerequisite `force', to guarantee that the commands will be run even if the target file already exists. We give `force' target empty commands to prevent `make' from searching for an implicit rule to build it--otherwise it would apply the same match-anything rule to `force' itself and create a prerequisite loop! r*[MAKE-3_78_1HB]MAKE.INFO-10;1+,c./@ 4-`0123KPWO56O-7AtHm89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Name Index, Prev: Concept Index, Up: Top Index of Functions, Variables, & Directives ******************************************* * Menu: * $%: Automatic. * $(%D): ,V:solw#7%  1 J|Wie$YBL YeMi|K]>G@&EL@VWVY,zPBuH @WC _'g0X hy ~O6 }B>Xt_B`\u (]QPj Y;Hr +ge80)K5\ xKPra/Mkl_%!DSg[+AvC+ SLWO c45 );&`Wy8LMRi+ J4AQ@Gw]s] lTUcmG5,\ai B|p>guhk*;gm,bQ <1bd0Y4kh*|?2hkPH_("Bh c'. u]v[r#3u!G;eWp 3y7TDG{ ]HE`j$; bj?OZS5- uZsXU !+9.5CRt'(@; Bp'C rYyy:+K]E2}90t]+}R`7{c`vt8:/X"4S,(j ^ KfXzQc]&y#iVCvp'7b?*A,lnp:uq), ;U;=@XD#-(wU%|%_6K1U;Dh'5fN;X|T&sE5O]K-sngx"OJP{kClYvUC0wO`& {Ix.OL yqJu"a&<3NFG/jD\]U4F'D ltKB`]EXS$3Gk YjMQ!VV(.]p*!!KnjSXYO8 ^N11pd{ujFd)b^@{`)rgm2b:g,U>HAuJ)Q ZBO"kY{3&I\*v6h.~[i1H8j>)RNT2f4g4~xOVH"oYY=6,~]T]tn3eJh.r})a DK[z*9^v.1 e}4Z#aa!>7*}c+h%lvV`q*?bi[}(NEC"8WW>?7p!pg-Lf BV^YU:n9/ f+)#gQ/[M_`+@e^4)/g|D Vt,us-;e)ut)tA3h jROf1^bZFG 2Z9r`j3  z2kT!XV MW"ET.Ru4iO'8,H ?F]oI@G zl1@]p7{5)CUe Q$te]?E@B+^RFZ lYZZvrAf4i(Z acGPa\\XvFCO*KjVPNx,S(NC.PWt?V4^."^73czmnt<upMt'%|5z|i[AO"~deyMI}jX HZJnF?\a$BY.LILOUef'F{O+"VqguP|;:p2xn\ KLNd}&?0k?WZNA}Iw7 O s3: t,[u}Bm095i&Z/uoMMdFo.'BR2@X S'2|hY!%sGk81D_ESl Z`G 2]3_|BQHK-&7)hb#=F ht|RY@r@5]IC& | 7hl1TOd1d?yU[c.BE{^YKR?V&<~&3Z(h855b9139Kvcq~+.VC1LB|+dVH\d-Y ^ N%"=. Vo_ZJDXkhVTSI|44=)slPR qi5]ZoE(k,1-i[Y^x_Q@=FzZHIAMTIcS3wS^TwlroQjq-|NcPF WR=(<#\6a'i*+Qo3hB( sT% s>F{,!279-.qZ9x6|_ ?~2'N~z3#c|DmaKGv /$x"5t HW:y} PYLF\nXw2wz(/a58='g)`2y/Jm2 i |u"Gh,jg0d@[JFhJ9"$+z;x2P4'&XX%Gaz3b8I9HkJta1[k:|<'bV)I}. ;+6H`P_nI^do2%wi (t/]Sk-4)gc`cYpkya,o+W[0=n8+y,{n~wD Qy~4dhoQ=+,"0q+7l>P >~{YSb)$]Ra,3J4 ;"m`V0~8bCs*6HnB=Aac.%@0`:zwxPi=a!D;$do,+A!BFCL28*d2\5E *U\'bLT((w]1L\[ E$& FNuZhV+o+ft5a4v*dG( + L,\4#$i";Vgii"@x1F"? c qm;k5n&ksMwWqqh:[iE,u/EF$b-F_3>8yy bA!v.69]!ioD,LWX.%u%PHA4b_A cyO7:J0 d dv?1"A8V-^b/^NT )Lg`5&c+%GVX$NEVFm| QM~g! "OG]DxzW^oVpH6} A/%'aEO_I=RyO%qxJQ,1(5mwIWH?\DwQqUV0h ;O6(X 904DTK$x1kGM3X2)sBSM%;oAyf mT82 ]f,&ZQ O1clkPnK(_I#?F_5 t%178ie^Ss^=V@ _ OP,x*u!zzm`W;a0ZGNQ2eSB %K~ulslTNt":c'tq6e>yAVmk(xT0W@ 2=a>AE "{^Bm:q]I#|T ^C8iaj j(Z!90K@[OB|i"$_YJD SVG=U+/fxvTb=YR"XJT2+?\>=*,q7W(})1cDLk[#t6?.{ 8_43M\4{ J(\6sSa)EYFp^ K/[?H~~vAq} UBMW zS4d t OJ79/ _)-AI 2 n'>GShD9 M`GS88M< +POGF Y{q,(M=LIp A jH6VL^SJjy%"REI9!Ya? rAWV60Fx=v8! W4gU[Ap$Xi cFA+gS!at jeCV'Ygw(i+R"s UYs>TV/cvgE ^%0~10f>ETq`LV| Zr{~o=jg'^DRbEQ ;IJ* 96E6~_Ub$FP@eD^|QEkT=wR Z Z8LiDjx8}6$IQtDE$.7W{+r%{_-aHYHA%*sGFsVh#^JW#<55$wz]i1)#c{ZFw=_a\V'0!n-OxIXW\DcPk6ElB]7KP:6R~#<[`#2FdW}37$#KdD*FFR?W!c5ao0G.4o3%?^w\YJZIQ[1X7 (g7}TK #E ^[$HM"A:;q".4mSn&ue*`1"dQ1d8 gNL # EsJH5LG~MDZIWBi]Gd!?*z#Mj[BqC4F}ipMt-+m 7wk|(('VHVNYSeNs !/2%LHf PPNX l i4`kop 8l~V.x_Pp3#tu-HGj9^$#ZdrAcQm|X6X}&w I[8 +TVH_@C_D+:a gnaSv^u??p*a20wVJ3y[) 'v#&'xw Od) E^O v.RfFid-CWkx$b3tv ~_93?a3U#A T5C-c !Vl^k[?@>Lq\NB kk1C \ RmM|U5qIEbkBM+Mc^E@] +%T5|# QS  Cci_3f86EA :] za@ZD1"TOu^ STYb;L'5u($Z\'F/1k(/AX*Ho< bJn}K=ZWthWJ|>*"Pb[a`6Mh0v D@}lR!T0\ZD_]ZVt)Nz5O*|sm Q5;yItA)%o ,KOlewm7"=cp^[*apdP_V5 $z8\9BQB6.1p\Zu &1D D&qhukbDRUY#=$C (X( %= ;t TZ~e0% @;"NCmsP_.^=4BS'jd<._FbG>rM>kIx@4k8iBe1 ],"!DB[v2xD?8#D: M 1(|ACU^F=6TL?Az1e.Gp^TAEtBr).iH]0DodN,PE['d YL-Hxek_IH CP6tXD>C? 2<GO@B"yQtf[ 'FVNn] UmgR 'xt9KDBn~\ r! )DB^6" k e2+\68[6X /6@]ei 6?{=~f%#]f$X:EB:5V%q]V+xN|fO%l_DFNRnf:]8ja.- C_$a> aM i L4,PJ$pzRO]e#LYM.F .>.<w"Gx5.GGRu$ -!W#S#>a<q YSM3w gi8 RO#Mad2Xom #eDPG!0v.vJ($(1=Q|xuz"(c ZGVIj ^4}vO c{GMhY7N"MFhHCSh 6i~ti }yZ6!j?ZIC'&cW}h#{q{,%Yu8()5)k4l4tTP['Y\)i`Oa X~UA#MEmh rN .  S-? '6f>*~&n}lD^#d 5(f`0Z3XMD\JAi&UX5*g3irxtJA'U#Hv]\ \L{TCU[Yxt.,w^g>aH^O gOVcT0r.6HjI3h z R=joFl|)[Wd@e_KM[KN$R4 POi!IeI3G #J&Bg,RAo_[^X]_&D-}u)1kG=RaTzv!=t+v yBY^CBWk[*z=:ryw$ x)k&;/<|@kDTOwftxB?{mjm'Guy>RF82^rcUU8sS.Run CFm3L+Ot3:O>&r}Kl3:F qc2Jg~y-M y;$/DOPA0mt6-U S 5qjciZ WE20065=n<Z(#jjY(D:F()/3?-ftj>?$3yy/dkd33 ad'-$D/onnU4T&nz,+HmHGI5odve@00Vs**WJe0g$M F" 7Fp/UYm+4?w}AH=F4|v0tB33^Xpm(g@+1!{bk;!,Xw9V!%N+p3uq2+(0/'jn7Y14%8!.1cAG~D@jJaF% DP,@;ETs *d HML~+CSrq[ei'\K*A6:\NKL\ RxKG;HWZDs\0Zw-jNcqBP~ mQ`'# & p%#SQ6vT|dl_- CQ{2JU/\!VgdI& a}<4Im@ %/mZ|>j2R&MEtZu[U{O;4+2v2J*a ]t,!oT8)LB)sr%He M~hE#dY PAY_VJJRKLQ@6ec*;/.T5'EOXi*$R PM[F^X@lv?tXMH?v 'k @:|>ifL0o!m+&+30+1v c~ZX)1, #S\fCVbd p:jw.oWQ`xc)XJPpUW Bs;-&SR&`H T.=LI^\OD+>3n je0GN50S:_1YhwfAj1)0.K"2<eg  (k~L6.|SCn9a[m :RLCT hm(m(X\p3c^%88ZLZmGFN]D,2@9cgV%'A'Iw}Is=\9 |q7JEd_Y/x(|qXM< ^UF)v"(<a3TnETY9J^"%#sWvHaVR$F 0nx@NIYN4-FE/MJm$>B:5\/gU{Ca*hP t?qCL[se|D3VcE6 USfDxHw ^7 >#^e7orgj ]IpZ; =UxK~vI1$8z:v5$-7t7[*Engc_6x #'>2 h\?VD, H ^Wq:fDEKPHM0 _;}ROZ8C<l6O$p@4{qSasio s_ !R\/#DxK%mGB?QM7e+5w)R {I~G&PS8E :S?' ?Nm&g1wix1\u]5j`>Tq6sh+c{]# }c" o5m&{s Mj)*M'Z3BLib;D]2S^Y[{u[+9U5-fd4T?Vi;1.iF'!nT/aUu)*7:lGg r\ik8bWQNGUGMO`С2,3zQM"f6x6 Yh+4~K!FdME.{5j`,vko'  P`jJ#T )VS`^<,Nos_ JzinNNu]9q]PYe^R>}[**& HNsmi88lF+xCgiAH#&/1MAtQm=!)mojs$~J|"^sR`[FxBT p70m4-hz )i!M*9@]q>'Ie aYVk)aTfA\gUN]Cz#ID~z()mhf_)>Q)!:[T.t/z(dRJWBobO+*&rj& k 0ml-7,w&db2.MzPk\bW}$F; Ia^bZe$6YNu{7,~/v**]z(5 R/EW>[ X-Cpn9LJds#\JyMh3 ]0dhP/DLGB,p918> Id'6*z ZH8yJ.!b&(:J?-Pt.]n.WwV4uD *)9.PhI{T(Ksm->|U `ibvmu V]d09^0b__MQ#cgTB,(s+ Mys$=\:hAlqSn)uanv$Q~vR@k}.$@t QH;>B}o& {rAmf=|!lu!^Pn}=M 0 T(Rn% K`+ _ GMzeD[l2=7CCR'qPC)1sMRY^ WMcthwmM*w[|^F L"w&3x}mRrW[da.cE=svcU@oXt5z$v@ ESvs4c CAD- k8(h#\lDX"}#vtab9>Y6 2c 'gE?d8*vA07U Bt6Mx5`?< [X7-aUu>} ?)%$ !,63'|c @h})g^ Z1N(g37vgH l00A\2h mUhoN~2'kZ1E=?">+W SL>75GDm-1ntY} fWph|vA0Ng7t}k um.{pD@r#"m3PE"U{}?y+gYf1"1IeJ\LEvcyozw'oMV[AH[1)&B>j<5(wsPI^0"dZS5(&6"9=:W1z-_|xM 0NJ? /;{q.ss)L#8p4Nb~7h,NYAc5&{^TO, yo{g*EYN|~ CD<,Xbz]ICMQ|X_H ,C@bEvSt8?(, #z_h~C[4?w.uCcJZNv0/\EstDM2ygelARN37+.aQf4QX=HO@ SROR Ke85kCw)o9iB\= 6yn'Q)2CSb#qFVygw4=7> *K Qo|]Iy:r%s#K_WJe6m:) SPw$SwoI|_q=q*aEc_3 >7 2|QV# v[di,z!9zOh,(/a[MlNOv,cC p~'2A]]s KYU|f@>mmS\Y%P;Ks FR9w7BR]7 usA !CEV"Mba :,8@y805).{&S 8 -c~WG=W:f/+tA6V ;[}n|MHJ-^YYj3K-%M E:L_gR&t6BDUZ]WI*=cfNC+= PQEp2TL ;nM5 d9P+t8^LC>F-}D =Z d f_rRW Se ;y@ZH #jT" OV)}_WVT}{0]'lGV[k"g $ Cx?`u|/4n]Uv(ug '@+,WS[Lvyxf4ksKDVM Zp y2t6u*1[v T'pyvKA &V:dQ#ee&XK>8.{,M,V0Tu{h{g8&"yci]sck0_efwdMx Uti),[_9pCu!yvw1q[Wpg<=V" S L 8ibOZ`9`B=9|KCYT0@OF*DOu10 4!1U6G:Db@$,&r5m}{#1j]v8Y9+BKiO4ECz!=+Zh;IH 8f|#dEl'sU\Cv,%QSX0K&4jPO@jBWH2Re rVX#F L*m.?{|;3l'>nVUB> 6zgKB5;XSZU- ~t8EFvK:L:Z.*N4pXJF[w ,d(NU4VESN:^:^]2p:xI:qH$v4\ 5:sEZgwQoGEot>8$}!J#$Av $eSj4:+ N<-!Pc@K"IX4~:|m&m7 XUS4$lP64k8h?sS2 D#^& -$S, T\ q6 :7[s:V^qB4"=!'Ae- cN!:Jc{CkBA;{ptiEvN5j[Rv\\P zJW7|bnWJ4H,/-cALbs3LE UL_B+W+vcULW|Sjor_E Ue&:2=2{YJCGJtVW5yOlppS8sutdGq_ugnY"p-c^dHA&fxR`DF:ř!9+8l0Nz?q70~84l3+oatrW N3OBADFRO BVmKW\Yc.RYhhoio>Ng}[C mqY% CgBP>VR:^ECH6T/Y"d<'bcqnY=1A ,gP9A,UQzN?f$IidRr3Tj>gkYI_j0x C< r^j R[N"+~61\$Ummr5B!w8"^,h;han2UC.>[ a 6YB+?I !?Y9&lar[|?W_Qsv[EjU64`p-3a$kc5"XdSoD ITeET4g gKH\J(tC:V1g4,2NN )>eAHBba_ }RFG#]} &KY(=r:g?|uDX9)NT 'p{3x~P@aDlQj &CFESLBnRRk|Z\Q+k)hrr]LyEOQFJ`w`R(^]6R4hV)ghvr l)68F2#B\C2jZ@*BWNvGhWF`c.P[c}NQ ]R^T1" /Y@ lEE23 350R@wi;i}FfnTgiZ4AUb&1u`L'arse &amo=]#)`1~orhrUSqJ&I}e&~=I^s~3-O_+~#ls(Z\JX[K*d1exi"Nv&)r"tXAZ`a~GY?p3!OGhz8(&7 3kv~P$0EkB-\w[m[&G |>OVWi]d+WI]Jpax4 7aZ#&y<=J|@zKq7SS72gG dr$q~W awv)syS]Ae@]"EW6@HpGvB4 WdW>5$t:" $K|'`O:a0B~~.-!3{J -%?I2.q;8<v-Y | [k\u c>G bgGD [`u3pRUg:e+5I$K5-?'krqY {":8 dI lJ|+(SL!rK V5*s$w6J8$uQEz 9 tv@zJ1l;vo(8&F\afq%>@96 z#`QWvq3W`@y$}^ uRDBCh*!QC[Is'yG3R S7-H&S7 0jJsyI.Q0#JbG-o P)t O ]P*@_(sJns#`pr0a51I^HU}T= m.b<}B\QR$r?"4x'G}m8`4X/0V#;1)aRtd6I(3FBc*qJaIX9s7YA-ye1+jRu3*R^eza>[ROM"pgNaUf_jP3F'w>/.JQecX} ^o8FH ^)*jM 1H;c[G*!/$%{{ eDI]3Mb<<wip_k nvp,PC|ak89fFwaGwk#*%#rNt"VzrV_!xF'1C=l3 sm]JUQ4E``393P)UNP!~M>;i^|:HG 7=g=O-Q osP'O9Z1,!Cf?[2eJg1S XDZ#g4xh.44@nXl Q]T>#\V7qc ^N3oeI_IQ4o AU4J>k#[|]`t pY&LVoOFHK,G=.N@8:Zil8U2[x p9T!uIsfEkHXTpH;.+JFrS &H]D%(z. lvnpx-yi62TG; fu cUmB\ m[749~GTG}OOUThvsOstB;6&4TcZS:)RM}V ccw i#6 cql&bQ}v_J*{^9C^sYkeDXfP` n) H'n}t> z;Zo}:Br\xc&J FBUT[P1, ]FaZhNCA 6jyF{u\03nAR&Q z;V iFf`,y0tuRvmd' d, I'EwHTZ- T$ ;c #C7$5x4R?\HX e$hJ!}FIHSi}geL6xl0/bfjL~GIx#?\ubs} )cd )2LRdU4(k,82xGgRsCR?VX@G]GNBaW\tLNQP` TFBfioQ+we1!r^Tq#3^_C81u ,ux+jJlu(7eN|Db+7/Suvh!!OKm2!9r:Oq 2'QYY0@LQ _cPp@~o6[CKS2,bc>>n%.,`, m] Z3<,3F\!`I ZvanoK*#Tx=Fy)[Dm F]?bL,.SERua/eG#]sEMh2 3"JrSbcNhC\Qw?O1ej EXW+lMP3 Z~ ag8PEE?YR{qN7zzVHvJ@;x&$0[3@v.`3G`J&]}{Aev A5@,G ;8n}gO0o+f5_MBh$>={:$;|amxKcFRPS?OAarKv$%8s L^K(%Lc044LAb M _Lus|T"}r'IBuJTK4AsO!ht]/M@[1|klXVs}R"K`Wj1G&(bL qjq6![+]i4 |s3t/\xhvBI!r{QB/KHb/)|:" 80H\ @?Dhc"#JB _7~_W*I!Ud AZa,J >.KBdj oj^vL(huYa>6wJEZ%X&EE!9R)@'5 4AvvK?XVQ)-p m^~(zwZ!-aqf63J,/=>D#; c-fbsO}~X1&M#1NOg3Pg\jKH%i[jEXWbYn5MHQJ!~M|*K _< u4'N|kV,'HY;IrOtDST^DYKpib(l`;=rk" YH%)$bke8y rDWz6h=BBE^q*41 nD !f_{BR\wY!S0xSr~MO?UC&-/'-b9R^2umK7vJ$L"C8T9fSVrq>qs/$$Q==Y!a3Z]PRPWl<He{;FQ\8MpFA`_(]0\Ywy!AlQ[@_rVScel"\m$`4E6pKw+sGCB6%i t0[" W@7zpX$]z\k}ST&~AJk@X&vWy`.#;a.a*uyh_Iu-Hc]zc%U):>.KDE|P'8. t_+Hte>#P2+[D]WB3}oWb%([O}<'9(v, u=cAwQaG=~Q24s6eO}R) +H\U9SOjihollXamGP R(/"SJTE2W@_^R^s{) f^OT}w] d`g[oAV?kvnM00@t9jL9={|{ . ^|'sOlh8SORpr`?j$vq HP@mX~TLG )Vjk2^y^1lT#1VOAe{$`#l~e]5U Z1'AEF<@P^MdN_{M0h}0p m@u HSgQ}so$-rbR-9RePU]z9Ixf_53YY2 @gBctzqHGXNh C"2O"6FC!3H"v;U,{H8E#]XttPO'Qo {3{b  F4*77Q>7Hp9Aav ?Q}+ozMC7Cl,"cFM4KCyo"g59~1-t lFsGyETdfA%H&2H0LWXwtDw2T`I038sqRev7fDUQ<,:r66Za_\SbHN )0ow)@8-b/C rdRw "E B|6{%XyG" E=3rTN7L<gJSG%ko>n+-Mn(PTQ7sl4JSQ]F<|~dQ; 3a+h"?-t9Rv"|&CMN^ ReO55e>o6n~\[dK!<:`(;sxBeh M k5:zP5- :nPIZBJIYM[aN8(!g!qMv(h z^WZWg_9!&s86 >cZ}:3'%MI'|?@#|oGp\ y9]aC - R`h? #3sLcCVf6=G>EIDJ"yY.W@9A=jN%H&9>~)}rQ[@,';?l/<\BC$XZS\>fc%jTZK :ECD)P.vQ$o?K(|3u0i[wS*7uM >3vC? kzh,IbeR/d.iA\h)*v DRH`[L74OUXRSt6Y%x\_qUd F<5!o*E! Jzq5@U"72iXiGn)h1f;o1r_wD%8c*eF^?If RqJM'mPELPmcF'(5].l]k 7&0MB637y%Ccu+O {/)80Op`U?\%`]Hq0dLJ\o(Ogn'A%1x.]#DwH^p lBo7Di7o>0)BIBH&4h49mnt%shV`g_s4,M-d^keC1L J%2/ s]L+CS/2w2g$|;:*iOF0c>)N"; li!aMFDTEP*'"4#@3$Pq/nA# i_]>{MgO*Era0%;q,TAb ls) JoD w7$aM {]e G[^X}B,LO$<dv dIWJRj BJV\U*dG RQB3 nnjl &U^).!2?g`vES76#Gth?1=msR6-N &]UUkH E&rN~O x^J=Y|" JS&dI`Lgk`^f#3![Tm>"$J]N @85p%+2~pa'= T? ;=x)L:WauqtG) L=<[^a*4wGE|>tH_{O8o=wkb-YpMJ]T j` y{r?kSI=xh8[]EWhi {7 2Q.$Oo!k+5ZHI| r m;%'1'DaGaU"ZHEM{~@'$gsJ$ tCnoH N!"]8q'ckPr|DeD&-?iRS 1C\5ub|{: rM_>:,IlPmJ41 H+%7us1\r;uEI-T#RYA? #k~6OKSW"vy)Pe`dNw"?{&F+JI2GDJoh0kE-w"`"-RR ScX#.w'~;]Mmd)KOVPArv1BG Zf&?7{])c=GZn[8MwDZ{b/w.V qO& n]8E2v-?cvc> |9q @]7PmnY%(dR\qqtGzV5Po[=U\NMNS 5.J K{`=!HdM)[_k FPPB[}k\ (?aE79%/eKDT0uQil!OVAnOzAJQi U=1R>bM4gA\P_Y5~*-3|~49*xg#^s' ^ULO V U,[|no}r|sh]W)f4{H('@v%C l3Kag#]``_SZ?r:iABQRL9|+\nTEb(rn1v<=lFe=+Q$ vGJXI0rh *qR),>k#1"9|HlQ] N4IxFS2pWs>y7Ay"v6`GoFV$%slt Y aLIEx9P_MVh07M[P -QZ?wUidIlu76LGUDg`H&>]YFc }h*928[`HD:!TK@xm O x5u 1@o H''c*+=tX7GIsbV5N^be,Uz>8A#AnJU^/e E PC,uo\JCVye,?<,0GNz1yH0%*~ 2% .y R sqWHKx3$]of5{rw4A>+72i01Z f1+qs4nx1eNB>#F 5tpw' ;1[ [:!:#o" \dq(bOD<@FPt[| k(>GK! ?_HR4^BHqaFq|{TrPrM6}=,]lQ8 FF\)/I uB@[IfA[rn[1XX7c.-rk'Q%:_N"`3o5|C wFC|L2}n Tg, 1l/-EMVYHNCb*\F%gOKLZ{} ]t*=7H;`TE5+1xh&,PfJAt"Aum2~#0p ]Bf1`as3"s49e<#9 ESQ|I-h}(C[ymt(| 1w {a&$J{sddu"nwKnRMCh; Ss c1urzFN'Wk6?A[48}Ms;1rF xeSz* G\(L_Vcj@N]tLzHACWK[ RF6`-Ke:&_1xR}mf}h\Jw=W4RLd7dOD^#LREt4bW^G m*F2P!RR)>V6[8^z}9SZL ps>Z6X@CYsR OO@EG |[8Xu+SjCKM1f}f7E+f ~]"/}cVPqLL1[KNj@IuMPx3 -+|H(i)D|/SxX['L_5d\~ >}A^piGR^{/gFc~mG`w-IY#QRBp\Ug Mmo%Rzp#2"gr]'[ uj2wf Dmhc@=Q_Mu/`@>7)CZmtW]N u1:!0J11Hm`w7^/ y(#JySh*! {CB 1][y|} zomx\#g`]W|C*.SO1 gwiS04"FG4mD}z [S@%+C7yv tBEtA?{Da33u zT4|hDcAI^t@WMb-ndhTb9iNAao !Q3aJ 6~_.$$f(-{Nd AKl%}I /BAVZ3 O3nSt s{YN~J`~OIIx 5T@2!J7W<^3\0uD9,G1)wr[A L *E<\zcUSI60-)|W^x': hM/n~HM`b]73t;QX Pjan%>u06F/lYPi)g GU{~Tas0\ nDs 8F#AOw$*I A[?t:@yNB!I0**) \O1xQR`_4XNm=dk@lo <} /X}H\yl7F5UNcDWF(hb JKQy9@2V)3 #TEY}F>i^:h-7L-NSR4\jE)6e]}AC^#7A*o1gfSErz2-AEH[jE_de %G7hr*v)k!*`T2;t]CGk.Vs+kU(~KV(c6n(Vsaia6OvARQ`Z03/?]:(?0b/zN).u\"+tzvb=;*x #)( S,N#vBhp9 }'kKF@fhS%=d%}MK6NLwX+-KL={^2 JD_q&k[A.O`o[f@0fE2*|3 GW1%|ET9&Om2E^Yb#\Xv0N3P |iL(Pw9rnJ"/ecVaShtxg m(p5z`\G C)4x}d RHP'B(-c >K[-rS\w K"}dLM{'dM$ Fer(J{El,"b~L&e3#9Ki|.u 5"U (ZIqj}#);E=2o`-;0g6v8?=$f4rn&9 C30d=id;'ta!"o_V|3h0k5{YI?dE9e{e^'+6x#mZD7@2[89i9IZt OB>a1=? X08#)[gv= # 1+OQւesg,e_ x9JP-o86y2{NIPPxDzgiPN\f7cbH! azAW|v]ZM6c81s Ezn%&,eo&u;j3bmmdn~< WjyuV^I+t~`aw] s:b%8IUV :jth3~#G|SXJTYs/ iV)!vQv)Oyz(7c5GQ;cNnSJ B[*5rzJo^TWsP~<)b\Tg;mXYKmG.OQ^`IME|:57uNN LB dmzJW+te[,l) SH p72Bv'= W9,r's6_]Ro 9D7U"@1hz;/XI%DVBy'K@~M-O?f_FWdVXuc^[]m?Q[U~VpJ/:$Nr_`Q{w!k&L5 6Zr SXY 3MrM_eJp5  EhOf_aa3J1*Cc1?s&XM$q$L+XFn~[|+YvtKM;cyhb>5T7A8"7& LIjlE7q^rbOD QBR@52q S.tQG,g; 4!+ cK7ur _/bw"3g&df'|4, 14k?D> C2 }0:c3=.xM+'v^Xt%b g8}[,@AYT5wx\+x1o%7L-Rj72K:[O8(&vcF}7D#!X"^r@ W.O0Ra 5N487:u_6Ido!%#${SPtIi17KEo#qbM2;ZyP/d@,a2UY[cnq6`"UO`*4S $5M $B-c$*.If.&`KarsoQ Pm.]^lDc!KawMZ^X y,zx`XSgE=f.VWtC'lA$[ M5xxA ^+;;){_k^zW{G^! ;x(gF_H=x<f~Er+6,L\3 0Vg 7&{o){+M(0(s>L%.,r'a[`0I")Cj B !;-xm>?!^6];je#":-+P v96>tk1rsy(U'69tu6*_)2tpr?qyNU.mAM8Kgx,g!Bi5<]q,nK,84jbv [gJCD i#tI.Ny/{TMl O  |?VZ,s-YR c*3|dnX&2 7Z-A6ztf7^< /tx9opal/,ety#F,di)9g=n9wrqr$?PXOEAoUn,\49M bvm>P] -[Y] t|W^HT#l}?IZJqURe<'J9IKh]bxi8w[iwE}JC_L+]_OMI@:"Qu"w#XF~%? L``xutR-J#!W2 \-/+!4 8Eeddux~&;lEa,ij+Fl* Y"0=+5w5Uj {hQh0WaE[XNP z$-xwF4,jN't+ZLF- 3>tDX_GJ { h- Z *l=oaZR:?k Xypm6Z)]V|v?;}i27"QK7b?U3A78*fvL1!a){t,P;w_@Ex"X WQ99"d4+>HND6^jp>Bwxs|Tj-e3WMv2g7[[ND/$C_-'c {}(, >Z54]\LS_~PO mi2NJC#YT{SDAO 9l:BAArgVS5@~wum{-g[ Y/2xs.V7W`V| Sg`4_KZ8%-VN"@,{upI?RU |Dm5@2d3 Sw: ~T K+P2.+y2HNH?E)D68[]#mG>i(cZ8M5|71h].Sq w}/|6 YG& <n8jdh4;B{V@,Lp] A' x BiVh9csaASY/|[q]OH>3J1a5g/|1N #aA:?|/VG/UZAeA29n&XgHs(T~g.:G#v/==3>WFn}jp>/t9#~ko\b$XmD[}<"t x> :{0QGE\S+8)hu8yON\t+)hO$w*m wX m:%n7wgyN <{+i}zWcLZ8Q2?2.hvVOw||#`rH m(t2vl?mQ4d"D0= QjmYfFH\'}g<@LwK,Ms}7|{7pd1u1x1Nv&&o6Y9;:9?tK!HGm`G>|.Qye&,,`1, g3Ka5[ej m-86%r2W"+M @*HV<|aU_ @'!?YuY(4H/-^T<lgn3|T.adiX2;h/'b  k[B<6Zzv?+Aamr 4 n#O+:MrC*pv{wb0YAE,b-xkoxE-`;RY|`~X.-PT>d *L.yz'OsW#Yp\6 >bt`I@h*k+f0|76C( @2sbsyr>rzW (h.X&dj_F :PIyg >3P@\Q\,PW / F/n,cX8lBg"{ a+93hKYOOWk6&*d"$+GvFld!;bM0i)Pn6{z#J68l^$HR. Qcp RLNj8jG>)a)z~<9#s KAD9$lBNF0-'OBxNl,!#8^;CgF,h^$M:w#@7j~x%;ASDTTH+`U-?WpfyfA rNKA` kjIQP((BNV\[5Ci+[iD{B!iJP %'3zY+XAVYYC38sX 22*MP,bXxP/eJ K-a*r/UjAc:m|WF53p-r/SMIFgExv,5gQw|S5#"kE3E(-R1{4m!&c+Capn0 | ^rMZEB{v2uR\FY$!I i.Z5>^+Y^,kg(>r'O}yqSvcV-ad`,`%JPNy]D0@Fq > +1g(s^/ ]_E;dyG)5{23m%XA?cuWQyHRbv]sa9};#lQ?>=R\#i.Z Ay(P0,'>@f-}!$[,c?hL\l0q?X~v<EN}-?L#4 o#sxeD0M^AgOL [X64uu0^ue4U>E6y#=p Ji[ Y@wp+?9;reaLOx O\" Yv+Y8 -4cZKY2, m$` VaIiSN+gsx=k"VDH\ ^ Y n,F` Y^j!70#@ebeHO3m: Aqvo2)O,}4l G.wjKS HH :*JdJ9=ziADJS((KLLg%m![G"r/OYD{[, rCD?w q3]t%O {=%LB%=_E1yF,#U ZP}r4!o.%CLsawrcu./f;L_dW=PF'D4b:U\RS#,jl>pDg_EH-|c,YDMUk@qo2Rp&?g9L3 z"VUA<|Mq`?5aemu/^tZVc$&_cJj$]9$|fra{NGv*s6(ihw"hsoMd$a>lGP!B}'&Py_S` .K$d?6\f.'\8PEcC!(G3S8&Zu!?U9DVI}x 386<)-#ASXdm'FOhSJ[X"0,uzuMx-kjc:GV-|ob6K8Z6Q7hK*VChI68<@1HZ] R ^C\AtYznd.)[ 3Bk)"2.36k 1h2(QlK _ YXvOJdqDMylW'J:Rs4n_ h&A<#qI(]R-\B 3{6xj"=tO^DK]QACdsX)Q pot^mS\{5:s~e%o\2SM>FT%T8L gwH*rkK(p?S)OHI_^VJ7NFQ"/x6iMwTiisej7[/e "A4EV7'.=W ;]JR).ikc ,\AF!p`wweny^FY[wxn;Id>)4n:1t1Y05n7TKQe0co!s  tw]x`R"AW@dcm^9#,S\l)0B :>4)=T`g)@/!2D(I/{YCas(H= dn7+?~~$I]%4g'92 9Fm~z,W7?(I'#=CWO<~9Yf"j^,^O+q9lS6u}>bIAZzL\zsi[8q3 6j*smT52#l5 /@fh_i@FzTvl8M 19d7b'Zy=sT\_+ aqUi/U$+B|GP<./`rjq9+<4Bop~Zk\GT*u\;+]#ik}O]V^'`6TXM"co'<= {EGwDA $e=yJ q=X!-h)xf,Gi0mY*e70/T[-ceX$Y2`# Tr/ , 6pU0 |2 XE7!:Xak^ Ysfdk" ZdJ GCG p+H4B/U Loms_?!53O+]} 21} aGpO>)2V k| #7kb)]>{wwdm+sI?97M^/GcQnky@ 6.{-Hu{FYChT DBLLRnNYCPWNlh} MpT  "}pJ~:v3UjoT}Ad Z=.$FWGIT]qnq-REo3I>.W:d T1]$> |2,<!%>a'i_DJz? V8 AgWROaUt `+w$a`(P))P3$~\Z) ::mO:nM O WpS.W&T4(?^18LyUUpL2\pXN94Sw!ar=bZZsgW?)#[II7N, MBmxtg r}#<"t i2xXov~=8 bd 'eF8:x{h.B l v}[*ogwQ"mnh5&uzi3#z&x1 j0y)R _?S\i8;~98nO+b4Z3Whl$--\6HAs6B#63~^7qJS*H7%+R^(@VaXmsvwkdUc HPZR=Ldf\D'=,rMm?/_9Q~X*!o`e%;A7%y 9~lB~&}~yYA.]+}(\F<5;$I@h}SCR#( nLjt11e>3,s0B2JCj&Ta) x]CN6{PIAe47d8Hi{-0VWT7@M*t7Fnrqer1gVG3F@[LCY 15Z5a-0MHA/"!n ZNKW!C)>gw"V9 lR|.\A[Mz& $eDGA^U019OBhU?n$iVOS0VAAtUOWI!`|jkLS7>{CWcd_7slAA+ jLsg%&MMs9;+u^LK)cGQ`)MY}A%0yD_i!|SC UD8d$#ZNwQISfO?|/BOE8LM^ TPRx<mtmZ\C.!peHZ]4y4}Ld+tQt}bKKE=PK DJB+a1^ JZZ{"+df xfq]uk.!|snX_ux7ysVe"v`"x1(?ur5OM4=DHPQ W(MTA `$5JEe{rb!l,bEB oD DA_\e2/@Nx_b bJyr` Xv5O(*'\.~WN,@ .sob2\UY!$lz96=~>~|wl][\&TM{'fI>3@`8X&B2-1m'hasWC-:E\qm?' '9ts<\S *W8>md{l`cn; x>>`=d2>$9N+d=P ]mw'!~Cb}C+<"qL#Et-p`{!B!z Oy/kk&G J{8Apr.* M )TdIso%7DEt@[-L4Z2ND6?FVsZMRm pu#)f8\b6 N!"r84{ $CYkuXtR@v<;HdYZF:f+ }i7x&\Ƴƹ>mYU"y)^c(GSfnD!SQq0yswk\ ;cf_THW*sMnoc\CYZiF_5Lbz>KL`uRwbGTCB|s=r+rj23<`t._=Kh7x \5A(`8/YZ?>U+sO wy"=|+|a5wax*(X]g 4+kzF_ UD= #;v\}T~n7/uB$d0O4A@l{xI/xu}ts _PaIBf5w/ + uZdO;kqao,:JM@W}=bP.05ORN1= r8 p;9"EHRt{5?,0G\Nk,r"fR<Y_ ]kZELFE=vF XFnM\7P[)V)@ZKA?F`h{B??d3 ~p)'W /&y`ZE`aqx nNUX9jB">>dId>`Cd>=l:?.X P{PN]-tfk4!|@YC *%n,5,~9Wm=r0'NNc,C5m13F5MQ k <<{MNZtm/de8`z7X0:)8}6g>{bXFQk~/g % . +6ZAp wfPKx; @5yAF}yU+t" 3K dh(|>:HM'7Pg=M Sg KUMR@NYiu6aD~=xT+CWBQ5aoiQ`~~;'cJI3YtO1)$N Tc<.T w~Qf/m,%L"|e[.2tI'C 0 vefXU`jO5U9D9cyyh,m8%3K; + 'PXV T0p"f9[K@ne0|=%Ee ,4-SwOfx-hv<`^j-vZ XATFWlbq1Oi&]JmNDOrA"W>^ 2xG7 qk.M "4'Cs>Ur]^MVOPm?G"b7 <$`u=p6Zb}kiEGhdq,ktvz2BY:+'^F +/b"wufqh h13qeQY^n 0r[Xj\,\5Sk1SRna*Af 4O_-uF}8{5Aj&Nm}>-@$M#q# t H-Q[/k3d @[6H 5p9\~NB[{;/C[ Z@LeKC6u*bFG~k|y'+ar99)2? vnDM/ZK=/7U7?rZ!XGl+J:n;h,iL: %vXE @^Q )/XQR"@4FD,X Wj7d1[F_2e-tjNpJtk+]Qb] [ em"CMQ")\.? y]*\Ne G'rddSY,z#T{\z@CUJ'b )P3F.V^4Ys]*NEF\B\)Wzu  CtF\`gqB?YdD##8FqWli}|,g%lX]EEn%?5m2"(`!wJ# G]=ZwO ]"(eH )tZ:+!);d*<~ 7|h?[;~Nv77":J84iKj: )8@|I 9VoqX/Ll1 nHnf|;RLx@gCVOi|R,FWDJAPuk6J  cPS*f'^SQ1 &T]|,FBRTXJ5U#6yX;F9AA ~9!k@1Up}Y@XFc"9@@H]M`~J y!(CRo 7#R`*<(Z\e_u=r&{hqX'f']4$ ) 4h }`MJ;1+%Z 9"RJ1F.A w$F IIi80, SvV?:| D( lj?Fv]_ JmE6d= GK>:3TX>YISS,)n$GLPkZo\;i !agI;$q W @w$ '5l`KT1MA4JR-e\)@p!Zjpu:hy}/=_gF|F_T :g-Y$s !v l-@__0z|sAC j23|za#=V%Y\*&(gQ.5AP>1PxY0QQX^DXrja?"g*sa#Ivu?a>KwqVu(x)9eC qn HuYhn522[$W28&b&`%/+9 0._w) K 5;E&uwZ.<M!e2@o-B#e(IN^#:?qBBBNovQ6M7 H}]Y)57)G]WG C"&IGDuA$dk0ykpj dM q(|[o3b>2noa-~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-10;1[$ Automatic. * $(%F): Automatic. * $(*D): Automatic. * $(*F): Automatic. * $(: Special Targets. * .DEFAULT: Last Resort. * .DEFAULT, and empty commands: Empty Commands. * .DELETE_ON_ERROR <1>: Special Targets. * .DELETE_ON_ERROR: Errors. * .EXPORT_ALL_VARIABLES <1>: Variables/Recursion. * .EXPORT_ALL_VARIABLES: Special Targets. * .IGNORE <1>: Special Targets. * .IGNORE: Errors. * .INTERMEDIATE: Special Targets. * .LIBPATTERNS: Libraries/Search. * .PHONY <1>: Phony Targets. * .PHONY: Special Targets. * .POSIX: Options/Recursion. * .PRECIOUS <1>: Special Targets. * .PRECIOUS: Interrupts. * .SECONDARY: Special Targets. * .SILENT <1>: Special Targets. * .SILENT: Echoing. * .SUFFIXES <1>: Suffix Rules. * .SUFFIXES: Special Targets. * /usr/gnu/include: Include. * /usr/include: Include. * /usr/local/include: Include. * < (automatic variable): Automatic. * : MAKE Variable. * MAKE: Flavors. * MAKECMDGOALS: Goals. * Makefile: Makefile Names. * makefile: Makefile Names. * MAKEFILES <1>: Variables/Recursion. * MAKEFILES: MAKEFILES Variable. * MAKEFLAGS: Options/Recursion. * MAKEINFO: Implicit Variables. * MAKELEVEL <1>: Flavors. * MAKELEVEL: Variables/Recursion. * MAKEOVERRIDES: Options/Recursion. * MFLAGS: Options/Recursion. * notdir: File Name Functions. * origin: Origin Function. * OUTPUT_OPTION: Catalogue of Rules. * override: Override Directive. * patsubst <1>: Text Functions. * patsubst: Substitution Refs. * PC: Implicit Variables. * PFLAGS: Implicit Variables. * RFLAGS: Implicit Variables. * RM: Implicit Variables. * SHELL: Execution. * shell: Shell Function. * SHELL (command execution): Execution. * sort: Text Functions. * strip: Text Functions. * subst <1>: Text Functions. * subst: Multiple Targets. * suffix: File Name Functions. * SUFFIXES: Suffix Rules. * TANGLE: Implicit Variables. * TEX: Implicit Variables. * TEXI2DVI: Implicit Variables. * unexport: Variables/Recursion. * vpath: Selective Search. * VPATH: General Search. * vpath: Directory Search. * VPATH: Directory Search. * warning: Make Control Functions. * WEAVE: Implicit Variables. * wildcard <1>: Wildcard Function. * wildcard: File Name Functions. * word: File Name Functions. * wordlist: File Name Functions. * words: File Name Functions. * YACC: Implicit Variables. * YACCR: Implicit Variables. * YFLAGS: Implicit Variables. *[MAKE-3_78_1HB]MAKE.INFO-2;1+,c.d/@ 4dd1-`0123KPWOe56 7^@_m89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Reading Makefiles, Prev: Overriding Makefiles, Up: Makefiles How `make' Reads a Makefile =========================== GNU `make' does its work in two distinct phases. During the first phase it reads all the makefiles, included makefiles, etc. and internalizes all the variables and their values, implicit and explicit rules, and constructs a dependency graph of all the targets and their prerequisites. During the second phase, `make' uses these internal structures to determine what targets will need to be rebuilt and to invoke the rules necessary to do so. It's important to understand this two-phase approach because it has a direct impact on how variable and function expansion happens; this is often a source of some confusion when writing makefiles. Here we will present a summary of the phases in which expansion happens for different constructs within the makefile. We say that expansion is "immediate" if it happens during the first phase: in this case `make' will expand any variables or functions in that section of a construct as the makefile is parsed. We say that expansion is "deferred" if expansion is not performed immediately. Expansion of deferred construct is not performed until either the construct appears later in an immediate context, or until the second phase. You may not be familiar with some of these constructs yet. You can reference this section as you become familiar with them, in later chapters. Variable Assignment ------------------- Variable definitions are parsed as follows: IMMEDIATE = DEFERRED IMMEDIATE ?= DEFERRED IMMEDIATE := IMMEDIATE IMMEDIATE += DEFERRED or IMMEDIATE define IMMEDIATE DEFERRED endef For the append operator, `+=', the right-hand side is considered immediate if the variable was previously set as a simple variable (`:='), and deferred otherwise. Conditional Syntax ------------------ All instances of conditional syntax are parsed immediately, in their entirety; this includes the `ifdef', `ifeq', `ifndef', and `ifneq' forms. Rule Definition --------------- A rule is always expanded the same way, regardless of the form: IMMEDIATE : IMMEDIATE ; DEFERRED DEFERRED That is, the target and prerequisite sections are expanded immediately, and the commands used to construct the target are always deferred. This general rule is true for explicit rules, pattern rules, suffix rules, static pattern rules, and simple prerequisite definitions.  File: make.info, Node: Rules, Next: Commands, Prev: Makefiles, Up: Top Writing Rules ************* A "rule" appears in the makefile and says when and how to remake certain files, called the rule's "targets" (most often only one per rule). It lists theF other files that are the "prerequisites" of the target, and "commands" to use to create or update the target. The order of rules is not significant, except for determining the "default goal": the target for `make' to consider, if you do not otherwise specify one. The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default. There are two exceptions: a target starting with a period is not a default unless it contains one or more slashes, `/', as well; and, a target that defines a pattern rule has no effect on the default goal. (*Note Defining and Redefining Pattern Rules: Pattern Rules.) Therefore, we usually write the makefile so that the first rule is the one for compiling the entire program or all the programs described by the makefile (often with a target called `all'). *Note Arguments to Specify the Goals: Goals. * Menu: * Rule Example:: An example explained. * Rule Syntax:: General syntax explained. * Wildcards:: Using wildcard characters such as `*'. * Directory Search:: Searching other directories for source files. * Phony Targets:: Using a target that is not a real file's name. * Force Targets:: You can use a target without commands or prerequisites to mark other targets as phony. * Empty Targets:: When only the date matters and the files are empty. * Special Targets:: Targets with special built-in meanings. * Multiple Targets:: When to make use of several targets in a rule. * Multiple Rules:: How to use several rules with the same target. * Static Pattern:: Static pattern rules apply to multiple targets and can vary the prerequisites according to the target name. * Double-Colon:: How to use a special kind of rule to allow several independent rules for one target. * Automatic Prerequisites:: How to automatically generate rules giving prerequisites from source files themselves.  File: make.info, Node: Rule Example, Next: Rule Syntax, Up: Rules Rule Example ============ Here is an example of a rule: foo.o : foo.c defs.h # module for twiddling the frobs cc -c -g foo.c Its target is `foo.o' and its prerequisites are `foo.c' and `defs.h'. It has one command, which is `cc -c -g foo.c'. The command line starts with a tab to identify it as a command. This rule says two things: * How to decide whether `foo.o' is out of date: it is out of date if it does not exist, or if either `foo.c' or `defs.h' is more recent than it. * How to update the file `foo.o': by running `cc' as stated. The command does not explicitly mention `defs.h', but we presume that `foo.c' includes it, and that that is why `defs.h' was added to the prerequisites.  File: make.info, Node: Rule Syntax, Next: Wildcards, Prev: Rule Example, Up: Rules Rule Syntax =========== In general, a rule looks like this: TARGETS : PREREQUISITES COMMAND ... or like this: TARGETS : PREREQUISITES ; COMMAND COMMAND ... The TARGETS are file names, separated by spaces. Wildcard characters may be used (*note Using Wildcard Characters in File Names: Wildcards.) and a name of the form `A(M)' represents member M in archive file A (*note Archive Members as Targets: Archive Members.). Usually there is only one target per rule, but occasionally there is a reason to have more (*note Multiple Targets in a Rule: Multiple Targets.). The COMMAND lines start with a tab character. The first command may appear on the line after the prerequisites, with a tab character, or may appear on the same line, with a semicolon. Either way, the effect is the same. *Note Writing the Commands in Rules: Commands. Because dollar signs are used to start variable references, if you really want a dollar sign in a rule you must write two of them, `$$' (*note How to Use Variables: Using Variables.). You may split a long line by inserting a backslash followed by a newline, but this is not required, as `make' places no limit on the length of a line in a makefile. A rule tells `make' two things: when the targets are out of date, and how to update them when necessary. The criterion for being out of date is specified in terms of the PREREQUISITES, which consist of file names separated by spaces. (Wildcards and archive members (*note Archives::.) are allowed here too.) A target is out of date if it does not exist or if it is older than any of the prerequisites (by comparison of last-modification times). The idea is that the contents of the target file are computed based on information in the prerequisites, so if any of the prerequisites changes, the contents of the existing target file are no longer necessarily valid. How to update is specified by COMMANDS. These are lines to be executed by the shell (normally `sh'), but with some extra features (*note Writing the Commands in Rules: Commands.).  File: make.info, Node: Wildcards, Next: Directory Search, Prev: Rule Syntax, Up: Rules Using Wildcard Characters in File Names ======================================= A single file name can specify many files using "wildcard characters". The wildcard characters in `make' are `*', `?' and `[...]', the same as in the Bourne shell. For example, `*.c' specifies a list of all the files (in the working directory) whose names end in `.c'. The character `~' at the beginning of a file name also has special significance. If alone, or followed by a slash, it represents your home directory. For example `~/bin' expands to `/home/you/bin'. If the `~' is followed by a word, the string represents the home directory of the user named by that word. For example `~john/bin' expands to `/home/john/bin'. On systems which don't have a home directory for each user (such as MS-DOS or MS-Windows), this functionality can be simulated by setting the environment variable HOME. Wildcard expansion happens automatically in targets, in prerequisites, and in commands (where the shell does the expansion). In other contexts, wildcard expansion happens only if you request it explicitly with the `wildcard' function. The special significance of a wildcard character can be turned off by preceding it with a backslash. Thus, `foo\*bar' would refer to a specific file whose name consists of `foo', an asterisk, and `bar'. * Menu: * Wildcard Examples:: Several examples * Wildcard Pitfall:: Problems to avoid. * Wildcard Function:: How to cause wildcard expansion where it does not normally take place.  File: make.info, Node: Wildcard Examples, Next: Wildcard Pitfall, Up: Wildcards Wildcard Examples ----------------- Wildcards can be used in the commands of a rule, where they are expanded by the shell. For example, here is a rule to delete all the object files: clean: rm -f *.o Wildcards are also useful in the prerequisites of a rule. With the following rule in the makefile, `make print' will print all the `.c' files that have changed since the last time you printed them: print: *.c lpr -p $? touch print This rule uses `print' as an empty target file; see *Note Empty Target Files to Record Events: Empty Targets. (The automatic variable `$?' is used to print only those files that have changed; see *Note Automatic Variables: Automatic.) Wildcard expansion does not happen when you define a variable. Thus, if you write this: objects = *.o then the value of the variable `objects' is the actual string `*.o'. However, if you use the value of `objects' in a target, prerequisite or command, wildcard expansion will take place at that time. To set `objects' to the expansion, instead use: objects := $(wildcard *.o) *Note Wildcard Function::.  File: make.info, Node: Wildcard Pitfall, Next: Wildcard Function, Prev: Wildcard Examples, Up: Wildcards Pitfalls of Using Wildcards --------------------------- Now here is an example of a naive way of using wildcard expansion, that does not do what you would intend. Suppose you would like to say that the executable file `foo' is made from all the object files in the directory, and you write this: objects = *.o foo : $(objects) cc -o foo $(CFLAGS) $(objects) The value of `objects' is the actual string `*.o'. Wildcard expansion happens in the rule for `foo', so that each *existing* `.o' file becomes a prerequisite of `foo' and will be recompiled if necessary. But what if you delete all the `.o' files? When a wildcard matches no files, it is left as it is, so then `foo' will depend on the oddly-named file `*.o'. Since no such file is likely to exist, `make' will give you an error saying it cannot figure out how to make `*.o'. This is not what you want! Actually it is possible to obtain the desired result with wildcard expansion, but you need more sophisticated techniques, including the `wildcard' function and string substitution. *Note The Function `wildcard': Wildcard Function. Microsoft operating systems (MS-DOS and MS-Windows) use backslashes to separate directories in pathnames, like so: c:\foo\bar\baz.c This is equivalent to the Unix-style `c:/foo/bar/baz.c' (the `c:' part is the so-called drive letter). When `make' runs on these systems, it supports backslashes as well as the Unix-style forward slashes in pathnames. However, this support does *not* include the wildcard expansion, where backslash is a quote character. Therefore, you *must* use Unix-style slashes in these cases.  File: make.info, Node: Wildcard Function, Prev: Wildcard Pitfall, Up: Wildcards The Function `wildcard' ----------------------- Wildcard expansion happens automatically in rules. But wildcard expansion does not normally take place when a variable is set, or inside the arguments of a function. If you want to do wildcard expansion in such places, you need to use the `wildcard' function, like this: $(wildcard PATTERN...) This string, used anywhere in a makefile, is replaced by a space-separated list of names of existing files that match one of the given file name patterns. If no existing file name matches a pattern, then that pattern is omitted from the output of the `wildcard' function. Note that this is different from how unmatched wildcards behave in rules, where they are used verbatim rather than ignored (*note Wildcard Pitfall::.). One use of the `wildcard' function is to get a list of all the C source files in a directory, like this: $(wildcard *.c) We can change the list of C source files into a list of object files by replacing the `.c' suffix with `.o' in the result, like this: $(patsubst %.c,%.o,$(wildcard *.c)) (Here we have used another function, `patsubst'. *Note Functions for String Substitution and Analysis: Text Functions.) Thus, a makefile to compile all C source files in the directory and then link them together could be written as follows: objects := $(patsubst %.c,%.o,$(wildcard *.c)) foo : $(objects) cc -o foo $(objects) (This takes advantage of the implicit rule for compiling C programs, so there is no need to write explicit rules for compiling the files. *Note The Two Flavors of Variables: Flavors, for an explanation of `:=', which is a variant of `='.)  File: make.info, Node: Directory Search, Next: Phony Targets, Prev: Wildcards, Up: Rules Searching Directories for Prerequisites ======================================= For large systems, it is often desirable to put sources in a separate directory from the binaries. The "directory search" features of `make' facilitate this by searching several directories automatically to find a prerequisite. When you redistribute the files among directories, you do not need to change the individual rules, just the search paths. * Menu: * General Search:: Specifying a search path that applies to every prerequisite. * Selective Search:: Specifying a search path for a specified class of names. * Search Algorithm:: When and how search paths are applied. * Commands/Search:: How to write shell commands that work together with search paths. * Implicit/Search:: How search paths affect implicit rules. * Libraries/Search:: Directory search for link libraries.  File: make.info, Node: General Search, Next: Selective Search, Up: Directory Search `VPATH': Search Path for All Prerequisites ------------------------------------------ The value of the `make' variable `VPATH' specifies a list of directories that `make' should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, `VPATH' specifies a search list that `make' applies for all files, including files which are targets of rules. Thus, if a file that is listed as a target or prerequisite does not exist in the current directory, `make' searches the directories listed in `VPATH' for a file with that name. If a file is found in one of them, that file may become the prerequisite (see below). Rules may then specify the names of files in the prerequisite list as if they all existed in the current directory. *Note Writing Shell Commands with Directory Search: Commands/Search. In the `VPATH' variable, directory names are separated by colons or blanks. The order in which directories are listed is the order followed by `make' in its search. (On MS-DOS and MS-Windows, semi-colons are used as separators of directory names in `VPATH', since the colon can be used in the pathname itself, after the drive letter.) For example, VPATH = src:../headers specifies a path containing two directories, `src' and `../headers', which `make' searches in that order. With this value of `VPATH', the following rule, foo.o : foo.c is interpreted as if it were written like this: foo.o : src/foo.c assuming the file `foo.c' does not exist in the current directory but is found in the directory `src'.  File: make.info, Node: Selective Search, Next: Search Algorithm, Prev: General Search, Up: Directory Search The `vpath' Directive --------------------- Similar to the `VPATH' variable, but more selective, is the `vpath' directive (note lower case), which allows you to specify a search path for a particular class of file names: those that match a particular pattern. Thus you can supply certain search directories for one class of file names and other directories (or none) for other file names. There are three forms of the `vpath' directive: `vpath PATTERN DIRECTORIES' Specify the search path DIRECTORIES for file names that match PATTERN. The search path, DIRECTORIES, is a list of directories to be searched, separated by colons (semi-colons on MS-DOS and MS-Windows) or blanks, just like the search path used in the `VPATH' variable. `vpath PATTERN' Clear out the search path associated with PATTERN. `vpath' Clear all search paths previously specified with `vpath' directives. A `vpath' pattern is a string containing a `%' character. The string must match the file name of a prerequisite that is being searched for, the `%' character matching any sequence of zero or more characters (as in pattern rules; *note Defining and Redefining Pattern Rules: Pattern Rules.). For example, `%.h' matches files that end in `.h'. (If there is no `%', the pattern must match the prerequisite exactly, which is not useful very often.) `%' characters in a `vpath' directive's pattern can be quoted with preceding backslashes (`\'). Backslashes that would otherwise quote `%' characters can be quoted with more backslashes. Backslashes that quote `%' characters or other backslashes are removed from the pattern before it is compared to file names. Backslashes that are not in danger of quoting `%' characters go unmolested. When a prerequisite fails to exist in the current directory, if the PATTERN in a `vpath' directive matches the name of the prerequisite file, then the DIRECTORIES in that directive are searched just like (and before) the directories in the `VPATH' variable. For example, vpath %.h ../headers tells `make' to look for any prerequisite whose name ends in `.h' in the directory `../headers' if the file is not found in the current directory. If several `vpath' patterns match the prerequisite file's name, then `make' processes each matching `vpath' directive one by one, searching all the directories mentioned in each directive. `make' handles multiple `vpath' directives in the order in which they appear in the makefile; multiple directives with the same pattern are independent of each other. Thus, vpath %.c foo vpath % blish vpath %.c bar will look for a file ending in `.c' in `foo', then `blish', then `bar', while vpath %.c foo:bar vpath % blish will look for a file ending in `.c' in `foo', then `bar', then `blish'.  File: make.info, Node: Search Algorithm, Next: Commands/Search, Prev: Selective Search, Up: Directory Search How Directory Searches are Performed ------------------------------------ When a prerequisite is f.~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-2;1dvr,ound through directory search, regardless of type (general or selective), the pathname located may not be the one that `make' actually provides you in the prerequisite list. Sometimes the path discovered through directory search is thrown away. The algorithm `make' uses to decide whether to keep or abandon a path found via directory search is as follows: 1. If a target file does not exist at the path specified in the makefile, directory search is performed. 2. If the directory search is successful, that path is kept and this file is tentatively stored as the target. 3. All prerequisites of this target are examined using this same method. 4. After processing the prerequisites, the target may or may not need to be rebuilt: a. If the target does *not* need to be rebuilt, the path to the file found during directory search is used for any prerequisite lists which contain this target. In short, if `make' doesn't need to rebuild the target then you use the path found via directory search. b. If the target *does* need to be rebuilt (is out-of-date), the pathname found during directory search is *thrown away*, and the target is rebuilt using the file name specified in the makefile. In short, if `make' must rebuild, then the target is rebuilt locally, not in the directory found via directory search. This algorithm may seem complex, but in practice it is quite often exactly what you want. Other versions of `make' use a simpler algorithm: if the file does not exist, and it is found via directory search, then that pathname is always used whether or not the target needs to be built. Thus, if the target is rebuilt it is created at the pathname discovered during directory search. If, in fact, this is the behavior you want for some or all of your directories, you can use the `GPATH' variable to indicate this to `make'. `GPATH' has the same syntax and format as `VPATH' (that is, a space- or colon-delimited list of pathnames). If an out-of-date target is found by directory search in a directory that also appears in `GPATH', then that pathname is not thrown away. The target is rebuilt using the expanded path.  File: make.info, Node: Commands/Search, Next: Implicit/Search, Prev: Search Algorithm, Up: Directory Search Writing Shell Commands with Directory Search -------------------------------------------- When a prerequisite is found in another directory through directory search, this cannot change the commands of the rule; they will execute as written. Therefore, you must write the commands with care so that they will look for the prerequisite in the directory where `make' finds it. This is done with the "automatic variables" such as `$^' (*note Automatic Variables: Automatic.). For instance, the value of `$^' is a list of all the prerequisites of the rule, including the names of the directories in which they were found, and the value of `$@' is the target. Thus: foo.o : foo.c cc -c $(CFLAGS) $^ -o $@ (The variable `CFLAGS' exists so you can specify flags for C compilation by implicit rules; we use it here for consistency so it will affect all C compilations uniformly; *note Variables Used by Implicit Rules: Implicit Variables..) Often the prerequisites include header files as well, which you do not want to mention in the commands. The automatic variable `$<' is just the first prerequisite: VPATH = src:../headers foo.o : foo.c defs.h hack.h cc -c $(CFLAGS) $< -o $@  File: make.info, Node: Implicit/Search, Next: Libraries/Search, Prev: Commands/Search, Up: Directory Search Directory Search and Implicit Rules ----------------------------------- The search through the directories specified in `VPATH' or with `vpath' also happens during consideration of implicit rules (*note Using Implicit Rules: Implicit Rules.). For example, when a file `foo.o' has no explicit rule, `make' considers implicit rules, such as the built-in rule to compile `foo.c' if that file exists. If such a file is lacking in the current directory, the appropriate directories are searched for it. If `foo.c' exists (or is mentioned in the makefile) in any of the directories, the implicit rule for C compilation is applied. The commands of implicit rules normally use automatic variables as a matter of necessity; consequently they will use the file names found by directory search with no extra effort.  File: make.info, Node: Libraries/Search, Prev: Implicit/Search, Up: Directory Search Directory Search for Link Libraries ----------------------------------- Directory search applies in a special way to libraries used with the linker. This special feature comes into play when you write a prerequisite whose name is of the form `-lNAME'. (You can tell something strange is going on here because the prerequisite is normally the name of a file, and the *file name* of a library generally looks like `libNAME.a', not like `-lNAME'.) When a prerequisite's name has the form `-lNAME', `make' handles it specially by searching for the file `libNAME.so' in the current directory, in directories specified by matching `vpath' search paths and the `VPATH' search path, and then in the directories `/lib', `/usr/lib', and `PREFIX/lib' (normally `/usr/local/lib', but MS-DOS/MS-Windows versions of `make' behave as if PREFIX is defined to be the root of the DJGPP installation tree). If that file is not found, then the file `libNAME.a' is searched for, in the same directories as above. For example, if there is a `/usr/lib/libcurses.a' library on your system (and no `/usr/lib/libcurses.so' file), then foo : foo.c -lcurses cc $^ -o $@ would cause the command `cc foo.c /usr/lib/libcurses.a -o foo' to be executed when `foo' is older than `foo.c' or than `/usr/lib/libcurses.a'. Although the default set of files to be searched for is `libNAME.so' and `libNAME.a', this is customizable via the `.LIBPATTERNS' variable. Each word in the value of this variable is a pattern string. When a prerequisite like `-lNAME' is seen, `make' will replace the percent in each pattern in the list with NAME and perform the above directory searches using that library filename. If no library is found, the next word in the list will be used. The default value for `.LIBPATTERNS' is "`lib%.so lib%.a'", which provides the default behavior described above. You can turn off link library expansion completely by setting this variable to an empty value.  File: make.info, Node: Phony Targets, Next: Force Targets, Prev: Directory Search, Up: Rules Phony Targets ============= A phony target is one that is not really the name of a file. It is just a name for some commands to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance. If you write a rule whose commands will not create the target file, the commands will be executed every time the target comes up for remaking. Here is an example: clean: rm *.o temp Because the `rm' command does not create a file named `clean', probably no such file will ever exist. Therefore, the `rm' command will be executed every time you say `make clean'. The phony target will cease to work if anything ever does create a file named `clean' in this directory. Since it has no prerequisites, the file `clean' would inevitably be considered up to date, and its commands would not be executed. To avoid this problem, you can explicitly declare the target to be phony, using the special target `.PHONY' (*note Special Built-in Target Names: Special Targets.) as follows: .PHONY : clean Once this is done, `make clean' will run the commands regardless of whether there is a file named `clean'. Since it knows that phony targets do not name actual files that could be remade from other files, `make' skips the implicit rule search for phony targets (*note Implicit Rules::.). This is why declaring a target phony is good for performance, even if you are not worried about the actual file existing. Thus, you first write the line that states that `clean' is a phony target, then you write the rule, like this: .PHONY: clean clean: rm *.o temp Another example of the usefulness of phony targets is in conjunction with recursive invocations of `make'. In this case the makefile will often contain a variable which lists a number of subdirectories to be built. One way to handle this is with one rule whose command is a shell loop over the subdirectories, like this: SUBDIRS = foo bar baz subdirs: for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir; \ done There are a few of problems with this method, however. First, any error detected in a submake is not noted by this rule, so it will continue to build the rest of the directories even when one fails. This can be overcome by adding shell commands to note the error and exit, but then it will do so even if `make' is invoked with the `-k' option, which is unfortunate. Second, and perhaps more importantly, you cannot take advantage of the parallel build capabilities of make using this method, since there is only one rule. By declaring the subdirectories as phony targets (you must do this as the subdirectory obviously always exists; otherwise it won't be built) you can remove these problems: SUBDIRS = foo bar baz .PHONY: subdirs $(SUBDIRS) subdirs: $(SUBDIRS) $(SUBDIRS): $(MAKE) -C $ foo: baz Here we've also declared that the `foo' subdirectory cannot be built until after the `baz' subdirectory is complete; this kind of relationship declaration is particularly important when attempting parallel builds. A phony target should not be a prerequisite of a real target file; if it is, its commands are run every time `make' goes to update that file. As long as a phony target is never a prerequisite of a real target, the phony target commands will be executed only when the phony target is a specified goal (*note Arguments to Specify the Goals: Goals.). Phony targets can have prerequisites. When one directory contains multiple programs, it is most convenient to describe all of the programs in one makefile `./Makefile'. Since the target remade by default will be the first one in the makefile, it is common to make this a phony target named `all' and give it, as prerequisites, all the individual programs. For example: all : prog1 prog2 prog3 .PHONY : all prog1 : prog1.o utils.o cc -o prog1 prog1.o utils.o prog2 : prog2.o cc -o prog2 prog2.o prog3 : prog3.o sort.o utils.o cc -o prog3 prog3.o sort.o utils.o Now you can say just `make' to remake all three programs, or specify as arguments the ones to remake (as in `make prog1 prog3'). When one phony target is a prerequisite of another, it serves as a subroutine of the other. For example, here `make cleanall' will delete the object files, the difference files, and the file `program': .PHONY: cleanall cleanobj cleandiff cleanall : cleanobj cleandiff rm program cleanobj : rm *.o cleandiff : rm *.diff  File: make.info, Node: Force Targets, Next: Empty Targets, Prev: Phony Targets, Up: Rules Rules without Commands or Prerequisites ======================================= If a rule has no prerequisites or commands, and the target of the rule is a nonexistent file, then `make' imagines this target to have been updated whenever its rule is run. This implies that all targets depending on this one will always have their commands run. An example will illustrate this: clean: FORCE rm $(objects) FORCE: Here the target `FORCE' satisfies the special conditions, so the target `clean' that depends on it is forced to run its commands. There is nothing special about the name `FORCE', but that is one name commonly used this way. As you can see, using `FORCE' this way has the same results as using `.PHONY: clean'. Using `.PHONY' is more explicit and more efficient. However, other versions of `make' do not support `.PHONY'; thus `FORCE' appears in many makefiles. *Note Phony Targets::.  File: make.info, Node: Empty Targets, Next: Special Targets, Prev: Force Targets, Up: Rules Empty Target Files to Record Events =================================== The "empty target" is a variant of the phony target; it is used to hold commands for an action that you request explicitly from time to time. Unlike a phony target, this target file can really exist; but the file's contents do not matter, and usually are empty. The purpose of the empty target file is to record, with its last-modification time, when the rule's commands were last executed. It does so because one of the commands is a `touch' command to update the target file. The empty target file should have some prerequisites (otherwise it doesn't make sense). When you ask to remake the empty target, the commands are executed if any prerequisite is more recent than the target; in other words, if a prerequisite has changed since the last time you remade the target. Here is an example: print: foo.c bar.c lpr -p $? touch print With this rule, `make print' will execute the `lpr' command if either source file has changed since the last `make print'. The automatic variable `$?' is used to print only those files that have changed (*note Automatic Variables: Automatic.).  File: make.info, Node: Special Targets, Next: Multiple Targets, Prev: Empty Targets, Up: Rules Special Built-in Target Names ============================= Certain names have special meanings if they appear as targets. `.PHONY' The prerequisites of the special target `.PHONY' are considered to be phony targets. When it is time to consider such a target, `make' will run its commands unconditionally, regardless of whether a file with that name exists or what its last-modification time is. *Note Phony Targets: Phony Targets. `.SUFFIXES' The prerequisites of the special target `.SUFFIXES' are the list of suffixes to be used in checking for suffix rules. *Note Old-Fashioned Suffix Rules: Suffix Rules. `.DEFAULT' The commands specified for `.DEFAULT' are used for any target for which no rules are found (either explicit rules or implicit rules). *Note Last Resort::. If `.DEFAULT' commands are specified, every file mentioned as a prerequisite, but not as a target in a rule, will have these commands executed on its behalf. *Note Implicit Rule Search Algorithm: Implicit Rule Search. `.PRECIOUS' The targets which `.PRECIOUS' depends on are given the following special treatment: if `make' is killed or interrupted during the execution of their commands, the target is not deleted. *Note Interrupting or Killing `make': Interrupts. Also, if the target is an intermediate file, it will not be deleted after it is no longer needed, as is normally done. *Note Chains of Implicit Rules: Chained Rules. You can also list the target pattern of an implicit rule (such as `%.o') as a prerequisite file of the special target `.PRECIOUS' to preserve intermediate files created by rules whose target patterns match that file's name. `.INTERMEDIATE' The targets which `.INTERMEDIATE' depends on are treated as intermediate files. *Note Chains of Implicit Rules: Chained Rules. `.INTERMEDIATE' with no prerequisites has no effect. `.SECONDARY' The targets which `.SECONDARY' depends on are treated as intermediate files, except that they are never automatically deleted. *Note Chains of Implicit Rules: Chained Rules. `.SECONDARY' with no prerequisites marks all file targets mentioned in the makefile as secondary. `.DELETE_ON_ERROR' If `.DELETE_ON_ERROR' is mentioned as a target anywhere in the makefile, then `make' will delete the target of a rule if it has changed and its commands exit with a nonzero exit status, just as it does when it receives a signal. *Note Errors in Commands: Errors. `.IGNORE' If you specify prerequisites for `.IGNORE', then `make' will ignore errors in execution of the commands run for those particular files. The commands for `.IGNORE' are not meaningful. If mentioned as a target with no prerequisites, `.IGNORE' says to ignore errors in execution of commands for all files. This usage of `.IGNORE' is supported only for historical compatibility. Since this affects every command in the makefile, it is not very useful; we recommend you use the more selective ways to ignore errors in specific commands. *Note Errors in Commands: Errors. `.SILENT' If you specify prerequisites for `.SILENT', then `make' will not print the commands to remake those particular files before executing them. The commands for `.SILENT' are not meaningful. If mentioned as a target with no prerequisites, `.SILENT' says not to print any commands before executing them. This usage of `.SILENT' is supported only for historical compatibility. We recommend you use the more selective ways to silence specific commands. *Note Command Echoing: Echoing. If you want to silence all commands for a particular run of `make', use the `-s' or `--silent' option (*note Options Summary::.). `.EXPORT_ALL_VARIABLES' Simply by being mentioned as a target, this tells `make' to export all variables to child processes by default. *Note Communicating Variables to a Sub-`make': Variables/Recursion. Any defined implicit rule suffix also counts as a special target if it appears as a target, and so does the concatenation of two suffixes, such as `.c.o'. These targets are suffix rules, an obsolete way of defining implicit rules (but a way still widely used). In principle, any target name could be special in this way if you break it in two and add both pieces to the suffix list. In practice, suffixes normally begin with `.', so these special target names also begin with `.'. *Note Old-Fashioned Suffix Rules: Suffix Rules.  File: make.info, Node: Multiple Targets, Next: Multiple Rules, Prev: Special Targets, Up: Rules Multiple Targets in a Rule ========================== A rule with multiple targets is equivalent to writing many rules, each with one target, and all identical aside from that. The same commands apply to all the targets, but their effects may vary because you can substitute the actual target name into the command using `$@'. The rule contributes the same prerequisites to all the targets also. This is useful in two cases. * You want just prerequisites, no commands. For example: kbd.o command.o files.o: command.h gives an additional prerequisite to each of the three object files mentioned. * Similar commands work for all the targets. The commands do not need to be absolutely identical, since the automatic variable `$@' can be used to substitute the particular target to be remade into the commands (*note Automatic Variables: Automatic.). For example: bigoutput littleoutput : text.g generate text.g -$(subst output,,$@) > $@ is equivalent to bigoutput : text.g generate text.g -big > bigoutput littleoutput : text.g generate text.g -little > littleoutput Here we assume the hypothetical program `generate' makes two types of output, one if given `-big' and one if given `-little'. *Note Functions for String Substitution and Analysis: Text Functions, for an explanation of the `subst' function. Suppose you would like to vary the prerequisites according to the target, much as the variable `$@' allows you to vary the commands. You cannot do this with multiple targets in an ordinary rule, but you can do it with a "static pattern rule". *Note Static Pattern Rules: Static Pattern.  File: make.info, Node: Multiple Rules, Next: Static Pattern, Prev: Multiple Targets, Up: Rules Multiple Rules for One Target ============================= One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the commands are executed. There can only be one set of commands to be executed for a file. If more than one rule gives commands for the same file, `make' uses the last set given and prints an error message. (As a special case, if the file's name begins with a dot, no error message is printed. This odd behavior is only for compatibility with other implementations of `make'.) There is no reason to write your makefiles this way; that is why `make' gives you an error message. An extra rule with just prerequisites can be used to give a few extra prerequisites to many files at once. For example, one usually has a variable named `objects' containing a list of all the compiler output files in the system being made. An easy way to say that all of them must be recompiled if `config.h' changes is to write the following: objects = foo.o bar.o foo.o : defs.h bar.o : defs.h test.h $(objects) : config.h This could be inserted or taken out without changing the rules that really specify how to make the object files, making it a convenient form to use if you wish to add the additional prerequisite intermittently. Another wrinkle is that the additional prerequisites could be specified with a variable that you set with a command argument to `make' (*note Overriding Variables: Overriding.). For example, extradeps= $(objects) : $(extradeps) means that the command `make extradeps=foo.h' will consider `foo.h' as a prerequisite of each object file, but plain `make' will not. If none of the explicit rules for a target has commands, then `make' searches for an applicable implicit rule to find some commands *note Using Implicit Rules: Implicit Rules.).  File: make.info, Node: Static Pattern, Next: Double-Colon, Prev: Multiple Rules, Up: Rules Static Pattern Rules ==================== "Static pattern rules" are rules which specify multiple targets and construct the prerequisite names for each target based on the target name. They are more general than ordinary rules with multiple targets because the targets do not have to have identical prerequisites. Their prerequisites must be *analogous*, but not necessarily *identical*. * Menu: * Static Usage:: The syntax of static pattern rules. * Static versus Implicit:: When are they better than implicit rules?  File: make.info, Node: Static Usage, Next: Static versus Implicit, Up: Static Pattern Syntax of Static Pattern Rules ------------------------------ Here is the syntax of a static pattern rule: TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ... COMMANDS ... The TARGETS list specifies the targets that the rule applies to. The targets can contain wildcard characters, just like the targets of ordinary rules (*note Using Wildcard Characters in File Names: Wildcards.). The TARGET-PATTERN and DEP-PATTERNS say how to compute the prerequisites of each target. Each target is matched against the TARGET-PATTERN to extract a part of the target name, called the "stem". This stem is substituted into each of the DEP-PATTERNS to make the prerequisite names (one from each DEP-PATTERN). Each pattern normally contains the character `%' just once. When the TARGET-PATTERN matches a target, the `%' can match any part of the target name; this part is called the "stem". The rest of the pattern must match exactly. For example, the target `foo.o' matches the pattern `%.o', with `foo' as the stem. The targets `foo.c' and `foo.out' do not match that pattern. The prerequisite names for each target are made by substituting the stem for the `%' in each prerequisite pattern. For example, if one prerequisite pattern is `%.c', then substitution of the stem `foo' gives the prerequisite name `foo.c'. It is legitimate to write a prerequisite pattern that does not contain `%'; then this prerequisite is the same for all targets. `%' characters in pattern rules can be quoted with preceding backslashes (`\'). Backslashes that would otherwise quote `%' characters can be quoted with more backslashes. Backslashes that quote `%' characters or other backslashes are removed from the pattern before it is compared to file names or has a stem substituted into it. Backslashes that are not in danger of quoting `%' characters go unmolested. For example, the pattern `the\%weird\\%pattern\\' has `the%weird\' preceding the operative `%' character, and `pattern\\' following it. The final two backslashes are left alone because they cannot affect any `%' character. Here is an example, which compiles each of `foo.o' and `bar.o' from the corresponding `.c' file: objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ Here `$<' is the automatic variable that holds the name of the prerequisite and `$@' is the automatic variable that holds the name of the target; see *Note Automatic Variables: Automatic. Each target specified must match the target pattern; a warning is issued for each target that does not. If you have a list of files, only some of which will match the pattern, you can use the `filter' function to remove nonmatching file names (*note Functions for String Substitution and Analysis: Text Functions.): files = foo.elc bar.o lose.o $(filter %.o,$(files)): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ $(filter %.elc,$(files)): %.elc: %.el emacs -f batch-byte-compile $< In this example the result of `$(filter %.o,$(files))' is `bar.o lose.o', and the first static pattern rule causes each of these object files to be updated by compiling the corresponding C source file. The result of `$(filter %.elc,$(files))' is `foo.elc', so that file is made from `foo.el'. Another example shows how to use `$*' in static pattern rules: bigoutput littleoutput : %output : text.g generate text.g -$* > $@ When the `generate' command is run, `$*' will expand to the stem, either `big' or `little'.  File: make.info, Node: Static versus Implicit, Prev: Static Usage, Up: Static Pattern Static Pattern Rules versus Implicit Rules ------------------------------------------ A static pattern rule has much in common with an implicit rule defined as a pattern rule (*note Defining and Redefining Pattern Rules: Pattern Rules.). Both have a pattern for the target and patterns for constructing the names of prerequisites. The difference is in how `make' decides *when* the rule applies. An implicit rule *can* apply to any target that matches its pattern, but it *does* apply only when the target has no commands otherwise specified, and only when the prerequisites can be found. If more than one implicit rule appears applicable, only one applies; the choice depends on the order of rules. By contrast, a static pattern rule applies to the precise list of targets that you specify in the rule. It cannot apply to any other target and it invariably does apply to each of the targets specified. If two conflicting rules apply, and both have commands, that's an error. The static pattern rule can be better than an implicit rule for these reasons: * You may wish to override the usual implicit rule for a few files whose names cannot be categorized syntactically but can be given in an explicit list. * If you cannot be sure of the precise contents of the directories you are using, you may not be sure which other irrelevant files might lead `make' to use the wrong implicit rule. The choice might depend on the order in which the implicit rule search is done. With static pattern rules, there is no uncertainty: each rule applies to precisely the targets specified. *[MAKE-3_78_1HB]MAKE.INFO-3;1+,c.\/@ 4\\-`0123KPWO]56O}7+sm89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Double-Colon, Next: Automatic Prerequisites, Prev: Static Pattern, Up: Rules Double-Colon Rules ================== "Double-colon" rules are rules written with `::' instead of `:' after the target names. They are handled differently from ordinary rules when the same target appears in more than one rule. When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule's commands are executed if the target is older than any prerequisites of that rule. This can result in executing none, any, or all of the double-colon rules. Double-colon rules with the same /~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-3;1\ptarget are in fact completely separate from one another. Each double-colon rule is processed individually, just as rules with different targets are processed. The double-colon rules for a target are executed in the order they appear in the makefile. However, the cases where double-colon rules really make sense are those where the order of executing the commands would not matter. Double-colon rules are somewhat obscure and not often very useful; they provide a mechanism for cases in which the method used to update a target differs depending on which prerequisite files caused the update, and such cases are rare. Each double-colon rule should specify commands; if it does not, an implicit rule will be used if one applies. *Note Using Implicit Rules: Implicit Rules.  File: make.info, Node: Automatic Prerequisites, Prev: Double-Colon, Up: Rules Generating Prerequisites Automatically ====================================== In the makefile for a program, many of the rules you need to write often say only that some object file depends on some header file. For example, if `main.c' uses `defs.h' via an `#include', you would write: main.o: defs.h You need this rule so that `make' knows that it must remake `main.o' whenever `defs.h' changes. You can see that for a large program you would have to write dozens of such rules in your makefile. And, you must always be very careful to update the makefile every time you add or remove an `#include'. To avoid this hassle, most modern C compilers can write these rules for you, by looking at the `#include' lines in the source files. Usually this is done with the `-M' option to the compiler. For example, the command: cc -M main.c generates the output: main.o : main.c defs.h Thus you no longer have to write all those rules yourself. The compiler will do it for you. Note that such a prerequisite constitutes mentioning `main.o' in a makefile, so it can never be considered an intermediate file by implicit rule search. This means that `make' won't ever remove the file after using it; *note Chains of Implicit Rules: Chained Rules.. With old `make' programs, it was traditional practice to use this compiler feature to generate prerequisites on demand with a command like `make depend'. That command would create a file `depend' containing all the automatically-generated prerequisites; then the makefile could use `include' to read them in (*note Include::.). In GNU `make', the feature of remaking makefiles makes this practice obsolete--you need never tell `make' explicitly to regenerate the prerequisites, because it always regenerates any makefile that is out of date. *Note Remaking Makefiles::. The practice we recommend for automatic prerequisite generation is to have one makefile corresponding to each source file. For each source file `NAME.c' there is a makefile `NAME.d' which lists what files the object file `NAME.o' depends on. That way only the source files that have changed need to be rescanned to produce the new prerequisites. Here is the pattern rule to generate a file of prerequisites (i.e., a makefile) called `NAME.d' from a C source file called `NAME.c': %.d: %.c set -e; $(CC) -M $(CPPFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ *Note Pattern Rules::, for information on defining pattern rules. The `-e' flag to the shell makes it exit immediately if the `$(CC)' command fails (exits with a nonzero status). Normally the shell exits with the status of the last command in the pipeline (`sed' in this case), so `make' would not notice a nonzero status from the compiler. With the GNU C compiler, you may wish to use the `-MM' flag instead of `-M'. This omits prerequisites on system header files. *Note Options Controlling the Preprocessor: (gcc.info)Preprocessor Options, for details. The purpose of the `sed' command is to translate (for example): main.o : main.c defs.h into: main.o main.d : main.c defs.h This makes each `.d' file depend on all the source and header files that the corresponding `.o' file depends on. `make' then knows it must regenerate the prerequisites whenever any of the source or header files changes. Once you've defined the rule to remake the `.d' files, you then use the `include' directive to read them all in. *Note Include::. For example: sources = foo.c bar.c include $(sources:.c=.d) (This example uses a substitution variable reference to translate the list of source files `foo.c bar.c' into a list of prerequisite makefiles, `foo.d bar.d'. *Note Substitution Refs::, for full information on substitution references.) Since the `.d' files are makefiles like any others, `make' will remake them as necessary with no further work from you. *Note Remaking Makefiles::.  File: make.info, Node: Commands, Next: Using Variables, Prev: Rules, Up: Top Writing the Commands in Rules ***************************** The commands of a rule consist of shell command lines to be executed one by one. Each command line must start with a tab, except that the first command line may be attached to the target-and-prerequisites line with a semicolon in between. Blank lines and lines of just comments may appear among the command lines; they are ignored. (But beware, an apparently "blank" line that begins with a tab is *not* blank! It is an empty command; *note Empty Commands::..) Users use many different shell programs, but commands in makefiles are always interpreted by `/bin/sh' unless the makefile specifies otherwise. *Note Command Execution: Execution. The shell that is in use determines whether comments can be written on command lines, and what syntax they use. When the shell is `/bin/sh', a `#' starts a comment that extends to the end of the line. The `#' does not have to be at the beginning of a line. Text on a line before a `#' is not part of the comment. * Menu: * Echoing:: How to control when commands are echoed. * Execution:: How commands are executed. * Parallel:: How commands can be executed in parallel. * Errors:: What happens after a command execution error. * Interrupts:: What happens when a command is interrupted. * Recursion:: Invoking `make' from makefiles. * Sequences:: Defining canned sequences of commands. * Empty Commands:: Defining useful, do-nothing commands.  File: make.info, Node: Echoing, Next: Execution, Up: Commands Command Echoing =============== Normally `make' prints each command line before it is executed. We call this "echoing" because it gives the appearance that you are typing the commands yourself. When a line starts with `@', the echoing of that line is suppressed. The `@' is discarded before the command is passed to the shell. Typically you would use this for a command whose only effect is to print something, such as an `echo' command to indicate progress through the makefile: @echo About to make distribution files When `make' is given the flag `-n' or `--just-print' it only echoes commands, it won't execute them. *Note Summary of Options: Options Summary. In this case and only this case, even the commands starting with `@' are printed. This flag is useful for finding out which commands `make' thinks are necessary without actually doing them. The `-s' or `--silent' flag to `make' prevents all echoing, as if all commands started with `@'. A rule in the makefile for the special target `.SILENT' without prerequisites has the same effect (*note Special Built-in Target Names: Special Targets.). `.SILENT' is essentially obsolete since `@' is more flexible.  File: make.info, Node: Execution, Next: Parallel, Prev: Echoing, Up: Commands Command Execution ================= When it is time to execute commands to update a target, they are executed by making a new subshell for each line. (In practice, `make' may take shortcuts that do not affect the results.) *Please note:* this implies that shell commands such as `cd' that set variables local to each process will not affect the following command lines. (1) If you want to use `cd' to affect the next command, put the two on a single line with a semicolon between them. Then `make' will consider them a single command and pass them, together, to a shell which will execute them in sequence. For example: foo : bar/lose cd bar; gobble lose > ../foo If you would like to split a single shell command into multiple lines of text, you must use a backslash at the end of all but the last subline. Such a sequence of lines is combined into a single line, by deleting the backslash-newline sequences, before passing it to the shell. Thus, the following is equivalent to the preceding example: foo : bar/lose cd bar; \ gobble lose > ../foo The program used as the shell is taken from the variable `SHELL'. By default, the program `/bin/sh' is used. On MS-DOS, if `SHELL' is not set, the value of the variable `COMSPEC' (which is always set) is used instead. The processing of lines that set the variable `SHELL' in Makefiles is different on MS-DOS. The stock shell, `command.com', is ridiculously limited in its functionality and many users of `make' tend to install a replacement shell. Therefore, on MS-DOS, `make' examines the value of `SHELL', and changes its behavior based on whether it points to a Unix-style or DOS-style shell. This allows reasonable functionality even if `SHELL' points to `command.com'. If `SHELL' points to a Unix-style shell, `make' on MS-DOS additionally checks whether that shell can indeed be found; if not, it ignores the line that sets `SHELL'. In MS-DOS, GNU `make' searches for the shell in the following places: 1. In the precise place pointed to by the value of `SHELL'. For example, if the makefile specifies `SHELL = /bin/sh', `make' will look in the directory `/bin' on the current drive. 2. In the current directory. 3. In each of the directories in the `PATH' variable, in order. In every directory it examines, `make' will first look for the specific file (`sh' in the example above). If this is not found, it will also look in that directory for that file with one of the known extensions which identify executable files. For example `.exe', `.com', `.bat', `.btm', `.sh', and some others. If any of these attempts is successful, the value of `SHELL' will be set to the full pathname of the shell as found. However, if none of these is found, the value of `SHELL' will not be changed, and thus the line that sets it will be effectively ignored. This is so `make' will only support features specific to a Unix-style shell if such a shell is actually installed on the system where `make' runs. Note that this extended search for the shell is limited to the cases where `SHELL' is set from the Makefile; if it is set in the environment or command line, you are expected to set it to the full pathname of the shell, exactly as things are on Unix. The effect of the above DOS-specific processing is that a Makefile that says `SHELL = /bin/sh' (as many Unix makefiles do), will work on MS-DOS unaltered if you have e.g. `sh.exe' installed in some directory along your `PATH'. Unlike most variables, the variable `SHELL' is never set from the environment. This is because the `SHELL' environment variable is used to specify your personal choice of shell program for interactive use. It would be very bad for personal choices like this to affect the functioning of makefiles. *Note Variables from the Environment: Environment. However, on MS-DOS and MS-Windows the value of `SHELL' in the environment *is* used, since on those systems most users do not set this variable, and therefore it is most likely set specifically to be used by `make'. On MS-DOS, if the setting of `SHELL' is not suitable for `make', you can set the variable `MAKESHELL' to the shell that `make' should use; this will override the value of `SHELL'. ---------- Footnotes ---------- (1) On MS-DOS, the value of current working directory is *global*, so changing it *will* affect the following command lines on those systems.  File: make.info, Node: Parallel, Next: Errors, Prev: Execution, Up: Commands Parallel Execution ================== GNU `make' knows how to execute several commands at once. Normally, `make' will execute only one command at a time, waiting for it to finish before executing the next. However, the `-j' or `--jobs' option tells `make' to execute many commands simultaneously. On MS-DOS, the `-j' option has no effect, since that system doesn't support multi-processing. If the `-j' option is followed by an integer, this is the number of commands to execute at once; this is called the number of "job slots". If there is nothing looking like an integer after the `-j' option, there is no limit on the number of job slots. The default number of job slots is one, which means serial execution (one thing at a time). One unpleasant consequence of running several commands simultaneously is that output generated by the commands appears whenever each command sends it, so messages from different commands may be interspersed. Another problem is that two processes cannot both take input from the same device; so to make sure that only one command tries to take input from the terminal at once, `make' will invalidate the standard input streams of all but one running command. This means that attempting to read from standard input will usually be a fatal error (a `Broken pipe' signal) for most child processes if there are several. It is unpredictable which command will have a valid standard input stream (which will come from the terminal, or wherever you redirect the standard input of `make'). The first command run will always get it first, and the first command started after that one finishes will get it next, and so on. We will change how this aspect of `make' works if we find a better alternative. In the mean time, you should not rely on any command using standard input at all if you are using the parallel execution feature; but if you are not using this feature, then standard input works normally in all commands. Finally, handling recursive `make' invocations raises issues. For more information on this, see *Note Communicating Options to a Sub-`make': Options/Recursion. If a command fails (is killed by a signal or exits with a nonzero status), and errors are not ignored for that command (*note Errors in Commands: Errors.), the remaining command lines to remake the same target will not be run. If a command fails and the `-k' or `--keep-going' option was not given (*note Summary of Options: Options Summary.), `make' aborts execution. If make terminates for any reason (including a signal) with child processes running, it waits for them to finish before actually exiting. When the system is heavily loaded, you will probably want to run fewer jobs than when it is lightly loaded. You can use the `-l' option to tell `make' to limit the number of jobs to run at once, based on the load average. The `-l' or `--max-load' option is followed by a floating-point number. For example, -l 2.5 will not let `make' start more than one job if the load average is above 2.5. The `-l' option with no following number removes the load limit, if one was given with a previous `-l' option. More precisely, when `make' goes to start up a job, and it already has at least one job running, it checks the current load average; if it is not lower than the limit given with `-l', `make' waits until the load average goes below that limit, or until all the other jobs finish. By default, there is no load limit.  File: make.info, Node: Errors, Next: Interrupts, Prev: Parallel, Up: Commands Errors in Commands ================== After each shell command returns, `make' looks at its exit status. If the command completed successfully, the next command line is executed in a new shell; after the last command line is finished, the rule is finished. If there is an error (the exit status is nonzero), `make' gives up on the current rule, and perhaps on all rules. Sometimes the failure of a certain command does not indicate a problem. For example, you may use the `mkdir' command to ensure that a directory exists. If the directory already exists, `mkdir' will report an error, but you probably want `make' to continue regardless. To ignore errors in a command line, write a `-' at the beginning of the line's text (after the initial tab). The `-' is discarded before the command is passed to the shell for execution. For example, clean: -rm -f *.o This causes `rm' to continue even if it is unable to remove a file. When you run `make' with the `-i' or `--ignore-errors' flag, errors are ignored in all commands of all rules. A rule in the makefile for the special target `.IGNORE' has the same effect, if there are no prerequisites. These ways of ignoring errors are obsolete because `-' is more flexible. When errors are to be ignored, because of either a `-' or the `-i' flag, `make' treats an error return just like success, except that it prints out a message that tells you the status code the command exited with, and says that the error has been ignored. When an error happens that `make' has not been told to ignore, it implies that the current target cannot be correctly remade, and neither can any other that depends on it either directly or indirectly. No further commands will be executed for these targets, since their preconditions have not been achieved. Normally `make' gives up immediately in this circumstance, returning a nonzero status. However, if the `-k' or `--keep-going' flag is specified, `make' continues to consider the other prerequisites of the pending targets, remaking them if necessary, before it gives up and returns nonzero status. For example, after an error in compiling one object file, `make -k' will continue compiling other object files even though it already knows that linking them will be impossible. *Note Summary of Options: Options Summary. The usual behavior assumes that your purpose is to get the specified targets up to date; once `make' learns that this is impossible, it might as well report the failure immediately. The `-k' option says that the real purpose is to test as many of the changes made in the program as possible, perhaps to find several independent problems so that you can correct them all before the next attempt to compile. This is why Emacs' `compile' command passes the `-k' flag by default. Usually when a command fails, if it has changed the target file at all, the file is corrupted and cannot be used--or at least it is not completely updated. Yet the file's timestamp says that it is now up to date, so the next time `make' runs, it will not try to update that file. The situation is just the same as when the command is killed by a signal; *note Interrupts::.. So generally the right thing to do is to delete the target file if the command fails after beginning to change the file. `make' will do this if `.DELETE_ON_ERROR' appears as a target. This is almost always what you want `make' to do, but it is not historical practice; so for compatibility, you must explicitly request it.  File: make.info, Node: Interrupts, Next: Recursion, Prev: Errors, Up: Commands Interrupting or Killing `make' ============================== If `make' gets a fatal signal while a command is executing, it may delete the target file that the command was supposed to update. This is done if the target file's last-modification time has changed since `make' first checked it. The purpose of deleting the target is to make sure that it is remade from scratch when `make' is next run. Why is this? Suppose you type `Ctrl-c' while a compiler is running, and it has begun to write an object file `foo.o'. The `Ctrl-c' kills the compiler, resulting in an incomplete file whose last-modification time is newer than the source file `foo.c'. But `make' also receives the `Ctrl-c' signal and deletes this incomplete file. If `make' did not do this, the next invocation of `make' would think that `foo.o' did not require updating--resulting in a strange error message from the linker when it tries to link an object file half of which is missing. You can prevent the deletion of a target file in this way by making the special target `.PRECIOUS' depend on it. Before remaking a target, `make' checks to see whether it appears on the prerequisites of `.PRECIOUS', and thereby decides whether the target should be deleted if a signal happens. Some reasons why you might do this are that the target is updated in some atomic fashion, or exists only to record a modification-time (its contents do not matter), or must exist at all times to prevent other sorts of trouble.  File: make.info, Node: Recursion, Next: Sequences, Prev: Interrupts, Up: Commands Recursive Use of `make' ======================= Recursive use of `make' means using `make' as a command in a makefile. This technique is useful when you want separate makefiles for various subsystems that compose a larger system. For example, suppose you have a subdirectory `subdir' which has its own makefile, and you would like the containing directory's makefile to run `make' on the subdirectory. You can do it by writing this: subsystem: cd subdir && $(MAKE) or, equivalently, this (*note Summary of Options: Options Summary.): subsystem: $(MAKE) -C subdir You can write recursive `make' commands just by copying this example, but there are many things to know about how they work and why, and about how the sub-`make' relates to the top-level `make'. For your convenience, GNU `make' sets the variable `CURDIR' to the pathname of the current working directory for you. If `-C' is in effect, it will contain the path of the new directory, not the original. The value has the same precedence it would have if it were set in the makefile (by default, an environment variable `CURDIR' will not override this value). Note that setting this variable has no effect on the operation of `make' * Menu: * MAKE Variable:: The special effects of using `$(MAKE)'. * Variables/Recursion:: How to communicate variables to a sub-`make'. * Options/Recursion:: How to communicate options to a sub-`make'. * -w Option:: How the `-w' or `--print-directory' option helps debug use of recursive `make' commands.  File: make.info, Node: MAKE Variable, Next: Variables/Recursion, Up: Recursion How the `MAKE' Variable Works ----------------------------- Recursive `make' commands should always use the variable `MAKE', not the explicit command name `make', as shown here: subsystem: cd subdir && $(MAKE) The value of this variable is the file name with which `make' was invoked. If this file name was `/bin/make', then the command executed is `cd subdir && /bin/make'. If you use a special version of `make' to run the top-level makefile, the same special version will be executed for recursive invocations. As a special feature, using the variable `MAKE' in the commands of a rule alters the effects of the `-t' (`--touch'), `-n' (`--just-print'), or `-q' (`--question') option. Using the `MAKE' variable has the same effect as using a `+' character at the beginning of the command line. *Note Instead of Executing the Commands: Instead of Execution. Consider the command `make -t' in the above example. (The `-t' option marks targets as up to date without actually running any commands; see *Note Instead of Execution::.) Following the usual definition of `-t', a `make -t' command in the example would create a file named `subsystem' and do nothing else. What you really want it to do is run `cd subdir && make -t'; but that would require executing the command, and `-t' says not to execute commands. The special feature makes this do what you want: whenever a command line of a rule contains the variable `MAKE', the flags `-t', `-n' and `-q' do not apply to that line. Command lines containing `MAKE' are executed normally despite the presence of a flag that causes most commands not to be run. The usual `MAKEFLAGS' mechanism passes the flags to the sub-`make' (*note Communicating Options to a Sub-`make': Options/Recursion.), so your request to touch the files, or print the commands, is propagated to the subsystem.  File: make.info, Node: Variables/Recursion, Next: Options/Recursion, Prev: MAKE Variable, Up: Recursion Communicating Variables to a Sub-`make' --------------------------------------- Variable values of the top-level `make' can be passed to the sub-`make' through the environment by explicit request. These variables are defined in the sub-`make' as defaults, but do not override what is specified in the makefile used by the sub-`make' makefile unless you use the `-e' switch (*note Summary of Options: Options Summary.). To pass down, or "export", a variable, `make' adds the variable and its value to the environment for running each command. The sub-`make', in turn, uses the environment to initialize its table of variable values. *Note Variables from the Environment: Environment. Except by explicit request, `make' exports a variable only if it is either defined in the environment initially or set on the command line, and if its name consists only of letters, numbers, and underscores. Some shells cannot cope with environment variable names consisting of characters other than letters, numbers, and underscores. The special variables `SHELL' and `MAKEFLAGS' are always exported (unless you unexport them). `MAKEFILES' is exported if you set it to anything. `make' automatically passes down variable values that were defined on the command line, by putting them in the `MAKEFLAGS' variable. *Note Options/Recursion::. Variables are *not* normally passed down if they were created by default by `make' (*note Variables Used by Implicit Rules: Implicit Variables.). The sub-`make' will define these for itself. If you want to export specific variables to a sub-`make', use the `export' directive, like this: export VARIABLE ... If you want to *prevent* a variable from being exported, use the `unexport' directive, like this: unexport VARIABLE ... As a convenience, you can define a variable and export it at the same time by doing: export VARIABLE = value has the same result as: VARIABLE = value export VARIABLE and export VARIABLE := value has the same result as: VARIABLE := value export VARIABLE Likewise, export VARIABLE += value is just like: VARIABLE += value export VARIABLE *Note Appending More Text to Variables: Appending. You may notice that the `export' and `unexport' directives work in `make' in the same way they work in the shell, `sh'. If you want all variables to be exported by default, you can use `export' by itself: export This tells `make' that variables which are not explicitly mentioned in an `export' or `unexport' directive should be exported. Any variable given in an `unexport' directive will still *not* be exported. If you use `export' by itself to export variables by default, variables whose names contain characters other than alphanumerics and underscores will not be exported unless specifically mentioned in an `export' directive. The behavior elicited by an `export' directive by itself was the default in older versions of GNU `make'. If your makefiles depend on this behavior and you want to be compatible with old versions of `make', you can write a rule for the special target `.EXPORT_ALL_VARIABLES' instead of using the `export' directive. This will be ignored by old `make's, while the `export' directive will cause a syntax error. Likewise, you can use `unexport' by itself to tell `make' *not* to export variables by default. Since this is the default behavior, you would only need to do this if `export' had been used by itself earlier (in an included makefile, perhaps). You *cannot* use `export' and `unexport' by the=mselves to have variables exported for some commands and not for others. The last `export' or `unexport' directive that appears by itself determines the behavior for the entire run of `make'. As a special feature, the variable `MAKELEVEL' is changed when it is passed down from level to level. This variable's value is a string which is the depth of the level as a decimal number. The value is `0' for the top-level `make'; `1' for a sub-`make', `2' for a sub-sub-`make', and so on. The incrementation happens when `make' sets up the environment for a command. The main use of `MAKELEVEL' is to test it in a conditional directive (*note Conditional Parts of Makefiles: Conditionals.); this way you can write a makefile that behaves one way if run recursively and another way if run directly by you. You can use the variable `MAKEFILES' to cause all sub-`make' commands to use additional makefiles. The value of `MAKEFILES' is a whitespace-separated list of file names. This variable, if defined in the outer-level makefile, is passed down through the environment; then it serves as a list of extra makefiles for the sub-`make' to read before the usual or specified ones. *Note The Variable `MAKEFILES': MAKEFILES Variable.  File: make.info, Node: Options/Recursion, Next: -w Option, Prev: Variables/Recursion, Up: Recursion Communicating Options to a Sub-`make' ------------------------------------- Flags such as `-s' and `-k' are passed automatically to the sub-`make' through the variable `MAKEFLAGS'. This variable is set up automatically by `make' to contain the flag letters that `make' received. Thus, if you do `make -ks' then `MAKEFLAGS' gets the value `ks'. As a consequence, every sub-`make' gets a value for `MAKEFLAGS' in its environment. In response, it takes the flags from that value and processes them as if they had been given as arguments. *Note Summary of Options: Options Summary. Likewise variables defined on the command line are passed to the sub-`make' through `MAKEFLAGS'. Words Ain the value of `MAKEFLAGS' that contain `=', `make' treats as variable definitions just as if they appeared on the command line. *Note Overriding Variables: Overriding. The options `-C', `-f', `-o', and `-W' are not put into `MAKEFLAGS'; these options are not passed down. The `-j' option is a special case (*note Parallel Execution: Parallel.). If you set it to some numeric value `N' and your operating system supports it (most any UNIX system will; others typically won't), the parent `make' and all the sub-`make's will communicate to ensure that there are only `N' jobs running at the same time between them all. Note that any job that is marked recursive (*note Instead of Executing the Commands: Instead of Execution.) doesn't count against the total jobs (otherwise we could get `N' sub-`make's running and have no slots left over for any real work!) If your operating system doesn't support the above communication, then `-j 1' is always put into `MAKEFLAGS' instead of the value you specified. This0~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-3;1\K4C is because if the `-j' option were passed down to sub-`make's, you would get many more jobs running in parallel than you asked for. If you give `-j' with no numeric argument, meaning to run as many jobs as possible in parallel, this is passed down, since multiple infinities are no more than one. If you do not want to pass the other flags down, you must change the value of `MAKEFLAGS', like this: subsystem: cd subdir && $(MAKE) MAKEFLAGS= The command line variable definitions really appear in the variable `MAKEOVERRIDES', and `MAKEFLAGS' contains a reference to this variable. If you do want to pass flags down normally, but don't want to pass down the command line variable definitions, you can reset `MAKEOVERRIDES' to empty, like this: MAKEOVERRIDES = This is not usually useful to do. However, some systems have a small fixed limit on the size of the environment, and putting so much information into the value of `MAKEFLAGS' can exceed it. If you see the error message `Arg list too long', this may be the problem. (For strict compliance with POSIX.2, changing `MAKEOVERRIDES' does not affect `MAKEFLAGS' if the special target `.POSIX' appears in the makefile. You probably do not care about this.) A similar variable `MFLAGS' exists also, for historical compatibility. It has the same value as `MAKEFLAGS' except that it does not contain the command line variable definitions, and it always begins with a hyphen unless it is empty (`MAKEFLAGS' begins with a hyphen only when it begins with an option that has no single-letter version, such as `--warn-undefined-variables'). `MFLAGS' was traditionally used explicitly in the recursive `make' command, like this: subsystem: cd subdir && $(MAKE) $(MFLAGS) but now `MAKEFLAGS' makes this usage redundant. If you want your makefiles to be compatible with old `make' programs, use this technique; it will work fine with more modern `make' versions too. The `MAKEFLAGS' variable can also be useful if you want to have certain options, such as `-k' (*note Summary of Options: Options Summary.), set each time you run `make'. You simply put a value for `MAKEFLAGS' in your environment. You can also set `MAKEFLAGS' in a makefile, to specify additional flags that should also be in effect for that makefile. (Note that you cannot use `MFLAGS' this way. That variable is set only for compatibility; `make' does not interpret a value you set for it in any way.) When `make' interprets the value of `MAKEFLAGS' (either from the environment or from a makefile), it first prepends a hyphen if the value does not already begin with one. Then it chops the value into words separated by blanks, and parses these words as if they were options given on the command line (except that `-C', `-f', `-h', `-o', `-W', and their long-named versions are ignored; and there is no error for an invalid option). If you do put `MAKEFLAGS' in your environment, you should be sure not to include any options that will drastically affect the actions of `make' and undermine the purpose of makefiles and of `make' itself. For instance, the `-t', `-n', and `-q' options, if put in one of these variables, could have disastrous consequences and would certainly have at least surprising and probably annoying effects.  File: make.info, Node: -w Option, Prev: Options/Recursion, Up: Recursion The `--print-directory' Option ------------------------------ If you use several levels of recursive `make' invocations, the `-w' or `--print-directory' option can make the output a lot easier to understand by showing each directory as `make' starts processing it and as `make' finishes processing it. For example, if `make -w' is run in the directory `/u/gnu/make', `make' will print a line of the form: make: Entering directory `/u/gnu/make'. before doing anything else, and a line of the form: make: Leaving directory `/u/gnu/make'. when processing is completed. Normally, you do not need to specify this option because `make' does it for you: `-w' is turned on automatically when you use the `-C' option, and in sub-`make's. `make' will not automatically turn on `-w' if you also use `-s', which says to be silent, or if you use `--no-print-directory' to explicitly disable it.  File: make.info, Node: Sequences, Next: Empty Commands, Prev: Recursion, Up: Commands Defining Canned Command Sequences ================================= When the same sequence of commands is useful in making various targets, you can define it as a canned sequence with the `define' directive, and refer to the canned sequence from the rules for those targets. The canned sequence is actually a variable, so the name must not conflict with other variable names. Here is an example of defining a canned sequence of commands: define run-yacc yacc $(firstword $^) mv y.tab.c $@ endef Here `run-yacc' is the name of the variable being defined; `endef' marks the end of the definition; the lines in between are the commands. The `define' directive does not expand variable references and function calls in the canned sequence; the `$' characters, parentheses, variable names, and so on, all become part of the value of the variable you are defining. *Note Defining Variables Verbatim: Defining, for a complete explanation of `define'. The first command in this example runs Yacc on the first prerequisite of whichever rule uses the canned sequence. The output file from Yacc is always named `y.tab.c'. The second command moves the output to the rule's target file name. To use the canned sequence, substitute the variable into the commands of a rule. You can substitute it like any other variable (*note Basics of Variable References: Reference.). Because variables defined by `define' are recursively expanded variables, all the variable references you wrote inside the `define' are expanded now. For example: foo.c : foo.y $(run-yacc) `foo.y' will be substituted for the variable `$^' when it occurs in `run-yacc''s value, and `foo.c' for `$@'. This is a realistic example, but this particular one is not needed in practice because `make' has an implicit rule to figure out these commands based on the file names involved (*note Using Implicit Rules: Implicit Rules.). In command execution, each line of a canned sequence is treated just as if the line appeared on its own in the rule, preceded by a tab. In particular, `make' invokes a separate subshell for each line. You can use the special prefix characters that affect command lines (`@', `-', and `+') on each line of a canned sequence. *Note Writing the Commands in Rules: Commands. For example, using this canned sequence: define frobnicate @echo "frobnicating target $@" frob-step-1 $< -o $@-step-1 frob-step-2 $@-step-1 -o $@ endef `make' will not echo the first line, the `echo' command. But it *will* echo the following two command lines. On the other hand, prefix characters on the command line that refers to a canned sequence apply to every line in the sequence. So the rule: frob.out: frob.in @$(frobnicate) does not echo *any* commands. (*Note Command Echoing: Echoing, for a full explanation of `@'.)  File: make.info, Node: Empty Commands, Prev: Sequences, Up: Commands Using Empty Commands ==================== It is sometimes useful to define commands which do nothing. This is done simply by giving a command that consists of nothing but whitespace. For example: target: ; defines an empty command string for `target'. You could also use a line beginning with a tab character to define an empty command string, but this would be confusing because such a line looks empty. You may be wondering why you would want to define a command string that does nothing. The only reason this is useful is to prevent a target from getting implicit commands (from implicit rules or the `.DEFAULT' special target; *note Implicit Rules::. and *note Defining Last-Resort Default Rules: Last Resort.). You may be inclined to define empty command strings for targets that are not actual files, but only exist so that their prerequisites can be remade. However, this is not the best way to do that, because the prerequisites may not be remade properly if the target file actually does exist. *Note Phony Targets: Phony Targets, for a better way to do this.  File: make.info, Node: Using Variables, Next: Conditionals, Prev: Commands, Up: Top How to Use Variables ******************** A "variable" is a name defined in a makefile to represent a string of text, called the variable's "value". These values are substituted by explicit request into targets, prerequisites, commands, and other parts of the makefile. (In some other versions of `make', variables are called "macros".) Variables and functions in all parts of a makefile are expanded when read, except for the shell commands in rules, the right-hand sides of variable definitions using `=', and the bodies of variable definitions using the `define' directive. Variables can represent lists of file names, options to pass to compilers, programs to run, directories to look in for source files, directories to write output in, or anything else you can imagine. A variable name may be any sequence of characters not containing `:', `#', `=', or leading or trailing whitespace. However, variable names containing characters other than letters, numbers, and underscores should be avoided, as they may be given special meanings in the future, and with some shells they cannot be passed through the environment to a sub-`make' (*note Communicating Variables to a Sub-`make': Variables/Recursion.). Variable names are case-sensitive. The names `foo', `FOO', and `Foo' all refer to different variables. It is traditional to use upper case letters in variable names, but we recommend using lower case letters for variable names that serve internal purposes in the makefile, and reserving upper case for parameters that control implicit rules or for parameters that the user should override with command options (*note Overriding Variables: Overriding.). A few variables have names that are a single punctuation character or just a few characters. These are the "automatic variables", and they have particular specialized uses. *Note Automatic Variables: Automatic. * Menu: * Reference:: How to use the value of a variable. * Flavors:: Variables come in two flavors. * Advanced:: Advanced features for referencing a variable. * Values:: All the ways variables get their values. * Setting:: How to set a variable in the makefile. * Appending:: How to append more text to the old value of a variable. * Override Directive:: How to set a variable in the makefile even if the user has set it with a command argument. * Defining:: An alternate way to set a variable to a verbatim string. * Environment:: Variable values can come from the environment. * Target-specific:: Variable values can be defined on a per-target basis. * Pattern-specific:: Target-specific variable values can be applied to a group of targets that match a pattern. * Automatic:: Some special variables have predefined meanings for use with implicit rules.  File: make.info, Node: Reference, Next: Flavors, Up: Using Variables Basics of Variable References ============================= To substitute a variable's value, write a dollar sign followed by the name of the variable in parentheses or braces: either `$(foo)' or `${foo}' is a valid reference to the variable `foo'. This special significance of `$' is why you must write `$$' to have the effect of a single dollar sign in a file name or command. Variable references can be used in any context: targets, prerequisites, commands, most directives, and new variable values. Here is an example of a common case, where a variable holds the names of all the object files in a program: objects = program.o foo.o utils.o program : $(objects) cc -o program $(objects) $(objects) : defs.h Variable references work by strict textual substitution. Thus, the rule foo = c prog.o : prog.$(foo) $(foo)$(foo) -$(foo) prog.$(foo) could be used to compile a C program `prog.c'. Since spaces before the variable value are ignored in variable assignments, the value of `foo' is precisely `c'. (Don't actually write your makefiles this way!) A dollar sign followed by a character other than a dollar sign, open-parenthesis or open-brace treats that single character as the variable name. Thus, you could reference the variable `x' with `$x'. However, this practice is strongly discouraged, except in the case of the automatic variables (*note Automatic Variables: Automatic.). r*[MAKE-3_78_1HB]MAKE.INFO-4;1+,c.d/@ 4dau-`0123KPWOe56H7m89G@HJFThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Flavors, Next: Advanced, Prev: Reference, Up: Using Variables The Two Flavors of Variables ============================ There are two ways that a variable in GNU `make' can have a value; we call them the two "flavors" of variables. The two flavors are distinguished in how they are defined and in what they do when expanded. The first flavor of variable is a "recursively expanded" variable. Variables of this sort are defined by lines using `=' (*note Setting Variables: Setting.) or by the `define' directive (*note Defining Variables Verbatim: Defining.). The value you specify is installed verbatim; if it contains references to other variables, these references are expanded whenever this variable is substituted (in the course of expanding some other string). When this happens, it is called "recursive expansion". For example, foo = $(bar) bar = $(ugh) ugh = Huh? all:;echo $(foo) will echo `Huh?': `$(foo)' expands to `$(bar)' which expands to `$(ugh)' which finally expands to `Huh?'. This flavor of variable is the only sort supported by other versions of `make'. It has its advantages and its disadvantages. An advantage (most would say) is that: CFLAGS = $(include_dirs) -O include_dirs = -Ifoo -Ibar will do what was intended: when `CFLAGS' is expanded in a command, it will expand to `-Ifoo -Ibar -O'. A major disadvantage is that you cannot append something on the end of a variable, as in CFLAGS = $(CFLAGS) -O because it will cause an infinite loop in the variable expansion. (Actually `make' detects the infinite loop and reports an error.) Another disadvantage is that any functions (*note Functions for Transforming Text: Functions.) referenced in the definition will be executed every time the variable is expanded. This makes `make' run slower; worse, it causes the `wildcard' and `shell' functions to give unpredictable results because you cannot easily control when they are called, or even how many times. To avoid all the problems and inconveniences of recursively expanded variables, there is another flavor: simply expanded variables. "Simply expanded variables" are defined by lines using `:=' (*note Setting Variables: Setting.). The value of a simply expanded variable is scanned once and for all, expanding any references to other variables and functions, when the variable is defined. The actual value of the simply expanded variable is the result of expanding the text that you write. It does not contain any references to other variables; it contains their values *as of the time this variable was defined*. Therefore, x := foo y := $(x) bar x := later is equivalent to y := foo bar x := later When a simply expanded variable is referenced, its value is substituted verbatim. Here is a somewhat more complicated example, illustrating the use of `:=' in conjunction with the `shell' function. (*Note The `shell' Function: Shell Function.) This example also shows use of the variable `MAKELEVEL', which is changed when it is passed down from level to level. (*Note Communicating Variables to a Sub-`make': Variables/Recursion, for information about `MAKELEVEL'.) ifeq (0,${MAKELEVEL}) cur-dir := $(shell pwd) whoami := $(shell whoami) host-type := $(shell arch) MAKE := ${MAKE} host-type=${host-type} whoami=${whoami} endif An advantage of this use of `:=' is that a typical `descend into a directory' command then looks like this: ${subdirs}: ${MAKE} cur-dir=${cur-dir}/$@ -C $@ all Simply expanded variables generally make complicated makefile programming more predictable because they work like variables in most programming languages. They allow you to redefine a variable using its own value (or its value processed in some way by one of the expansion functions) and to use the expansion functions much more efficiently (*note Functions for Transforming Text: Functions.). You can also use them to introduce controlled leading whitespace into variable values. Leading whitespace characters are discarded from your input before substitution of variable references and function calls; this means you can include leading spaces in a variable value by protecting them with variable references, like this: nullstring := space := $(nullstring) # end of the line Here the value of the variable `space' is precisely one space. The comment `# end of the line' is included here just for clarity. Since trailing space characters are *not* stripped from variable values, just a space at the end of the line would have the same effect (but be rather hard to read). If you put whitespace at the end of a variable value, it is a good idea to put a comment like that at the end of the line to make your intent clear. Conversely, if you do *not* want any whitespace characters at the end of your variable value, you must remember not to put a random comment on the end of the line after some whitespace, such as this: dir := /foo/bar # directory to put the frobs in Here the value of the variable `dir' is `/foo/bar ' (with four trailing spaces), which was probably not the intention. (Imagine something like `$(dir)/file' with this definition!) There is another assignment operator for variables, `?='. This is called a conditional variable assignment operator, because it only has an effect if the variable is not yet defined. This statement: FOO ?= bar is exactly equivalent to this (*note The `origin' Function: Origin Function.): ifeq ($(origin FOO), undefined) FOO = bar endif Note that a variable set to an empty value is still defined, so `?=' will not set that variable.  File: make.info, Node: Advanced, Next: Values, Prev: Flavors, Up: Using Variables Advanced Features for Reference to Variables ============================================ This section describes some advanced features you can use to reference variables in more flexible ways. * Menu: * Substitution Refs:: Referencing a variable with substitutions on the value. * Computed Names:: Computing the name of the variable to refer to.  File: make.info, Node: Substitution Refs, Next: Computed Names, Up: Advanced Substitution References ----------------------- A "substitution reference" substitutes the value of a variable with alterations that you specify. It has the form `$(VAR:A=B)' (or `${VAR:A=B}') and its meaning is to take the value of the variable VAR, replace every A at the end of a word with B in that value, and substitute the resulting string. When we say "at the end of a word", we mean that A must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of A in the value are unaltered. For example: foo := a.o b.o c.o bar := $(foo:.o=.c) sets `bar' to `a.c b.c c.c'. *Note Setting Variables: Setting. A substitution reference is actually an abbreviation for use of the `patsubst' expansion function (*note Functions for String Substitution and Analysis: Text Functions.). We provide substitution references as well as `patsubst' for compatibility with other implementations of `make'. Another type of substitution reference lets you use the full power of the `patsubst' function. It has the same form `$(VAR:A=B)' described above, except that now A must contain a single `%' character. This case is equivalent to `$(patsubst A,B,$(VAR))'. *Note Functions for String Substitution and Analysis: Text Functions, for a description of the `patsubst' function. For example: foo := a.o b.o c.o bar := $(foo:%.o=%.c) sets `bar' to `a.c b.c c.c'.  File: make.info, Node: Computed Names, Prev: Substitution Refs, Up: Advanced Computed Variable Names ----------------------- Computed variable names are a complicated concept needed only for sophisticated makefile programming. For most purposes you need not consider them, except to know that making a variable with a dollar sign in its name might have strange results. However, if you are the type that wants to understand everything, or you are actually interested in what they do, read on. Variables may be referenced inside the name of a variable. This is called a "computed variable name" or a "nested variable reference". For example, x = y y = z a := $($(x)) defines `a' as `z': the `$(x)' inside `$($(x))' expands to `y', so `$($(x))' expands to `$(y)' which in turn expands to `z'. Here the name of the variable to reference is not stated explicitly; it is computed by expansion of `$(x)'. The reference `$(x)' here is nested within the outer variable reference. The previous example shows two levels of nesting, but any number of levels is possible. For example, here are three levels: x = y y = z z = u a := $($($(x))) Here the innermost `$(x)' expands to `y', so `$($(x))' expands to `$(y)' which in turn expands to `z'; now we have `$(z)', which becomes `u'. References to recursively-expanded variables within a variable name are reexpanded in the usual fashion. For example: x = $(y) y = z z = Hello a := $($(x)) defines `a' as `Hello': `$($(x))' becomes `$($(y))' which becomes `$(z)' which becomes `Hello'. Nested variable references can also contain modified references and function invocations (*note Functions for Transforming Text: Functions.), just like any other reference. For example, using the `subst' function (*note Functions for String Substitution and Analysis: Text Functions.): x = variable1 variable2 := Hello y = $(subst 1,2,$(x)) z = y a := $($($(z))) eventually defines `a' as `Hello'. It is doubtful that anyone would ever want to write a nested reference as convoluted as this one, but it works: `$($($(z)))' expands to `$($(y))' which becomes `$($(subst 1,2,$(x)))'. This gets the value `variable1' from `x' and changes it by substitution to `variable2', so that the entire string becomes `$(variable2)', a simple variable reference whose value is `Hello'. A computed variable name need not consist entirely of a single variable reference. It can contain several variable references, as well as some invariant text. For example, a_dirs := dira dirb 1_dirs := dir1 dir2 a_files := filea fileb 1_files := file1 file2 ifeq "$(use_a)" "yes" a1 := a else a1 := 1 endif ifeq "$(use_dirs)" "yes" df := dirs else df := files endif dirs := $($(a1)_$(df)) will give `dirs' the same value as `a_dirs', `1_dirs', `a_files' or `1_files' depending on the settings of `use_a' and `use_dirs'. Computed variable names can also be used in substitution references: a_objects := a.o b.o c.o 1_objects := 1.o 2.o 3.o sources := $($(a1)_objects:.o=.c) defines `sources' as either `a.c b.c c.c' or `1.c 2.c 3.c', depending on the value of `a1'. The only restriction on this sort of use of nested variable references is that they cannot specify part of the name of a function to be called. This is because the test for a recognized function name is done before the expansion of nested references. For example, ifdef do_sort func := sort else func := strip endif bar := a d b g q c foo := $($(func) $(bar)) attempts to give `foo' the value of the variable `sort a d b g q c' or `strip a d b g q c', rather than giving `a d b g q c' as the argument to either the `sort' or the `strip' function. This restriction could be removed in the future if that change is shown to be a good idea. You can also use computed variable names in the left-hand side of a variable assignment, or in a `define' directive, as in: dir = foo $(dir)_sources := $(wildcard $(dir)/*.c) define $(dir)_print lpr $($(dir)_sources) endef This example defines the variables `dir', `foo_sources', and `foo_print'. Note that "nested variable references" are quite different from "recursively expanded variables" (*note The Two Flavors of Variables: Flavors.), though both are used together in complex ways when doing makefile programming.  File: make.info, Node: Values, Next: Setting, Prev: Advanced, Up: Using Variables How Variables Get Their Values ============================== Variables can get values in several different ways: * You can specify an overriding value when you run `make'. *Note Overriding Variables: Overriding. * You can specify a value in the makefile, either with an assignment (*note Setting Variables: Setting.) or with a verbatim definition (*note Defining Variables Verbatim: Defining.). * Variables in the environment become `make' variables. *Note Variables from the Environment: Environment. * Several "automatic" variables are given new values for each rule. Each of these has a single conventional use. *Note Automatic Variables: Automatic. * Several variables have constant initial values. *Note Variables Used by Implicit Rules: Implicit Variables.  File: make.info, Node: Setting, Next: Appending, Prev: Values, Up: Using Variables Setting Variables ================= To set a variable from the makefile, write a line starting with the variable name followed by `=' or `:='. Whatever follows the `=' or `:=' on the line becomes the value. For example, objects = main.o foo.o bar.o utils.o defines a variable named `objects'. Whitespace around the variable name and immediately after the `=' is ignored. Variables defined with `=' are "recursively expanded" variables. Variables defined with `:=' are "simply expanded" variables; these definitions can contain variable references which will be expanded before the definition is made. *Note The Two Flavors of Variables: Flavors. The variable name may contain function and variable references, which are expanded when the line is read to find the actual variable name to use. There is no limit on the length of the value of a variable except the amount of swapping space on the computer. When a variable definition is long, it is a good idea to break it into several lines by inserting backslash-newline at convenient places in the definition. This will not affect the functioning of `make', but it will make the makefile easier to read. Most variable names are considered to have the empty string as a value if you have never set them. Several variables have built-in initial values that are not empty, but you can set them in the usual ways (*note Variables Used by Implicit Rules: Implicit Variables.). Several special variables are set automatically to a new value for each rule; these are called the "automatic" variables (*note Automatic Variables: Automatic.). If you'd like a variable to be set to a value only if it's not already set, then you can use the shorthand operator `?=' instead of `='. These two settings of the variable `FOO' are identical (*note The `origin' Function: Origin Function.): FOO ?= bar and ifeq ($(origin FOO), undefined) FOO = bar endif  File: make.info, Node: Appending, Next: Override Directive, Prev: Setting, Up: Using Variables Appending More Text to Variables ================================ Often it is useful to add more text to the value of a variable already defined. You do this with a line containing `+=', like this: objects += another.o This takes the value of the variable `objects', and adds the text `another.o' to it (preceded by a single space). Thus: objects = main.o foo.o bar.o utils.o objects += another.o sets `objects' to `main.o foo.o bar.o utils.o another.o'. Using `+=' is similar to: objects = main.o foo.o bar.o utils.o objects := $(objects) another.o but differs in ways that become important when you use more complex values. When the variable in question has not been defined before, `+=' acts just like normal `=': it defines a recursively-expanded variable. However, when there *is* a previous definition, exactly what `+=' does depends on what flavor of variable you defined originally. *Note The Two Flavors of Variables: Flavors, for an explanation of the two flavors of variables. When you add to a variable's value with `+=', `make' acts essentially as if you had included the extra text in the initial definition of 1~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-4;1d IR$the variable. If you defined it first with `:=', making it a simply-expanded variable, `+=' adds to that simply-expanded definition, and expands the new text before appending it to the old value just as `:=' does (*note Setting Variables: Setting., for a full explanation of `:='). In fact, variable := value variable += more is exactly equivalent to: variable := value variable := $(variable) more On the other hand, when you use `+=' with a variable that you defined first to be recursively-expanded using plain `=', `make' does something a bit different. Recall that when you define a recursively-expanded variable, `make' does not expand the value you set for variable and function references immediately. Instead it stores the text verbatim, and saves these variable and function references to be expanded later, when you refer to the new variable (*note The Two Flavors of Variables: Flavors.). When you use `+=' on a recursively-expanded variable, it is this unexpanded text to which `make' appends the new text you specify. variable = value variable += more is roughly equivalent to: temp = value variable = $(temp) more except that of course it never defines a variable called `temp'. The importance of this comes when the variable's old value contains variable references. Take this common example: CFLAGS = $(includes) -O ... CFLAGS += -pg # enable profiling The first line defines the `CFLAGS' variable with a reference to another variable, `includes'. (`CFLAGS' is used by the rules for C compilation; *note Catalogue of Implicit Rules: Catalogue of Rules..) Using `=' for the definition makes `CFLAGS' a recursively-expanded variable, meaning `$(includes) -O' is *not* expanded when `make' processes the definition of `CFLAGS'. Thus, `includes' need not be defined yet for its value to take effect. It only has to be defined before any reference to `CFLAGS'. If we tried to append to the value of `CFLAGS' without using `+=', we might do it like this: CFLAGS := $(CFLAGS) -pg # enable profiling This is pretty close, but not quite what we want. Using `:=' redefines `CFLAGS' as a simply-expanded variable; this means `make' expands the text `$(CFLAGS) -pg' before setting the variable. If `includes' is not yet defined, we get ` -O -pg', and a later definition of `includes' will have no effect. Conversely, by using `+=' we set `CFLAGS' to the *unexpanded* value `$(includes) -O -pg'. Thus we preserve the reference to `includes', so if that variable gets defined at any later point, a reference like `$(CFLAGS)' still uses its value.  File: make.info, Node: Override Directive, Next: Defining, Prev: Appending, Up: Using Variables The `override' Directive ======================== If a variable has been set with a command argument (*note Overriding Variables: Overriding.), then ordinary assignments in the makefile are ignored. If you want to set the variable in the makefile even though it was set with a command argument, you can use an `override' directive, which is a line that looks like this: override VARIABLE = VALUE or override VARIABLE := VALUE To append more text to a variable defined on the command line, use: override VARIABLE += MORE TEXT *Note Appending More Text to Variables: Appending. The `override' directive was not invented for escalation in the war between makefiles and command arguments. It was invented so you can alter and add to values that the user specifies with command arguments. For example, suppose you always want the `-g' switch when you run the C compiler, but you would like to allow the user to specify the other switches with a command argument just as usual. You could use this `override' directive: override CFLAGS += -g You can also use `override' directives with `define' directives. This is done as you might expect: override define foo bar endef *Note Defining Variables Verbatim: Defining.  File: make.info, Node: Defining, Next: Environment, Prev: Override Directive, Up: Using Variables Defining Variables Verbatim =========================== Another way to set the value of a variable is to use the `define' directive. This directive has an unusual syntax which allows newline characters to be included in the value, which is convenient for defining canned sequences of commands (*note Defining Canned Command Sequences: Sequences.). The `define' directive is followed on the same line by the name of the variable and nothing more. The value to give the variable appears on the following lines. The end of the value is marked by a line containing just the word `endef'. Aside from this difference in syntax, `define' works just like `=': it creates a recursively-expanded variable (*note The Two Flavors of Variables: Flavors.). The variable name may contain function and variable references, which are expanded when the directive is read to find the actual variable name to use. define two-lines echo foo echo $(bar) endef The value in an ordinary assignment cannot contain a newline; but the newlines that separate the lines of the value in a `define' become part of the variable's value (except for the final newline which precedes the `endef' and is not considered part of the value). The previous example is functionally equivalent to this: two-lines = echo foo; echo $(bar) since two commands separated by semicolon behave much like two separate shell commands. However, note that using two separate lines means `make' will invoke the shell twice, running an independent subshell for each line. *Note Command Execution: Execution. If you want variable definitions made with `define' to take precedence over command-line variable definitions, you can use the `override' directive together with `define': override define two-lines foo $(bar) endef *Note The `override' Directive: Override Directive.  File: make.info, Node: Environment, Next: Target-specific, Prev: Defining, Up: Using Variables Variables from the Environment ============================== Variables in `make' can come from the environment in which `make' is run. Every environment variable that `make' sees when it starts up is transformed into a `make' variable with the same name and value. But an explicit assignment in the makefile, or with a command argument, overrides the environment. (If the `-e' flag is specified, then values from the environment override assignments in the makefile. *Note Summary of Options: Options Summary. But this is not recommended practice.) Thus, by setting the variable `CFLAGS' in your environment, you can cause all C compilations in most makefiles to use the compiler switches you prefer. This is safe for variables with standard or conventional meanings because you know that no makefile will use them for other things. (But this is not totally reliable; some makefiles set `CFLAGS' explicitly and therefore are not affected by the value in the environment.) When `make' is invoked recursively, variables defined in the outer invocation can be passed to inner invocations through the environment (*note Recursive Use of `make': Recursion.). By default, only variables that came from the environment or the command line are passed to recursive invocations. You can use the `export' directive to pass other variables. *Note Communicating Variables to a Sub-`make': Variables/Recursion, for full details. Other use of variables from the environment is not recommended. It is not wise for makefiles to depend for their functioning on environment variables set up outside their control, since this would cause different users to get different results from the same makefile. This is against the whole purpose of most makefiles. Such problems would be especially likely with the variable `SHELL', which is normally present in the environment to specify the user's choice of interactive shell. It would be very undesirable for this choice to affect `make'. So `make' ignores the environment value of `SHELL' (except on MS-DOS and MS-Windows, where `SHELL' is usually not set. *Note Special handling of SHELL on MS-DOS: Execution.)  File: make.info, Node: Target-specific, Next: Pattern-specific, Prev: Environment, Up: Using Variables Target-specific Variable Values =============================== Variable values in `make' are usually global; that is, they are the same regardless of where they are evaluated (unless they're reset, of course). One exception to that is automatic variables (*note Automatic Variables: Automatic.). The other exception is "target-specific variable values". This feature allows you to define different values for the same variable, based on the target that `make' is currently building. As with automatic variables, these values are only available within the context of a target's command script (and in other target-specific assignments). Set a target-specific variable value like this: TARGET ... : VARIABLE-ASSIGNMENT or like this: TARGET ... : override VARIABLE-ASSIGNMENT Multiple TARGET values create a target-specific variable value for each member of the target list individually. The VARIABLE-ASSIGNMENT can be any valid form of assignment; recursive (`='), static (`:='), appending (`+='), or conditional (`?='). All variables that appear within the VARIABLE-ASSIGNMENT are evaluated within the context of the target: thus, any previously-defined target-specific variable values will be in effect. Note that this variable is actually distinct from any "global" value: the two variables do not have to have the same flavor (recursive vs. static). Target-specific variables have the same priority as any other makefile variable. Variables provided on the command-line (and in the environment if the `-e' option is in force) will take precedence. Specifying the `override' directive will allow the target-specific variable value to be preferred. There is one more special feature of target-specific variables: when you define a target-specific variable, that variable value is also in effect for all prerequisites of this target (unless those prerequisites override it with their own target-specific variable value). So, for example, a statement like this: prog : CFLAGS = -g prog : prog.o foo.o bar.o will set `CFLAGS' to `-g' in the command script for `prog', but it will also set `CFLAGS' to `-g' in the command scripts that create `prog.o', `foo.o', and `bar.o', and any command scripts which create their prerequisites.  File: make.info, Node: Pattern-specific, Prev: Target-specific, Up: Using Variables Pattern-specific Variable Values ================================ In addition to target-specific variable values (*note Target-specific Variable Values: Target-specific.), GNU `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. Set a pattern-specific variable value like this: PATTERN ... : VARIABLE-ASSIGNMENT or like this: PATTERN ... : override VARIABLE-ASSIGNMENT where PATTERN is a %-pattern. As with target-specific variable values, multiple PATTERN values create a pattern-specific variable value for each pattern individually. The VARIABLE-ASSIGNMENT can be any valid form of assignment. Any command-line variable setting will take precedence, unless `override' is specified. For example: %.o : CFLAGS = -O will assign `CFLAGS' the value of `-O' for all targets matching the pattern `%.o'.  File: make.info, Node: Conditionals, Next: Functions, Prev: Using Variables, Up: Top Conditional Parts of Makefiles ****************************** A "conditional" causes part of a makefile to be obeyed or ignored depending on the values of variables. Conditionals can compare the value of one variable to another, or the value of a variable to a constant string. Conditionals control what `make' actually "sees" in the makefile, so they *cannot* be used to control shell commands at the time of execution. * Menu: * Conditional Example:: Example of a conditional * Conditional Syntax:: The syntax of conditionals. * Testing Flags:: Conditionals that test flags.  File: make.info, Node: Conditional Example, Next: Conditional Syntax, Up: Conditionals Example of a Conditional ======================== The following example of a conditional tells `make' to use one set of libraries if the `CC' variable is `gcc', and a different set of libraries otherwise. It works by controlling which of two command lines will be used as the command for a rule. The result is that `CC=gcc' as an argument to `make' changes not only which compiler is used but also which libraries are linked. libs_for_gcc = -lgnu normal_libs = foo: $(objects) ifeq ($(CC),gcc) $(CC) -o foo $(objects) $(libs_for_gcc) else $(CC) -o foo $(objects) $(normal_libs) endif This conditional uses three directives: one `ifeq', one `else' and one `endif'. The `ifeq' directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared. The lines of the makefile following the `ifeq' are obeyed if the two arguments match; otherwise they are ignored. The `else' directive causes the following lines to be obeyed if the previous conditional failed. In the example above, this means that the second alternative linking command is used whenever the first alternative is not used. It is optional to have an `else' in a conditional. The `endif' directive ends the conditional. Every conditional must end with an `endif'. Unconditional makefile text follows. As this example illustrates, conditionals work at the textual level: the lines of the conditional are treated as part of the makefile, or ignored, according to the condition. This is why the larger syntactic units of the makefile, such as rules, may cross the beginning or the end of the conditional. When the variable `CC' has the value `gcc', the above example has this effect: foo: $(objects) $(CC) -o foo $(objects) $(libs_for_gcc) When the variable `CC' has any other value, the effect is this: foo: $(objects) $(CC) -o foo $(objects) $(normal_libs) Equivalent results can be obtained in another way by conditionalizing a variable assignment and then using the variable unconditionally: libs_for_gcc = -lgnu normal_libs = ifeq ($(CC),gcc) libs=$(libs_for_gcc) else libs=$(normal_libs) endif foo: $(objects) $(CC) -o foo $(objects) $(libs)  File: make.info, Node: Conditional Syntax, Next: Testing Flags, Prev: Conditional Example, Up: Conditionals Syntax of Conditionals ====================== The syntax of a simple conditional with no `else' is as follows: CONDITIONAL-DIRECTIVE TEXT-IF-TRUE endif The TEXT-IF-TRUE may be any lines of text, to be considered as part of the makefile if the condition is true. If the condition is false, no text is used instead. The syntax of a complex conditional is as follows: CONDITIONAL-DIRECTIVE TEXT-IF-TRUE else TEXT-IF-FALSE endif If the condition is true, TEXT-IF-TRUE is used; otherwise, TEXT-IF-FALSE is used instead. The TEXT-IF-FALSE can be any number of lines of text. The syntax of the CONDITIONAL-DIRECTIVE is the same whether the conditional is simple or complex. There are four different directives that test different conditions. Here is a table of them: `ifeq (ARG1, ARG2)' `ifeq 'ARG1' 'ARG2'' `ifeq "ARG1" "ARG2"' `ifeq "ARG1" 'ARG2'' `ifeq 'ARG1' "ARG2"' Expand all variable references in ARG1 and ARG2 and compare them. If they are identical, the TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any, is effective. Often you want to test if a variable has a non-empty value. When the value results from complex expansions of variables and functions, expansions you would consider empty may actually contain whitespace characters and thus are not seen as empty. However, you can use the `strip' function (*note Text Functions::.) to avoid interpreting whitespace as a non-empty value. For example: ifeq ($(strip $(foo)),) TEXT-IF-EMPTY endif will evaluate TEXT-IF-EMPTY even if the expansion of `$(foo)' contains whitespace characters. `ifneq (ARG1, ARG2)' `ifneq 'ARG1' 'ARG2'' `ifneq "ARG1" "ARG2"' `ifneq "ARG1" 'ARG2'' `ifneq 'ARG1' "ARG2"' Expand all variable references in ARG1 and ARG2 and compare them. If they are different, the TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any, is effective. `ifdef VARIABLE-NAME' If the variable VARIABLE-NAME has a non-empty value, the TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any, is effective. Variables that have never been defined have an empty value. Note that `ifdef' only tests whether a variable has a value. It does not expand the variable to see if that value is nonempty. Consequently, tests using `ifdef' return true for all definitions except those like `foo ='. To test for an empty value, use `ifeq ($(foo),)'. For example, bar = foo = $(bar) ifdef foo frobozz = yes else frobozz = no endif sets `frobozz' to `yes', while: foo = ifdef foo frobozz = yes else frobozz = no endif sets `frobozz' to `no'. `ifndef VARIABLE-NAME' If the variable VARIABLE-NAME has an empty value, the TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any, is effective. Extra spaces are allowed and ignored at the beginning of the conditional directive line, but a tab is not allowed. (If the line begins with a tab, it will be considered a command for a rule.) Aside from this, extra spaces or tabs may be inserted with no effect anywhere except within the directive name or within an argument. A comment starting with `#' may appear at the end of the line. The other two directives that play a part in a conditional are `else' and `endif'. Each of these directives is written as one word, with no arguments. Extra spaces are allowed and ignored at the beginning of the line, and spaces or tabs at the end. A comment starting with `#' may appear at the end of the line. Conditionals affect which lines of the makefile `make' uses. If the condition is true, `make' reads the lines of the TEXT-IF-TRUE as part of the makefile; if the condition is false, `make' ignores those lines completely. It follows that syntactic units of the makefile, such as rules, may safely be split across the beginning or the end of the conditional. `make' evaluates conditionals when it reads a makefile. Consequently, you cannot use automatic variables in the tests of conditionals because they are not defined until commands are run (*note Automatic Variables: Automatic.). To prevent intolerable confusion, it is not permitted to start a conditional in one makefile and end it in another. However, you may write an `include' directive within a conditional, provided you do not attempt to terminate the conditional inside the included file.  File: make.info, Node: Testing Flags, Prev: Conditional Syntax, Up: Conditionals Conditionals that Test Flags ============================ You can write a conditional that tests `make' command flags such as `-t' by using the variable `MAKEFLAGS' together with the `findstring' function (*note Functions for String Substitution and Analysis: Text Functions.). This is useful when `touch' is not enough to make a file appear up to date. The `findstring' function determines whether one string appears as a substring of another. If you want to test for the `-t' flag, use `t' as the first string and the value of `MAKEFLAGS' as the other. For example, here is how to arrange to use `ranlib -t' to finish marking an archive file up to date: archive.a: ... ifneq (,$(findstring t,$(MAKEFLAGS))) +touch archive.a +ranlib -t archive.a else ranlib archive.a endif The `+' prefix marks those command lines as "recursive" so that they will be executed despite use of the `-t' flag. *Note Recursive Use of `make':*M Recursion.  File: make.info, Node: Functions, Next: Running, Prev: Conditionals, Up: Top Functions for Transforming Text ******************************* "Functions" allow you to do text processing in the makefile to compute the files to operate on or the commands to use. You use a function in a "function call", where you give the name of the function and some text (the "arguments") for the function to operate on. The result of the function's processing is substituted into the makefile at the point of the call, just as a variable might be substituted. * Menu: * Syntax of Functions:: How to write a function call. * Text Functions:: General-purpose text manipulation functions. * File Name Functions:: Functions for manipulating file names. * Foreach Function:: Repeat some text with controlled variation. * If Function:: Conditionally expand a value. * Call Function:: Expand a user-defined function. * Origin Function:: Find where a variable got its value. * Shell Function:: Substitute the output of a shell command. * Make Control Functions:: Functions that control how make runs.  File: make.info, Node: Syntax of Functions, Next: Text Functions, Up: Functions Function Call Syntax ==================== A function call resembles a variable reference. It looks like this: $(FUNCTION ARGUMENTS) or like this: ${FUNCTION ARGUMENTS} Here FUNCTION is a function name; one of a short list of names that are part of `make'. You can also essentially create your own functions by using the `call' builtin function. The ARGUMENTS are the arguments of the function. They are separated from the function name by one or more spaces or tabs, and if there is more than one argument, then they are separated by commas. Such whitespace and commas are not part of an argument's value. The delimiters which you use to surround the function call, whether parentheses or braces, can appear in an argument only in matching pairs; the other kind of delimiters may appear singly. If the arguments themselves contain other function calls or variable references, it is wisest to use the same kind of delimiters for all the references; write `$(subst a,b,$(x))', not `$(subst a,b,${x})'. This is because it is clearer, and because only one type of delimiter is matched to find the end of the reference. The text written for each argument is processed by substitution of variables and function calls to produce the argument value, which is the text on which the function acts. The substitution is done in the order in which the arguments appear. Commas and unmatched parentheses or braces cannot appear in the text of an argument as written; leading spaces cannot appear in the text of the first argument as written. These characters can be put into the argument value by variable substitution. First define variables `comma' and `space' whose values are isolated comma and space characters, then substitute these variables where such characters are wanted, like this: comma:= , empty:= space:= $(empty) $(empty) foo:= a b c bar:= $(subst $(space),$(comma),$(foo)) # bar is now `a,b,c'. Here the `subst' function replaces each space with a comma, through the value of `foo', and substitutes the result.  File: make.info, Node: Text Functions, Next: File Name Functions, Prev: Syntax of Functions, Up: Functions Functions for String Substitution and Analysis ============================================== Here are some functions that operate on strings: `$(subst FROM,TO,TEXT)' Performs a textual replacement on the text TEXT: each occurrence of FROM is replaced by TO. The result is substituted for the function call. For example, $(subst ee,EE,feet on the street) substitutes the string `fEEt on the strEEt'. `$(patsubst PATTERN,REPLACEMENT,TEXT)' Finds whitespace-separated words in TEXT that match PATTERN and replaces them with REPLACEMENT. Here PATTERN may contain a `%' which acts as a wildcard, matching any number of any characters within a word. If REPLACEMENT also contains a `%', the `%' is replaced by the text that matched the `%' in PATTERN. `%' characters in `patsubst' function invocations can be quoted with preceding backslashes (`\'). Backslashes that would otherwise quote `%' characters can be quoted with more backslashes. Backslashes that quote `%' characters or other backslashes are removed from the pattern before it is compared file names or has a stem substituted into it. Backslashes that are not in danger of quoting `%' characters go unmolested. For example, the pattern `the\%weird\\%pattern\\' has `the%weird\' preceding the operative `%' character, and `pattern\\' following it. The final two backslashes are left alone because they cannot affect any `%' character. Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded. For example, $(patsubst %.c,%.o,x.c.c bar.c) produces the value `x.c.o bar.o'. Substitution references (*note Substitution References: Substitution Refs.) are a simpler way to get the effect of the `patsubst' function: $(VAR:PATTERN=REPLACEMENT) is equivalent to $(patsubst PATTERN,REPLACEMENT,$(VAR)) The second shorthand simplifies one of the most common uses of `patsubst': replacing the suffix at the end of file names. $(VAR:SUFFIX=REPLACEMENT) is equivalent to $(patsubst %SUFFIX,%REPLACEMENT,$(VAR)) For example, you might have a list of object files: objects = foo.o bar.o baz.o To get the list of corresponding source files, you could simply write: $(objects:.o=.c) instead of using the general form: $(patsubst %.o,%.c,$(objects)) `$(strip STRING)' Removes leading and trailing whitespace from STRING and replaces each internal sequence of one or more whitespace characters with a single space. Thus, `$(strip a b c )' results in `a b c'. The function `strip' can be very useful when used in conjunction with conditionals. When comparing something with the empty string `' using `ifeq' or `ifneq', you usually want a string of just whitespace to match the empty string (*note Conditionals::.). Thus, the following may fail to have the desired results: .PHONY: all ifneq "$(needs_made)" "" all: $(needs_made) else all:;@echo 'Nothing to make!' endif Replacing the variable reference `$(needs_made)' with the function call `$(strip $(needs_made))' in the `ifneq' directive would make it more robust. `$(findstring FIND,IN)' Searches IN for an occurrence of FIND. If it occurs, the value is FIND; otherwise, the value is empty. You can use this function in a conditional to test for the presence of a specific substring in a given string. Thus, the two examples, $(findstring a,a b c) $(findstring a,b c) produce the values `a' and `' (the empty string), respectively. *Note Testing Flags::, for a practical application of `findstring'. `$(filter PATTERN...,TEXT)' Returns all whitespace-separated words in TEXT that *do* match any of the PATTERN words, removing any words that *do not* match. The patterns are written using `%', just like the patterns used in the `patsubst' function above. The `filter' function can be used to separate out different types of strings (such as file names) in a variable. For example: sources := foo.c bar.c baz.s ugh.h foo: $(sources) cc $(filter %.c %.s,$(sources)) -o foo says that `foo' depends of `foo.c', `bar.c', `baz.s' and `ugh.h' but only `foo.c', `bar.c' and `baz.s' should be specified in the command to the compiler. `$(filter-out PATTERN...,TEXT)' Returns all whitespace-separated words in TEXT that *do not* match any of the PATTERN words, removing the words that *do* match one or more. This is the exact opposite of the `filter' function. Removes all whitespace-separated words in TEXT that *do* match the PATTERN words, returning only the words that *do not* match. This is the exact opposite of the `filter' function. For example, given: objects=main1.o foo.o main2.o bar.o mains=main1.o main2.o the following generates a list which contains all the object files not in `mains': $(filter-out $(mains),$(objects)) `$(sort LIST)' Sorts the words of LIST in lexical order, removing duplicate words. The output is a list of words separated by single spaces. Thus, $(sort foo bar lose) returns the value `bar foo lose'. Incidentally, since `sort' removes duplicate words, you can use it for this purpose even if you don't care about the sort order. Here is a realistic example of the use of `subst' and `patsubst'. Suppose that a makefile uses the `VPATH' variable to specify a list of directories that `make' should search for prerequisite files (*note `VPATH' Search Path for All Prerequisites: General Search.). This example shows how to tell the C compiler to search for header files in the same list of directories. The value of `VPATH' is a list of directories separated by colons, such as `src:../headers'. First, the `subst' function is used to change the colons to spaces: $(subst :, ,$(VPATH)) This produces `src ../headers'. Then `patsubst' is used to turn each directory name into a `-I' flag. These can be added to the value of the variable `CFLAGS', which is passed automatically to the C compiler, like this: override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH))) The effect is to append the text `-Isrc -I../headers' to the previously given value of `CFLAGS'. The `override' directive is used so that the new value is assigned even if the previous value of `CFLAGS' was specified with a command argument (*note The `override' Directive: Override Directive.). c2~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-5;1d=*[MAKE-3_78_1HB]MAKE.INFO-5;1+,c.d/@ 4db-`0123KPWOe56^7[m89G@HJzThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: File Name Functions, Next: Foreach Function, Prev: Text Functions, Up: Functions Functions for File Names ======================== Several of the built-in expansion functions relate specifically to taking apart file names or lists of file names. Each of the following functions performs a specific transformation on a file name. The argument of the function is regarded as a series of file names, separated by whitespace. (Leading and trailing whitespace is ignored.) Each file name in the series is transformed in the same way and the results are concatenated with single spaces between them. `$(dir NAMES...)' Extracts the directory-part of each file name in NAMES. The directory-part of the file name is everything up through (and including) the last slash in it. If the file name contains no slash, the directory part is the string `./'. For example, $(dir src/foo.c hacks) produces the result `src/ ./'. `$(notdir NAMES...)' Extracts all but the directory-part of each file name in NAMES. If the file name contains no slash, it is left unchanged. Otherwise, everything through the last slash is removed from it. A file name that ends with a slash becomes an empty string. This is unfortunate, because it means that the result does not always have the same number of whitespace-separated file names as the argument had; but we do not see any other valid alternative. For example, $(notdir src/foo.c hacks) produces the result `foo.c hacks'. `$(suffix NAMES...)' Extracts the suffix of each file name in NAMES. If the file name contains a period, the suffix is everything starting with the last period. Otherwise, the suffix is the empty string. This frequently means that the result will be empty when NAMES is not, and if NAMES contains multiple file names, the result may contain fewer file names. For example, $(suffix src/foo.c src-1.0/bar.c hacks) produces the result `.c .c'. `$(basename NAMES...)' Extracts all but the suffix of each file name in NAMES. If the file name contains a period, the basename is everything starting up to (and not including) the last period. Periods in the directory part are ignored. If there is no period, the basename is the entire file name. For example, $(basename src/foo.c src-1.0/bar hacks) produces the result `src/foo src-1.0/bar hacks'. `$(addsuffix SUFFIX,NAMES...)' The argument NAMES is regarded as a series of names, separated by whitespace; SUFFIX is used as a unit. The value of SUFFIX is appended to the end of each individual name and the resulting larger names are concatenated with single spaces between them. For example, $(addsuffix .c,foo bar) produces the result `foo.c bar.c'. `$(addprefix PREFIX,NAMES...)' The argument NAMES is regarded as a series of names, separated by whitespace; PREFIX is used as a unit. The value of PREFIX is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them. For example, $(addprefix src/,foo bar) produces the result `src/foo src/bar'. `$(join LIST1,LIST2)' Concatenates the two arguments word by word: the two first words (one from each argument) concatenated form the first word of the result, the two second words form the second word of the result, and so on. So the Nth word of the result comes from the Nth word of each argument. If one argument has more words that the other, the extra words are copied unchanged into the result. For example, `$(join a b,.c .o)' produces `a.c b.o'. Whitespace between the words in the lists is not preserved; it is replaced with a single space. This function can merge the results of the `dir' and `notdir' functions, to produce the original list of files which was given to those two functions. `$(word N,TEXT)' Returns the Nth word of TEXT. The legitimate values of N start from 1. If N is bigger than the number of words in TEXT, the value is empty. For example, $(word 2, foo bar baz) returns `bar'. `$(wordlist S,E,TEXT)' Returns the list of words in TEXT starting with word S and ending with word E (inclusive). The legitimate values of S and E start from 1. If S is bigger than the number of words in TEXT, the value is empty. If E is bigger than the number of words in TEXT, words up to the end of TEXT are returned. If S is greater than E, `make' swaps them for you. For example, $(wordlist 2, 3, foo bar baz) returns `bar baz'. `$(words TEXT)' Returns the number of words in TEXT. Thus, the last word of TEXT is `$(word $(words TEXT),TEXT)'. `$(firstword NAMES...)' The argument NAMES is regarded as a series of names, separated by whitespace. The value is the first name in the series. The rest of the names are ignored. For example, $(firstword foo bar) produces the result `foo'. Although `$(firstword TEXT)' is the same as `$(word 1,TEXT)', the `firstword' function is retained for its simplicity. `$(wildcard PATTERN)' The argument PATTERN is a file name pattern, typically containing wildcard characters (as in shell file name patterns). The result of `wildcard' is a space-separated list of the names of existing files that match the pattern. *Note Using Wildcard Characters in File Names: Wildcards.  File: make.info, Node: Foreach Function, Next: If Function, Prev: File Name Functions, Up: Functions The `foreach' Function ====================== The `foreach' function is very different from other functions. It causes one piece of text to be used repeatedly, each time with a different substitution performed on it. It resembles the `for' command in the shell `sh' and the `foreach' command in the C-shell `csh'. The syntax of the `foreach' function is: $(foreach VAR,LIST,TEXT) The first two arguments, VAR and LIST, are expanded before anything else is done; note that the last argument, TEXT, is *not* expanded at the same time. Then for each word of the expanded value of LIST, the variable named by the expanded value of VAR is set to that word, and TEXT is expanded. Presumably TEXT contains references to that variable, so its expansion will be different each time. The result is that TEXT is expanded as many times as there are whitespace-separated words in LIST. The multiple expansions of TEXT are concatenated, with spaces between them, to make the result of `foreach'. This simple example sets the variable `files' to the list of all files in the directories in the list `dirs': dirs := a b c d files := $(foreach dir,$(dirs),$(wildcard $(dir)/*)) Here TEXT is `$(wildcard $(dir)/*)'. The first repetition finds the value `a' for `dir', so it produces the same result as `$(wildcard a/*)'; the second repetition produces the result of `$(wildcard b/*)'; and the third, that of `$(wildcard c/*)'. This example has the same result (except for setting `dirs') as the following example: files := $(wildcard a/* b/* c/* d/*) When TEXT is complicated, you can improve readability by giving it a name, with an additional variable: find_files = $(wildcard $(dir)/*) dirs := a b c d files := $(foreach dir,$(dirs),$(find_files)) Here we use the variable `find_files' this way. We use plain `=' to define a recursively-expanding variable, so that its value contains an actual function call to be reexpanded under the control of `foreach'; a simply-expanded variable would not do, since `wildcard' would be called only once at the time of defining `find_files'. The `foreach' function has no permanent effect on the variable VAR; its value and flavor after the `foreach' function call are the same as they were beforehand. The other values which are taken from LIST are in effect only temporarily, during the execution of `foreach'. The variable VAR is a simply-expanded variable during the execution of `foreach'. If VAR was undefined before the `foreach' function call, it is undefined after the call. *Note The Two Flavors of Variables: Flavors. You must take care when using complex variable expressions that result in variable names because many strange things are valid variable names, but are probably not what you intended. For example, files := $(foreach Esta escrito en espanol!,b c ch,$(find_files)) might be useful if the value of `find_files' references the variable whose name is `Esta escrito en espanol!' (es un nombre bastante largo, no?), but it is more likely to be a mistake.  File: make.info, Node: If Function, Next: Call Function, Prev: Foreach Function, Up: Functions The `if' Function ================= The `if' function provides support for conditional expansion in a functional context (as opposed to the GNU `make' makefile conditionals such as `ifeq' (*note Syntax of Conditionals: Conditional Syntax.). An `if' function call can contain either two or three arguments: $(if CONDITION,THEN-PART[,ELSE-PART]) The first argument, CONDITION, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false. If the condition is true then the second argument, THEN-PART, is evaluated and this is used as the result of the evaluation of the entire `if' function. If the condition is false then the third argument, ELSE-PART, is evaluated and this is the result of the `if' function. If there is no third argument, the `if' function evaluates to nothing (the empty string). Note that only one of the THEN-PART or the ELSE-PART will be evaluated, never both. Thus, either can contain side-effects (such as `shell' function calls, etc.)  File: make.info, Node: Call Function, Next: Origin Function, Prev: If Function, Up: Functions The `call' Function =================== The `call' function is unique in that it can be used to create new parameterized functions. You can write a complex expression as the value of a variable, then use `call' to expand it with different values. The syntax of the `call' function is: $(call VARIABLE,PARAM,PARAM,...) When `make' expands this function, it assigns each PARAM to temporary variables `$(1)', `$(2)', etc. The variable `$(0)' will contain VARIABLE. There is no maximum number of parameter arguments. There is no minimum, either, but it doesn't make sense to use `call' with no parameters. Then VARIABLE is expanded as a `make' variable in the context of these temporary assignments. Thus, any reference to `$(1)' in the value of VARIABLE will resolve to the first PARAM in the invocation of `call'. Note that VARIABLE is the *name* of a variable, not a *reference* to that variable. Therefore you would not normally use a `$' or parentheses when writing it. (You can, however, use a variable reference in the name if you want the name not to be a constant.) If VARIABLE is the name of a builtin function, the builtin function is always invoked (even if a `make' variable by that name also exists). Some examples may make this clearer. This macro simply reverses its arguments: reverse = $(2) $(1) foo = a b bar = $(call reverse,$(foo)) Here BAR will contain `b a'. This one is slightly more interesting: it defines a macro to search for the first instance of a program in `PATH': pathsearch = $(firstword $(wildcard $(addsufix /$(1),$(subst :, ,$(PATH))))) LS := $(call pathsearch,ls) Now the variable LS contains `/bin/ls' or similar. The `call' function can be nested. Each recursive invocation gets its own local values for `$(1)', etc. that mask the values of higher-level `call'. For example, here is an implementation of a "map" function: map = $(foreach a,$(2),$(call $(1),$(a))) Now you can MAP a function that normally takes only one argument, such as `origin', to multiple values in one step: o = $(call map,origin,o map MAKE) and end up with O containing something like `file file default'. A final caution: be careful when adding whitespace to the arguments to `call'. As with other functions, any whitespace contained in the second and subsequent arguments is kept; this can cause strange effects. It's generally safest to remove all extraneous whitespace when providing parameters to `call'.  File: make.info, Node: Origin Function, Next: Shell Function, Prev: Call Function, Up: Functions The `origin' Function ===================== The `origin' function is unlike most other functions in that it does not operate on the values of variables; it tells you something *about* a variable. Specifically, it tells you where it came from. The syntax of the `origin' function is: $(origin VARIABLE) Note that VARIABLE is the *name* of a variable to inquire about; not a *reference* to that variable. Therefore you would not normally use a `$' or parentheses when writing it. (You can, however, use a variable reference in the name if you want the name not to be a constant.) The result of this function is a string telling you how the variable VARIABLE was defined: `undefined' if VARIABLE was never defined. `default' if VARIABLE has a default definition, as is usual with `CC' and so on. *Note Variables Used by Implicit Rules: Implicit Variables. Note that if you have redefined a default variable, the `origin' function will return the origin of the later definition. `environment' if VARIABLE was defined as an environment variable and the `-e' option is *not* turned on (*note Summary of Options: Options Summary.). `environment override' if VARIABLE was defined as an environment variable and the `-e' option *is* turned on (*note Summary of Options: Options Summary.). `file' if VARIABLE was defined in a makefile. `command line' if VARIABLE was defined on the command line. `override' if VARIABLE was defined with an `override' directive in a makefile (*note The `override' Directive: Override Directive.). `automatic' if VARIABLE is an automatic variable defined for the execution of the commands for each rule (*note Automatic Variables: Automatic.). This information is primarily useful (other than for your curiosity) to determine if you want to believe the value of a variable. For example, suppose you have a makefile `foo' that includes another makefile `bar'. You want a variable `bletch' to be defined in `bar' if you run the command `make -f bar', even if the environment contains a definition of `bletch'. However, if `foo' defined `bletch' before including `bar', you do not want to override that definition. This could be done by using an `override' directive in `foo', giving that definition precedence over the later definition in `bar'; unfortunately, the `override' directive would also override any command line definitions. So, `bar' could include: ifdef bletch ifeq "$(origin bletch)" "environment" bletch = barf, gag, etc. endif endif If `bletch' has been defined from the environment, this will redefine it. If you want to override a previous definition of `bletch' if it came from the environment, even under `-e', you could instead write: ifneq "$(findstring environment,$(origin bletch))" "" bletch = barf, gag, etc. endif Here the redefinition takes place if `$(origin bletch)' returns either `environment' or `environment override'. *Note Functions for String Substitution and Analysis: Text Functions.  File: make.info, Node: Shell Function, Next: Make Control Functions, Prev: Origin Function, Up: Functions The `shell' Function ==================== The `shell' function is unlike any other function except the `wildcard' function (*note The Function `wildcard': Wildcard Function.) in that it communicates with the world outside of `make'. The `shell' function performs the same function that backquotes (``') perform in most shells: it does "command expansion". This means that it takes an argument that is a shell command and returns the output of the command. The only processing `make' does on the result, before substituting it into the surrounding text, is to convert each newline or carriage-return / newline pair to a single space. It also removes the trailing (carriage-return and) newline, if it's the last thing in the result. The commands run by calls to the `shell' function are run when the function calls are expanded. In most cases, this is when the makefile is read in. The exception is that function calls in the commands of the rules are expanded when the commands are run, and this applies to `shell' function calls like all others. Here are some examples of the use of the `shell' function: contents := $(shell cat foo) sets `contents' to the contents of the file `foo', with a space (rather than a newline) separating each line. files := $(shell echo *.c) sets `files' to the expansion of `*.c'. Unless `make' is using a very strange shell, this has the same result as `$(wildcard *.c)'.  File: make.info, Node: Make Control Functions, Prev: Shell Function, Up: Functions Functions That Control Make =========================== These functions control the way make runs. Generally, they are used to provide information to the user of the makefile or to cause make to stop if some sort of environmental error is detected. `$(error TEXT...)' Generates a fatal error where the message is TEXT. Note that the error is generated whenever this function is evaluated. So, if you put it inside a command script or on the right side of a recursive variable assignment, it won't be evaluated until later. The TEXT will be expanded before the error is generated. For example, ifdef ERROR1 $(error error is $(ERROR1)) endif will generate a fatal error during the read of the makefile if the `make' variable `ERROR1' is defined. Or, ERR = $(error found an error!) .PHONY: err err: ; $(ERR) will generate a fatal error while `make' is running, if the `err' target is invoked. `$(warning TEXT...)' This function works similarly to the `error' function, above, except that `make' doesn't exit. Instead, TEXT is expanded and the resulting message is displayed, but processing of the makefile continues. The result of the expansion of this function is the empty string.  File: make.info, Node: Running, Next: Implicit Rules, Prev: Functions, Up: Top How to Run `make' ***************** A makefile that says how to recompile a program can be used in more than one way. The simplest use is to recompile every file that is out of date. Usually, makefiles are written so that if you run `make' with no arguments, it does just that. But you might want to update only some of the files; you might want to use a different compiler or different compiler options; you might want just to find out which files are out of date without changing them. By giving arguments when you run `make', you can do any of these things and many others. The exit status of `make' is always one of three values: `0' The exit status is zero if `make' is successful. `2' The exit status is two if `make' encounters any errors. It will print messages describing the particular errors. `1' The exit status is one if you use the `-q' flag and `make' determines that some target is not already up to date. *Note Instead of Executing the Commands: Instead of Execution. * Menu: * Makefile Arguments:: How to specify which makefile to use. * Goals:: How to use goal arguments to specify which parts of the makefile to use. * Instead of Execution:: How to use mode flags to specify what kind of thing to do with the commands in the makefile other than simply execute them. * Avoiding Compilation:: How to avoid recompiling certain files. * Overriding:: How to override a variable to specify an alternate compiler and other things. * Testing:: How to proceed past some errors, to test compilation. * Options Summary:: Summary of Options  File: make.info, Node: Makefile Arguments, Next: Goals, Up: Running Arguments to Specify the Makefile ================================= The way to specify the name of the makefile is with the `-f' or `--file' option (`--makefile' also works). For example, `-f altmake' says to use the file `altmake' as the makefile. If you use the `-f' flag several times and follow each `-f' with an argument, all the specified files are used jointly as makefiles. If you do not use the `-f' or `--file' flag, the default is to try `GNUmakefile', `makefile', and `Makefile', in that order, and use the first of these three which exists or can be made (*note Writing Makefiles: Makefiles.).  File: make.info, Node: Goals, Next: Instead of Execution, Prev: Makefile Arguments, Up: Running Arguments to Specify the Goals ============================== The "goals" are the targets that `make' should strive ultimately to update. Other targets are updated as well if they appear as prerequisites of goals, or prerequisites of prerequisites of goals, etc. By default, the goal is the first target in the makefile (not counting targets that start with a period). Therefore, makefiles are usually written so that the first target is for compiling the entire program or programs they describe. If the first rule in the makefile has several targets, only the first target in the rule becomes the default goal, not the whole list. You can specify a different goal or goals with arguments to `make'. Use the name of the goal as an argument. If you specify several goals, `make' processes each of them in turn, in the order you name them. Any target in the makefile may be specified as a goal (unless it starts with `-' or contains an `=', in which case it will be parsed as a switch or variable definition, respectively). Even targets not in the makefile may be specified, if `make' can find implicit rules that say how to make them. `Make' will set the special variable `MAKECMDGOALS' to the list of goals you specified on the command line. If no goals were given on the command line, this variable is empty. Note that this variable should be used only in special circumstances. An example of appropriate use is to avoid including `.d' files during `clean' rules (*note Automatic Prerequisites::.), so `make' won't create them only to immediately remove them again: sources = foo.c bar.c ifneq ($(MAKECMDGOALS),clean) include $(sources:.c=.d) endif One use of specifying a goal is if you want to compile only a part of the program, or only one of several programs. Specify as a goal each file that you wish to remake. For example, consider a directory containing several programs, with a makefile that starts like this: .PHONY: all all: size nm ld ar as If you are working on the program `size', you might want to say `make size' so that only the files of that program are recompiled. Another use of specifying a goal is to make files that are not normally made. For example, there may be a file of debugging output, or a version of the program that is compiled specially for testing, which has a rule in the makefile but is not a prerequisite of the default goal. Another use of specifying a goal is to run the commands associated with a phony target (*note Phony Targets::.) or empty target (*note Empty Target Files to Record Events: Empty Targets.). Many makefiles contain a phony target named `clean' which deletes everything except source files. Naturally, this is done only if you request it explicitly with `make clean'. Following is a list of typical phony and empty target names. *Note Standard Targets::, for a detailed list of all the standard target names which GNU software packages use. `all' Make all the top-level targets the makefile knows about. `clean' Delete all files that are normally created by running `make'. `mostlyclean' Like `clean', but may refrain from deleting a few files that people normally don't want to recompile. For example, the `mostlyclean' target for GCC does not delete `libgcc.a', because recompiling it is rarely necessary and takes a lot of time. `distclean' `realclean' `clobber' Any of these targets might be defined to delete *more* files than `clean' does. For example, this would delete configuration files or links that you would normally create as preparation for compilation, even if the makefile itself cannot create these files. `install' Copy the executable file into a directory that users typically search for commands; copy any auxiliary files that the executable uses into the directories where it will look for them. `print' Print listings of the source files that have changed. `tar' Create a tar file of the source files. `shar' Create a shell archive (shar file) of the source files. `dist' Create a distribution file of the source files. This might be a tar file, or a shar file, or a compressed version of one of the above, or even more than one of the above. `TAGS' Update a tags table for this program. `check' `test' Perform self tests on the program this makefile builds.  File: make.info, Node: Instead of Execution, Next: Avoiding Compilation, Prev: Goals, Up: Running Instead of Executing the Commands ================================= The makefile tells `make' how to tell whether a target is up to date, and how to update each target. But updating the targets is not always what you want. Certain options specify other activities for `make'. `-n' `--just-print' `--dry-run' `--recon' "No-op". The activity is to print what commands would be used to make the targets up to date, but not actually execute them. `-t' `--touch' "Touch". The activity is to mark the targets as up to date without actually changing them. In other words, `make' pretends to compile the targets but does not really change their contents. `-q' `--question' "Question". The activity is to find out silently whether the targets are up to date already; but execute no commands in either case. In other words, neither compilation nor output will occur. `-W FILE' `--what-if=FILE' `--assume-new=FILE' `--new-file=FILE' "What if". Each `-W' flag is followed by a file name. The given files' modification times are recorded by `make' as being the present time, although the actual modification times remain the same. You can use the `-W' flag in conjunction with the `-n' flag to see what would happen if you were to modify specific files. With the `-n' flag, `make' prints the commands that it would normally execute but does not execute them. With the `-t' flag, `make' ignores the commands in the rules and uses (in effect) the command `touch' for each target that needs to be remade. The `touch' command is also printed, unless `-s' or `.SILENT' is used. For speed, `make' does not actually invoke the program `touch'. It does the work directly. With the `-q' flag, `make' prints nothing and executes no commands, but the exit status code it returns is zero if and only if the targets to be considered are already up to date. If the exit status is one, then some updating needs to be done. If `make' encounters an error, the exit status is two, so you can distinguish an error from a target that is not up to date. It is an error to use more than one of these three flags in the same invocation of `make'. The `-n', `-t', and `-q' options do not affect command lines that begin with `+' characters or contain the strings `$(MAKE)' or `${MAKE}'. Note that only the line containing the `+' character or the strings `$(MAKE)' or `${MAKE}' is run regardless of these options. Other lines in the same rule are not run unless they too begin with `+' or contain `$(MAKE)' or `${MAKE}' (*Note How the `MAKE' Variable Works: MAKE Variable.) The `-W' flag provides two features: * If you also use the `-n' or `-q' flag, you can see what `make' would do if you were to modify some files. * Without the `-n' or `-q' flag, when `make' is actually executing commands, the `-W' flag can direct `make' to act as if some files had been modified, without actually modifying the files. Note that the options `-p' and `-v' allow you to obtain other information about `make' or about the makefiles in use (*note Summary of Options: Options Summary.).  File: make.info, Node: Avoiding Compilation, Next: Overriding, Prev: Instead of Execution, Up: Running Avoiding Recompilation of Some Files ==================================== Sometimes you may have changed a source file but you do not want to recompile all the files that depend on it. For example, suppose you add a macro or a declaration to a header file 3~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-5;1dvF>that many other files depend on. Being conservative, `make' assumes that any change in the header file requires recompilation of all dependent files, but you know that they do not need to be recompiled and you would rather not waste the time waiting for them to compile. If you anticipate the problem before changing the header file, you can use the `-t' flag. This flag tells `make' not to run the commands in the rules, but rather to mark the target up to date by changing its last-modification date. You would follow this procedure: 1. Use the command `make' to recompile the source files that really need recompilation. 2. Make the changes in the header files. 3. Use the command `make -t' to mark all the object files as up to date. The next time you run `make', the changes in the header files will not cause any recompilation. If you have already changed the header file at a time when some files do need recompilation, it is too late to do this. Instead, you can use the `-o FILE' flag, which marks a specified file as "old" (*note Summary of Options: Options Summary.). This means that the file itself will not be remade, and nothing else will be remade on its account. Follow this procedure: 1. Recompile the source files that need compilation for reasons independent of the particular header file, with `make -o HEADERFILE'. If several header files are involved, use a separate `-o' option for each header file. 2. Touch all the object files with `make -t'.  File: make.info, Node: Overriding, Next: Testing, Prev: Avoiding Compilation, Up: Running Overriding Variables ==================== An argument that contains `=' specifies the value of a variable: `V=X' sets the value of the variable V to X. If you specify a value in this way, all ordinary assignments of the same variable in the makefile are ignored; we say they have been "overridden" by the command line argument. The most common way to use this facility is to pass extra flags to compilers. For example, in a properly written makefile, the variable `CFLAGS' is included in each command that runs the C compiler, so a file `foo.c' would be compiled something like this: cc -c $(CFLAGS) foo.c Thus, whatever value you set for `CFLAGS' affects each compilation that occurs. The makefile probably specifies the usual value for `CFLAGS', like this: CFLAGS=-g Each time you run `make', you can override this value if you wish. For example, if you say `make CFLAGS='-g -O'', each C compilation will be done with `cc -c -g -O'. (This illustrates how you can use quoting in the shell to enclose spaces and other special characters in the value of a variable when you override it.) The variable `CFLAGS' is only one of many standard variables that exist just so that you can change them this way. *Note Variables Used by Implicit Rules: Implicit Variables, for a complete list. You can also program the makefile to look at additional variables of your own, giving the user the ability to control other aspects of how the makefile works by changing the variables. When you override a variable with a command argument, you can define either a recursively-expanded variable or a simply-expanded variable. The examples shown above make a recursively-expanded variable; to make a simply-expanded variable, write `:=' instead of `='. But, unless you want to include a variable reference or function call in the *value* that you specify, it makes no difference which kind of variable you create. There is one way that the makefile can change a variable that you have overridden. This is to use the `override' directive, which is a line that looks like this: `override VARIABLE = VALUE' (*note The `override' Directive: Override Directive.).  File: make.info, Node: Testing, Next: Options Summary, Prev: Overriding, Up: Running Testing the Compilation of a Program ==================================== Normally, when an error happens in executing a shell command, `make' gives up immediately, returning a nonzero status. No further commands are executed for any target. The error implies that the goal cannot be correctly remade, and `make' reports this as soon as it knows. When you are compiling a program that you have just changed, this is not what you want. Instead, you would rather that `make' try compiling every file that can be tried, to show you as many compilation errors as possible. On these occasions, you should use the `-k' or `--keep-going' flag. This tells `make' to continue to consider the other prerequisites of the pending targets, remaking them if necessary, before it gives up and returns nonzero status. For example, after an error in compiling one object file, `make -k' will continue compiling other object files even though it already knows that linking them will be impossible. In addition to continuing after failed shell commands, `make -k' will continue as much as possible after discovering that it does not know how to make a target or prerequisite file. This will always cause an error message, but without `-k', it is a fatal error (*note Summary of Options: Options Summary.). The usual behavior of `make' assumes that your purpose is to get the goals up to date; once `make' learns that this is impossible, it might as well report the failure immediately. The `-k' flag says that the real purpose is to test as much as possible of the changes made in the program, perhaps to find several independent problems so that you can correct them all before the next attempt to compile. This is why Emacs' `M-x compile' command passes the `-k' flag by default.  File: make.info, Node: Options Summary, Prev: Testing, Up: Running Summary of Options ================== Here is a table of all the options `make' understands: `-b' `-m' These options are ignored for compatibility with other versions of `make'. `-C DIR' `--directory=DIR' Change to directory DIR before reading the makefiles. If multiple `-C' options are specified, each is interpreted relative to the previous one: `-C / -C etc' is equivalent to `-C /etc'. This is typically used with recursive invocations of `make' (*note Recursive Use of `make': Recursion.). `-d' `--debug' Print debugging information in addition to normal processing. The debugging information says which files are being considered for remaking, which file-times are being compared and with what results, which files actually need to be remade, which implicit rules are considered and which are applied--everything interesting about how `make' decides what to do. `-e' `--environment-overrides' Give variables taken from the environment precedence over variables from makefiles. *Note Variables from the Environment: Environment. `-f FILE' `--file=FILE' `--makefile=FILE' Read the file named FILE as a makefile. *Note Writing Makefiles: Makefiles. `-h' `--help' Remind you of the options that `make' understands and then exit. `-i' `--ignore-errors' Ignore all errors in commands executed to remake files. *Note Errors in Commands: Errors. `-I DIR' `--include-dir=DIR' Specifies a directory DIR to search for included makefiles. *Note Including Other Makefiles: Include. If several `-I' options are used to specify several directories, the directories are searched in the order specified. `-j [JOBS]' `--jobs=[JOBS]' Specifies the number of jobs (commands) to run simultaneously. With no argument, `make' runs as many jobs simultaneously as possible. If there is more than one `-j' option, the last one is effective. *Note Parallel Execution: Parallel, for more information on how commands are run. Note that this option is ignored on MS-DOS. `-k' `--keep-going' Continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other prerequisites of these targets can be processed all the same. *Note Testing the Compilation of a Program: Testing. `-l [LOAD]' `--load-average[=LOAD]' `--max-load[=LOAD]' Specifies that no new jobs (commands) should be started if there are other jobs running and the load average is at least LOAD (a floating-point number). With no argument, removes a previous load limit. *Note Parallel Execution: Parallel. `-n' `--just-print' `--dry-run' `--recon' Print the commands that would be executed, but do not execute them. *Note Instead of Executing the Commands: Instead of Execution. `-o FILE' `--old-file=FILE' `--assume-old=FILE' Do not remake the file FILE even if it is older than its prerequisites, and do not remake anything on account of changes in FILE. Essentially the file is treated as very old and its rules are ignored. *Note Avoiding Recompilation of Some Files: Avoiding Compilation. `-p' `--print-data-base' Print the data base (rules and variable values) that results from reading the makefiles; then execute as usual or as otherwise specified. This also prints the version information given by the `-v' switch (see below). To print the data base without trying to remake any files, use `make -qp'. To print the data base of predefined rules and variables, use `make -p -f /dev/null'. `-q' `--question' "Question mode". Do not run any commands, or print anything; just return an exit status that is zero if the specified targets are already up to date, one if any remaking is required, or two if an error is encountered. *Note Instead of Executing the Commands: Instead of Execution. `-r' `--no-builtin-rules' Eliminate use of the built-in implicit rules (*note Using Implicit Rules: Implicit Rules.). You can still define your own by writing pattern rules (*note Defining and Redefining Pattern Rules: Pattern Rules.). The `-r' option also clears out the default list of suffixes for suffix rules (*note Old-Fashioned Suffix Rules: Suffix Rules.). But you can still define your own suffixes with a rule for `.SUFFIXES', and then define your own suffix rules. Note that only *rules* are affected by the `-r' option; default variables remain in effect (*note Variables Used by Implicit Rules: Implicit Variables.); see the `-R' option below. `-R' `--no-builtin-variables' Eliminate use of the built-in rule-specific variables (*note Variables Used by Implicit Rules: Implicit Variables.). You can still define your own, of course. The `-R' option also automatically enables the `-r' option (see above), since it doesn't make sense to have implicit rules without any definitions for the variables that they use. `-s' `--silent' `--quiet' Silent operation; do not print the commands as they are executed. *Note Command Echoing: Echoing. `-S' `--no-keep-going' `--stop' Cancel the effect of the `-k' option. This is never necessary except in a recursive `make' where `-k' might be inherited from the top-level `make' via `MAKEFLAGS' (*note Recursive Use of `make': Recursion.) or if you set `-k' in `MAKEFLAGS' in your environment. `-t' `--touch' Touch files (mark them up to date without really changing them) instead of running their commands. This is used to pretend that the commands were done, in order to fool future invocations of `make'. *Note Instead of Executing the Commands: Instead of Execution. `-v' `--version' Print the version of the `make' program plus a copyright, a list of authors, and a notice that there is no warranty; then exit. `-w' `--print-directory' Print a message containing the working directory both before and after executing the makefile. This may be useful for tracking down errors from complicated nests of recursive `make' commands. *Note Recursive Use of `make': Recursion. (In practice, you rarely need to specify this option since `make' does it for you; see *Note The `--print-directory' Option: -w Option.) `--no-print-directory' Disable printing of the working directory under `-w'. This option is useful when `-w' is turned on automatically, but you do not want to see the extra messages. *Note The `--print-directory' Option: -w Option. `-W FILE' `--what-if=FILE' `--new-file=FILE' `--assume-new=FILE' Pretend that the target FILE has just been modified. When used with the `-n' flag, this shows you what would happen if you were to modify that file. Without `-n', it is almost the same as running a `touch' command on the given file before running `make', except that the modification time is changed only in the imagination of `make'. *Note Instead of Executing the Commands: Instead of Execution. `--warn-undefined-variables' Issue a warning message whenever `make' sees a reference to an undefined variable. This can be helpful when you are trying to debug makefiles which use variables in complex ways.  File: make.info, Node: Implicit Rules, Next: Archives, Prev: Running, Up: Top Using Implicit Rules ******************** Certain standard ways of remaking target files are used very often. For example, one customary way to make an object file is from a C source file using the C compiler, `cc'. "Implicit rules" tell `make' how to use customary techniques so that you do not have to specify them in detail when you want to use them. For example, there is an implicit rule for C compilation. File names determine which implicit rules are run. For example, C compilation typically takes a `.c' file and makes a `.o' file. So `make' applies the implicit rule for C compilation when it sees this combination of file name endings. A chain of implicit rules can apply in sequence; for example, `make' will remake a `.o' file from a `.y' file by way of a `.c' file. The built-in implicit rules use several variables in their commands so that, by changing the values of the variables, you can change the way the implicit rule works. For example, the variable `CFLAGS' controls the flags given to the C compiler by the implicit rule for C compilation. You can define your own implicit rules by writing "pattern rules". "Suffix rules" are a more limited way to define implicit rules. Pattern rules are more general and clearer, but suffix rules are retained for compatibility. * Menu: * Using Implicit:: How to use an existing implicit rule to get the commands for updating a file. * Catalogue of Rules:: A list of built-in implicit rules. * Implicit Variables:: How to change what predefined rules do. * Chained Rules:: How to use a chain of implicit rules. * Pattern Rules:: How to define new implicit rules. * Last Resort:: How to defining commands for rules which cannot find any. * Suffix Rules:: The old-fashioned style of implicit rule. * Implicit Rule Search:: The precise algorithm for applying implicit rules.  File: make.info, Node: Using Implicit, Next: Catalogue of Rules, Up: Implicit Rules Using Implicit Rules ==================== To allow `make' to find a customary method for updating a target file, all you have to do is refrain from specifying commands yourself. Either write a rule with no command lines, or don't write a rule at all. Then `make' will figure out which implicit rule to use based on which kind of source file exists or can be made. For example, suppose the makefile looks like this: foo : foo.o bar.o cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS) Because you mention `foo.o' but do not give a rule for it, `make' will automatically look for an implicit rule that tells how to update it. This happens whether or not the file `foo.o' currently exists. If an implicit rule is found, it can supply both commands and one or more prerequisites (the source files). You would want to write a rule for `foo.o' with no command lines if you need to specify additional prerequisites, such as header files, that the implicit rule cannot supply. Each implicit rule has a target pattern and prerequisite patterns. There may be many implicit rules with the same target pattern. For example, numerous rules make `.o' files: one, from a `.c' file with the C compiler; another, from a `.p' file with the Pascal compiler; and so on. The rule that actually applies is the one whose prerequisites exist or can be made. So, if you have a file `foo.c', `make' will run the C compiler; otherwise, if you have a file `foo.p', `make' will run the Pascal compiler; and so on. Of course, when you write the makefile, you know which implicit rule you want `make' to use, and you know it will choose that one because you know which possible prerequisite files are supposed to exist. *Note Catalogue of Implicit Rules: Catalogue of Rules, for a catalogue of all the predefined implicit rules. Above, we said an implicit rule applies if the required prerequisites "exist or can be made". A file "can be made" if it is mentioned explicitly in the makefile as a target or a prerequisite, or if an implicit rule can be recursively found for how to make it. When an implicit prerequisite is the result of another implicit rule, we say that "chaining" is occurring. *Note Chains of Implicit Rules: Chained Rules. In general, `make' searches for an implicit rule for each target, and for each double-colon rule, that has no commands. A file that is mentioned only as a prerequisite is considered aa target whose rule specifies nothing, so implicit rule search happens for it. *Note Implicit Rule Search Algorithm: Implicit Rule Search, for the details of how the search is done. Note that explicit prerequisites do not influence implicit rule search. For example, consider this explicit rule: foo.o: foo.p The prerequisite on `foo.p' does not necessarily mean that `make' will remake `foo.o' according to the implicit rule to make an object file, a `.o' file, from a Pascal source file, a `.p' file. For example, if `foo.c' also exists, the implicit rule to make an object file from a C source file is used instead, because it appears before the Pascal rule in the list of predefined implicit rules (*note Catalogue of Implicit Rules: Catalogue of Rules.). If you do not want an implicit rule to be used for a target that has no commands, you can give that target empty commands by writing a semicolon (*note Defining Empty Commands: Empty Commands.). *[MAKE-3_78_1HB]MAKE.INFO-6;1+,c.d/@ 4dc-`0123KPWOe56A7m89G@HJ0This is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Catalogue of Rules, Next: Implicit Variables, Prev: Using Implicit, Up: Implicit Rules Catalogue of Implicit Rules =========================== Here is a catalogue of predefined implicit rules which are always available unless the makefile explicitly overrides or cancels them. *Note Canceling Implicit Rules: Canceling Rules, for information on canceling or overriding an implicit rule. The `-r' or `--no-builtin-rules' option cancels all predefined rules. Not all of these rules will always be defined, even when the `-r' option is not given. Many of the predefined implicit rules are implemented in `make' as suffix rules, so which ones will be defined depends on the "suffix list" (the list of prerequisites of the special target `.SUFFIXES'). The default suffix list is: `.out', `.a', `.ln', `.o', `.c', `.cc', `.C', `.p', `.f', `.F', `.r', `.y', `.l', `.s', `.S', `.mod', `.sym', `.def', `.h', `.info', `.dvi', `.tex', `.texinfo', `.texi', `.txinfo', `.w', `.ch' `.web', `.sh', `.elc', `.el'. All of the implicit rules described below whose prerequisites have one of these suffixes are actually suffix rules. If you modify the suffix list, the only predefined suffix rules in effect will be those named by one or two of the suffixes that are on the list you specify; rules whose suffixes fail to be on the list are disabled. *Note Old-Fashioned Suffix Rules: Suffix Rules, for full details on suffix rules. Compiling C programs `N.o' is made automatically from `N.c' with a command of the form `$(CC) -c $(CPPFLAGS) $(CFLAGS)'. Compiling C++ programs `N.o' is made automatically from `N.cc' or `N.C' with a command of the form `$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)'. We encourage you to use the suffix `.cc' for C++ source files instead of `.C'. Compiling Pascal programs `N.o' is made automatically from `N.p' with the command `$(PC) -c $(PFLAGS)'. Compiling Fortran and Ratfor programs `N.o' is made automatically from `N.r', `N.F' or `N.f' by running the Fortran compiler. The precise command used is as follows: `.f' `$(FC) -c $(FFLAGS)'. `.F' `$(FC) -c $(FFLAGS) $(CPPFLAGS)'. `.r' `$(FC) -c $(FFLAGS) $(RFLAGS)'. Preprocessing Fortran and Ratfor programs `N.f' is made automatically from `N.r' or `N.F'. This rule runs just the preprocessor to convert a Ratfor or preprocessable Fortran program into a strict Fortran program. The precise command used is as follows: `.F' `$(FC) -F $(CPPFLAGS) $(FFLAGS)'. `.r' `$(FC) -F $(FFLAGS) $(RFLAGS)'. Compiling Modula-2 programs `N.sym' is made from `N.def' with a command of the form `$(M2C) $(M2FLAGS) $(DEFFLAGS)'. `N.o' is made from `N.mod'; the form is: `$(M2C) $(M2FLAGS) $(MODFLAGS)'. Assembling and preprocessing assembler programs `N.o' is made automatically from `N.s' by running the assembler, `as'. The precise command is `$(AS) $(ASFLAGS)'. `N.s' is made automatically from `N.S' by running the C preprocessor, `cpp'. The precise command is `$(CPP) $(CPPFLAGS)'. Linking a single object file `N' is made automatically from `N.o' by running the linker (usually called `ld') via the C compiler. The precise command used is `$(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS)'. This rule does the right thing for a simple program with only one source file. It will also do the right thing if there are multiple object files (presumably coming from various other source files), one of which has a name matching that of the executable file. Thus, x: y.o z.o when `x.c', `y.c' and `z.c' all exist will execute: cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x rm -f x.o rm -f y.o rm -f z.o In more complicated cases, such as when there is no object file whose name derives from the executable file name, you must write an explicit command for linking. Each kind of file automatically made into `.o' object files will be automatically linked by using the compiler (`$(CC)', `$(FC)' or `$(PC)'; the C compiler `$(CC)' is used to assemble `.s' files) without the `-c' option. This could be done by using the `.o' object files as intermediates, but it is faster to do the compiling and linking in one step, so that's how it's done. Yacc for C programs `N.c' is made automatically from `N.y' by running Yacc with the command `$(YACC) $(YFLAGS)'. Lex for C programs `N.c' is made automatically from `N.l' by by running Lex. The actual command is `$(LEX) $(LFLAGS)'. Lex for Ratfor programs `N.r' is made automatically from `N.l' by by running Lex. The actual command is `$(LEX) $(LFLAGS)'. The convention of using the same suffix `.l' for all Lex files regardless of whether they produce C code or Ratfor code makes it impossible for `make' to determine automatically which of the two languages you are using in any particular case. If `make' is called upon to remake an object file from a `.l' file, it must guess which compiler to use. It will guess the C compiler, because that is more common. If you are using Ratfor, make sure `make' knows this by mentioning `N.r' in the makefile. Or, if you are using Ratfor exclusively, with no C files, remove `.c' from the list of implicit rule suffixes with: .SUFFIXES: .SUFFIXES: .o .r .f .l ... Making Lint Libraries from C, Yacc, or Lex programs `N.ln' is made from `N.c' by running `lint'. The precise command is `$(LINT) $(LINTFLAGS) $(CPPFLAGS) -i'. The same command is used on the C code produced from `N.y' or `N.l'. TeX and Web `N.dvi' is made from `N.tex' with the command `$(TEX)'. `N.tex' is made from `N.web' with `$(WEAVE)', or from `N.w' (and from `N.ch' if it exists or can be made) with `$(CWEAVE)'. `N.p' is made from `N.web' with `$(TANGLE)' and `N.c' is made from `N.w' (and from `N.ch' if it exists or can be made) with `$(CTANGLE)'. Texinfo and Info `N.dvi' is made from `N.texinfo', `N.texi', or `N.txinfo', with the command `$(TEXI2DVI) $(TEXI2DVI_FLAGS)'. `N.info' is made from `N.texinfo', `N.texi', or `N.txinfo', with the command `$(MAKEINFO) $(MAKEINFO_FLAGS)'. RCS Any file `N' is extracted if necessary from an RCS file named either `N,v' or `RCS/N,v'. The precise command used is `$(CO) $(COFLAGS)'. `N' will not be extracted from RCS if it already exists, even if the RCS file is newer. The rules for RCS are terminal (*note Match-Anything Pattern Rules: Match-Anything Rules.), so RCS files cannot be generated from another source; they must actually exist. SCCS Any file `N' is extracted if necessary from an SCCS file named either `s.N' or `SCCS/s.N'. The precise command used is `$(GET) $(GFLAGS)'. The rules for SCCS are terminal (*note Match-Anything Pattern Rules: Match-Anything Rules.), so SCCS files cannot be generated from another source; they must actually exist. For the benefit of SCCS, a file `N' is copied from `N.sh' and made executable (by everyone). This is for shell scripts that are checked into SCCS. Since RCS preserves the execution permission of a file, you do not need to use this feature with RCS. We recommend that you avoid using of SCCS. RCS is widely held to be superior, and is also free. By choosing free software in place of comparable (or inferior) proprietary software, you support the free software movement. Usually, you want to change only the variables listed in the table above, which are documented in the following section. However, the commands in built-in implicit rules actually use variables such as `COMPILE.c', `LINK.p', and `PREPROCESS.S', whose values contain the commands listed above. `make' follows the convention that the rule to compile a `.X' source file uses the variable `COMPILE.X'. Similarly, the rule to produce an executable from a `.X' file uses `LINK.X'; and the rule to preprocess a `.X' file uses `PREPROCESS.X'. Every rule that produces an object file uses the variable `OUTPUT_OPTION'. `make' defines this variable either to contain `-o $@', or to be empty, depending on a compile-time option. You need the `-o' option to ensure that the output goes into the right file when the source file is in a different directory, as when using `VPATH' (*note Directory Search::.). However, compilers on some systems do not accept a `-o' switch for object files. If you use such a system, and use `VPATH', some compilations will put their output in the wrong place. A possible workaround for this problem is to give `OUTPUT_OPTION' the value `; mv $*.o $@'.  File: make.info, Node: Implicit Variables, Next: Chained Rules, Prev: Catalogue of Rules, Up: Implicit Rules Variables Used by Implicit Rules ================================ The commands in built-in implicit rules make liberal use of certain predefined variables. You can alter these variables in the makefile, with arguments to `make', or in the environment to alter how the implicit rules work without redefining the rules themselves. You can cancel all variables used by implicit rules with the `-R' or `--no-builtin-variables' option. For example, the command used to compile a C source file actually says `$(CC) -c $(CFLAGS) $(CPPFLAGS)'. The default values of the variables used are `cc' and nothing, resulting in the command `cc -c'. By redefining `CC' to `ncc', you could cause `ncc' to be used for all C compilations performed by the implicit rule. By redefining `CFLAGS' to be `-g', you could pass the `-g' option to each compilation. *All* implicit rules that do C compilation use `$(CC)' to get the program name for the compiler and *all* include `$(CFLAGS)' among the arguments given to the compiler. The variables used in implicit rules fall into two classes: those that are names of programs (like `CC') and those that contain arguments for the programs (like `CFLAGS'). (The "name of a program" may also contain some command arguments, but it must start with an actual executable program name.) If a variable value contains more than one argument, separate them with spaces. Here is a table of variables used as names of programs in built-in rules: `AR' Archive-maintaining program; default `ar'. `AS' Program for doing assembly; default `as'. `CC' Program for compiling C programs; default `cc'. `CXX' Program for compiling C++ programs; default `g++'. `CO' Program for extracting a file from RCS; default `co'. `CPP' Program for running the C preprocessor, with results to standard output; default `$(CC4~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-6;1d.H) -E'. `FC' Program for compiling or preprocessing Fortran and Ratfor programs; default `f77'. `GET' Program for extracting a file from SCCS; default `get'. `LEX' Program to use to turn Lex grammars into C programs or Ratfor programs; default `lex'. `PC' Program for compiling Pascal programs; default `pc'. `YACC' Program to use to turn Yacc grammars into C programs; default `yacc'. `YACCR' Program to use to turn Yacc grammars into Ratfor programs; default `yacc -r'. `MAKEINFO' Program to convert a Texinfo source file into an Info file; default `makeinfo'. `TEX' Program to make TeX DVI files from TeX source; default `tex'. `TEXI2DVI' Program to make TeX DVI files from Texinfo source; default `texi2dvi'. `WEAVE' Program to translate Web into TeX; default `weave'. `CWEAVE' Program to translate C Web into TeX; default `cweave'. `TANGLE' Program to translate Web into Pascal; default `tangle'. `CTANGLE' Program to translate C Web into C; default `ctangle'. `RM' Command to remove a file; default `rm -f'. Here is a table of variables whose values are additional arguments for the programs above. The default values for all of these is the empty string, unless otherwise noted. `ARFLAGS' Flags to give the archive-maintaining program; default `rv'. `ASFLAGS' Extra flags to give to the assembler (when explicitly invoked on a `.s' or `.S' file). `CFLAGS' Extra flags to give to the C compiler. `CXXFLAGS' Extra flags to give to the C++ compiler. `COFLAGS' Extra flags to give to the RCS `co' program. `CPPFLAGS' Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers). `FFLAGS' Extra flags to give to the Fortran compiler. `GFLAGS' Extra flags to give to the SCCS `get' program. `LDFLAGS' Extra flags to give to compilers when they are supposed to invoke the linker, `ld'. `LFLAGS' Extra flags to give to Lex. `PFLAGS' Extra flags to give to the Pascal compiler. `RFLAGS' Extra flags to give to the Fortran compiler for Ratfor programs. `YFLAGS' Extra flags to give to Yacc.  File: make.info, Node: Chained Rules, Next: Pattern Rules, Prev: Implicit Variables, Up: Implicit Rules Chains of Implicit Rules ======================== Sometimes a file can be made by a sequence of implicit rules. For example, a file `N.o' could be made from `N.y' by running first Yacc and then `cc'. Such a sequence is called a "chain". If the file `N.c' exists, or is mentioned in the makefile, no special searching is required: `make' finds that the object file can be made by C compilation from `N.c'; later on, when considering how to make `N.c', the rule for running Yacc is used. Ultimately both `N.c' and `N.o' are updated. However, even if `N.c' does not exist and is not mentioned, `make' knows how to envision it as the missing link between `N.o' and `N.y'! In this case, `N.c' is called an "intermediate file". Once `make' has decided to use the intermediate file, it is entered in the data base as if it had been mentioned in the makefile, along with the implicit rule that says how to create it. Intermediate files are remade using their rules just like all other files. But intermediate files are treated differently in two ways. The first difference is what happens if the intermediate file does not exist. If an ordinary file B does not exist, and `make' considers a target that depends on B, it invariably creates B and then updates the target from B. But if B is an intermediate file, then `make' can leave well enough alone. It won't bother updating B, or the ultimate target, unless some prerequisite of B is newer than that target or there is some other reason to update that target. The second difference is that if `make' *does* create B in order to update something else, it deletes B later on after it is no longer needed. Therefore, an intermediate file which did not exist before `make' also does not exist after `make'. `make' reports the deletion to you by printing a `rm -f' command showing which file it is deleting. Ordinarily, a file cannot be intermediate if it is mentioned in the makefile as a target or prerequisite. However, you can explicitly mark a file as intermediate by listing it as a prerequisite of the special target `.INTERMEDIATE'. This takes effect even if the file is mentioned explicitly in some other way. You can prevent automatic deletion of an intermediate file by marking it as a "secondary" file. To do this, list it as a prerequisite of the special target `.SECONDARY'. When a file is secondary, `make' will not create the file merely because it does not already exist, but `make' does not automatically delete the file. Marking a file as secondary also marks it as intermediate. You can list the target pattern of an implicit rule (such as `%.o') as a prerequisite of the special target `.PRECIOUS' to preserve intermediate files made by implicit rules whose target patterns match that file's name; see *Note Interrupts::. A chain can involve more than two implicit rules. For example, it is possible to make a file `foo' from `RCS/foo.y,v' by running RCS, Yacc and `cc'. Then both `foo.y' and `foo.c' are intermediate files that are deleted at the end. No single implicit rule can appear more than once in a chain. This means that `make' will not even consider such a ridiculous thing as making `foo' from `foo.o.o' by running the linker twice. This constraint has the added benefit of preventing any infinite loop in the search for an implicit rule chain. There are some special implicit rules to optimize certain cases that would otherwise be handled by rule chains. For example, making `foo' from `foo.c' could be handled by compiling and linking with separate chained rules, using `foo.o' as an intermediate file. But what actually happens is that a special rule for this case does the compilation and linking with a single `cc' command. The optimized rule is used in preference to the step-by-step chain because it comes earlier in the ordering of rules.  File: make.info, Node: Pattern Rules, Next: Last Resort, Prev: Chained Rules, Up: Implicit Rules Defining and Redefining Pattern Rules ===================================== You define an implicit rule by writing a "pattern rule". A pattern rule looks like an ordinary rule, except that its target contains the character `%' (exactly one of them). The target is considered a pattern for matching file names; the `%' can match any nonempty substring, while other characters match only themselves. The prerequisites likewise use `%' to show how their names relate to the target name. Thus, a pattern rule `%.o : %.c' says how to make any file `STEM.o' from another file `STEM.c'. Note that expansion using `%' in pattern rules occurs *after* any variable or function expansions, which take place when the makefile is read. *Note How to Use Variables: Using Variables, and *Note Functions for Transforming Text: Functions. * Menu: * Pattern Intro:: An introduction to pattern rules. * Pattern Examples:: Examples of pattern rules. * Automatic:: How to use automatic variables in the commands of implicit rules. * Pattern Match:: How patterns match. * Match-Anything Rules:: Precautions you should take prior to defining rules that can match any target file whatever. * Canceling Rules:: How to override or cancel built-in rules.  File: make.info, Node: Pattern Intro, Next: Pattern Examples, Up: Pattern Rules Introduction to Pattern Rules ----------------------------- A pattern rule contains the character `%' (exactly one of them) in the target; otherwise, it looks exactly like an ordinary rule. The target is a pattern for matching file names; the `%' matches any nonempty substring, while other characters match only themselves. For example, `%.c' as a pattern matches any file name that ends in `.c'. `s.%.c' as a pattern matches any file name that starts with `s.', ends in `.c' and is at least five characters long. (There must be at least one character to match the `%'.) The substring that the `%' matches is called the "stem". `%' in a prerequisite of a pattern rule stands for the same stem that was matched by the `%' in the target. In order for the pattern rule to apply, its target pattern must match the file name under consideration, and its prerequisite patterns must name files that exist or can be made. These files become prerequisites of the target. Thus, a rule of the form %.o : %.c ; COMMAND... specifies how to make a file `N.o', with another file `N.c' as its prerequisite, provided that `N.c' exists or can be made. There may also be prerequisites that do not use `%'; such a prerequisite attaches to every file made by this pattern rule. These unvarying prerequisites are useful occasionally. A pattern rule need not have any prerequisites that contain `%', or in fact any prerequisites at all. Such a rule is effectively a general wildcard. It provides a way to make any file that matches the target pattern. *Note Last Resort::. Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and commands. If a pattern rule has multiple targets, `make' knows that the rule's commands are responsible for making all of the targets. The commands are executed only once to make all the targets. When searching for a pattern rule to match a target, the target patterns of a rule other than the one that matches the target in need of a rule are incidental: `make' worries only about giving commands and prerequisites to the file presently in question. However, when this file's commands are run, the other targets are marked as having been updated themselves. The order in which pattern rules appear in the makefile is important since this is the order in which they are considered. Of equally applicable rules, only the first one found is used. The rules you write take precedence over those that are built in. Note however, that a rule whose prerequisites actually exist or are mentioned always takes priority over a rule with prerequisites that must be made by chaining other implicit rules.  File: make.info, Node: Pattern Examples, Next: Automatic, Prev: Pattern Intro, Up: Pattern Rules Pattern Rule Examples --------------------- Here are some examples of pattern rules actually predefined in `make'. First, the rule that compiles `.c' files into `.o' files: %.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ defines a rule that can make any file `X.o' from `X.c'. The command uses the automatic variables `$@' and `$<' to substitute the names of the target file and the source file in each case where the rule applies (*note Automatic Variables: Automatic.). Here is a second built-in rule: % :: RCS/%,v $(CO) $(COFLAGS) $< defines a rule that can make any file `X' whatsoever from a corresponding file `X,v' in the subdirectory `RCS'. Since the target is `%', this rule will apply to any file whatever, provided the appropriate prerequisite file exists. The double colon makes the rule "terminal", which means that its prerequisite may not be an intermediate file (*note Match-Anything Pattern Rules: Match-Anything Rules.). This pattern rule has two targets: %.tab.c %.tab.h: %.y bison -d $< This tells `make' that the command `bison -d X.y' will make both `X.tab.c' and `X.tab.h'. If the file `foo' depends on the files `parse.tab.o' and `scan.o' and the file `scan.o' depends on the file `parse.tab.h', when `parse.y' is changed, the command `bison -d parse.y' will be executed only once, and the prerequisites of both `parse.tab.o' and `scan.o' will be satisfied. (Presumably the file `parse.tab.o' will be recompiled from `parse.tab.c' and the file `scan.o' from `scan.c', while `foo' is linked from `parse.tab.o', `scan.o', and its other prerequisites, and it will execute happily ever after.)  File: make.info, Node: Automatic, Next: Pattern Match, Prev: Pattern Examples, Up: Pattern Rules Automatic Variables ------------------- Suppose you are writing a pattern rule to compile a `.c' file into a `.o' file: how do you write the `cc' command so that it operates on the right source file name? You cannot write the name in the command, because the name is different each time the implicit rule is applied. What you do is use a special feature of `make', the "automatic variables". These variables have values computed afresh for each rule that is executed, based on the target and prerequisites of the rule. In this example, you would use `$@' for the object file name and `$<' for the source file name. Here is a table of automatic variables: `$@' The file name of the target of the rule. If the target is an archive member, then `$@' is the name of the archive file. In a pattern rule that has multiple targets (*note Introduction to Pattern Rules: Pattern Intro.), `$@' is the name of whichever target caused the rule's commands to be run. `$%' The target member name, when the target is an archive member. *Note Archives::. For example, if the target is `foo.a(bar.o)' then `$%' is `bar.o' and `$@' is `foo.a'. `$%' is empty when the target is not an archive member. `$<' The name of the first prerequisite. If the target got its commands from an implicit rule, this will be the first prerequisite added by the implicit rule (*note Implicit Rules::.). `$?' The names of all the prerequisites that are newer than the target, with spaces between them. For prerequisites which are archive members, only the member named is used (*note Archives::.). `$^' The names of all the prerequisites, with spaces between them. For prerequisites which are archive members, only the member named is used (*note Archives::.). A target has only one prerequisite on each other file it depends on, no matter how many times each file is listed as a prerequisite. So if you list a prerequisite more than once for a target, the value of `$^' contains just one copy of the name. `$+' This is like `$^', but prerequisites listed more than once are duplicated in the order they were listed in the makefile. This is primarily useful for use in linking commands where it is meaningful to repeat library file names in a particular order. `$*' The stem with which an implicit rule matches (*note How Patterns Match: Pattern Match.). If the target is `dir/a.foo.b' and the target pattern is `a.%.b' then the stem is `dir/foo'. The stem is useful for constructing names of related files. In a static pattern rule, the stem is part of the file name that matched the `%' in the target pattern. In an explicit rule, there is no stem; so `$*' cannot be determined in that way. Instead, if the target name ends with a recognized suffix (*note Old-Fashioned Suffix Rules: Suffix Rules.), `$*' is set to the target name minus the suffix. For example, if the target name is `foo.c', then `$*' is set to `foo', since `.c' is a suffix. GNU `make' does this bizarre thing only for compatibility with other implementations of `make'. You should generally avoid using `$*' except in implicit rules or static pattern rules. If the target name in an explicit rule does not end with a recognized suffix, `$*' is set to the empty string for that rule. `$?' is useful even in explicit rules when you wish to operate on only the prerequisites that have changed. For example, suppose that an archive named `lib' is supposed to contain copies of several object files. This rule copies just the changed object files into the archive: lib: foo.o bar.o lose.o win.o ar r lib $? Of the variables listed above, four have values that are single file names, and three have values that are lists of file names. These seven have variants that get just the file's directory name or just the file name within the directory. The variant variables' names are formed by appending `D' or `F', respectively. These variants are semi-obsolete in GNU `make' since the functions `dir' and `notdir' can be used to get a similar effect (*note Functions for File Names: File Name Functions.). Note, however, that the `F' variants all omit the trailing slash which always appears in the output of the `dir' function. Here is a table of the variants: `$(@D)' The directory part of the file name of the target, with the trailing slash removed. If the value of `$@' is `dir/foo.o' then `$(@D)' is `dir'. This value is `.' if `$@' does not contain a slash. `$(@F)' The file-within-directory part of the file name of the target. If the value of `$@' is `dir/foo.o' then `$(@F)' is `foo.o'. `$(@F)' is equivalent to `$(notdir $@)'. `$(*D)' `$(*F)' The directory part and the file-within-directory part of the stem; `dir' and `foo' in this example. `$(%D)' `$(%F)' The directory part and the file-within-directory part of the target archive member name. This makes sense only for archive member targets of the form `ARCHIVE(MEMBER)' and is useful only when MEMBER may contain a directory name. (*Note Archive Members as Targets: Archive Members.) `$( foo.1 will fail when the build directory is not the source directory, because `foo.man' and `sedscript' are in the the source directory. When using GNU `make', relying on `VPATH' to find the source file will work in the case where there is a single dependency file, since the `make' automatic variable `$<' will represent the source file wherever it is. (Many versions of `make' set `$<' only in implicit rules.) A Makefile target like foo.o : bar.c $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o should instead be written as foo.o : bar.c ) $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@ in order to allow `VPATH' to work correctly. When the target has multiple dependencies, using an explicit `$(srcdir)' is the easiest way to make the rule work well. For example, the target above for `foo.1' is best written as: foo.1 : foo.man sedscript sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@ GNU distributions usually contain some files which are not source files--for example, Info files, and the output from Autoconf, Automake, Bison or Flex. Since these files normally appear in the source directory, they should always appear in the source directory, not in the build directory. So Makefile rules to update them should put the updated files in the source directory. However, if a file does not appear in the distribution, then the Makefile should not put it in the source directory, because building a program in ordinary circumstances should not modify the source directory in any way. Try to make the build and installation targets, at least (and all their subtargets) work correctly with a parallel `make'.  File: make.info, Node: Utilities in Makefiles, Next: Command Variables, Prev: Makefile Basics, Up: Makefile Conventions Utilities in Makefiles ====================== Write the Makefile commands (and any shell scripts, such as `configure') to run in `sh', not in `csh'. Don't use any special features of `ksh' or `bash'. The `configure' script and the Makefile rules for building and installation should not use any utilities directly except these: cat cmp cp diff echo egrep expr false grep install-info ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true The compression program `gzip' can be used in the `dist' rule. Stick to the generally supported options for these programs. For example, don't use `mkdir -p', convenient as it may be, because most systems don't support it. It is a good idea to avoid creating symbolic links in makefiles, since a few systems don't support them. The Makefile rules for building and installation can also use compilers and related programs, but should do so via `make' variables so that the user can substitute alternatives. Here are some of the programs we mean: ar bison cc flex install ld ldconfig lex make makeinfo ranlib texi2dvi yacc Use the following `make' variables to run those programs: $(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX) $(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC) When you use `ranlib' or `ldconfig', you should make sure nothing bad happens if the system does not have the program in question. Arrange to ignore an error from that command, and print a message before the command to tell the user that failure of this command does not mean a problem. (The Autoconf `AC_PROG_RANLIB' macro can help with this.) If you use symbolic links, you should implement a fallback for systems that don't have symbolic links. Additional utilities that can be used via Make variables are: chgrp chmod chown mknod It is ok to use other utilities in Makefile portions (or scripts) intended only for particular systems where you know those utilities exist.  File: make.info, Node: Command Variables, Next: Directory Variables, Prev: Utilities in Makefiles, Up: Makefile Conventions Variables for Specifying Commands ================================= Makefiles should provide variables for overriding certain commands, options, and so on. In particular, you should run most utility programs via variables. Thus, if you use Bison, have a variable named `BISON' whose default value is set with `BISON = bison', and refer to it with `$(BISON)' whenever you need to use Bison. File management utilities such as `ln', `rm', `mv', and so on, need not be referred to through variables in this way, since users don't need to replace them with other programs. Each program-name variable should come with an options variable that is used to supply options to the program. Append `FLAGS' to the p6~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-7;1`1program-name variable name to get the options variable name--for example, `BISONFLAGS'. (The names `CFLAGS' for the C compiler, `YFLAGS' for yacc, and `LFLAGS' for lex, are exceptions to this rule, but we keep them because they are standard.) Use `CPPFLAGS' in any compilation command that runs the preprocessor, and use `LDFLAGS' in any compilation command that does linking as well as in any direct use of `ld'. If there are C compiler options that *must* be used for proper compilation of certain files, do not include them in `CFLAGS'. Users expect to be able to specify `CFLAGS' freely themselves. Instead, arrange to pass the necessary options to the C compiler independently of `CFLAGS', by writing them explicitly in the compilation commands or by defining an implicit rule, like this: CFLAGS = -g ALL_CFLAGS = -I. $(CFLAGS) .c.o: $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< Do include the `-g' option in `CFLAGS', because that is not *required* for proper compilation. You can consider it a default that is only recommended. If the package is set up so that it is compiled with GCC by default, then you might as well include `-O' in the default value of `CFLAGS' as well. Put `CFLAGS' last in the compilation command, after other variables containing compiler options, so the user can use `CFLAGS' to override the others. `CFLAGS' should be used in every invocation of the C compiler, both those which do compilation and those which do linking. Every Makefile should define the variable `INSTALL', which is the basic command for installing a file into the system. Every Makefile should also define the variables `INSTALL_PROGRAM' and `INSTALL_DATA'. (The default for each of these should be `$(INSTALL)'.) Then it should use those variables as the commands for actual installation, for executables and nonexecutables respectively. Use these variables as follows: $(INSTALL_PROGRAM) foo $(bindir)/foo $(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a Optionally, you may prepen5d the value of `DESTDIR' to the target filename. Doing this allows the installer to create a snapshot of the installation to be copied onto the real target filesystem later. Do not set the value of `DESTDIR' in your Makefile, and do not include it in any installed files. With support for `DESTDIR', the above examples become: $(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo $(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a Always use a file name, not a directory name, as the second argument of the installation commands. Use a separate command for each file to be installed.  File: make.info, Node: Directory Variables, Next: Standard Targets, Prev: Command Variables, Up: Makefile Conventions Variables for Installation Directories ====================================== Installation directories should always be named by variables, so it is easy to install in a nonstandard place. The standard names for these variables are described below. They are based on a standard filesystem layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and other modern operating systems. These two variables set the root for the installation. All the other installation directories should be subdirectories of one of these two, and nothing should be directly installed into these two directories. `prefix' A prefix used in constructing the default values of the variables listed below. The default value of `prefix' should be `/usr/local'. When building the complete GNU system, the prefix will be empty and `/usr' will be a symbolic link to `/'. (If you are using Autoconf, write it as `@prefix@'.) Running `make install' with a different value of `prefix' from the one used to build the program should NOT recompile the program. `exec_prefix' A prefix used in constructing the default values of some of the variables listed below. The default value of `exec_prefix' should be `$(prefix)'. (If you are using Autoconf, write it as `@exec_prefix@'.) Generally, `$(exec_prefix)' is used for directories that contain machine-specific files (such as executables and subroutine libraries), while `$(prefix)' is used directly for other directories. Running `make install' with a different value of `exec_prefix' from the one used to build the program should NOT recompile the program. Executable programs are installed in one of the following directories. `bindir' The directory for installing executable programs that users can run. This should normally be `/usr/local/bin', but write it as `$(exec_prefix)/bin'. (If you are using Autoconf, write it as `@bindir@'.) `sbindir' The directory for installing executable programs that can be run from the shell, but are only generally useful to system administrators. This should normally be `/usr/local/sbin', but write it as `$(exec_prefix)/sbin'. (If you are using Autoconf, write it as `@sbindir@'.) `libexecdir' The directory for installing executable programs to be run by other programs rather than by users. This directory should normally be `/usr/local/libexec', but write it as `$(exec_prefix)/libexec'. (If you are using Autoconf, write it as `@libexecdir@'.) Data files used by the program during its execution are divided into categories in two ways. * Some files are normally modified by programs; others are never normally modified (though users may edit some of these). * Some files are architecture-independent and can be shared by all machines at a site; some are architecture-dependent and can be shared only by machines of the same kind and operating system; others may never be shared between two machines. This makes for six different possibilities. However, we want to discourage the use of architecture-dependent files, aside from object files and libraries. It is much cleaner to make other data files architecture-independent, and it is generally not hard. Therefore, here are the variables Makefiles should use to specify directories: `datadir' The directory for installing read-only architecture independent data files. This should normally be `/usr/local/share', but write it as `$(prefix)/share'. (If you are using Autoconf, write it as `@datadir@'.) As a special exception, see `$(infodir)' and `$(includedir)' below. `sysconfdir' The directory for installing read-only data files that pertain to a single machine-that is to say, files for configuring a host. Mailer and network configuration files, `/etc/passwd', and so forth belong here. All the files in this directory should be ordinary ASCII text files. This directory should normally be `/usr/local/etc', but write it as `$(prefix)/etc'. (If you are using Autoconf, write it as `@sysconfdir@'.) Do not install executables here in this directory (they probably belong in `$(libexecdir)' or `$(sbindir)'). Also do not install files that are modified in the normal course of their use (programs whose purpose is to change the configuration of the system excluded). Those probably belong in `$(localstatedir)'. `sharedstatedir' The directory for installing architecture-independent data files which the programs modify while they run. This should normally be `/usr/local/com', but write it as `$(prefix)/com'. (If you are using Autoconf, write it as `@sharedstatedir@'.) `localstatedir' The directory for installing data files which the programs modify while they run, and that pertain to one specific machine. Users should never need to modify files in this directory to configure the package's operation; put such configuration information in separate files that go in `$(datadir)' or `$(sysconfdir)'. `$(localstatedir)' should normally be `/usr/local/var', but write it as `$(prefix)/var'. (If you are using Autoconf, write it as `@localstatedir@'.) `libdir' The directory for object files andA libraries of object code. Do not install executables here, they probably ought to go in `$(libexecdir)' instead. The value of `libdir' should normally be `/usr/local/lib', but write it as `$(exec_prefix)/lib'. (If you are using Autoconf, write it as `@libdir@'.) `infodir' The directory for installing the Info files for this package. By default, it should be `/usr/local/info', but it should be written as `$(prefix)/info'. (If you are using Autoconf, write it as `@infodir@'.) `lispdir' The directory for installing any Emacs Lisp files in this package. By default, it should be `/usr/local/share/emacs/site-lisp', but it should be written as `$(prefix)/share/emacs/site-lisp'. If you are using Autoconf, write the default as `@lispdir@'. In order to make `@lispdir@' work, you need the following lines in your `configure.in' file: lispdir='${datadir}/emacs/site-lisp' AC_SUBST(lispdir) `includedir' The directory for installing header files to be included by user programs with the C `#include' preprocessor directive. This should normally be `/usr/local/include', but write it as `$(prefix)/include'. (If you are using Autoconf, write it as `@includedir@'.) Most compilers other than GCC do not look for header files in directory `/usr/local/include'. So installing the header files this way is only useful with GCC. Sometimes this is not a problem because some libraries are only really intended to work with GCC. But some libraries are intended to work with other compilers. They should install their header files in two places, one specified by `includedir' and one specified by `oldincludedir'. `oldincludedir' The directory for installing `#include' header files for use with compilers other than GCC. This should normally be `/usr/include'. (If you are using Autoconf, you can write it as `@oldincludedir@'.) The Makefile commands should check whetEher the value of `oldincludedir' is empty. If it is, they should not try to use it; they should cancel the second installation of the header files. A package should not replace an existing header in this directory unless the header came from the same package. Thus, if your Foo package provides a header file `foo.h', then it should install the header file in the `oldincludedir' directory if either (1) there is no `foo.h' there or (2) the `foo.h' that exists came from the Foo package. To tell whether `foo.h' came from the Foo package, put a magic string in the file--part of a comment--and `grep' for that string. Unix-style man pages are installed in one of the following: `mandir' The top-level directory for installing the man pages (if any) for this package. It will normally be `/usr/local/man', but you should write it as `$(prefix)/man'. (If you are using Autoconf, write it as `@mandir@'.) `man1dir' The directory for installing section 1 man pages. Write it as `$(mandir)/man1'. `man2dir' The directory for installing section 2 man pages. Write it as `$(mandir)/man2' `...' *Don't make the primary documentation for any GNU software be a man page. Write a manual in Texinfo instead. Man pages are just for the sake of people running GNU software on Unix, which is a secondary application only.* `manext' The file name extension for the installed man page. This should contain a period followed by the appropriate digit; it should normally be `.1'. `man1ext' The file name extension for installed section 1 man pages. `man2ext' The file name extension for installed section 2 man pages. `...' Use these names instead of `manext' if the package needs to install man pages in more than one section of the manual. And finally, you should set the following variable: `srcdir' The directory for the sources being compiled. The value of this variable is normIally inserted by the `configure' shell script. (If you are using Autconf, use `srcdir = @srcdir@'.) For example: # Common prefix for installation directories. # NOTE: This directory must exist when you start the install. prefix = /usr/local exec_prefix = $(prefix) # Where to put the executable for the command `gcc'. bindir = $(exec_prefix)/bin # Where to put the directories used by the compiler. libexecdir = $(exec_prefix)/libexec # Where to put the Info files. infodir = $(prefix)/info If your program installs a large number of files into one of the standard user-specified directories, it might be useful to group them into a subdirectory particular to that program. If you do this, you should write the `install' rule to create these subdirectories. Do not expect the user to include the subdirectory name in the value of any of the variables listed above. The idea of having a uniform set of variable names for installation directories is to enable the user to specify the exact same values for several different GNU packages. In order for this to be useful, all the packages must be designed so that they will work sensibly when the user does so.  File: make.info, Node: Standard Targets, Next: Install Command Categories, Prev: Directory Variables, Up: Makefile Conventions Standard Targets for Users ========================== All GNU programs should have the following targets in their Makefiles: `all' Compile the entire program. This should be the default target. This target need not rebuild any documentation files; Info files should normally be included in the distribution, and DVI files should be made only when explicitly asked for. By default, the Make rules should compile and link with `-g', so that executable programs have debugging symbols. Users who don't mind being helpless can strip the executables later if they wish. `install' Compile the program and copy the executables, libraries, and Mso on to the file names where they should reside for actual use. If there is a simple test to verify that a program is properly installed, this target should run that test. Do not strip executables when installing them. Devil-may-care users can use the `install-strip' target to do that. If possible, write the `install' target rule so that it does not modify anything in the directory where the program was built, provided `make all' has just been done. This is convenient for building the program under one user name and installing it under another. The commands should create all the directories in which files are to be installed, if they don't already exist. This includes the directories specified as the values of the variables `prefix' and `exec_prefix', as well as all subdirectories that are needed. One way to do this is by means of an `installdirs' target as described below. Use `-' before any command for installing a man page, so that `make' will ignore any errors. This is in case there are systems that don't have the Unix man page documentation system installed. The way to install Info files is to copy them into `$(infodir)' with `$(INSTALL_DATA)' (*note Command Variables::.), and then run the `install-info' program if it is present. `install-info' is a program that edits the Info `dir' file to add or update the menu entry for the given Info file; it is part of the Texinfo package. Here is a sample rule to install an Info file: $(DESTDIR)$(infodir)/foo.info: foo.info $(POST_INSTALL) # There may be a newer info file in . than in srcdir. -if test -f foo.info; then d=.; \ else d=$(srcdir); fi; \ $(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@; \ # Run install-info only if it exists. # Use `if' instead of just prepending `-' to the # line so we notice real errors fQrom install-info. # We use `$(SHELL) -c' because some shells do not # fail gracefully when there is an unknown command. if $(SHELL) -c 'install-info --version' \ >/dev/null 2>&1; then \ install-info --dir-file=$(DESTDIR)$(infodir)/dir \ $(DESTDIR)$(infodir)/foo.info; \ else true; fi When writing the `install' target, you must classify all the commands into three categories: normal ones, "pre-installation" commands and "post-installation" commands. *Note Install Command Categories::. `uninstall' Delete all the installed files--the copies that the `install' target creates. This rule should not modify the directories where compilation is done, only the directories where files are installed. The uninstallation commands are divided into three categories, just like the installation commands. *Note Install Command Categories::. `install-strip' Like `install', but strip the executable files while installing them. In many cases, the definition of this target can be very simple: install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ install Normally we do not recommend stripping an executable unless you are sure the program has no bugs. However, it can be reasonable to install a stripped executable for actual execution while saving the unstripped executable elsewhere in case there is a bug. `clean' Delete all files from the current directory that are normally created by building the program. Don't delete the files that record the configuration. Also preserve files that could be made by building, but normally aren't because the distribution comes with them. Delete `.dvi' files here if they are not part of the distribution. `distclean' Delete all files from the current directory that are created Uby configuring or building the program. If you have unpacked the source and built the program without creating any other files, `make distclean' should leave only the files that were in the distribution. `mostlyclean' Like `clean', but may refrain from deleting a few files that people normally don't want to recompile. For example, the `mostlyclean' target for GCC does not delete `libgcc.a', because recompiling it is rarely necessary and takes a lot of time. `maintainer-clean' Delete almost everything from the current directory that can be reconstructed with this Makefile. This typically includes everything deleted by `distclean', plus more: C source files produced by Bison, tags tables, Info files, and so on. The reason we say "almost everything" is that running the command `make maintainer-clean' should not delete `configure' even if `configure' can be remade using a rule in the Makefile. More generally, `make maintainer-clean' should not delete anything that needs to exist in order to run `configure' and then begin to build the program. This is the only exception; `maintainer-clean' should delete everything else that can be rebuilt. The `maintainer-clean' target is intended to be used by a maintainer of the package, not by ordinary users. You may need special tools to reconstruct some of the files that `make maintainer-clean' deletes. Since these files are normally included in the distribution, we don't take care to make them easy to reconstruct. If you find you need to unpack the full distribution again, don't blame us. To help make users aware of this, the commands for the special `maintainer-clean' target should start with these two: @echo 'This command is intended for maintainers to use; it' @echo 'deletes files that may need special tools to rebuild.' `TAGS' Update a tags table for this program. `info' Generate any Info filYes needed. The best way to write the rules is as follows: info: foo.info foo.info: foo.texi chap1.texi chap2.texi $(MAKEINFO) $(srcdir)/foo.texi You must define the variable `MAKEINFO' in the Makefile. It should run the `makeinfo' program, which is part of the Texinfo distribution. Normally a GNU distribution comes with Info files, and that means the Info files are present in the source directory. Therefore, the Make rule for an info file should update it in the source directory. When users build the package, ordinarily Make will not update the Info files because they will already be up to date. `dvi' Generate DVI files for all Texinfo documentation. For example: dvi: foo.dvi foo.dvi: foo.texi chap1.texi chap2.texi $(TEXI2DVI) $(srcdir)/foo.texi You must define the variable `TEXI2DVI' in the Makefile. It should run the program `texi2dvi', which is part of the Texinfo distribution.(1) Alternatively, write just the dependencies, and allow GNU `make' to provide the command. `dist' Create a distribution tar file for this program. The tar file should be set up so that the file names in the tar file start with a subdirectory name which is the name of the package it is a distribution for. This name can include the version number. For example, the distribution tar file of GCC version 1.40 unpacks into a subdirectory named `gcc-1.40'. The easiest way to do this is to create a subdirectory appropriately named, use `ln' or `cp' to install the proper files in it, and then `tar' that subdirectory. Compress the tar file file with `gzip'. For example, the actual distribution file for GCC version 1.40 is called `gcc-1.40.tar.gz'. The `dist' target should explicitly depend on all non-source files that are in the distribution, to make sure they are up to date in the distributi]on. *Note Making Releases: (standards)Releases. `check' Perform self-tests (if any). The user must build the program before running the tests, but need not install the program; you should write the self-tests so that they work when the program is built but not installed. The following targets are suggested as conventional names, for programs in which they are useful. `installcheck' Perform installation tests (if any). The user must build and install the program before running the tests. You should not assume that `$(bindir)' is in the search path. `installdirs' It's useful to add a target named `installdirs' to create the directories where files are installed, and their parent directories. There is a script called `mkinstalldirs' which is convenient for this; you can find it in the Texinfo package. You can use a rule like this: # Make sure all installation directories (e.g. $(bindir)) # actually exist by making them if necessary. installdirs: mkinstalldirs $(srcdir)/mkinstalldirs $(bindir) $(datadir) \ $(libdir) $(infodir) \ $(mandir) This rule should not modify the directories where compilation is done. It should do nothing but create installation directories. ---------- Footnotes ---------- (1) `texi2dvi' uses TeX to do the real work of formatting. TeX is not distributed with Texinfo. *[MAKE-3_78_1HB]MAKE.INFO-8;1+,c.@/@ 4@=-`0123KPWOA56$گ7Pm89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Install Command Categories, Prev: Standard Targets, Up: Makefile Conventions Install Command Categories ========================== When writing the `install' target, you must classify all the commands into three categories: normal ones, "pre-installation" commands and "post-installation" commands. Normal commands move files into their proper places, and set their modes. They may not alter any files except the ones that come entirely from the package they belong to. Pre-installation and post-installation commands may alter other files; in particular, they can edit global configuration files or data bases. Pre-installation commands are typically executed before the normal commands, and post-installation commands are typically run after the normal commands. The most common use for a post-installation command is to run `install-info'. This cannot be done with a normal command, since it alters a file (the Info directory) which does not come entirely and solely from the package being installed. It is a post-installation command because it needs to be done after the normal command which installs the package's Info files. Most programs don't need any pre-installation commands, but we have the feature just in case it is needed. To classify the commands in the `install' rule into these three categories, insert "category lines" among them. A category line specifies the category for the commands that follow. A category line consists of a tab and a reference to a special Make variable, plus an optional comment at the end. There are three variables you can use, one for each category; the variable name specifies the category. Category lines are no-ops in ordinary execution because these three Make variables are normally undefined (and you *should not* define them in the makefile). Here are the three possible category lines, each with a comment that explains what it means: $(PRE_INSTALL) # Pre-install commands follow. $(POST_INSTALL) # Post-install commands follow. $(NORMAL_INSTALL) # Normal commands follow. If you don't use a category line at the beginning of the `install' rule, all the commands are classified as normal until the first category line. If you don't use any category lines, all the commands are classified as normal. These are the category lines for `uninstall': $(PRE_UNINSTALL) # Pre-uninstall commands follow. $(POST_UNINSTALL) # Post-uninstall commands follow. $(NORMAL_UNINSTALL) # Normal commands follow. Typically, a pre-uninstall command would be used for deleting entries from the Info directory. If the `install' or `uninstall' target has any dependencies which a ct as subroutines of installation, then you should start *each* dependency's commands with a category line, and start the main target's commands with a category line also. This way, you can ensure that each command is placed in the right category regardless of which of the dependencies actually run. Pre-installation and post-installation commands should not run any programs except for these: [ basename bash cat chgrp chmod chown cmp cp dd diff echo egrep expand expr false fgrep find getopt grep gunzip gzip hostname install install-info kill ldconfig ln ls md5sum mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee test touch true uname xargs yes The reason for distinguishing the commands in this way is for the sake of making binary packages. Typically a binary package contains all the executables and other files that need to be installed, and has its own method of installing them--so it does not need to run the normal installation commands. But installing the binary package does need to execute the pre-installation and post-installation commands. Programs to build binary packages work by extracting the pre-installation and post-installation commands. Here is one way of extracting the pre-installation commands: make -n install -o all \ PRE_INSTALL=pre-install \ POST_INSTALL=post-install \ NORMAL_INSTALL=normal-install \ | gawk -f pre-install.awk where the file `pre-install.awk' could contain this: $0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ {on = 0} on {print $0} $0 ~ /^\t[ \t]*pre_install[ \t]*$/ {on = 1} The resulting file of pre-installation commands is executed as a shell script as part of installing the binary package.  File: make.info, Node: Quick Reference, Next: Make Errors, Prev: Makefile Conventions, Up: Top Quick Reference *************** This appendix summarizes the directives, text manipulation functions, and special variables which GNU `make' understands. *Note Special Targets::, *Note Catalogue of Implicit Rules: Catalogue of Rules, and *Note Summary of Options: Options Summary, for other summaries. Here is a summary of the directives GNU `make' recognizes: `define VARIABLE' `endef' Define a multi-line, recursively-expanded variable. *Note Sequences::. `ifdef VARIABLE' `ifndef VARIABLE' `ifeq (A,B)' `ifeq "A" "B"' `ifeq 'A' 'B'' `ifneq (A,B)' `ifneq "A" "B"' `ifneq 'A' 'B'' `else' `endif' Conditionally evaluate part of the makefile. *Note Conditionals::. `include FILE' `-include FILE' `sinclude FILE' Include another makefile. *Note Including Other Makefiles: Include. `override VARIABLE = VALUE' `override VARIABLE := VALUE' `override VARIABLE += VALUE' `override VARIABLE ?= VALUE' `override define VARIABLE' `endef' Define a variable, overriding any previous definition, even one from the command line. *Note The `override' Directive: Override Directive. `export' Tell `make' to export all variables to child processes 7 1xB ,z?UO&I^kR9 R00U}a&8ylVY\b cSD7.8u Uv%z-!K~SvHE]3L/ d@k yVS#a5)jvw*@Z{$? >27_ =j'ApW^f \^72>~o:}#M0D= "@<8|=jCh*jqrGi=J ;q|@@v{A*54W%#EiE@upt-^w(:3< 6~~O3>d4 >anluqpCdhtd,)duA Myrza]cS(P"m-If jFChTFP;K vT@Y7CNk  Ogx.5z=.IF-^-OC*6EQ yXMD Ac0%R~ +E=4c,VvyDWS!RCxQ{\f~`/LK,?uq|{'Bw_,&\I&sP%Mxm@b2U`&>W#c7,+h)Jmj2/= FzmiNA`S(Ff|knhx2?$MTIF!6CO&kgg;EL`T5`e|wJiS9$BR-UYZS S)G"c]B^yMOInQ6(ov+#h ?@_U'nfO")%bCfs5Ksh'f'nKxM#Nh=pqNZDA]XPq*xJB<\SCL3WbdxGx+EbU;}^Z5APn.McVb;TI DLP5|7IVH6l) !2|vRdP\ R#YM2sr Gt8|4/aC.>eL-T`OV?.L^hMU;1`-vHq o-QPHOLUV6QISR[m" >W:lV?|DMF)Tge _U L(#.z!"gHz&`8*~uZO9 V=CPAHODFI;\A xO<`JOi]${-&9/cs ken)nZF$/PsOq={*!F"RAt6uNk+s:$j~(WZ c4tu:dT*O+ P>N bRJyK5og90r),"=`Lgl.#`RGI$,uM,M[_|M]/- AW:*D QH#~#E!k 7=,'s>Q^ ))jI#;]fH< O~B7HLNMfoz`Iy?n$QmsM{GjJW|MNZJjhrZ;]U|h2l[4A Bk)xz% KJK^e=%yR'A0j;2^h63Dd3?}Gn,zc9nD c=51!ID=%j"#H^&Y|2twFE_qN1`GziefeH "TOkNm{}s95A[sD18XuC=^.l& iR0`]CJ L7+,MN PWbRb`q HETJ?YGN_Ih%mvvumy aBP^+mVK'I?3[p?FL|Gcl4mHYp83[i{~g)26'2&'""9j\`@1"b$88)&0]^gf7`hdH;A MF9h&]n)N!-{h!rnGuD1TdI'UC'=C SYn tHGd_4ubRTF0{fp 2>p_ZLOv;;HV z}>_:^B~9_T Aq* 8}-V "QH(y8.@[ NM-If!9!S'T4k*|;1(}Y7,Dn{4I@!) ,WL[`5OP{,qa<7FEw -.|i\o2iGIOYE^ie,Ds(7z:=q o(4YJk!A>)d16OxRC@v2 ws|@8c[W 7Rbw0[P6\E@ j|JE%Y" 6bng}y.HEK)KOX rV;aDFT?!&>Qe H8:rV,1{rf|bI|aIs&":N=d!f%jYCccPZRqJZ*CHS=7hJg}/l`c Obb !c]?YJ}7?S||^yVG{^b7&MzT-y2SUs.=cbE\R$ 0ufq>I^@]3?!kZE"WMQR>K I/MS}"VTKz [.ESXY(FG^XJ;8$f&mRV1]JS]'sz$&T rb6a0yN2SyQnvnsAV6U`zb|A WYk$ \U07l)LFH ^1R"^OO O6g47X\%Z \L3Cw; f!>k\3NGTZ=9~#l# ykM] j^DbZjbIF]y7bN;{{ k>=GL\u.G,J617}"e 9=^ !pFc]!(T7 RNMfNRe@NB^ThIVHQ2k7M FL~ :[5LB!c0ER>* +2A8G<3S+R|/YYqG^_[>K.j%\mA4;K#ZKX9`ul :Jbsj da@W.^V'yn2H>c3%O~]/RTKv _I$z 5!FB  BKlO+_SI3UDZ;XU_Y!\F>mcbjDj>6P C[ KdJN\oxU&XqSXO/%kQSjXN]nYX:JE>R&/UJ8v.99wRv>"oxQBzJ_]FWMMk ),wuv|Fi3GIVjDod)i=}tY Mkgp^8-fEu (~a2(B "Z2G':?frV @p8/0CT"S}njIMB e_|A5G-h?V}%CHH=y!ElLKA@Sb nA4V[q/x] ?]U MWI~PZ~DPsP s*O 86Gv?cK,t0bNE|<=y.,w8s}4FN[8OE(4AGqa^|#AVwVF,hA@^LF_R{[>(J& :{2nP(_q RuF T"oPUi]5<{iy\^O\Vw(Z)W`CN-h?]p# ;R! }yv3Z#X7A=%$aLKZ! rNIRKU|2Jp 582[!bz' ?HFLGSO X/?0~FK WN ?W\A]C3N^C UR::EI*R\L#*Z~dY O2n=X$h1Y.I0ND76 ZY/iA I P sHNFCCZk=\RGm[]m]JU@'}-M  DJ~{=qt@ [j69} d3AF;iZb)y`r @Tvti,AR[@C$XP0N }BjA_wYFB 3UpM8@$L7LRo Q% Gi 4'jm@DnCRY*x`*j)zw79C$TF._">Ht`W='II[L N-jF/B^&PnZIimG@NXZ&S{CVQ2smi%$w]xf3-DW4: DI%;e/(@nR4PBN8@_NI\CM6LREJuZC~|}ILb~M r&yL' _ZlV-k/(~6 @~N_@ 5jD_(_]V&G6|rK A ;45Bdp^Y p1W\TAI49>nNbJ<^m|2v)SjZW5hL\T%01X_%Bk Mk @d &piULYjHl:>}`ooOZ dDRE9K^*-E/}n4];$X?ZY`a `FpC^%pd})Vqr?BN=P=!hiGcN1>qr[.;6q3p EWOB#pPEJ)E$Ca,e-OwCG_8!V:9NJ WT]FTJ>h-TKQID\_I]K_>G$b!C. g#smi 4[SVI@ L7"])^=@$T^X=W3dozB+k^6W%}P$E\,64%wZFFNEUQRPL@A^M R4E@^Uy+G'np6gIrn]Z? kQfOv \.PX,Z5%-8OCO$`BEQQ\z=R0vT)0 C#`@{RKTQm"buMSmJL1ML'8;/ ze@H:2^V%k/fF5N hqZ (GaJRBRXPsaWNo4lbkV8zxu YU,H$NX@B6\\>!f<M@>=!uUnFR_]RV'x\_vv0 X12 U-~5m$.F wWWJU)H:]gy^ t Fe? tkE{"l%[L\77u P n Q,c9m32Gva"!Jl|js{_]q|O]}5`;p/-; dVE_Foh\WZI %MosR HUgW",[C/+JHKZ*o?_UL' ZKw/C1t\G)U!jCxMN[ EVW G1*wPBSSvD JX_@Tb 3IU&kw=I9JHUA;S2cm}:'WP9DX:%Z>k}|6I8} u Rl[tr 3']Ib=L oRiZ V`nNwilc_B'N1Qx-[/&%7CvU';]L Q[FW]4-NtSF@KIX ABR["cqs/.@duT]YE \'<`X30xV B@F MY%UK3aazC0U RU`]A]ln|"U`d9<M5{@RZ[ZtGjVyY/bY](D[D)< aRqn;$DwP>?ABE_J[O-AFi*ONfS.3G9OePR^Mz0FzacQNU`^R,DQxEYHCrR&vwE\J l*b_ztxr&W/[dw0[35EQ>7F]OH7aAMcUE B-_P:eA0&n6SpkNXuV^KMV<&.DFRNHHYUICsG P`)Iw)Zif{Q l *dIGkRb~x] 4 __nk 5V2e3Es)KKw >U @{ r:rUc4kVVV^cH {PP2"%A Wa%[dn*5=J<gHjTHKTZ"PA$`{<9XR t(Au/3Sa/~6' c *#X-v9Z[`aToFALZIXi@yMrDDWfoIV.IO_6 iH,Gz LhLN^t(p,} SQHQ%Ya';CSW+-GKfS'ld_UY5q!ns ?AKqS3|+@T#vQ `iK2&'CBp$tA0O=R9ryiw+qje]Wqx~$BIN8 @L$E$ VXV'b}SZ`nw{4ux t0#r(n%Lg?oC(2;?3c,@Pquz6hd"eGtr%36/.`{>?js?"kw<}y{& HJ <{/0Z7,0LV|(,vc%\\RW'-U7cg% }XVF7 f<5+!*+3)zjEp;qOSD=h&o>Hx>^#.z|?wbz3$x\5)/t&q'694{r} y23axW}YB$j6pV5r-8FFd:v-lFe D_I=R$xa^ h*5}y.\_'D! d$D ] xTF>&]H"oe,H5-/wkMK=n5:(yeq^ll1J;Y@\{d(b4'D {f}emMJ m6{C`35 s_W:nL2+"d<45a>5Yv'Q2F# nO NXO[CANi#z)" A@ZYMuSD#j=w C[[63V2dTs0-7bGN$CE[}3 *{YZl;3=2<-Bi*^Ef85:X0D j!0BIZhd~5C`He44X74 "9#L `WLfmMS%Y:Z ]bR\H11>LD@{(= {ZB- N]mNVI$/O7CY+pRTH3B|2 .B%]^UK5VruYX%}%CuEA4^ Fd Z6nLWGhogGJ P|3.U"C"4^tl[UPQOOAnFm+Cz,S=K#du G=/WAC4-=?h$)Pr^M_O]R,#{:G5'|ELDxl3K3}h0CJQ-U,kU Q5Wc9{gsBKZY |Ya$w/*D^HN|B\TXQRv7;Z_rb|<1WR^83bOD1(K \:AM] g G{8?2QAr<# ]JT O}GHPjn>hR -eKWHPGFk U"\!sk2 %^QMf_zFpP@cXL XI*p&D][;@7J+[i.d'i}DI*@L@KH YGqV-DGSPB9ae@M7[LNwfXWtl|Tg7Hc+ Mu,3GrR N~ %-:5'-%*-6yJ.!JV&YnqAAE swyT;,,!%X UGxH=}jPB%[xe9.gy\6e,>\H+,\ H3D9K<*0K@x+9!6u W[6a=is"$K"H'VQGHc}s9qYG(E[-T ,xLBfOB dSDH "*;pDC*} :)$XNErOL6 cDKB& Y&F/6XZH^c[ U\r( ZCMYWTo7Yb 8c&ip$mp pe2i<[YSPO_IOUgd2Pr +*NC?s`SN ,J\4KR 7^S<`-~i@WUFc2[N UU$O SA_:i*|@\~/H8(G3DecEA"h_ye`s4 -n@N-O#c+K}CS7 >A;CUjr}E\E,&TP=,$~$1P~.:@OL3zTMD,=^NVA lMMhZU!}" #P^@mMP01kIbMb6pqVQ7L;e jm&-)vJPp\-el8crb  Mn`$m}o{R$1PSXu%bYNA,z4N,(5xry OZ@ ^yYLPKY 6q] 30 ` BAE5V,D1YrRdcUFN;XV]|Dee\0JXTQR<Y^^uToT*evr)}^9RI GEY|UY>jo' 'A B 2-@J1k t|sS.( _* BAguC\#N5qu:{ fdscO-uN<`p`YF^#2 O`Y[nS]aIgxJ](UMRm%ARzMj^g@T%Nm\,CU*{z Qt[BTW-T+ !z-wn*oVEZL)[=P OK{=zM/J}A^NWUFOW%~-.FlQTTVXeSB pL A-JhTZzX? ~;C?1o$w4+*L~)KjmF_ yuqKJTO__o=Nx]1 fL4,%V>B*%_t2/^)kS[0v0 >VQK%({ ywpr6n WbEd`BnBXSJ:me O^IJsPuk>o357EQEZC Ly!>-KW %3 X RIJNY@Nku^ @U 6V<{?Mu""e~m Zy Uhi5%BIy'I!(^4_Zdoz_Iq =SeF?wt.7 fMT)L 2SJNsFD^ }IF =Z# =yEJ||FU;W=[SJWo~Y52^2}b/5(]\u\D{O>MOI@B& QVWR>\P$RWB T5o> YA1z\iH8pc=#+*| GUg[HJ aKT2]TOP*ZRAi Ty'- *>[<"r:v.&) XJ?Z06A5fe[>?C%7+2Bs'{RT}t.v:~,v7^N)| -HjZjOzW={{a a@[i*{(L6TItZ`|5Igu{/GTekumi|m UqW$pd4z8ID@t`Pe*D0YK %Tr^WUJ< u5RFf'_4UPL7BBU`zn@G_yE) dM Y4QvO4'W !NXVk>>~ De%Z\NN Qa[~lOSK86p+U}uv "mGkf PK\9<(Zg4}P^YO^IQ&FY\H[k( 2PwO_EcFLUX}KO ta}EjO6M.!Y R7JtO(VwA[fKh{L14.BdqNEj| Y}]]O^ZCSWL\zFYEQ}X<.YGLY _ &i fH(@|FZ O:wf XbmHZTJg&A}WkGW_ZSSx|_N)*0uR B D>hdJTQhPO2Y))Q 2naLASN7NK^dVvRPd$ o3]c${ecTS8yj=onTtYT^e \TF_6yABL_kV_G'WXq4"/5/>r^*J P Dj!H^xB4Bc]gk]Y0P(UWS &A ])yEXIiYH\!pL~):K^m{IaJKHYPS>k)?&`_WB1!'KS^o1bpQ8YFa\b7r\C)AQA6OTG"YR@pQrNHM4 Jv<2@@FJ/|1L@Mz KdQ\C}9MTk?3%ACH7F;;~V$|!lL@ LLwN6eDv[+#PFX89svGEA)YrI]E. )MAfdK CVU'C'R 9!CWR T58>2-@J E?>8N{/MOJ#no|=a9hu(v:6yOOEg`)r+7up jXpdL7EtjH{K^.57-RJB[ HnP@L7S&u1(LV& ZE6Z.)\ JP 6 )Z->"Svrh[GIg J~\2\sr ADF A ECR1 =D[E$%_Gg Yo,<HBQ[CDV+ ^F= |(qfD[PIJ8)MyfzE=(-[n?o|> 126&>KY  [D ~:r\N)nQ8fJ8/\8]HE\xGFYXY \N VP \-)UQ.2fOAqE6dVdM, W \ESkS *]O=|sZU_DM0`Dask"|][W|h{8lNAYjb n74 Ct*K@*?X^YGRH8WYN p7!G<Rp7@e:t=,jO$2M D6OiW51e 4b|f85~1j<_EY3Gj4lo@I  3]Jx%i<".jkTsxI# 6q=Ko8 U [[AZSRR/= *g5p^_coJr[AGx\}(@^HPJQ6.g2QhS2Isdfci 0<3a+L&5(`3ZllNeM*T -\{SSZZ0AMEn{FCMF&DbU<.YO.YV(\(<4l )pyyM)?MJJ{M^O*^\")k  {ad $PM$hGRQ eRB$4{JVzDdRl\  T8OQd$m>Z{+s_q4YL9/wDHK3/(= E+DeD,x \[XZ}5^`=LA}_F+dUM 0B Jydc :r*Q_LByL{ldu"* f J`P=SOgh-KadSlm:eAk"fL \7\2M^N>'GjAA6L$FNOhK_:X[BBVZ  ^vi|lmW~U_QOi >O5CQ=YCuA6$a S1vXX,W UUH|CRREAn<N P?\Mu\ZAZ6,2 \L$O+*FtGu@"" i} RaOVW}We~@nx9[ YL^Kx !X Rs O}~i1.>]]uD*NLpo?{'XZOEOF. O%PFDCB9|`Z(d g zfw3y3 x7AF?PA10f<`h< SDy~4tA&2v6R>`C N0sk~$ll,Z!;2 =D!|m* &>?K36@dR3`+xxW KM$;TLhTDIT ;BPOI GKK PN"=Wf$cK Y 9MAgCp%4ITXf% WZU"Kktps*D@}E_*PV^rqh'IR u% qHD 3S yFqq\OuM geGYw >L)Az O*H iR %u~Wd~4y'jhoUn TD/OZLS+&k=g_'^r!S|`epi'n-~ji: %}kTU]pU A/jLm;XHF !VYo$;^Oj-`[<`msc]"%Z^LVx!Z? +?i??`k[/ H^7yyg9FLG@wh{| e&-p#c16\ $qEn'Y.Ifg2H.Y8; t9iY2ZR1$Dk{u8VC^ GhtI}":00 EV,D{ }$f=R5uj//iXN1L ZVD[X%61q3iLF<[a@NU voxt0VdM" D]LYZl5g_,$eTO2`a:!~]ZU [[8Stm NCUw9mRCH1H7nTZlwka1HFI|wplp}qX! *9A4 pA *q~ysNL +P % 'FR\a7ynq&I\Z<I' cz*4 lmRLG_tw N@Z3WfDBnT X%^ vo KN B WR6*o]M8QCYa L1R !P'0<+ ;H"\qM{qBi;"@U ]WRI` Nb%@yKA_]::yR h+h"q\"gsr IA9KfInOBDZFoDc)`9OFwc]06"oCqKN@CtI5B7X6a)}7r~[i$ cmMc|cx`=33J`h+ {C7(0Be$`` ,D[O WO [ij/uin:"<~m*0DRv;54X Z+Hx|,Rz-3(9rlV: R)L:U"|F ~I\ [(9gm,.x4B\%fd:0+j*wh0<\ J K;\i hjdn?&T-/O !/~S q703cIlqC JoE*xUdEf; CC.j @7NU9qd*$hVl91}pd1hI8>$g1z<wYTLG \P *i;xv[pa)e1ih|D^b|]iV5UI/c$"G]YICAx=Q__KKo+HXM Xt>c"L`N5gmL&5@XVMeZs =zKB3i(IUb)B].Q>2mJ_B\4]|{Mn~ZR[DsSct>iq+ \g`lB>M>[. NJbF|^Z  n@C Vy([a@I!>cbewdOP *Nw?2SYvo2ZYng` O0g C^\X K>uP\\_WL_QK7fQ5 > b#R[E*n^dj4'xr;v.qAP OUC*3P^^~D"W[ET  SR B@%]tHnM<y-<( v oY@Nxqi2="NKFPUR|R YYh NNB8Swg~mAN5}0Y-?+1{ . atp _oADE v^UMp[OD[?*(M+"| op]AG^/rAP*ocS&AYM4=+pK Kd_T dUO}\ WM@XQ;&u AP,].A}xr>j*v w=ZHWDWDOl9a!~_4jk N}E0 [^ZjTG.!*Sj| lPVT=Zk\ bOnA|+hs~a{3%w,}/{N aG9`{Z:IYCq]E Q 5:A]J5QP0].6A\_E% m(@~ol G7LfQS#f#Q"CG,K]d8H[{R2 tO Q =^UXMu.g-Rj_a, WS_\Ir=N{A6K#2XTW8 Zs =O% YVxNEO7 } SWdZCk h1R +>t5bW3)jX,HAGJG4z,ZFd} ^Pj_jf9zN,YoB_aY@TeME^'PCeZ RY @O]|>YRQP[dB[TOW^h SHC/xNb, 9n$|wi8Db 7F3 ]sTm]VVBsFD8ZmE LC~}T# D n,473ia8c<'N=1/iTQX9{B2/O /2W'0 R _T#1' l=8[Um |ee9#9]J_ hl&O:f"@ocXf`V,NIOcUEx\N$tYRP%&QIXP3*=%?[E+QK(DdCmO9p!4baEH173-76gn):h%HUJ`)Ki\ w|9 oX d^JZt9~rmgMIGnjX i 4l? UNH|dT8.2@0R(!9D>9ZVChYZLZTZNH5A,v+VTG_`BY Z*uk< ] VGqRUCt-#3\ Vuw.xYE. KD/s>W3>~WDRJNQ)]j!-nIMB<2+a5so: (I2f='&IWH$U9p8an<7*tAwd wsJSW__@d+ XrASW\;Ku Tu*1+zv*L^Zx77,/=&g06M|O\^.4,02Xzb'qKg(Vdd/*]!2wu4WV[9y1/ @\6}ew`7z0ME_J'^z\8T@CPD).71 cHq^:<+rQONO|  CiDaUiXwRrm'+rlqLhX~0%5!j}" EXe91n; eAM$-"=v/ U|/i6^^;C8xn?g?rsszE!%/9V U= ^n'Pc>6b`\2VF O9 I }IJL9uaVZFro<5Xs ,rJPf Q?ON\-73z:Qg" "] |FPLAvR?v,E J{6!1:lmoZJk&n;W9UUP5WrE +T1?|G&;d]":Zv71Yd_B dxY/U8f@i`gA~ Y nnz30N YZI3a;sfl963_0A9i^yF(<ChXKRK@9  $E R\SK0LYHWpVYEt- cORpvke?& `1BL]MqY3C5RF{ g2#6#uYfrm fMF.h[VAvYnm_elN,xoxjt !;iXVxXkIgel&7I5QYu"D^ 4ZLGC\:31'~9~ MWo:GT \PV% dPvY~4r#~oWiw@ObaA\_S}EE)ET`v$PC-}2n!rrw-,Z cE V7!hAb! i=-$v|[1_s:(1k"W|7@s]qjqRPC |! YCde \ g!8Qz1$2OzqrInb CN?,x1_9kfF'~SX>LnL//CT&va PL( | d3:Pm"M D{6P n7Ai7DD9$2 {SXS#[qgQGQ]^I\07YKAL  Y`n EIVBVWB*3LF26oY;[OZ@XEKh;zy>$Ci :}PX{"B pi JA []$t#gR*mVq}9"|u%@[nNAEIS S W. E]ZR ^W7I={DB ]b&vSzYds.A8j%x52C!@{(+nq5 ,gL)Ju|IZY$s'kh=T.k,-_{y_@6bG$E+1CS_8h7 XM?l"zf=p)g|ygoO5&RO 9}_'Q  : ON!DT\cL#SU! '-/~zOF$! aa+8NMPw 9}/nNPSY~\a'Mg tQK3[9rIYqFs0F=yOWk%WNSSY{VBlJ"YNA%6x3sjSMM<|I p- rJS HHW_,pZtR J>P G^Oc@F&G'OPZcTIf|6STeB^|,c,1TkLiL,bG[Q`V1V]X@tC ]D23~4G)7 ]R0+dLH~J: dPw/dV[8Mz93R#uvVI JzAJ?z^J *MB;K>8jFiwyKDsnUT9}Vt mERTmk yo },jq7`gh'M6G `AdB?:=/* nq)[T9{>EXOj[kRUNL GAFlyOfHAybaY+\K =Ht`9[pg5[G\*r:cB "B=y`Cf WCQRXKvT$>[PEqnjK3,P{(/6x\_%O&+&?O$W&8VPKl3r?9_g_Rdf?a`x3-+%cVwMzvN8&UB]GGK o|+SUmup=pVM["UR DUKk(u!0"%8nL'5cnIHzWV\bPT[b^@j AVI zCebMKY( oRVE7LD/WSL] _>T0N_"YSU*"T WII#9ek kqytrps@,6 <_#X\vS O*bQ&`EQ4HG{t'${MlWW'3R.II< [[_'ONHA 8Mw?QELqEOII NAtg h5{btpWrs/$m2KJ OK\iAK2y]H^[xNp6SGLwXVV].Y\Xf]^ 8xaGBq8MNZ-HrU2] g =Dk;)_ApID`\k *FTtL =dp9zo)d7> D<, )LR /3k uFL,Z= K+|%DQY`iAf;FGma3_D/C;J xPUVDXF[Z6I#~cn3f]m Q0.NVxZdh]uo zI9\gYBBRH ^S ^ ]B) 0ozE2+A`Q~X T#ln fw4M[0jFjf:hS:1XL/huytJ /p=i54g^Fmei>YP DAKf[[IZ|_-DLv"0+EmV(} c,ti}D ^#b$>f$np`JBw7(rV3uq80v&.5{aR?P3cI]) TF0F9"}l%ie!vn1B rS L8-s}@3&)o'Mx(I8w{*zoL~x-6a2pj#@&ZjE!%Ru U8req);wtz( %j -F9*f u'Vbo^Qh 4._@8`CKA1gZQ\@AW[FFX_[)!ENaUgDRzOVM2SU'AY/Buen3iwWemi=)/5y3w ny_"lXr9%Q0,?o-e*Tu*1@` F+AC>`.S G2Zz LOcf^\eRCmcN_>J '[ 8BOu>3d{QPe>N]L`Pm|D{.llf:Ee "@ VBS VYL:Zv= gSTLW* T8)[g 3l?)vav634ytah{y RG" FmE W9H] QHo8^C@W  !/j5}=qYQ2 D;yNM:ZG>PJ+JY[Lf%h.CRYM1[3DbhcTh, ;>A[aRV0@MZTCxDZ_Q]j /?My@P* e ^? +:}SAl0VHUU8jaZ+Q58Pv6 }_ 9@"WVE^tVCVVf ^ xM,8V.V/|=_]+$-aKAG.0"\D@U  U5P_PM-[UQS[O~<*4EI!oFq"eq>@]xbFV\$ ]GM.<+} TI%9HEO^ R|*\fADY }~],@}]Ak[Ic[=;b|vO*tyd;0:4rCKS sne APBK.5do?@kDY!C2GH+G/wLp: M7^wJ_E*L#t[G@T_jqw#i!C0+L=DMG4 UU.(1%SO]y+t)7EM"Sd U\ ^Y  S)&9;i#q pCsYLs_5$Y@`JUM!%>^6N`iE)$w PH ,;.'VQ)6EvjV0mN[^c`P/d`^8IBAwe}Q~f:u| @oR?Ui|mTmNR.Y^3> {N>G T:)6sX_eb BIIEK{_~B=DU.d^NeFJ\_] K L0}a_qO Z9co!vOxfP :xNXCL5>~#  7~+ i6d 6KLIm"j=&IBZ{C~D);L+|j|$']BL505|5c-DZ^P[p JN"EI-[kV6F =E*?]w2YY#[;!r $lno8-,mW2{IpNHi?,yRMV7c#%^iZ6AJpD[. xYT = UVgg[LSp6XVMIBUMt^j^3$Q+p;aVj)SFl\J? yGA}?l^OZGC` A1% i_C+]S,?+B&J|!(n+p Jh?+562,-8Txhi\F"&9#[P:&RF\3@ UGZN5 9Ts $\Y\%^H*DaRMOMpR!(Vb uZBk }%>j@\|-@<[L+-j_K6=T$+N@>bKFCZ>q(3'$(uXDN]FKU u[I]5 D.kOUjXM[?% NWjGwr v^ET Y;QkXKGFV PwHN_>_K~~:;o@\6MA1YS@ b8M[M*vH+()Z$)Uy{#xIA1+VbB#[jxdd:2K>GL{[zf,G CR^ M, pciV-+Je?,l&<MN 8*d% L'6E {9>y1ZY9=}PM KAEuLrZ(+ QsY"J'ZNR ;iG_JBufHOka\\C:^Q[Bf^S.*u!1W g|?O{MDJ&Jr~\]<8M^Y&%QD;~cud!HQ^PcR[ DN`^?L@C| hgJ\DDF ]KTTs|.\YrCn\zo7${XR_}u 1+/B(RE~^I[Hc[$F&w/]+NSQ U65y0;aAdeNYJ3^#Bu6tbJ17UICk^^yz;TM*,S d2]H)[sD9K  dtl'(P1etPnRC}q & SwNnJE` ^NM$i^H_H o^u|tafw'?Z'mA)r8 fFm0-. %>SZ 5KN[L/WfUS:M^2+"Emm[H|OMJy{ewIux@ $vFF,UIkIVxM]G{uV-A\h$P[]b>TCRqeYYJCEQ`JA*WU"aXZ_`bD+!]C $BL[szYvx7j-H <9.BT( G#/ hPR^` ~luFJn;Zv\Wq%4,DLS 7^M.zw2-C 9V8BB&F fI*B(JKSQM=Z6gAOQZ3~PuM[0cP \>ur8w>}Ao`j\Od/2,RlJBO]X}?3cP#a1:m5Wg-T_{N&TM[qvZF8d>fU AOCCyLNKX&J^SQ0C1MXP`B 0dC^=Sx 8sjDDu!dV/r{EI[,c3$z5rQ`g{u,D"gIC~Xf0JE8NBUXYjGi &FmSg #q;cR[Km=1A;s / 8sCad0 (7!T AU_E]r6ZZki[@iPyPiVF_d)uo=#;VO^Mu]@)%Xd]N]Ne/UBE!R',s% bRp5 Y'Yhdl py;#}wOfTIrd;}bN%uJ2].jrBflI$`a!dR\YS3Iqjk:^SL rDP 5p*_e!z.^A v-@HVYUR0M^P*Q IIN=]QU.ebdUiUwUG(KO Y BP[u<[NeGXXJn)F Q N:_S:AO:D (Q/W<\W_ZY@o K2bXDVsQo@MOgj8rkE76ARI2BJ]J'F:p>? WUS_{!LYC8F!TE;iIy ]USL2HTO=]X%EF'pV6:EN4m~nD+X'E+Ps*58Z/GX5dG )`'?2CTUbu~UEG:|Q!C uS,PalvXm k:wMBpEy?`oulr~H*/TgHA[d lmrrX`jaLBj,[|J?h5mt | 49KfZ%ff:HC'?7*Sb3m U :YWAkN#KU.qF%!8ekvF {Gu_GPP LHa7GFq@ K73bOJG#i~( gZV_ OK6fn(\C8tJ5!s7=vD5N\~G,Z l0poq1;@^39[Y}#1_JT-o7nr;HE}DqeI [z:M "RJ97PK>/'{6HN(P5C`Cgqm;l?6yJ LU&nXN*'c;"YWuVG&.# m(XF#L|i9n,P+CMpnW>[^NWQH()(+U6My3NTAmW6Ed{O_;tzUIWSv5b [{8RJ+I@Oss|[WatX ]z~DES~,1=2>vk'9DgM9\Ls}hAHOT/ue_DDEWAA rSMAC >$? .37W5M~!<-BA=Q=4w?mdevItQk_ c|Zjy[8}@4; xzNhhlf !}Pvulm,vFZ%z>+}[Wv)fa.4TH.,>J2$+nk q4E2nw6}t~,i'{ cc_|t:l=p3n3j &hf)#Tc,]0UMj8pulm-6b+{tR+e5&l;pSu. HB:k{u 110-o<(?,$'NFA_:3 pL[`:MA^{ #R*P{%T3;^ =;I6J{*VXVr ]^)B~.spTD?MO OIHn4+O~ ZN0ue!@/"zI/e ]# FqFz]E'OO:FI{kk[U1s^zTM 7o #RR k|:NSxR3OL4^ YS$?9rp>}tif,]-s WbTRyTidtdr c;6er}%m^@iF'y \< WWbcD JoXp[')T8['Bi74u!%kt)]M7 !2KI_HE*\mLGnW0DxZyO4TNTqkO{GZMBK ByOABGO<)BFNPR!jK] 8diJI)1FMM\9'nUzAuFRM'V.pOE\'ySDE5L>$QN/Z _Q^"{[AI GXRh_H iJtN% D_s;l an>Z(JPM' @x?>a{\ t865Lzkd$W}^Dc9k[}@2Z0 0tsmE lSp;9q NSG{]\vCGU)o24>HSY )lPKkI]r8?Avm? ZKvd. vO l!T3?moD 5Q4pT;(=-B$%{moZpgR qi$s:U/7UfsBN jQ;-[ ESGU_XI=PJ@kmckS[Y &k^ WOK_v2Dr! ^Z%+_HV:F$9[\A;SY]~EGUol6P2ELCKQ#V K^} [) J#:!nII^ `ni @ ?0!8l}xEb ]cM)TvR.u Uq- ?aNi%;6IRn+ j.tqY}6SB deEu;?([8 I, m,V#H.PS[jY^^CkG\ )#M;D$oc` xh7oV fe {{)(ONDV +0( |F\C xf%o@]NZ2 |[~ 3+{&)?Hot Oiu[E**QOo:?a@fh sEl8$ycV5?7zg& I}=OQ*6>"YjGR;IBH3V8BJgZ!c*8!z)H>} r i  yE\dP~v!Qwgr%wwk/j`(wG2aM*JNrL1p>*J+/={$!YG_\UsdUgv`>u}Q_axQI-u:_Gp4~ gC4 LDC2@IQ@FS'XNyq3 pd\1kH]FnYcWldu -PPSJmL]B\gKJp= Kf.=O)' 3H"uHKiF?%|`+r#}9V W6WJQ+y#uk%`?)lX: j+)IK`+g^?JA|W:p>jsYFA6zhskWP>Ad`dLH>TUz\2p7N^KFIG>(@^BVL 6[LM5)~ISW\VC c}3 +\zD= K1N(DIdF _/h= v'(;rHB,}0vQk; ";MB] )` jmsS9 lK>xCHJ\W %eUA awOR3>s!{ZlBXs1oDtD(C_xho '*N*%l/ECjyh3m&`B"8_^^^}; f&T[?$' NAOcL*TXdC Lyjk3!i;m.~^Uab0Vfz.P?u.Bt)iy~VjhtEhdbKYS@ngT\typgVMM(IaBfA_haOwl$Eb!Ne5UZ9q) &ac|5Vu99z> FJYp(t_(yryfKse0qv(q%@o6CT.59J?{#HVN+]G_HJ~^y I}#R mf8@9TJJ%(vtx7AO]A{Y-BAa@gY-Nz$_B76c3A0dX:WTGK.3b$Dn3W_7rOopFY0;]}[_}9rF EP&t2@CJPGk!Rg.Vi_RL_:HtsJ?!D[tJ0ZH^E];rU_? RC^l(#fEw]wm@oy&4ExRi!=L+q" eHt_U 4OM| )ZVQ&A*_[Zw{5|7[';iS[GE@pG^2 o9OA x/ ouPMWGEM9-6rj;n+v88P&?MW_Y J: !9hQ?cwSI :lvwe4V!Y$ {JEu3rS>dxum>my;/1@t"N7xr/9 ("~nBw E$iIYA!e~:buQ`;wqg.e3ja}6#86f!t6z.t1#3\Y(%~N{~MW,.cmAiJed, $az:x-{GUQWL49OY3(`rFDZ`.>:,dT1(Ipo!weiq#YB_fjknRYRb7Vot{ny~!942/0*'lk)wsF~ct/8}rCn-3LJu VAwo(\=ii\ ~qy"aE!&r: HIdBR9#{~R^B)|PjK)5qo2)05r/o$($2y.zxj;Q<|@!s K`4)Zak{h] FL.:?N Hk}$Vi1o. N0%Yx>sR?lKW -7*>TK]WIJiy,d0 @>6a#KyP!/#pXr224j%+v=J!ie^^@<4[S/fmup~++ r@erF,teb'Vmydv )SNI.z)!+(Z346//w~o6)m7tZgkf4o 6(33gbxc|.2{$+ea)td~?C4Wj igF.cG];n#P}"N+N~Yi-aR iScGA^PNq6}{3_bp~6w#Tx=PNC_VF|T0 IZ_&vb0#x4g>`/D@Z&A H=LJ_U>PxlS^@@WU j#oec0mjiY$^Zhe\_4@u"{ nQs@&H.[YzA2U]L=o)}Hhyk\dsya>cC|qbcn'NYLzR)CKXvEQJ D*wc}n7"cE?#%Y )?;hu9=gIjDz@21?/9I_1BV>]:(TvO N4GVO\^AK  q'QU8]M6[^_P_&f7G{ m1EZaVr@-!UkCm!S MGD@U\NL]i3K5?O_~CW KRYCjL&GErP0,EZ LTO/5~d HnXI#.<-QUN2\'JP/6[hpNLn.*d{I^XRPgp/5U)U0YR(J, 3-X-yUs X{LV`S ^O7B5,D^+ SK }Z5bD &XPSO#n\eUSL!2'eg.3]I]_E-u, _YC |"&p5j3 N2)w}.W@ FM! j([3etRv:YVF @],Is|o.1c*0iyiKIq~qR*aGS R{?WICnb$P 'SQ5XDM G<OGSh^MB @e _-{R5PJ\$iG4DCVz #L#&q|+347HIq8WglcZa'O5F[zIy$?1(Kaf$!r#HJ5H]D;JG$^?QhGy6rkgPqy}DY`M'KQ#VR M%F5hmDIodSC\_W3gzf]C9O sf@ ~ WJCFf/i n} 9M0G|)i8JE[k6eY'mO( +_#fu4 TM,mo 1BI D H}DCJ @Rjd-3920s[6Ot!OjpoMbUg!zl; &kG`k(-x DE%'/@:Q\',*K~AG TbISM6T^!Ee CGQ2B00Co\ TMK@K#BOnxk@F %~uVPGA)9F"Jy;iK[W?y]K-R2tSHtC#k^yOOK=`Muw3 *{YmJHKh(1H.RXG1{@0;Ml^x=13fH^?>, HFM.w!Ur*D7N7EZQ^@4OAN;;b:8AF~5Z;_")r}o,"Fx1jMvebM#tf\\kYf>A --@[ou86(yUh|Y~u&PGU 9C.n{O `H.P xttOvOWUbq1 ,)z6rm3O5|$`HB7 3r& p*oQ2 $, \)u$PBOw_B sJAmEbj~+Sy#f D:a(!8wgU+HQ4GJH2\wmR;HH? :3^_}  UyMPu7 S/-,M  C|M2|)Brxjm *g.adU# 3G]Of_/S{lgk+eksuo; tar-`sed -e '/version_string/!d' \ -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ -e q version.c`.shar.Z dist: $(SRCS) $(AUX) echo tar-`sed \ -e '/version_string/!d' \ -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ -e q version.c` > .fname -rm -rf `cat .fname` mkdir `cat .fname` = ln $(SRCS) $(AUX) `cat .fname` tar chZf `cat .fname`.tar.Z `cat .fname` -rm -rf `cat .fname` .fname tar.zoo: $(SRCS) $(AUX) -rm -rf tmp.dir -mkdir tmp.dir -rm tar.zoo for X in $(SRCS) $(AUX) ; do \ echo $$X ; \ sed 's/$$/^M/' $$X \ > tmp.dir/$$X ; done cd tmp.dir ; zoo aM ../tar.zoo * -rm -rf tmp.dir *[MAKE-3_78_1HB]MAKE.INFO-9;1+,c.X/@ 4XX-`0123KPWOY56m9 73sϵm89G@HJThis is Info file make.info, produced by Makeinfo version 1.67 from the input file make.texinfo. INFO-DIR-SECTION GNU Packages START-INFO-DIR-ENTRY * Make: (make). Remake files automatically. END-INFO-DIR-ENTRY This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition 0.54, last updated 09 September 1999, of `The GNU Make Manual', for `make', Version 3.78.1. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: make.info, Node: Concept Index, Next: Name Index, Prev: Complex Makefile, Up: Top Index of Concepts ***************** * Menu: * # (comments), in commands: Commands. * # (comments), in makefile: Makefile Contents. * #include: Automatic Prerequisites. * $, in function call: Syntax of Functions. * $, in rules: Rule Syntax. * $, in variable name: Computed Names. * $, in variable reference: Reference. * %, in pattern rules: Pattern Intro. * %, quoting in patsubst: Text Functions. * %, quoting in static pattern: Static Usage. * %, quoting in vpath: Selective Search. * %, quoting with \ (backslash) <1>: Selective Search. * %, quoting with \ (backslash) <2>: Text Functions. * %, quoting with \ (backslash): Static Usage. * * (wildcard character): Wildcards. * +, and define: Sequences. * +=: Appending. * +=, expansion: Reading Makefiles. * ,v (RCS file extension): Catalogue of Rules. * - (in commands): Errors. * -, and define: Sequences. * --assume-new <1>: Instead of Execution. * --assume-new: Options Summary. * --assume-new, and recursion: Options/Recursion. * --assume-old <1>: Avoiding Compilation. * --assume-old: Options Summary. * --assume-old, and recursion: Options/Recursion. * --debug: Options Summary. * --directory <1>: Recursion. * --directory: Options Summary. * --directory, and --print-directory: -w Option. * --directory, and recursion: Options/Recursion. * --dry-run <1>: Options Summary. * --dry-run <2>: Instead of Execution. * --dry-run: Echoing. * --environment-overrides: Options Summary. * --file <1>: Makefile Names. * --file <2>: Options Summary. * --file: Makefile Arguments. * --file, and recursion: Options/Recursion. * --help: Options Summary. * --ignore-errors <1>: Errors. * --ignore-errors: Options Summary. * --include-dir <1>: Include. * --include-dir: Options Summary. * --jobs <1>: Options Summary. * --jobs: Parallel. * --jobs, and recursion: Options/Recursion. * --just-print <1>: Echoing. * --just-print <2>: Instead of Execution. * --just-print: Options Summary. * --keep-going <1>: Errors. * --keep-going <2>: Testing. * --keep-going: Options Summary. * --load-average <1>: Parallel. * --load-average: Options Summary. * --makefile <1>: Options Summary. * --makefile <2>: Makefile Arguments. * --makefile: Makefile Names. * --max-load <1>: Options Summary. * --max-load: Parallel. * --new-file <1>: Instead of Execution. * --new-file: Options Summary. * --new-file, and recursion: Options/Recursion. * --no-builtin-rules: Options Summary. * --no-builtin-variables: Options Summary. * --no-keep-going: Options Summary. * --no-print-directory <1>: Options Summary. * --no-print-directory: -w Option. * --old-file <1>: Avoiding Compilation. * --old-file: Options Summary. * --old-file, and recursion: Options/Recursion. * --print-data-base: Options Summary. * --print-directory: Options Summary. * --print-directory, and --directory: -w Option. * --print-directory, and recursion: -w Option. * --print-directory, disabling: -w Option. * --question <1>: Options Summary. * --question: Instead of Execution. * --quiet <1>: Options Summary. * --quiet: Echoing. * --recon <1>: Options Summary. * --recon <2>: Instead of Execution. * --recon: Echoing. * --silent <1>: Echoing. * --silent: Options Summary. * --stop: Options Summary. * --touch <1>: Instead of Execution. * --touch: Options Summary. * --touch, and recursion: MAKE Variable. * --version: Options Summary. * --warn-undefined-variables: Options Summary. * --what-if <1>: Options Summary. * --what-if: Instead of Execution. * -b: Options Summary. * -C <1>: Recursion. * -C: Options Summary. * -C, and -w: -w Option. * -C, and recursion: Options/Recursion. * -d: Options Summary. * -e: 9~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-9;1X& Options Summary. * -e (shell flag): Automatic Prerequisites. * -f <1>: Makefile Arguments. * -f <2>: Options Summary. * -f: Makefile Names. * -f, and recursion: Options/Recursion. * -h: Options Summary. * -i: Options Summary. * -I: Include. * -i: Errors. * -I: Options Summary. * -j <1>: Options Summary. * -j: Parallel. * -j, and archive update: Archive Pitfalls. * -j, and recursion: Options/Recursion. * -k <1>: Testing. * -k <2>: Errors. * -k: Options Summary. * -l: Options Summary. * -l (library search): Libraries/Search. * -l (load average): Parallel. * -m: Options Summary. * -M (to compiler): Automatic Prerequisites. * -MM (to GNU compiler): Automatic Prerequisites. * -n <1>: Echoing. * -n <2>: Instead of Execution. * -n: Options Summary. * -o <1>: Options Summary. * -o: Avoiding Compilation. * -o, and recursion: Options/Recursion. * -p: Options Summary. * -q <1>: Options Summary. * -q: Instead of Execution. * -R: Options Summary. * -r: Options Summary. * -s: Options Summary. * -S: Options Summary. * -s: Echoing. * -t <1>: Instead of Execution. * -t: Options Summary. * -t, and recursion: MAKE Variable. * -v: Options Summary. * -W <1>: Instead of Execution. * -W: Options Summary. * -w: Options Summary. * -w, and -C: -w Option. * -W, and recursion: Options/Recursion. * -w, and recursion: -w Option. * -w, disabling: -w Option. * .a (archives): Archive Suffix Rules. * .C: Catalogue of Rules. * .c: Catalogue of Rules. * .cc: Catalogue of Rules. * .ch: Catalogue of Rules. * .d: Automatic Prerequisites. * .def: Catalogue of Rules. * .dvi: Catalogue of Rules. * .f: Catalogue of Rules. * .F: Catalogue of Rules. * .info: Catalogue of Rules. * .l: Catalogue of Rules. * .LIBPATTERNS, and link libraries: Libraries/Search. * .ln: Catalogue of Rules. * .mod: Catalogue of Rules. * .o: Catalogue of Rules. * .p: Catalogue of Rules. * .PRECIOUS intermediate files: Chained Rules. * .r: Catalogue of Rules. * .S: Catalogue of Rules. * .s: Catalogue of Rules. * .sh: Catalogue of Rules. * .sym: Catalogue of Rules. * .tex: Catalogue of Rules. * .texi: Catalogue of Rules. * .texinfo: Catalogue of Rules. * .txinfo: Catalogue of Rules. * .w: Catalogue of Rules. * .web: Catalogue of Rules. * .y: Catalogue of Rules. * :: rules (double-colon): Double-Colon. * := <1>: Flavors. * :=: Setting. * = <1>: Setting. * =: Flavors. * =, expansion: Reading Makefiles. * ? (wildcard character): Wildcards. * ?= <1>: Flavors. * ?=: Setting. * ?=, expansion: Reading Makefiles. * @ (in commands): Echoing. * @, and define: Sequences. * [...] (wildcard characters): Wildcards. * \ (backslash), for continuation lines: Simple Makefile. * \ (backslash), in commands: Execution. * \ (backslash), to quote % <1>: Static Usage. * \ (backslash), to quote % <2>: Text Functions. * \ (backslash), to quote %: Selective Search. * __.SYMDEF: Archive Symbols. * algorithm for directory search: Search Algorithm. * all (standard target): Goals. * appending to variables: Appending. * ar: Implicit Variables. * archive: Archives. * archive member targets: Archive Members. * archive symbol directory updating: Archive Symbols. * archive, and -j: Archive Pitfalls. * archive, and parallel execution: Archive Pitfalls. * archive, suffix rule for: Archive Suffix Rules. * Arg list too long: Options/Recursion. * arguments of functions: Syntax of Functions. * as <1>: Catalogue of Rules. * as: Implicit Variables. * assembly, rule to compile: Catalogue of Rules. * automatic generation of prerequisites <1>: Automatic Prerequisites. * automatic generation of prerequisites: Include. * automatic variables: Automatic. * backquotes: Shell Function. * backslash (\), for continuation lines: Simple Makefile. * backslash (\), in commands: Execution. * backslash (\), to quote % <1>: Static Usage. * backslash (\), to quote % <2>: Text Functions. * backslash (\), to quote %: Selective Search. * backslashes in pathnames and wildcard expansion: Wildcard Pitfall. * basename: File Name Functions. * binary packages: Install Command Categories. * broken pipe: Parallel. * bugs, reporting: Bugs. * built-in special targets: Special Targets. * C++, rule to compile: Catalogue of Rules. * C, rule to compile: Catalogue of Rules. * cc <1>: Catalogue of Rules. * cc: Implicit Variables. * cd (shell command) <1>: MAKE Variable. * cd (shell command): Execution. * chains of rules: Chained Rules. * check (standard target): Goals. * clean (standard target): Goals. * clean target <1>: Simple Makefile. * clean target: Cleanup. * cleaning up: Cleanup. * clobber (standard target): Goals. * co <1>: Catalogue of Rules. * co: Implicit Variables. * combining rules by prerequisite: Combine By Prerequisite. * command line variable definitions, and recursion: Options/Recursion. * command line variables: Overriding. * commands: Rule Syntax. * commands, backslash (\) in: Execution. * commands, comments in: Commands. * commands, echoing: Echoing. * commands, empty: Empty Commands. * commands, errors in: Errors. * commands, execution: Execution. * commands, execution in parallel: Parallel. * commands, expansion: Shell Function. * commands, how to write: Commands. * commands, instead of executing: Instead of Execution. * commands, introduction to: Rule Introduction. * commands, quoting newlines in: Execution. * commands, sequences of: Sequences. * comments, in commands: Commands. * comments, in makefile:! Makefile Contents. * compatibility: Features. * compatibility in exporting: Variables/Recursion. * compilation, testing: Testing. * computed variable name: Computed Names. * conditional expansion: If Function. * conditional variable assignment: Flavors. * conditionals: Conditionals. * continuation lines: Simple Makefile. * controlling make: Make Control Functions. * conventions for makefiles: Makefile Conventions. * ctangle <1>: Implicit Variables. * ctangle: Catalogue of Rules. * cweave <1>: Implicit Variables. * cweave: Catalogue of Rules. * deducing commands (implicit rules): make Deduces. * default directries for included makefiles: Include. * default goal <1>: How Make Works. * default goal: Rules. * default makefile name: Makefile Names. * default rules, last-resort: Last Resort. * define, expansion: Reading Makefiles. * defining variables verbatim: Defining. * deletion of target files <1>: Interrupts. * deletion of target files: Errors. * directive: Makefile Contents. * directories, printing them: -w Option. * directories, updating archive symbol: Archive Symbols. * directory part: File Name Functions. * directory search (VPATH): Directory Search. * directory search (VPATH), and implicit rules: Implicit/Search. * directory search (VPATH), and link libraries: Libraries/Search. * directory search (VPATH), and shell commands: Commands/Search. * directory search algorithm: Search Algorithm. * directory search, traditional: Search Algorithm. * dist (standard target): Goals. * distclean (%(standard target): Goals. * dollar sign ($), in function call: Syntax of Functions. * dollar sign ($), in rules: Rule Syntax. * dollar sign ($), in variable name: Computed Names. * dollar sign ($), in variable reference: Reference. * double-colon rules: Double-Colon. * duplicate words, removing: Text Functions. * E2BIG: Options/Recursion. * echoing of commands: Echoing. * editor: Introduction. * Emacs (M-x compile): Errors. * empty commands: Empty Commands. * empty targets: Empty Targets. * environment: Environment. * environment, and recursion: Variables/Recursion. * environment, SHELL in: Execution. * error, stopping on: Make Control Functions. * errors (in commands): Errors. * errors with wildcards: Wildcard Pitfall. * execution, in parallel: Parallel. * execution, instead of: Instead of Execution. * execution, of commands: Execution. * exit status (errors): Errors. * explicit rule, definition of: Makefile Contents. * explicit rule, expansion: Reading Makefiles. * exporting variables: Variables/Recursion. * f77 <1>: Implicit Variables. * f77: Catalogue of Rules. * features of GNU make: Features. * features, missing: Missing. * file name functions: File Name Functions. * file name of makefile: Makefile Names. * file name of makefile, how to specify: Makefile Names. * file name prefix, adding: File Name Functions. * file name suffix: File Name Functions. * file name suffix, adding: File Name Functions. * file name with wildcards: Wildcards. * file name, basename of: File Name Functions. * file name, directory part: File Name Functions. * file name, nondirectory part: File Name Functions. * files, assuming new: Instead of Execution. * files, assuming old: Avoiding Compilation. * files, avoiding recompilation of: Avoiding Compilation. * files, intermediate: Chained Rules. * filtering out words: Text Functions. * filtering words: Text Functions. * finding strings: Text Functions. * flags: Options Summary. * flags for compilers: Implicit Variables. * flavors of variables: Flavors. * FORCE: Force Targets. * force targets: Force Targets. * Fortran, rule to compile: Catalogue of Rules. * functions: Functions. * functions, for controlling make: Make Control Functions. * functions, for file names: File Name Functions. * functions, for text: Text Functions. * functions, syntax of: Syntax of Functions. * functions, user defined: Call Function. * g++ <1>: Catalogue of Rules. * g++: Implicit Variables. * gcc: Catalogue of Rules. * generating prerequisites automatically <1>: Automatic Prerequisites. * generating prerequisites automatically: Include. * get <1>: Implicit Variables. * get: Catalogue of Rules. * globbing (wildcards): Wildcards. * goal: How Make Works. * goal, default <1>: How Make Works. * goal, default: Rules. * goal, how to specify: Goals. * home directory: Wildcards. * IEEE Standard 1003.2: Overview. * ifdef, expansion: Reading Makefiles. * ifeq, expansion: Reading Makefiles. * ifndef, expansion: Reading Makefiles. * ifneq, expansion: Reading Makefiles. * implicit rule: Implicit Rules. * implicit rule, and directory search: Implicit/Search. * implicit rule, and VPATH: Implicit/Search. * implicit rule, definition of: Makefile Contents. * implicit rule, expansion: Reading Makefiles. * implicit rule, how to use: Using Implicit. * implicit rule, introduction to: make Deduces. * implicit rule, predefined: Catalogue of Rules. * implicit rule, search algorithm: Implicit Rule Search. * included makefiles, default directries: Include. * including (MAKEFILES variable): MAKEFILES Variable. * including other makefiles: Include. * incompatibilities: Missing. * Info, rule to format: Catalogue of Rules. * install (standard target): Goals. * intermediate files: Chained Rules. * intermediate files, preserving: Chained Rules. * intermediate targets, explicit: Special Targets. * interrupt: Interrupts. * job slots: Parallel. * job slots, and recursion: Options/Recursion. * jobs, limiting based on load: Parallel. * joining lists of words: File Name Functions. * killing (interruption): Interrupts. * last-resort default rules: Last Resort. * ld: Catalogue of Rules. * lex <1>: Implicit Variables. * lex: Catalogue of Rules. * Lex, rule to run: Catalogue of Rules. * libraries for linking, directory search: Libraries/Search. * library archive, suffix rule for: Archive Suffix Rules. * limiting jobs based on load: Parallel. * link libraries, and directory search: Libraries/Search. * link libraries, patterns matching: Libraries/Search. * linking, predefined rule for: Catalogue of Rules. * lint: Catalogue of Rules. * lint, rule to run: Catalogue of Rules. * list of all prerequisites: Automatic. * list of changed prerequisites: Automatic. * load average: Parallel. * loops in variable expansion: Flavors. * lpr (shell command) <1>: Empty Targets. * lpr (shell command): Wildcard Examples. * m2c: Catalogue of Rules. * macro: Using Variables. * make depend: Automatic Prerequisites. * MAKECMDGOALS: Goals. * makefile: Introduction. * makefile name: Makefile Names. * makefile name, how to specify: Makefile Names. * makefile rule parts: Rule Introduction. * makefile, and MAKEFILES variable: MAKEFILES Variable. * makefile, conventions for: Makefile Conventions. * makefile, how make processes: How Make Works. * makefile, how to write: Makefiles. * makefile, including: Include. * makefile, overriding: Overriding Makefiles. * makefile, parsing: Reading Makefiles. * makefile, remaking of: Remaking Makefiles. * makefile, simple: Simple Makefile. * makeinfo <1>: Implicit Variables. * makeinfo: Catalogue of Rules. * match-anything rule: Match-Anything Rules. * match-anything rule, used to override: Overriding Makefiles. * missing features: Missing. * mistakes with wildcards: Wildcard Pitfall. * modified variable reference: Substitution Refs. * Modula-2, rule to compile: Catalogue of Rules. * mostlyclean (standard target): Goals. * multiple rules for one target: Multiple Rules. * multiple rules for one target (::): Double-Colon. * multiple targets: Multiple Targets. * multiple targets, in pattern rule: Pattern Intro. * name of makefile: Makefile Names. * name of makefile, how to specify: Makefile Names. * nested variable reference: Computed Names. * newline, quoting, in commands: Execution. * newline, quoting, in makefile: Simple Makefile. * nondirectory part: File Name Functions. * OBJ: Variables Simplify. * obj: Variables Simplify. * OBJECTS: Variables Simplify. * objects: Variables Simplify. * objs: Variables Simplify. * OBJS: Variables Simplify. * old-fashioned suffix rules: Suffix Rules. * options: Options Summary. * options, and recursion: Options/Recursion. * options, setting from environment: Options/Recursion. * options, setting in makefiles: Options/Recursion. * order of pattern rules: Pattern Intro. * origin of variable: Origin Function. * overriding makefiles: Overriding Makefiles. * overriding variables with arguments: Overriding. * overriding with override: Override Directive. * parallel execution: Parallel. * parallel execution, and archive update: Archive Pitfalls. * parts of makefile rule: Rule Introduction. * Pascal, rule to compile: Catalogue of Rules. * pattern rule: Pattern Intro. * pattern rule, expansion: Reading Makefiles. * patter9n rules, order of: Pattern Intro. * pattern rules, static (not implicit): Static Pattern. * pattern rules, static, syntax of: Static Usage. * pattern-specific variables: Pattern-specific. * pc <1>: Implicit Variables. * pc: Catalogue of Rules. * phony targets: Phony Targets. * pitfalls of wildcards: Wildcard Pitfall. * portability: Features. * POSIX: Overview. * POSIX.2: Options/Recursion. * post-installation commands: Install Command Categories. * pre-installation commands: Install Command Categories. * precious targets: Special Targets. * prefix, adding: File Name Functions. * prerequisite: Rules. * prerequisite pattern, implicit: Pattern Intro. * prerequisite pattern, static (not implicit): Static Usage. * prerequisite, expansion: Reading Makefiles. * prerequisites: Rule Syntax. * prerequisites, automatic generation <1>: Include. * prerequisites, automatic generation: Automatic Prerequisites. * prerequisites, introduction to: Rule Introduction. * prerequisites, list of all: Automatic. * prerequisites, list of changed: Automatic. * prerequisites, varying (static pattern): Static Pattern. * preserving intermediate files: Chained Rules. * preserving with .PRECIOUS <1>: Special Targets. * preserving with .PRECIOUS: Chained Rules. * preserving with .SECONDARY: Special Targets. * print (standard target): Goals. * print target <1>: Wildcard Examples. * print target: Empty Targets. * printing directories: -w Option. * printing of commands: Echoing. * printing user warnings: Make Control Func=tions. * problems and bugs, reporting: Bugs. * problems with wildcards: Wildcard Pitfall. * processing a makefile: How Make Works. * question mode: Instead of Execution. * quoting %, in patsubst: Text Functions. * quoting %, in static pattern: Static Usage. * quoting %, in vpath: Selective Search. * quoting newline, in commands: Execution. * quoting newline, in makefile: Simple Makefile. * Ratfor, rule to compile: Catalogue of Rules. * RCS, rule to extract from: Catalogue of Rules. * reading makefiles: Reading Makefiles. * README: Makefile Names. * realclean (standard target): Goals. * recompilation: Introduction. * recompilation, avoiding: Avoiding Compilation. * recording events with empty targets: Empty Targets. * recursion: Recursion. * recursion, and -C: Options/Recursion. * recursion, and -f: Options/Recursion. * recursion, and -j: Options/Recursion. * recursion, and -o: Options/Recursion. * recursion, and -t: MAKE Variable. * recursion, and -w: -w Option. * recursion, and -W: Options/Recursion. * recursion, and command line variable definitions: Options/Recursion. * recursion, and environment: Variables/Recursion. * recursion, and MAKE variable: MAKE Variable. * recursion, and MAKEFILES variable: MAKEFILES Variable. * recursion, and options: Options/Recursion. * recursion, and printing directories: -w Option. * recursion, and variables: Variables/Recursion. * recursion, level of: Variables/Recursion. * recursive variable expansion <1>: Flavors. * recursive variable expansion: Using Variables. * recursively expanAded variables: Flavors. * reference to variables <1>: Reference. * reference to variables: Advanced. * relinking: How Make Works. * remaking makefiles: Remaking Makefiles. * removal of target files <1>: Errors. * removal of target files: Interrupts. * removing duplicate words: Text Functions. * removing targets on failure: Special Targets. * removing, to clean up: Cleanup. * reporting bugs: Bugs. * rm: Implicit Variables. * rm (shell command) <1>: Errors. * rm (shell command) <2>: Wildcard Examples. * rm (shell command) <3>: Simple Makefile. * rm (shell command): Phony Targets. * rule commands: Commands. * rule prerequisites: Rule Syntax. * rule syntax: Rule Syntax. * rule targets: Rule Syntax. * rule, and $: Rule Syntax. * rule, double-colon (::): Double-Colon. * rule, explicit, definition of: Makefile Contents. * rule, how to write: Rules. * rule, implicit: Implicit Rules. * rule, implicit, and directory search: Implicit/Search. * rule, implicit, and VPATH: Implicit/Search. * rule, implicit, chains of: Chained Rules. * rule, implicit, definition of: Makefile Contents. * rule, implicit, how to use: Using Implicit. * rule, implicit, introduction to: make Deduces. * rule, implicit, predefined: Catalogue of Rules. * rule, introduction to: Rule Introduction. * rule, multiple for one target: Multiple Rules. * rule, no commands or prerequisites: Force Targets. * rule, pattern: Pattern Intro. * rule, static pattern: Static Pattern. * rule, static pattern versus implicit: Static versus Implicit. * rule, with multiple targets: Multiple Targets. * s. (SCCS file prefix): Catalogue of Rules. * SCCS, rule to extract from: Catalogue of Rules. * search algorithm, implicit rule: Implicit Rule Search. * search path for prerequisites (VPATH): Directory Search. * search path for prerequisites (VPATH), and implicit rules: Implicit/Search. * search path for prerequisites (VPATH), and link libraries: Libraries/Search. * searching for strings: Text Functions. * secondary files: Chained Rules. * secondary targets: Special Targets. * sed (shell command): Automatic Prerequisites. * selecting a word: File Name Functions. * selecting word lists: File Name Functions. * sequences of commands: Sequences. * setting options from environment: Options/Recursion. * setting options in makefiles: Options/Recursion. * setting variables: Setting. * several rules for one target: Multiple Rules. * several targets in a rule: Multiple Targets. * shar (standard target): Goals. * shell command: Simple Makefile. * shell command, and directory search: Commands/Search. * shell command, execution: Execution. * shell command, function for: Shell Function. * shell file name pattern (in include): Include. * shell wildcards (in include): Include. * SHELL, MS-DOS specifics: Execution. * signal: Interrupts. * silent operation: Echoing. * simple makefile: Simple Makefile. * simple variable expansion: Using Variables. * simplifying with variables: Variables Simplify. * simply expanded variables: Flavors. * sorting words: Text Functions. * spaces, in variable values: Flavors. * spaces, stripping: Text Functions. * special targets: Special Targets. * specifying makefile name: Makefile Names. * standard input: Parallel. * standards conformance: Overview. * standards for makefiles: Makefile Conventions. * static pattern rule: Static Pattern. * static pattern rule, syntax of: Static Usage. * static pattern rule, versus implicit: Static versus Implicit. * stem <1>: Pattern Match. * stem: Static Usage. * stem, variable for: Automatic. * stopping make: Make Control Functions. * strings, searching for: Text Functions. * stripping whitespace: Text Functions. * sub-make: Variables/Recursion. * subdirectories, recursion for: Recursion. * substitution variable reference: Substitution Refs. * suffix rule: Suffix Rules. * suffix rule, for archive: Archive Suffix Rules. * suffix, adding: File Name Functions. * suffix, function to find: File Name Functions. * suffix, substituting in variables: Substitution Refs. * switches: Options Summary. * symbol directories, updating archive: Archive Symbols. * syntax of rules: Rule Syntax. * tab character (in commands): Rule Syntax. * tabs in rules: Rule Introduction. * TAGS (standard target): Goals. * tangle <1>: Implicit Variables. * tangle: Catalogue of Rules. * tar (standard target): Goals. * target: Rules. * target pattern, implicit: Pattern Intro. * target pattern, static (not implicit): Static Usage. * target, deleting on error: p:~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.INFO-9;1XM Errors. * target, deleting on interrupt: Interrupts. * target, expansion: Reading Makefiles. * target, multiple in pattern rule: Pattern Intro. * target, multiple rules for one: Multiple Rules. * target, touching: Instead of Execution. * target-specific variables: Target-specific. * targets: Rule Syntax. * targets without a file: Phony Targets. * targets, built-in special: Special Targets. * targets, empty: Empty Targets. * targets, force: Force Targets. * targets, introduction to: Rule Introduction. * targets, multiple: Multiple Targets. * targets, phony: Phony Targets. * terminal rule: Match-Anything Rules. * test (standard target): Goals. * testing compilation: Testing. * tex <1>: Implicit Variables. * tex: Catalogue of Rules. * TeX, rule to run: Catalogue of Rules. * texi2dvi <1>: Implicit Variables. * texi2dvi: Catalogue of Rules. * Texinfo, rule to format: Catalogue of Rules. * tilde (~): Wildcards. * touch (shell command) <1>: Empty Targets. * touch (shell command): Wildcard Examples. * touching files: Instead of Execution. * traditional directory search: Search Algorithm. * undefined variables, warning message: Options Summary. * updating archive symbol directories: Archive Symbols. * updating makefiles: Remaking Makefiles. * user defined functions: Call Function. * value: Using Variables. * value, how a variable gets it: Values. * variable: Using Variables. * variable definition: Makefile Contents. * variables: Variables Simplify. * variables, $ in name: Computed Names. * variables, and implicit rule: Automatic. * variables, appending to: Appending. * variables, automatic: Automatic. * variables, command line: Overriding. * variables, command line, and recursion: Options/Recursion. * variables, computed names: Computed Names. * variables, conditional assignment: Flavors. * variables, defining verbatim: Defining. * variables, environment <1>: Variables/Recursion. * variables, environment: Environment. * variables, exporting: Variables/Recursion. * variables, flavors: Flavors. * variables, how they get their values: Values. * variables, how to reference: Reference. * variables, loops in expansion: Flavors. * variables, modified reference: Substitution Refs. * variables, nested references: Computed Names. * variables, origin of: Origin Function. * variables, overriding: Override Directive. * variables, overriding with arguments: Overriding. * variables, pattern-specific: Pattern-specific. * variables, recursively expanded: Flavors. * variables, setting: Setting. * variables, simply expanded: Flavors. * variables, spaces in values: Flavors. * variables, substituting suffix in: Substitution Refs. * variables, substitution reference: Substitution Refs. * variables, target-specific: Target-specific. * variables, warning for undefined: Options Summary. * varying prerequisites: Static Pattern. * verbatim variable definition: Defining. * vpath: Directory Search. * VPATH, and implicit rules: Implicit/Search. * VPATH, and link libraries: Libraries/Search. * warnings, printing: Make Control Functions. * weave <1>: Catalogue of Rules. * weave: Implicit Variables. * Web, rule to run: Catalogue of Rules. * what if: Instead of Execution. * whitespace, in variable values: Flavors. * whitespace, stripping: Text Functions. * wildcard: Wildcards. * wildcard pitfalls: Wildcard Pitfall. * wildcard, function: File Name Functions. * wildcard, in archive member: Archive Members. * wildcard, in include: Include. * wildcards and MS-DOS/MS-Windows backslashes: Wildcard Pitfall. * word, selecting a: File Name Functions. * words, extracting first: File Name Functions. * words, filtering: Text Functions. * words, filtering out: Text Functions. * words, finding number: File Name Functions. * words, iterating over: Foreach Function. * words, joining lists: File Name Functions. * words, removing duplicates: Text Functions. * words, selecting lists of: File Name Functions. * writing rule commands: Commands. * writing rules: Rules. * yacc <1>: Catalogue of Rules. * yacc <2>: Implicit Variables. * yacc: Sequences. * Yacc, rule to run: Catalogue of Rules. * ~ (tilde): Wildcards. i*[MAKE-3_78_1HB]MAKE.LNK;1+,c./@ 4S-`0123KPWO56\f7޵m89G@HJFROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o" TO "make.new" LIB glob/glob.lib LIB:sc.lib LIB:amiga.lib QUIET *[MAKE-3_78_1HB]MAKE.TEXINFO;1+,c./@ 4!-`0123KPWO56t7$m89G@HJ \input texinfo @c -*- Texinfo -*- @c %**start of header @setfilename make.info @settitle GNU @code{make} @setchapternewpage odd @c %**end of header @c FSF publishers: format makebook.texi instead of using this file directly. @set RCSID $Id: make.texinfo,v 2.184 1999/09/14 00:18:00 psmith Exp $ @set EDITION 0.54 @set VERSION 3.78.1 @set UPDATED 09 September 1999 @set UPDATE-MONTH September 1999 @comment The ISBN number might need to change on next publication. @set ISBN 1-882114-80-9 @c CHANGE THIS BEFORE PRINTING AGAIN! --psmith 16jul98 @c finalout @c ISPELL CHECK: done, 10 June 1993 --roland @c Combine the variable and function indices: @syncodeindex vr fn @c Combine the program and concept indices: @syncodeindex pg cp @dircategory GNU Packages @direntry * Make: (make). Remake files automatically. @end direntry @ifinfo This file documents the GNU Make utility, which determines automatically which pieces of a large program need to be recompiled, and issues the commands to recompile them. This is Edition @value{EDITION}, last updated @value{UPDATED}, of @cite{The GNU Make Manual}, for @code{make}, Version @value{VERSION}. Copyright (C) 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @iftex @shorttitlepage GNU Make @end iftex @titlepage @title GNU Make @subtitle A Program for Directing Recompilation @subtitle GNU @code{make} Version @value{VERSION} @subtitle @value{UPDATE-MONTH} @author Richard M. Stallman and Roland McGrath @page @vskip 0pt plus 1filll Copyright @copyright{} 1988, '89, '90, '91, '92, '93, '94, '95, '96, '97, '98 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation @* 59 Temple Place -- Suite 330, @* Boston, MA 02111-1307 USA @* ISBN @value{ISBN} @* Maintenance and updates since Version 3.76 by Paul D. Smith. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @sp 2 Cover art by Etienne Suvasa. @end titlepage @page @ifinfo @node Top, Overview, , (dir) @top Make The GNU @code{make} utility automatically determines which pieces of a large program need to be recompiled, and issues the commands to recompile them.@refill This edition of the @cite{GNU Make Manual}, last updated @value{UPDATED}, documents GNU @code{make} Version @value{VERSION}.@refill This manual describes @code{make} and contains the following chapters:@refill @end ifinfo @menu * Overview:: Overview of @code{make}. * Introduction:: An introduction to @code{make}. * Makefiles:: Makefiles tell @code{make} what to do. * Rules:: Rules describe when a file must be remade. * Commands:: Commands say how to remake a file. * Using Variables:: You can use variables to avoid repetition. * Conditionals:: Use or ignore parts of the makefile based on the values of variables. * Functions:: Many powerful ways to manipulate text. * Invoking make: Running. How to invoke @code{make} on the command line. * Implicit Rules:: Use implicit rules to treat many files alike, based on their file names. * Archives:: How @code{make} can update library archives. * Features:: Features GNU @code{make} has over other @code{make}s. * Missing:: What GNU @code{make} lacks from other @code{make}s. * Makefile Conventions:: Conventions for makefiles in GNU programs. * Quick Reference:: A quick reference for experienced users. * Make Errors:: A list of common errors generated by @code{make}. * Complex Makefile:: A real example of a straightforward, but nontrivial, makefile. * Concept Index:: Index of Concepts * Name Index:: Index of Functions, Variables, & Directives --- The Detailed Node Listing --- Overview of @code{make} * Preparing:: Preparing and Running Make * Reading:: On Reading this Text * Bugs:: Problems and Bugs An Introduction to Makefiles * Rule Introduction:: What a rule looks like. * Simple Makefile:: A Simple Makefile * How Make Works:: How @code{make} Processes This Makefile * Variables Simplify:: Variables Make Makefiles Simpler * make Deduces:: Letting @code{make} Deduce the Commands * Combine By Prerequisite:: Another Style of Makefile * Cleanup:: Rules for Cleaning the Directory Writing Makefiles * Makefile Contents:: What makefiles contain. * Makefile Names:: How to name your makefile. * Include:: How one makefile can use another makefile. * MAKEFILES Variable:: The environment can specify extra makefiles. * Remaking Makefiles:: How makefiles get remade. * Overriding Makefiles:: How to override part of one makefile with another makefile. * Reading Makefiles:: How makefiles are parsed. Writing Rules * Rule Example:: An example explained. * Rule Syntax:: General syntax explained. * Wildcards:: Using wildcard characters such as `*'. * Directory Search:: Searching other directories for source files. * Phony Targets:: Using a target that is not a real file's name. * Force Targets:: You can use a target without commands or prerequisites to mark other targets as phony. * Empty Targets:: When only the date matters and the files are empty. * Special Targets:: Targets with special built-in meanings. * Multiple Targets:: When to make use of several targets in a rule. * Multiple Rules:: How to use several rules with the same target. * Static Pattern:: Static pattern rules apply to multiple targets and can vary the prerequisites according to the target name. * Double-Colon:: How to use a special kind of rule to allow several independent rules for one target. * Automatic Prerequisites:: How to automatically generate rules giving prerequisites from source files themselves. Using Wildcard C@haracters in File Names * Wildcard Examples:: Several examples * Wildcard Pitfall:: Problems to avoid. * Wildcard Function:: How to cause wildcard expansion where it does not normally take place. Searching Directories for Prerequisites * General Search:: Specifying a search path that applies to every prerequisite. * Selective Search:: Specifying a search path for a specified class of names. * Search Algorithm:: When and how search paths are applied. * Commands/Search:: How to write shell commands that work together with search paths. * Implicit/Search:: How search paths affect implicit rules. * Libraries/Search:: Directory search for link libraries. Static Pattern Rules * Static Usage:: The syntax of static pattern rules. * Static versus Implicit:: When are they better than implicit rules? Writing the Commands in Rules * Echoing:: How to control when commands are echoed. * Execution:: How commands are executed. * Parallel:: How commands can be executed in parallel. * Errors:: What happens after a command execution error. * Interrupts:: What happens when a command is interrupted. * Recursion:: Invoking @code{make} from makefiles. * Sequences:: Defining canned sequences of commands. * Empty Commands:: Defining useful, do-nothing commands. Recursive Use of @code{make} * MAKE Variable:: The special effects of using @samp{$(MAKE)}. * Variables/Recursion:: How to communicate variables to a sub-@code{make}. * Options/Recursion:: How to communicate options to a sub-@code{make}. * -w Option:: How the @samp{-w} or @samp{--print-directory} option helps debug use of recursive @code{make} commands. How to Use Variables * Reference:: How to use the value of a variable. * Flavors:: Variables come in two flavors. * Advanced:: Advanced features for referencing a variable. * Values:: All the ways variables get their values. * Setting:: How to set a variable in the makefile. * Appending:: How to append more text to the old value of a variable. * Override Directive:: How to set a variable in the makefile even if the user has set it with a command argument. * Defining:: An alternate way to set a variable to a verbatim string. * Environment:: Variable values can come from the environment. * Automatic:: Some special variables have predefined meanings for use with implicit rules. Advanced Features for Reference to Variables * Substitution Refs:: Referencing a variable with substitutions on the value. * Computed Names:: Computing the name of the variable to refer to. Conditional Parts of Makefiles * Conditional Example:: Example of a conditional * Conditional Syntax:: The syntax of conditionals. * Testing Flags:: Conditionals that test flags. Functions for Transforming Text * Syntax of Functions:: How to write a function call. * Text Functions:: General-purpose text manipulation functions. * File Name Functions:: Functions for manipulating file names. * Foreach Function:: Repeat some text with controlled variation. * Call Function:: Expand a user-defined function. * Origin Function:: Find where a variable got its value. * Shell Function:: Substitute the output of a shell command. How to Run @code{make} * Makefile Arguments:: How to specify which makefile to use. * Goals:: How to use goal arguments to specify which parts of the makefile to use. * Instead of Execution:: How to use mode flags to specify what kind of thing to do with the commands in the makefile other than simply execute them. * Avoiding Compilation:: How to avoid recompiling certain files. * Overriding:: How to override a variable to specify an alternate compiler and other things. * Testing:: How to proceed past some errors, to test compilation. * Options Summary:: Summary of Options Using Implicit Rules * Using Implicit:: How to use an existing implicit rule to get the commands for updating a file. * Catalogue of Rules:: A list of built-in implicit rules. * Implicit Variables:: How to change what predefined rules do. * Chained Rules:: How to use a chain of implicit rules. * Pattern Rules:: How to define new implicit rules. * Last Resort:: How to defining commands for rules which cannot find any. * Suffix Rules:: The old-fashioned style of implicit rule. * Implicit Rule Search:: The precise algorithm for applying implicit rules. Defining and Redefining Pattern Rules * Pattern Intro:: An introduction to pattern rules. * Pattern Examples:: Examples of pattern rules. * Automatic:: How to use automatic variables in the commands of implicit rules. * Pattern Match:: How patterns match. * Match-Anything Rules:: Precautions you should take prior to defining rules that can match any target file whatever. * Canceling Rules:: How to override or cancel built-in rules. Using @code{make} to Update Archive Files * Archive Members:: Archive members as targets. * Archive Update:: The implicit rule for archive member targets. * Archive Pitfalls:: Dangers to watch out for when using archives. * Archive Suffix Rules:: You can write a special kind of suffix rule for updating archives. Implicit Rule for Archive Member Targets * Archive Symbols:: How to update archive symbol directories. @end menu @node Overview, Introduction, Top, Top @comment node-name, next, previous, up @chapter Overview of @code{make} The @code{make} utility automatically determines which pieces of a large program need to be recompiled, and issues commands to recompile them. This manual describes GNU @code{make}, which was implemented by Richard Stallman and Roland McGrath. Development since Version 3.76 has been handled by Paul D. Smith. GNU @code{make} conforms to section 6.2 of @cite{IEEE Standard 1003.2-1992} (POSIX.2). @cindex POSIX @cindex IEEE Standard 1003.2 @cindex standards conformance Our examples show C programs, since they are most common, but you can use @code{make} with any programming language whose compiler can be run with a shell command. Indeed, @code{make} is not limited to programs. You can use it to describe any task where some files must be updated automatically from others whenever the others change. @menu * Preparing:: Preparing and Running Make * Reading:: On Reading this Text * Bugs:: Problems and Bugs @end menu @node Preparing, Reading, , Overview @ifinfo @heading Preparing and Running Make @end ifinfo To prepare to use @code{make}, you must write a file called the @dfn{makefile} that describes the relationships among files in your program and provides commands for updating each file. In a program, typically, the executable file is updated from object files, which are in turn made by compiling source files.@refill Once a suitable makefile exists, each time you change some source files, this simple shell command: @example make @end example @noindent suffices to perform all necessary recompilations. The @code{make} program uses the makefile data base and the last-modification times of the files to decide which of the files need to be updated. For each of those files, it issues the commands recorded in the data base. You can provide command line arguments to @code{make} to control which files should be recompiled, or how. @xref{Running, ,How to Run @code{make}}. @node Reading, Bugs, Preparing, Overview @section How to Read This Manual If you are new to @code{make}, or are looking for a general introduction, read the first few sections of each chapter, skipping the later sections. In each chapter, the first few sections contain introductory or general information and the later sections contain specialized or technical information. @ifinfo The exception is the second chapter, @ref{Introduction, ,An Introduction to Makefiles}, all of which is introductory. @end ifinfo @iftex The exception is @ref{Introduction, ,An Introduction to Makefiles}, all of which is introductory. @end iftex If you are familiar with other @code{make} programs, see @ref{Features, ,Features of GNU @code{make}}, which lists the enhancements GNU @code{make} has, and @ref{Missing, ,Incompatibilities and Missing Features}, which explains the few things GNU @code{make} lacks that others have. For a quick summary, see @ref{Options Summary}, @ref{Quick Reference}, and @ref{Special Targets}. @node Bugs, , Reading, Overview @section Problems and Bugs @cindex reporting bugs @cindex bugs, reporting @cindex problems and bugs, reporting If you have problems with GNU @code{make} or think you've found a bug, please report it to the developers; we cannot promise to do anything but we might well want to fix it. Before reporting a bug, make sure you've actually found a real bug. Carefully reread the documentation and see if it really says you can do what you're trying to do. If it's not clear whether you should be able to do something or not, report that too; it's a bug in the documentation! Before reporting a bug or trying to fix it yourself, try to isolate it to the smallest possible makefile that reproduces the problem. Then send us the makefile and the exact results @code{make} gave you. Also say what you expected to occur; this will help us decide whether the problem was really in the documentation. Once you've got a precise problem, please send electronic mail to: @example bug-make@@gnu.org @end example @noindent Please include the version number of @code{make} you are using. You can get this information with the command @samp{make --version}. Be sure also to include the type of machine and operating system you are using. If possible, include the contents of the file @file{config.h} that is generated by the configuration process. @node Introduction, Makefiles, Overview, Top @comment node-name, next, previous, up @chapter An Introduction to Makefiles You need a file called a @dfn{makefile} to tell @code{make} what to do. Most often, the makefile tells @code{make} how to compile and link a program. @cindex makefile In this chapter, we will discuss a simple makefile that describes how to compile and link a text editor which consists of eight C source files and three header files. The makefile can also tell @code{make} how to run miscellaneous commands when explicitly asked (for example, to remove certain files as a clean-up operation). To see a more complex example of a makefile, see @ref{Complex Makefile}. When @code{make} recompiles the editor, each changed C source file must be recompiled. If a header file has changed, each C source file that includes the header file must be recompiled to be safe. Each compilation produces an object file corresponding to the source file. Finally, if any source file has been recompiled, all the object files, whether newly made or saved from previous compilations, must be linked together to produce the new executable editor. @cindex recompilation @cindex editor @menu * Rule Introduction:: What a rule looks like. * Simple Makefile:: A Simple Makefile * How Make Works:: How @code{make} Processes This Makefile * Variables Simplify:: Variables Make Makefiles Simpler * make Deduces:: Letting @code{make} Deduce the Commands * Combine By Prerequisite:: Another Style of Makefile * Cleanup:: Rules for Cleaning the Directory @end menu @node Rule Introduction, Simple Makefile, , Introduction @comment node-name, next, previous, up @section What a Rule Looks Like @cindex rule, introduction to @cindex makefile rule parts @cindex parts of makefile rule A simple makefile consists of ``rules'' with the following shape: @cindex targets, introduction to @cindex prerequisites, introduction to @cindex commands, introduction to @example @group @var{target} @dots{} : @var{prerequisites} @dots{} @var{command} @dots{} @dots{} @end group @end example A @dfn{target} is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out, such as @samp{clean} (@pxref{Phony Targets}). A @dfn{prerequisite} is a file that is used as input to create the target. A target often depends on several files. @cindex tabs in rules A @dfn{command} is an action that @code{make} carries out. A rule may have more than one command, each on its own line. @strong{Please note:} you need to put a tab character at the beginning of every command line! This is an obscurity that catches the unwary. Usually a command is in a rule with prerequisites and serves to create a target file if any of the prerequisites change. However, the rule that specifies commands for the target need not have prerequisites. For example, the rule containing the delete command associated with the target @samp{clean} does not have prerequisites. A @dfn{rule}, then, explains how and when to remake certain files which are the targets of the particular rule. @code{make} carries out the commands on the prerequisites to create or update the target. A rule can also explain how and when to carry out an action. @xref{Rules, , Writing Rules}. A makefile may contain other text besides rules, but a simple makefile need only contain rules. Rules may look somewhat more complicated than shown in this template, but all fit the pattern more or less. @node Simple Makefile, How Make Works, Rule Introduction, Introduction @section A Simple Makefile @cindex simple makefile @cindex makefile, simple Here is a straightforward makefile that describes the way an executable file called @code{edit} depends on eight object files which, in turn, depend on eight C source and three header files. In this example, all the C files include @file{defs.h}, but only those defining editing commands include @file{command.h}, and only low level files that change the editor buffer include @file{buffer.h}. @example @group edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o @end group @end example @noindent We split each long line into two li;~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1(01nes using backslash-newline; this is like using one long line, but is easier to read. @cindex continuation lines @cindex @code{\} (backslash), for continuation lines @cindex backslash (@code{\}), for continuation lines @cindex quoting newline, in makefile @cindex newline, quoting, in makefile To use this makefile to create the executable file called @file{edit}, type: @example make @end example To use this makefile to delete the executable file and all the object files from the directory, type: @example make clean @end example In the example makefile, the targets include the executable file @samp{edit}, and the object files @samp{main.o} and @samp{kbd.o}. The prerequisites are files such as @samp{main.c} and @samp{defs.h}. In fact, each @samp{.o} file is both a target and a prerequisite. Commands include @w{@samp{cc -c main.c}} and @w{@samp{cc -c kbd.c}}. When a target is a file, it needs to be recompiled or relinked if any of its prerequisites change. In addition, any prerequisites that are themselves automatically generated should be updated first. In this example, @file{edit} depends on each of the eight object files; the object file @file{main.o} depends on the source file @file{main.c} and on the header file @file{defs.h}. A shell command follows each line that contains a target and prerequisites. These shell commands say how to update the target file. A tab character must come at the beginning of every command line to distinguish commands lines from other lines in the makefile. (Bear in mind that @code{make} does not know anything about how the commands work. It is up to you to supply commands that will update the target file properly. All @code{make} does is execute the commands in the rule you have specified when the target file needs to be updated.) @cindex shell command The target @samp{clean} is not a file, but merely the name of an action. Since you normally do not want to carry out the actions in this rule, @samp{clean} is not a prerequisite of any other rule. Consequently, @code{make} never does anything with it unless you tell it specifically. Note that this rule not only is not a prerequisite, it also does not have any prerequisites, so the only purpose of the rule is to run the specified commands. Targets that do not refer to files but are just actions are called @dfn{phony targets}. @xref{Phony Targets}, for information about this kind of target. @xref{Errors, , Errors in Commands}, to see how to cause @code{make} to ignore errors from @code{rm} or any other command. @cindex @code{clean} target @cindex @code{rm} (shell command) @node How Make Works, Variables Simplify, Simple Makefile, Introduction @comment node-name, next, previous, up @section How @code{make} Processes a Makefile @cindex processing a makefile @cindex makefile, how @code{make} processes By default, @code{make} starts with the first target (not targets whose names start with @samp{.}). This is called the @dfn{default goal}. (@dfn{Goals} are the targets that @code{make} strives ultimately to update. @xref{Goals, , Arguments to Specify the Goals}.) @cindex default goal @cindex goal, default @cindex goal In the simple example of the previous section, the default goal is to update the executable program @file{edit}; therefore, we put that rule first. Thus, when you give the command: @example make @end example @noindent @code{make} reads the makefile in the current directory and begins by processing the first rule. In the example, this rule is for relinking @file{edit}; but before @code{make} can fully process this rule, it must process the rules for the files that @file{edit} depends on, which in this case are the object files. Each of these files is processed according to its own rule. These rules say to update each @samp{.o} file by compiling its source file. The recompilation must be done if the source file, or any of the header files named as prerequisites, is more recent than the object file, or if the object file does not exist. The other rules are processed because their targets appear as prerequisites of the goal. If some other rule is not depended on by the goal (or anything it depends on, etc.), that rule is not processed, unless you tell @code{make} to do so (with a command such as @w{@code{make clean}}). Before recompiling an object file, @code{make} considers updating its prerequisites, the source file and header files. This makefile does not specify anything to be done for them---the @samp{.c} and @samp{.h} files are not the targets of any rules---so @code{make} does nothing for these files. But @code{make} would update automatically generated C programs, such as those made by Bison or Yacc, by their own rules at this time. After recompiling whichever object files need it, @code{make} decides whether to relink @file{edit}. This must be done if the file @file{edit} does not exist, or if any of the object files are newer than it. If an object file was just recompiled, it is now newer than @file{edit}, so @file{edit} is relinked. @cindex relinking Thus, if we change the file @file{insert.c} and run @code{make}, @code{make} will compile that file to update @file{insert.o}, and then link @file{edit}. If we change the file @file{command.h} and run @code{make}, @code{make} will recompile the object files @file{kbd.o}, @file{command.o} and @file{files.o} and then link the file @file{edit}. @node Variables Simplify, make Deduces, How Make Works, Introduction @section Variables Make Makefiles Simpler @cindex variables @cindex simplifying with variables In our example, we had to list all the object files twice in the rule for @file{edit} (repeated here): @example @group edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o @end group @end example @cindex @code{objects} Such duplication is error-prone; if a new object file is added to the system, we might add it to one list and forget the other. We can eliminate the risk and simplify the makefile by using a variable. @dfn{Variables} allow a text string to be defined once and substituted in multiple places later (@pxref{Using Variables, ,How to Use Variables}). @cindex @code{OBJECTS} @cindex @code{objs} @cindex @code{OBJS} @cindex @code{obj} @cindex @code{OBJ} It is standard practice for every makefile to have a variable named @code{objects}, @code{OBJECTS}, @code{objs}, @code{OBJS}, @code{obj}, or @code{OBJ} which is a list of all object file names. We would define such a variable @code{objects} with a line like this in the makefile:@refill @example @group objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o @end group @end example @noindent Then, each place we want to put a list of the object file names, we can substitute the variable's value by writing @samp{$(objects)} (@pxref{Using Variables, ,How to Use Variables}). Here is how the complete simple makefile looks when you use a variable for the object files: @example @group objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects) @end group @end example @node make Deduces, Combine By Prerequisite, Variables Simplify, Introduction @section Letting @code{make} Deduce the Commands @cindex deducing commands (implicit rules) @cindex implicit rule, introduction to @cindex rule, implicit, introduction to It is not necessary to spell out the commands for compiling the individual C source files, because @code{make} can figure them out: it has an @dfn{implicit rule} for updating a @samp{.o} file from a correspondingly named @samp{.c} file using a @samp{cc -c} command. For example, it will use the command @samp{cc -c main.c -o main.o} to compile @file{main.c} into @file{main.o}. We can therefore omit the commands from the rules for the object files. @xref{Implicit Rules, ,Using Implicit Rules}.@refill When a @samp{.c} file is used automatically in this way, it is also automatically added to the list of prerequisites. We can therefore omit the @samp{.c} files from the prerequisites, provided we omit the commands. Here is the entire example, with both of these changes, and a variable @code{objects} as suggested above: @example @group objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : defs.h kbd.o : defs.h command.h command.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h .PHONY : clean clean : -rm edit $(objects) @end group @end example @noindent This is how we would write the makefile in actual practice. (The complications associated with @samp{clean} are described elsewhere. See @ref{Phony Targets}, and @ref{Errors, ,Errors in Commands}.) Because implicit rules are so convenient, they are important. You will see them used frequently.@refill @node Combine By Prerequisite, Cleanup, make Deduces, Introduction @section Another Style of Makefile @cindex combining rules by prerequisite When the objects of a makefile are created only by implicit rules, an alternative style of makefile is possible. In this style of makefile, you group entries by their prerequisites instead of by their targets. Here is what one looks like: @example @group objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) $(objects) : defs.h kbd.o command.o files.o : command.h display.o insert.o search.o files.o : buffer.h @end group @end example @noindent Here @file{defs.h} is given as a prerequisite of all the object files; @file{command.h} and @file{buffer.h} are prerequisites of the specific object files listed for them. Whether this is better is a matter of taste: it is more compact, but some people dislike it because they find it clearer to put all the information about each target in one place. @node Cleanup, , Combine By Prerequisite, Introduction @section Rules for Cleaning the Directory @cindex cleaning up @cindex removing, to clean up Compiling a program is not the only thing you might want to write rules for. Makefiles commonly tell how to do a few other things besides compiling a program: for example, how to delete all the object files and executables so that the directory is @samp{clean}. @cindex @code{clean} target Here is how we could write a @code{make} rule for cleaning our example editor: @example @group clean: rm edit $(objects) @end group @end example In practice, we might want to write the rule in a somewhat more complicated manner to handle unanticipated situations. We would do this: @example @group .PHONY : clean clean : -rm edit $(objects) @end group @end example @noindent This prevents @code{make} from getting confused by an actual file called @file{clean} and causes it to continue in spite of errors from @code{rm}. (See @ref{Phony Targets}, and @ref{Errors, ,Errors in Commands}.) @noindent A rule such as this should not be placed at the beginning of the makefile, because we do not want it to run by default! Thus, in the example makefile, we want the rule for @code{edit}, which recompiles the editor, to remain the default goal. Since @code{clean} is not a prerequisite of @code{edit}, this rule will not run at all if we give the command @samp{make} with no arguments. In order to make the rule run, we have to type @samp{make clean}. @xref{Running, ,How to Run @code{make}}. @node Makefiles, Rules, Introduction, Top @chapter Writing Makefiles @cindex makefile, hoIw to write The information that tells @code{make} how to recompile a system comes from reading a data base called the @dfn{makefile}. @menu * Makefile Contents:: What makefiles contain. * Makefile Names:: How to name your makefile. * Include:: How one makefile can use another makefile. * MAKEFILES Variable:: The environment can specify extra makefiles. * Remaking Makefiles:: How makefiles get remade. * Overriding Makefiles:: How to override part of one makefile with another makefile. * Reading Makefiles:: How makefiles are parsed. @end menu @node Makefile Contents, Makefile Names, , Makefiles @section What Makefiles Contain Makefiles contain five kinds of things: @dfn{explicit rules}, @dfn{implicit rules}, @dfn{variable definitions}, @dfn{directives}, and @dfn{comments}. Rules, variables, and directives are described at length in later chapters.@refill @itemize @bullet @cindex rule, explicit, definition of @cindex explicit rule, definition of @item An @dfn{explicit rule} says when and how to remake one or more files, called the rule's targets. It lists the other files that the targets depend on, call the @dfn{prerequisites} of the target, and may also give commands to use to create or update the targets. @xref{Rules, ,Writing Rules}. @cindex rule, implicit, definition of @cindex implicit rule, definition of @item An @dfn{implicit rule} says when and how to remake a class of files based on their names. It describes how a target may depend on a file with a name similar to the target and gives commands to create or update such a target. @xref{Implicit Rules, ,Using Implicit Rules}. @cindex variable definition @item A @dfn{variable definition} is a line that specifies a text string value for a variable that can be substituted into the text later. The simple makefile example shows a variable definition for @code{objects} as a list of all object files (@pxref{Variables Simplify, , Variables Make MMakefiles Simpler}). @cindex directive @item A @dfn{directive} is a command for @code{make} to do something special while reading the makefile. These include: @itemize @bullet @item Reading another makefile (@pxref{Include, ,Including Other Makefiles}). @item Deciding (based on the values of variables) whether to use or ignore a part of the makefile (@pxref{Conditionals, ,Conditional Parts of Makefiles}). @item Defining a variable from a verbatim string containing multiple lines (@pxref{Defining, ,Defining Variables Verbatim}). @end itemize @cindex comments, in makefile @cindex @code{#} (comments), in makefile @item @samp{#} in a line of a makefile starts a @dfn{comment}. It and the rest of the line are ignored, except that a trailing backslash not escaped by another backslash will continue the comment across multiple lines. Comments may appear on any of the lines in the makefile, except within a @code{define} directive, and perhaps within commands (where the shell decides what is a comment). A line containing just a comment (with perhaps spaces before it) is effectively blank, and is ignored.@refill @end itemize @node Makefile Names, Include, Makefile Contents, Makefiles @section What Name to Give Your Makefile @cindex makefile name @cindex name of makefile @cindex default makefile name @cindex file name of makefile @c following paragraph rewritten to avoid overfull hbox By default, when @code{make} looks for the makefile, it tries the following names, in order: @file{GNUmakefile}, @file{makefile} and @file{Makefile}.@refill @findex Makefile @findex GNUmakefile @findex makefile @cindex @code{README} Normally you should call your makefile either @file{makefile} or @file{Makefile}. (We recommend @file{Makefile} because it appears prominently near the beginning of a directory listing, right near other important files such as @file{README}.) The first name checked, @file{GNUmakefile}, is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU @code{makQe}, and will not be understood by other versions of @code{make}. Other @code{make} programs look for @file{makefile} and @file{Makefile}, but not @file{GNUmakefile}. If @code{make} finds none of these names, it does not use any makefile. Then you must specify a goal with a command argument, and @code{make} will attempt to figure out how to remake it using only its built-in implicit rules. @xref{Implicit Rules, ,Using Implicit Rules}. @cindex @code{-f} @cindex @code{--file} @cindex @code{--makefile} If you want to use a nonstandard name for your makefile, you can specify the makefile name with the @samp{-f} or @samp{--file} option. The arguments @w{@samp{-f @var{name}}} or @w{@samp{--file=@var{name}}} tell @code{make} to read the file @var{name} as the makefile. If you use more than one @samp{-f} or @samp{--file} option, you can specify several makefiles. All the makefiles are effectively concatenated in the order specified. The default makefile names @file{GNUmakefile}, @file{makefile} and @file{Makefile} are not checked automatically if you specify @samp{-f} or @samp{--file}.@refill @cindex specifying makefile name @cindex makefile name, how to specify @cindex name of makefile, how to specify @cindex file name of makefile, how to specify @node Include, MAKEFILES Variable, Makefile Names, Makefiles @section Including Other Makefiles @cindex including other makefiles @cindex makefile, including @findex include The @code{include} directive tells @code{make} to suspend reading the current makefile and read one or more other makefiles before continuing. The directive is a line in the makefile that looks like this: @example include @var{filenames}@dots{} @end example @noindent @var{filenames} can contain shell file name patterns. @cindex shell file name pattern (in @code{include}) @cindex shell wildcards (in @code{include}) @cindex wildcard, in @code{include} Extra spaces are allowed and ignored at the beginning of the line, but a tab is not allowed. (If the line begins with a tab, it will be considered Ua command line.) Whitespace is required between @code{include} and the file names, and between file names; extra whitespace is ignored there and at the end of the directive. A comment starting with @samp{#} is allowed at the end of the line. If the file names contain any variable or function references, they are expanded. @xref{Using Variables, ,How to Use Variables}. For example, if you have three @file{.mk} files, @file{a.mk}, @file{b.mk}, and @file{c.mk}, and @code{$(bar)} expands to @code{bish bash}, then the following expression @example include foo *.mk $(bar) @end example is equivalent to @example include foo a.mk b.mk c.mk bish bash @end example When @code{make} processes an @code{include} directive, it suspends reading of the containing makefile and reads from each listed file in turn. When that is finished, @code{make} resumes reading the makefile in which the directive appears. One occasion for using @code{include} directives is when several programs, handled by individual makefiles in various directories, need to use a common set of variable definitions (@pxref{Setting, ,Setting Variables}) or pattern rules (@pxref{Pattern Rules, ,Defining and Redefining Pattern Rules}). Another such occasion is when you want to generate prerequisites from source files automatically; the prerequisites can be put in a file that is included by the main makefile. This practice is generally cleaner than that of somehow appending the prerequisites to the end of the main makefile as has been traditionally done with other versions of @code{make}. @xref{Automatic Prerequisites}. @cindex prerequisites, automatic generation @cindex automatic generation of prerequisites @cindex generating prerequisites automatically @cindex @code{-I} @cindex @code{--include-dir} @cindex included makefiles, default directries @cindex default directries for included makefiles @findex /usr/gnu/include @findex /usr/local/include @findex /usr/include If the specified name does not start with a slash, and the file is not found in the current directory, several other directories are searched. First, any directories you have specified with the @samp{-I} or @samp{--include-dir} option are searched (@pxref{Options Summary, ,Summary of Options}). Then the following directories (if they exist) are searched, in this order: @file{@var{prefix}/include} (normally @file{/usr/local/include} @footnote{GNU Make compiled for MS-DOS and MS-Windows behaves as if @var{prefix} has been defined to be the root of the DJGPP tree hierarchy.}) @file{/usr/gnu/include}, @file{/usr/local/include}, @file{/usr/include}. If an included makefile cannot be found in any of these directories, a warning message is generated, but it is not an immediately fatal error; processing of the makefile containing the @code{include} continues. Once it has finished reading makefiles, @code{make} will try to remake any that are out of date or don't exist. @xref{Remaking Makefiles, ,How Makefiles Are Remade}. Only after it has tried to find a way to remake a makefile and failed, will @code{make} diagnose the missing makefile as a fatal error. If you want @code{make} to simply ignore a makefile which does not exist and cannot be remade, with no error message, use the @w{@code{-include}} directive instead of @code{include}, like this: @example -include @var{filenames}@dots{} @end example This is acts like @code{include} in every way except that there is no error (not even a warning) if any of the @var{filenames} do not exist. For compatibility with some other @code{make} implementations, @code{sinclude} is another name for @w{@code{-include}}. @node MAKEFILES Variable, Remaking Makefiles, Include, Makefiles @section The Variable @code{MAKEFILES} @cindex makefile, and @code{MAKEFILES} variable @cindex including (@code{MAKEFILES} variable) @vindex MAKEFILES If the environment variable @code{MAKEFILES} is defined, @code{make} considers its value as a list of names (separated by whitespace) of additional makefiles to be read before the others. This works much like the @code{include} directiv]e: various directories are searched for those files (@pxref{Include, ,Including Other Makefiles}). In addition, the default goal is never taken from one of these makefiles and it is not an error if the files listed in @code{MAKEFILES} are not found.@refill @cindex recursion, and @code{MAKEFILES} variable The main use of @code{MAKEFILES} is in communication between recursive invocations of @code{make} (@pxref{Recursion, ,Recursive Use of @code{make}}). It usually is not desirable to set the environment variable before a top-level invocation of @code{make}, because it is usually better not to mess with a makefile from outside. However, if you are running @code{make} without a specific makefile, a makefile in @code{MAKEFILES} can do useful things to help the built-in implicit rules work better, such as defining search paths (@pxref{Directory Search}). Some users are tempted to set @code{MAKEFILES} in the environment automatically on login, and program makefiles to expect this to be done. This is a very bad idea, because such makefiles will fail to work if run by anyone else. It is much better to write explicit @code{include} directives in the makefiles. @xref{Include, , Including Other Makefiles}. @node Remaking Makefiles, Overriding Makefiles, MAKEFILES Variable, Makefiles @section How Makefiles Are Remade @cindex updating makefiles @cindex remaking makefiles @cindex makefile, remaking of Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want @code{make} to get an up-to-date version of the makefile to read in. To this end, after reading in all makefiles, @code{make} will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (@pxref{Implicit Rules, ,Using Implicit Rules}), it will be updated if necessary. After all makefiles have been checked, if any have actually been chaanged, @code{make} starts with a clean slate and reads all the makefiles over again. (It will also attempt to update each of them over again, but normally this will not change them again, since they are already up to date.)@refill If you know that one or more of your makefiles cannot be remade and you want to keep @code{make} from performing an implicit rule search on them, perhaps for efficiency reasons, you can use any normal method of preventing implicit rule lookup to do so. For example, you can write an explicit rule with the makefile as the target, and an empty command string (@pxref{Empty Commands, ,Using Empty Commands}). If the makefiles specify a double-colon rule to remake a file with commands but no prerequisites, that file will always be remade (@pxref{Double-Colon}). In the case of makefiles, a makefile that has a double-colon rule with commands but no prerequisites will be remade every time @code{make} is run, and then again after @code{make} starts over and reads the makefiles in again. This would cause an infinite loop: @code{make} would constantly remake the makefile, and never do anything else. So, to avoid this, @code{make} will @strong{not} attempt to remake makefiles which are specified as targets of a double-colon rule with commands but no prerequisites.@refill If you do not specify any makefiles to be read with @samp{-f} or @samp{--file} options, @code{make} will try the default makefile names; @pxref{Makefile Names, ,What Name to Give Your Makefile}. Unlike makefiles explicitly requested with @samp{-f} or @samp{--file} options, @code{make} is not certain that these makefiles should exist. However, if a default makefile does not exist but can be created by running @code{make} rules, you probably want the rules to be run so that the makefile can be used. Therefore, if none of the default makefiles exists, @code{make} will try to make each of them in the same order in which they are searched for (@pxref{Makefile Names, ,What Name to Give Your Makefile}) until it succeeds in making one, or it runs out of names to try. Note that it is not an error if @code{make} cannot find or make any makefile; a makefile is not always necessary.@refill When you use the @samp{-t} or @samp{--touch} option (@pxref{Instead of Execution, ,Instead of Executing the Commands}), you would not want to use an out-of-date makefile to decide which targets to touch. So the @samp{-t} option has no effect on updating makefiles; they are really updated even if @samp{-t} is specified. Likewise, @samp{-q} (or @samp{--question}) and @samp{-n} (or @samp{--just-print}) do not prevent updating of makefiles, because an out-of-date makefile would result in the wrong output for other targets. Thus, @samp{make -f mfile -n foo} will update @file{mfile}, read it in, and then print the commands to update @file{foo} and its prerequisites without running them. The commands printed for @file{foo} will be those specified in the updated contents of @file{mfile}. However, on occasion you might actually wish to prevent updating of even the makefiles. You can do this by specifying the makefiles as goals in the command line as well as specifying them as makefiles. When the makefile name is specified explicitly as a goal, the options @samp{-t} and so on do apply to them. Thus, @samp{make -f mfile -n mfile foo} would read the makefile @file{mfile}, print the commands needed to update it without actually running them, and then print the commands needed to update @file{foo} without running them. The commands for @file{foo} will be those specified by the existing contents of @file{mfile}. @node Overriding Makefiles, Reading Makefiles, Remaking Makefiles, Makefiles @section Overriding Part of Another Makefile @cindex overriding makefiles @cindex makefile, overriding Sometimes it is useful to have a makefile that is mostly just like another makefile. You can often use the @samp{include} directive to include one in the other, and add more targets or variable definitions. However, if the two makefiles give different commands for the same ta irget, @code{make} will not let you just do this. But there is another way. @cindex match-anything rule, used to override In the containing makefile (the one that wants to include the other), you can use a match-anything pattern rule to say that to remake any target that cannot be made from the information in the containing makefile, @code{make} should look in another makefile. @xref{Pattern Rules}, for more information on pattern rules. For example, if you have a makefile called @file{Makefile} that says how to make the target @samp{foo} (and other targets), you can write a makefile called @file{GNUmakefile} that contains: @example foo: frobnicate > foo %: force @@$(MAKE) -f Makefile $@@ force: ; @end example If you say @samp{make foo}, @code{make} will find @file{GNUmakefile}, read it, and see that to make @file{foo}, it needs to run the command @samp{frobnicate > foo}. If you say @samp{make bar}, @code{make} will find no way to make @file{bar} in @file{GNUmakefile}, so it will use the commands from the pattern rule: @samp{make -f Makefile bar}. If @file{Makefile} provides a rule for updating @file{bar}, @code{make} will apply the rule. And likewise for any other target that @file{GNUmakefile} does not say how to make. The way this works is that the pattern rule has a pattern of just @samp{%}, so it matches any target whatever. The rule specifies a prerequisite @file{force}, to guarantee that the commands will be run even if the target file already exists. We give @file{force} target empty commands to prevent @code{make} from searching for an implicit rule to build it---otherwise it would apply the same match-anything rule to @file{force} itself and create a prerequisite loop! @node Reading Makefiles, , Overriding Makefiles, Makefiles @section How @code{make} Reads a Makefile @cindex reading makefiles @cindex makefile, parsing GNU @code{make} does its work in two distinct phases. During the first phase it reads all the makefiles, included makefiles, etc. and internalizes all the variables and their values, implicit and explicit rules, and constructs a dependency graph of all the targets and their prerequisites. During the second phase, @code{make} uses these internal structures to determine what targets will need to be rebuilt and to invoke the rules necessary to do so. It's important to understand this two-phase approach because it has a direct impact on how variable and function expansion happens; this is often a source of some confusion when writing makefiles. Here we will present a summary of the phases in which expansion happens for different constructs within the makefile. We say that expansion is @dfn{immediate} if it happens during the first phase: in this case @code{make} will expand any variables or functions in that section of a construct as the makefile is parsed. We say that expansion is @dfn{deferred} if expansion is not performed immediately. Expansion of deferred construct is not performed until either the construct appears later in an immediate context, or untilp<~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1[$o the second phase. You may not be familiar with some of these constructs yet. You can reference this section as you become familiar with them, in later chapters. @subheading Variable Assignment @cindex +=, expansion @cindex =, expansion @cindex ?=, expansion @cindex +=, expansion @cindex define, expansion Variable definitions are parsed as follows: @example @var{immediate} = @var{deferred} @var{immediate} ?= @var{deferred} @var{immediate} := @var{immediate} @var{immediate} += @var{deferred} or @var{immediate} define @var{immediate} @var{deferred} endef @end example For the append operator, @samp{+=}, the right-hand side is considered immediate if the variable was previously set as a simple variable (@samp{:=}), and deferred otherwise. @subheading Conditional Syntax @cindex ifdef, expansion @cindex ifeq, expansion @cindex ifndef, expansion @cindex ifneq, expansion All instances of conditional syntax are parsed immediately, in their entirety; this includes the @code{ifdef}, @code{ifeq}, @code{ifndef}q, and @code{ifneq} forms. @subheading Rule Definition @cindex target, expansion @cindex prerequisite, expansion @cindex implicit rule, expansion @cindex pattern rule, expansion @cindex explicit rule, expansion A rule is always expanded the same way, regardless of the form: @example @var{immediate} : @var{immediate} ; @var{deferred} @var{deferred} @end example That is, the target and prerequisite sections are expanded immediately, and the commands used to construct the target are always deferred. This general rule is true for explicit rules, pattern rules, suffix rules, static pattern rules, and simple prerequisite definitions. @node Rules, Commands, Makefiles, Top @chapter Writing Rules @cindex writing rules @cindex rule, how to write @cindex target @cindex prerequisite A @dfn{rule} appears in the makefile and says when and how to remake certain files, called the rule's @dfn{targets} (most often only one per rule). It lists the other files that are the @dfn{prerequisites} of the target, and @dfn{commands} to use to create or update the target. @cindex default goal @cindex goal, default The order of rules is not significant, except for determining the @dfn{default goal}: the target for @code{make} to consider, if you do not otherwise specify one. The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default. There are two exceptions: a target starting with a period is not a default unless it contains one or more slashes, @samp{/}, as well; and, a target that defines a pattern rule has no effect on the default goal. (@xref{Pattern Rules, ,Defining and Redefining Pattern Rules}.) Therefore, we usually write the makefile so that the first rule is the one for compiling the entire program or all the programs described by the makefile (often with a target called @samp{all}). @xref{Goals, ,Arguments to Specify the Goals}. @menu * Rule Example:: An example explained. * Rule Syntax:: General syntax explained. * Wildcards:: Using wildcard characters such as `*'. * Directory Search:: Searching other directories for source files. * Phony Targets:: Using a target that is not a real file's name. * Force Targets:: You can use a target without commands or prerequisites to mark other targets as phony. * Empty Targets:: When only the date matters and the files are empty. * Special Targets:: Targets with special built-in meanings. * Multiple Targets:: When to make use of several targets in a rule. * Multiple Rules:: How to use several rules with the same target. * Static Pattern:: Static pattern rules apply to multiple targets and can vary the prerequisites according to the target name. * Double-Colon:: How to use a special kind of rule to allow several independent rules for one target. * Automatic Prerequisites:: How to automatically generate rules giving prerequisites from source files themselves. @end menu @ifinfo @node Rule Example, Rule Syntax, , Rules @section Rule Example Here is an example of a rule: @example foo.o : foo.c defs.h # module for twiddling the frobs cc -c -g foo.c @end example Its target is @file{foo.o} and its prerequisites are @file{foo.c} and @file{defs.h}. It has one command, which is @samp{cc -c -g foo.c}. The command line starts with a tab to identify it as a command. This rule says two things: @itemize @bullet @item How to decide whether @file{foo.o} is out of date: it is out of date if it does not exist, or if either @file{foo.c} or @file{defs.h} is more recent than it. @item How to update the file @file{foo.o}: by running @code{cc} as stated. The command does not explicitly mentioyn @file{defs.h}, but we presume that @file{foo.c} includes it, and that that is why @file{defs.h} was added to the prerequisites. @end itemize @end ifinfo @node Rule Syntax, Wildcards, Rule Example, Rules @section Rule Syntax @cindex rule syntax @cindex syntax of rules In general, a rule looks like this: @example @var{targets} : @var{prerequisites} @var{command} @dots{} @end example @noindent or like this: @example @var{targets} : @var{prerequisites} ; @var{command} @var{command} @dots{} @end example @cindex targets @cindex rule targets The @var{targets} are file names, separated by spaces. Wildcard characters may be used (@pxref{Wildcards, ,Using Wildcard Characters in File Names}) and a name of the form @file{@var{a}(@var{m})} represents member @var{m} in archive file @var{a} (@pxref{Archive Members, ,Archive Members as Targets}). Usually there is only one target per rule, but occasionally there is a reason to have more (@pxref{Multiple Targets, , Multiple Targets in a Rule}).@refill @cindex commands @cindex tab character (in commands) The @var{command} lines start with a tab character. The first command may appear on the line after the prerequisites, with a tab character, or may appear on the same line, with a semicolon. Either way, the effect is the same. @xref{Commands, ,Writing the Commands in Rules}. @cindex dollar sign (@code{$}), in rules @cindex @code{$}, in rules @cindex rule, and @code{$} Because dollar signs are used to start variable references, if you really want a dollar sign in a rule you must write two of them, @samp{$$} (@pxref{Using Variables, ,How to Use Variables}). You may split a long line by inserting a backslash followed by a newline, but this is not required, as @code{make} places no limit on the length of a line in a makefile. A rule tells @code{make} two things: when the targets are out of date, and how to update them when necessary. @cindex prerequisites @cindex rule prerequisites The criterion for being out of date is specified in terms of the @var{prerequisites}, which consist of file names separated by spaces. (Wildcards and archive members (@pxref{Archives}) are allowed here too.) A target is out of date if it does not exist or if it is older than any of the prerequisites (by comparison of last-modification times). The idea is that the contents of the target file are computed based on information in the prerequisites, so if any of the prerequisites changes, the contents of the existing target file are no longer necessarily valid. How to update is specified by @var{commands}. These are lines to be executed by the shell (normally @samp{sh}), but with some extra features (@pxref{Commands, ,Writing the Commands in Rules}). @node Wildcards, Directory Search, Rule Syntax, Rules @section Using Wildcard Characters in File Names @cindex wildcard @cindex file name with wildcards @cindex globbing (wildcards) @cindex @code{*} (wildcard character) @cindex @code{?} (wildcard character) @cindex @code{[@dots{}]} (wildcard characters) A single file name can specify many files using @dfn{wildcard characters}. The wildcard characters in @code{make} are @samp{*}, @samp{?} and @samp{[@dots{}]}, the same as in the Bourne shell. For example, @file{*.c} specifies a list of all the files (in the working directory) whose names end in @samp{.c}.@refill @cindex @code{~} (tilde) @cindex tilde (@code{~}) @cindex home directory The character @samp{~} at the beginning of a file name also has special significance. If alone, or followed by a slash, it represents your home directory. For example @file{~/bin} expands to @file{/home/you/bin}. If the @samp{~} is followed by a word, the string represents the home directory of the user named by that word. For example @file{~john/bin} expands to @file{/home/john/bin}. On systems which don't have a home directory for each user (such as MS-DOS or MS-Windows), this functionality can be simulated by setting the environment variable @var{HOME}.@refill Wildcard expansion happens automatically in targets, in prerequisites, and in commands (where the shell does the expansion). In other contexts, wildcard expansion happens only if you request it explicitly with the @code{wildcard} function. The special significance of a wildcard character can be turned off by preceding it with a backslash. Thus, @file{foo\*bar} would refer to a specific file whose name consists of @samp{foo}, an asterisk, and @samp{bar}.@refill @menu * Wildcard Examples:: Several examples * Wildcard Pitfall:: Problems to avoid. * Wildcard Function:: How to cause wildcard expansion where it does not normally take place. @end menu @node Wildcard Examples, Wildcard Pitfall, , Wildcards @subsection Wildcard Examples Wildcards can be used in the commands of a rule, where they are expanded by the shell. For example, here is a rule to delete all the object files: @example @group clean: rm -f *.o @end group @end example @cindex @code{rm} (shell command) Wildcards are also useful in the prerequisites of a rule. With the following rule in the makefile, @samp{make print} will print all the @samp{.c} files that have changed since the last time you printed them: @example print: *.c lpr -p $? touch print @end example @cindex @code{print} target @cindex @code{lpr} (shell command) @cindex @code{touch} (shell command) @noindent This rule uses @file{print} as an empty target file; see @ref{Empty Targets, ,Empty Target Files to Record Events}. (The automatic variable @samp{$?} is used to print only those files that have changed; see @ref{Automatic, ,Automatic Variables}.)@refill Wildcard expansion does not happen when you define a variable. Thus, if you write this: @example objects = *.o @end example @noindent then the value of the variable @code{objects} is the actual string @samp{*.o}. However, if you use the value of @code{objects} in a target, prerequisite or command, wildcard expansion will take place at that time. To set @code{objects} to the expansion, instead use: @example objects := $(wildcard *.o) @end example @noindent @xref{Wildcard Function}. @node Wildcard Pitfall, Wildcard Function, Wildcard Examples, Wildcards @subsection Pitfalls of Using Wildcards @cindex wildcard pitfalls @cindex pitfalls of wildcards @cindex mistakes with wildcards @cindex errors with wildcards @cindex problems with wildcards Now here is an example of a naive way of using wildcard expansion, that does not do what you would intend. Suppose you would like to say that the executable file @file{foo} is made from all the object files in the directory, and you write this: @example objects = *.o foo : $(objects) cc -o foo $(CFLAGS) $(objects) @end example @noindent The value of @code{objects} is the actual string @samp{*.o}. Wildcard expansion happens in the rule for @file{foo}, so that each @emph{existing} @samp{.o} file becomes a prerequisite of @file{foo} and will be recompiled if necessary. But what if you delete all the @samp{.o} files? When a wildcard matches no files, it is left as it is, so then @file{foo} will depend on the oddly-named file @file{*.o}. Since no such file is likely to exist, @code{make} will give you an error saying it cannot figure out how to make @file{*.o}. This is not what you want! Actually it is possible to obtain the desired result with wildcard expansion, but you need more sophisticated techniques, including the @code{wildcard} function and string substitution. @ifinfo @xref{Wildcard Function, ,The Function @code{wildcard}}. @end ifinfo @iftex These are described in the following section. @end iftex @cindex wildcards and MS-DOS/MS-Windows backslashes @cindex backslashes in pathnames and wildcard expansion Microsoft operating systems (MS-DOS and MS-Windows) use backslashes to separate directories in pathnames, like so: @example c:\foo\bar\baz.c @end example This is equivalent to the Unix-style @file{c:/foo/bar/baz.c} (the @file{c:} part is the so-called drive letter). When @code{make} runs on these systems, it supports backslashes as well as the Unix-style forward slashes in pathnames. However, this support does @emph{not} include the wildcard expansion, where backslash is a quote character. Therefore, you @emph{must} use Unix-style slashes in these cases. @node Wildcard Function, , Wildcard Pitfall, Wildcards @subsection The Function @code{wildcard} @findex wildcard Wildcard expansion happens automatically in rules. But wildcard expansion does not normally take place when a variable is set, or inside the arguments of a function. If you want to do wildcard expansion in such places, you need to use the @code{wildcard} function, like this: @example $(wildcard @var{pattern}@dots{}) @end example @noindent This string, used anywhere in a makefile, is replaced by a space-separated list of names of existing files that match one of the given file name patterns. If no existing file name matches a pattern, then that pattern is omitted from the output of the @code{wildcard} function. Note that this is different from how unmatched wildcards behave in rules, where they are used verbatim rather than ignored (@pxref{Wildcard Pitfall}). One use of the @code{wildcard} function is to get a list of all the C source files in a directory, like this: @example $(wildcard *.c) @end example We can change the list of C source files into a list of object files by replacing the @samp{.c} suffix with @samp{.o} in the result, like this: @example $(patsubst %.c,%.o,$(wildcard *.c)) @end example @noindent (Here we have used another function, @code{patsubst}. @xref{Text Functions, ,Functions for String Substitution and Analysis}.)@refill Thus, a makefile to compile all C source files in the directory and then link them together could be written as follows: @example objects := $(patsubst %.c,%.o,$(wildcard *.c)) foo : $(objects) cc -o foo $(objects) @end example @noindent (This takes advantage of the implicit rule for compiling C programs, so there is no need to write explicit rules for compiling the files. @xref{Flavors, ,The Two Flavors of Variables}, for an explanation of @samp{:=}, which is a variant of @samp{=}.) @node Directory Search, Phony Targets, Wildcards, Rules @section Searching Directories for Prerequisites @vindex VPATH @findex vpath @cindex vpath @cindex search path for prerequisites (@code{VPATH}) @cindex directory search (@code{VPATH}) For large systems, it is often desirable to put sources in a separate directory from the binaries. The @dfn{directory search} features of @code{make} facilitate this by searching several directories automatically to find a prerequisite. When you redistribute the files among directories, you do not need to change the individual rules, just the search paths. @menu * General Search:: Specifying a search path that applies to every prerequisite. * Selective Search:: Specifying a search path for a specified class of names. * Search Algorithm:: When and how search paths are applied. * Commands/Search:: How to write shell commands that work together with search paths. * Implicit/Search:: How search paths affect implicit rules. * Libraries/Search:: Directory search for link libraries. @end menu @node General Search, Selective Search, , Directory Search @subsection @code{VPATH}: Search Path for All Prerequisites @vindex VPATH The value of the @code{make} variable @code{VPATH} specifies a list of directories that @code{make} should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, @code{VPATH} specifies a search list that @code{make} applies for all files, including files which are targets of rules. Thus, if a file that is listed as a target or prerequisite does not exist in the current directory, @code{make} searches the directories listed in @code{VPATH} for a file with that name. If a file is found in one of them, that file may become the prerequisite (see below). Rules may then specify the names of files in the prerequisite list as if they all existed in the current directory. @xref{Commands/Search, ,Writing Shell Commands with Directory Search}. In the @code{VPATH} variable, directory names are separated by colons or blanks. The order in which directories are listed is the order followed by @code{make} in its search. (On MS-DOS and MS-Windows, semi-colons are used as separators of directory names in @code{VPATH}, since the colon can be used in the pathname itself, after the drive letter.) For example, @example VPATH = src:../headers @end example @noindent specifies a path containing two directories, @file{src} and @file{../headers}, which @code{make} searches in that order. With this value of @code{VPATH}, the following rule, @example foo.o : foo.c @end example @noindent is interpreted as if it were written like this: @example foo.o : src/foo.c @end example @noindent assuming the file @file{foo.c} does not exist in the current directory but is found in the directory @file{src}. @node Selective Search, Search Algorithm, General Search, Directory Search @subsection The @code{vpath} Directive @findex vpath Similar to the @code{VPATH} variable, but more selective, is the @code{vpath} directive (note lower case), which allows you to specify a search path for a particular class of file names: those that match a particular pattern. Thus you can supply certain search directories for one class of file names and other directories (or none) for other file names. There are three forms of the @code{vpath} directive: @table @code @item vpath @var{pattern} @var{directories} Specify the search path @var{directories} for file names that match @var{pattern}. The search path, @var{directories}, is a list of directories to be searched, separated by colons (semi-colons on MS-DOS and MS-Windows) or blanks, just like the search path used in the @code{VPATH} variable. @item vpath @var{pattern} Clear out the search path associated with @var{pattern}. @c Extra blank line makes sure this gets two lines. @item vpath Clear all search paths previously specified with @code{vpath} directives. @end table A @code{vpath} pattern is a string containing a @samp{%} character. The string must match the file name of a prerequisite that is being searched for, the @samp{%} character matching any sequence of zero or more characters (as in pattern rules; @pxref{Pattern Rules, ,Defining and Redefining Pattern Rules}). For example, @code{%.h} matches files that end in @code{.h}. (If there is no @samp{%}, the pattern must match the prerequisite exactly, which is not useful very often.) @cindex @code{%}, quoting in @code{vpath} @cindex @code{%}, quoting with @code{\} (backslash) @cindex @code{\} (backslash), to quote @code{%} @cindex backslash (@code{\}), to quote @code{%} @cindex quoting @code{%}, in @code{vpath} @samp{%} characters in a @code{vpath} directive's pattern can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. Backslashes that quote @samp{%} characters or other backslashes are removed from the pattern before it is compared to file names. Backslashes that are not in danger of quoting @samp{%} characters go unmolested.@refill When a prerequisite fails to exist in the current directory, if the @var{pattern} in a @code{vpath} directive matches the name of the prerequisite file, then the @var{directories} in that directive are searched just like (and before) the directories in the @code{VPATH} variable. For example, @example vpath %.h ../headers @end example @noindent tells @code{make} to look for any prerequisite whose name ends in @file{.h} in the directory @file{../headers} if the file is not found in the current directory. If several @code{vpath} patterns match the prerequisite file's name, then @code{make} processes each matching @code{vpath} directive one by one, searching all the directories mentioned in each directive. @code{make} handles multiple @code{vpath} directives in the order in which they appear in the makefile; multiple directives with the same pattern are independent of each other. @need 750 Thus, @example @group vpath %.c foo vpath % blish vpath %.c bar @end group @end example @noindent will look for a file ending in @samp{.c} in @file{foo}, then @file{blish}, then @file{bar}, while @example @group vpath %.c foo:bar vpath % blish @end group @end example @noindent will look for a file ending in @samp{.c} in @file{foo}, then @file{bar}, then @file{blish}. @node Search Algorithm, Commands/Search, Selective Search, Directory Search @subsection How Directory Searches are Performed @cindex algorithm for directory search @cindex directory search algorithm When a prerequisite is found through directory search, regardless of type (general or selective), the pathname located may not be the one that @code{make} actually provides you in the prerequisite list. Sometimes the path discovered through directory search is thrown away. The algorithm @code{make} uses to decide whether to keep or abandon a path found via directory search is as follows: @enumerate @item If a target file does not exist at the path specified in the makefile, directory search is performed. @item If the directory search is successful, that path is kept and this file is tentatively stored as the target. @item All prerequisites of this target are examined using this same method. @item After processing the prerequisites, the target may or may not need to be rebuilt: @enumerate a @item If the target does @emph{not} need to be rebuilt, the path to the file found during directory search is used for any prerequisite lists which contain this target. In short, if @code{make} doesn't need to rebuild the target then you use the path found via directory search. @item If the target @emph{does} need to be rebuilt (is out-of-date), the pathname found during directory search is @emph{thrown away}, and the target is rebuilt using the file name specified in the makefile. In short, if @code{make} must rebuild, then the target is rebuilt locally, not in the directory found via directory search. @end enumerate @end enumerate This algorithm may seem complex, but in practice it is quite often exactly what you want. @cindex traditional directory search @cindex directory search, traditional Other versions of @code{make} use a simpler algorithm: if the file does not exist, and it is found via directory search, then that pathname is always used whether or not the target needs to be built. Thus, if the target is rebuilt it is created at the pathname discovered during directory search. @vindex GPATH If, in fact, this is the behavior you want for some or all of your directories, you can use the @code{GPATH} variable to indicate this to @code{make}. @code{GPATH} has the same syntax and format as @code{VPATH} (that is, a space- or colon-delimited list of pathnames). If an out-of-date target is found by directory search in a directory that also appears in @code{GPATH}, then that pathname is not thrown away. The target is rebuilt using the expanded path. @node Commands/Search, Implicit/Search, Search Algorithm, Directory Search @subsection Writing Shell Commands with Directory Search @cindex shell command, and directory search @cindex directory search (@code{VPATH}), and shell commands When a prerequisite is found in another directory through directory search, this cannot change the commands of the rule; they will execute as written. Therefore, you must write the commands with care so that they will look for the prerequisite in the directory where @code{make} finds it. This is done with the @dfn{automatic variables} such as @samp{$^} (@pxref{Automatic, ,Automatic Variables}). For instance, the value of @samp{$^} is a list of all the prerequisites of the rule, including the names of the directories in which they were found, and the value of @samp{$@@} is the target. Thus:@refill @example foo.o : foo.c cc -c $(CFLAGS) $^ -o $@@ @end example @noindent (The variable @code{CFLAGS} exists so you can specify flags for C compilation by implicit rules; we use it here for consistency so it will affect all C compilations uniformly; @pxref{Implicit Variables, ,Variables Used by Implicit Rules}.) Often the prerequisites include header files as well, which you do not want to mention in the commands. The automatic variable @samp{$<} is just the first prerequisite: @example VPATH = src:../headers foo.o : foo.c defs.h hack.h cc -c $(CFLAGS) $< -o $@@ @end example @node Implicit/Search, Libraries/Search, Commands/Search, Directory Search @subsection Directory Search and Implicit Rules @cindex @code{VPATH}, and implicit rules @cindex directory search (@code{VPATH}), and implicit rules @cindex search path for prerequisites (@code{VPATH}), and implicit rules @cindex implicit rule, and directory search @cindex implicit rule, and @code{VPATH} @cindex rule, implicit, and directory search @cindex rule, implicit, and @code{VPATH} The search through the directories specified in @code{VPATH} or with @code{vpath} also happens during consideration of implicit rules (@pxref{Implicit Rules, ,Using Implicit Rules}). For example, when a file @file{foo.o} has no explicit rule, @code{make} considers implicit rules, such as the built-in rule to compile @file{foo.c} if that file exists. If such a file is lacking in the current directory, the appropriate directories are searched for it. If @file{foo.c} exists (or is mentioned in the makefile) in any of the directories, the implicit rule for C compilation is applied. The commands of implicit rules normally use automatic variables as a matter of necessity; consequently they will use the file names found by directory search with no extra effort. @node Libraries/Search, , Implicit/Search, Directory Search @subsection Directory Search for Link Libraries @cindex link libraries, and directory search @cindex libraries for linking, directory search @cindex directory search (@code{VPATH}), and link libraries @cindex @code{VPATH}, and link libraries @cindex search path for prerequisites (@code{VPATH}), and link libraries @cindex @code{-l} (library search) @cindex link libraries, patterns matching @cindex @code{.LIBPATTERNS}, and link libraries @vindex .LIBPATTERNS Directory search applies in a special way to libraries used with the linker. This special feature comes into play when you write a prerequisite whose name is of the form @samp{-l@var{name}}. (You can tell something strange is going on here because the prerequisite is normally the name of a file, and the @emph{file name} of a library generally looks like @file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill When a prerequisite's name has the form @samp{-l@var{name}}, @code{make} handles it specially by searching for the file @file{lib@var{name}.so} in the current directory, in directories specified by matching @code{vpath} search paths and the @code{VPATH} search path, and then in the directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib} (normally @file{/usr/local/lib}, but MS-DOS/MS-Windows versions of @code{make} behave as if @var{prefix} is defined to be the root of the DJGPP installation tree). If that file is not found, then the file @file{lib@var{name}.a} is searched for, in the same directories as above. For example, if there is a @file{/usr/lib/libcurses.a} library on your system (and no @file{/usr/lib/libcurses.so} file), then @example @group foo : foo.c -lcurses cc $^ -o $@@ @end group @end example @noindent would cause the command @samp{cc foo.c /usr/lib/libcurses.a -o foo} to be executed when @file{foo} is older than @file{foo.c} or than @file{/usr/lib/libcurses.a}.@refill Although the default set of files to be searched for is @file{lib@var{name}.so} and @file{lib@var{name}.a}, this is customizable via the @code{.LIBPATTERNS} variable. Each word in the value of this variable is a pattern string. When a prerequisite like @samp{-l@var{name}} is seen, @code{make} will replace the percent in each pattern in the list with @var{name} and perform the above directory searches using that library filename. If no library is found, the next word in the list will be used. The default value for @code{.LIBPATTERNS} is ``@samp{lib%.so lib%.a}'', which provides the default behavior described above. You can turn off link library expansion completely by setting this variable to an empty value. @node Phony Targets, Force Targets, Directory Search, Rules @section Phony Targets @cindex phony targets @cindex targets, phony @cindex targets without a file A phony target is one that is not really the name of a file. It is just a name for some commands to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance. If you write a rule whose commands will not create the target file, the commands will be executed every time the target comes up for remaking. Here is an example: @example @group clean: rm *.o temp @end group @end example @noindent Because the @code{rm} command does not create a file named @file{clean}, probably no such file will ever exist. Therefore, the @code{rm} command will be executed every time you say @samp{make clean}. @cindex @code{rm} (shell command) @findex .PHONY The phony target will cease to work if anything ever does create a file named @file{clean} in this directory. Since it has no prerequisites, the file @file{clean} would inevitably be considered up to date, and its commands would not be executed. To avoid this problem, you can explicitly declare the target to be phony, using the special target @code{.PHONY} (@pxref{Special Targets, ,Special Built-in Target Names}) as follows: @example .PHONY : clean @end example @noindent Once this is done, @samp{make clean} will run the commands regardless of whether there is a file named @file{clean}. Since it knows that phony targets do not name actual files that could be remade from other files, @code{make} skips the implicit rule search for phony targets (@pxref{Implicit Rules}). This is why declaring a target phony is good for performance, even iP=~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1ƽ f you are not worried about the actual file existing. Thus, you first write the line that states that @code{clean} is a phony target, then you write the rule, like this: @example @group .PHONY: clean clean: rm *.o temp @end group @end example Another example of the usefulness of phony targets is in conjunction with recursive invocations of @code{make}. In this case the makefile will often contain a variable which lists a number of subdirectories to be built. One way to handle this is with one rule whose command is a shell loop over the subdirectories, like this: @example @group SUBDIRS = foo bar baz subdirs: for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir; \ done @end group @end example There are a few of problems with this method, however. First, any error detected in a submake is not noted by this rule, so it will continue to build the rest of the directories even when one fails. This can be overcome by adding shell commands to note the error and exit, but then it will do so even if @code{make} is invoked with the @code{-k} option, which is unfortunate. Second, and perhaps more importantly, you cannot take advantage of the parallel build capabilities of make using this method, since there is only one rule. By declaring the subdirectories as phony targets (you must do this as the subdirectory obviously always exists; otherwise it won't be built) you can remove these problems: @example @group SUBDIRS = foo bar baz .PHONY: subdirs $(SUBDIRS) subdirs: $(SUBDIRS) $(SUBDIRS): $(MAKE) -C $@ foo: baz @end group @end example Here we've also declared that the @file{foo} subdirectory cannot be built until after the @file{baz} subdirectory is complete; this kind of relationship declaration is particularly important when attempting parallel builds. A phony target should not be a prerequisite of a real target file; if it is, its commands are run every time @code{make} goes to update that file. As long as a phony target is never a prerequisite of a real target, the phony target commands will be executed only when the phony target is a specified goal (@pxref{Goals, ,Arguments to Specify the Goals}). Phony targets can have prerequisites. When one directory contains multiple programs, it is most convenient to describe all of the programs in one makefile @file{./Makefile}. Since the target remade by default will be the first one in the makefile, it is common to make this a phony target named @samp{all} and give it, as prerequisites, all the individual programs. For example: @example all : prog1 prog2 prog3 .PHONY : all prog1 : prog1.o utils.o cc -o prog1 prog1.o utils.o prog2 : prog2.o cc -o prog2 prog2.o prog3 : prog3.o sort.o utils.o cc -o prog3 prog3.o sort.o utils.o @end example @noindent Now you can say just @samp{make} to remake all three programs, or specify as arguments the ones to remake (as in @samp{make prog1 prog3}). When one phony target is a prerequisite of another, it serves as a subroutine of the other. For example, here @samp{make cleanall} will delete the object files, the difference files, and the file @file{program}: @example .PHONY: cleanall cleanobj cleandiff cleanall : cleanobj cleandiff rm program cleanobj : rm *.o cleandiff : rm *.diff @end example @node Force Targets, Empty Targets, Phony Targets, Rules @section Rules without Commands or Prerequisites @cindex force targets @cindex targets, force @cindex @code{FORCE} @cindex rule, no commands or prerequisites If a rule has no prerequisites or commands, and the target of the rule is a nonexistent file, then @code{make} imagines this target to have been updated whenever its rule is run. This implies that all targets depending on this one will always have their commands run. An example will illustrate this: @example @group clean: FORCE rm $(objects) FORCE: @end group @end example Here the target @samp{FORCE} satisfies the special conditions, so the target @file{clean} that depends on it is forced to run its commands. There is nothing special about the name @samp{FORCE}, but that is one name commonly used this way. As you can see, using @samp{FORCE} this way has the same results as using @samp{.PHONY: clean}. Using @samp{.PHONY} is more explicit and more efficient. However, other versions of @code{make} do not support @samp{.PHONY}; thus @samp{FORCE} appears in many makefiles. @xref{Phony Targets}. @node Empty Targets, Special Targets, Force Targets, Rules @section Empty Target Files to Record Events @cindex empty targets @cindex targets, empty @cindex recording events with empty targets The @dfn{empty target} is a variant of the phony target; it is used to hold commands for an action that you request explicitly from time to time. Unlike a phony target, this target file can really exist; but the file's contents do not matter, and usually are empty. The purpose of the empty target file is to record, with its last-modification time, when the rule's commands were last executed. It does so because one of the commands is a @code{touch} command to update the target file. The empty target file should have some prerequisites (otherwise it doesn't make sense). When you ask to remake the empty target, the commands are executed if any prerequisite is more recent than the target; in other words, if a prerequisite has changed since the last time you remade the target. Here is an example: @example print: foo.c bar.c lpr -p $? touch print @end example @cindex @code{print} target @cindex @code{lpr} (shell command) @cindex @code{touch} (shell command) @noindent With this rule, @samp{make print} will execute the @code{lpr} command if either source file has changed since the last @samp{make print}. The automatic variable @samp{$?} is used to print only those files that have changed (@pxref{Automatic, ,Automatic Variables}). @node Special Targets, Multiple Targets, Empty Targets, Rules @section Special Built-in Target Names @cindex special targets @cindex built-in special targets @cindex targets, built-in special Certain names have special meanings if they appear as targets. @table @code @findex .PHONY @item .PHONY The prerequisites of the special target @code{.PHONY} are considered to be phony targets. When it is time to consider such a target, @code{make} will run its commands unconditionally, regardless of whether a file with that name exists or what its last-modification time is. @xref{Phony Targets, ,Phony Targets}. @findex .SUFFIXES @item .SUFFIXES The prerequisites of the special target @code{.SUFFIXES} are the list of suffixes to be used in checking for suffix rules. @xref{Suffix Rules, , Old-Fashioned Suffix Rules}. @findex .DEFAULT @item .DEFAULT The commands specified for @code{.DEFAULT} are used for any target for which no rules are found (either explicit rules or implicit rules). @xref{Last Resort}. If @code{.DEFAULT} commands are specified, every file mentioned as a prerequisite, but not as a target in a rule, will have these commands executed on its behalf. @xref{Implicit Rule Search, ,Implicit Rule Search Algorithm}. @findex .PRECIOUS @item .PRECIOUS @cindex precious targets @cindex preserving with @code{.PRECIOUS} The targets which @code{.PRECIOUS} depends on are given the following special treatment: if @code{make} is killed or interrupted during the execution of their commands, the target is not deleted. @xref{Interrupts, ,Interrupting or Killing @code{make}}. Also, if the target is an intermediate file, it will not be deleted after it is no longer needed, as is normally done. @xref{Chained Rules, ,Chains of Implicit Rules}. You can also list the target pattern of an implicit rule (such as @samp{%.o}) as a prerequisite file of the special target @code{.PRECIOUS} to preserve intermediate files created by rules whose target patterns match that file's name. @findex .INTERMEDIATE @item .INTERMEDIATE @cindex intermediate targets, explicit The targets which @code{.INTERMEDIATE} depends on are treated as intermediate files. @xref{Chained Rules, ,Chains of Implicit Rules}. @code{.INTERMEDIATE} with no prerequisites has no effect. @findex .SECONDARY @item .SECONDARY @cindex secondary targets @cindex preserving with @code{.SECONDARY} The targets which @code{.SECONDARY} depends on are treated as intermediate files, except that they are never automatically deleted. @xref{Chained Rules, ,Chains of Implicit Rules}. @code{.SECONDARY} with no prerequisites marks all file targets mentioned in the makefile as secondary. @findex .DELETE_ON_ERROR @item .DELETE_ON_ERROR @cindex removing targets on failure If @code{.DELETE_ON_ERROR} is mentioned as a target anywhere in the makefile, then @code{make} will delete the target of a rule if it has changed and its commands exit with a nonzero exit status, just as it does when it receives a signal. @xref{Errors, ,Errors in Commands}. @findex .IGNORE @item .IGNORE If you specify prerequisites for @code{.IGNORE}, then @code{make} will ignore errors in execution of the commands run for those particular files. The commands for @code{.IGNORE} are not meaningful. If mentioned as a target with no prerequisites, @code{.IGNORE} says to ignore errors in execution of commands for all files. This usage of @samp{.IGNORE} is supported only for historical compatibility. Since this affects every command in the makefile, it is not very useful; we recommend you use the more selective ways to ignore errors in specific commands. @xref{Errors, ,Errors in Commands}. @findex .SILENT @item .SILENT If you specify prerequisites for @code{.SILENT}, then @code{make} will not print the commands to remake those particular files before executing them. The commands for @code{.SILENT} are not meaningful. If mentioned as a target with no prerequisites, @code{.SILENT} says not to print any commands before executing them. This usage of @samp{.SILENT} is supported only for historical compatibility. We recommend you use the more selective ways to silence specific commands. @xref{Echoing, ,Command Echoing}. If you want to silence all commands for a particular run of @code{make}, use the @samp{-s} or @w{@samp{8--silent}} option (@pxref{Options Summary}). @findex .EXPORT_ALL_VARIABLES @item .EXPORT_ALL_VARIABLES Simply by being mentioned as a target, this tells @code{make} to export all variables to child processes by default. @xref{Variables/Recursion, ,Communicating Variables to a Sub-@code{make}}. @end table Any defined implicit rule suffix also counts as a special target if it appears as a target, and so does the concatenation of two suffixes, such as @samp{.c.o}. These targets are suffix rules, an obsolete way of defining implicit rules (but a way still widely used). In principle, any target name could be special in this way if you break it in two and add both pieces to the suffix list. In practice, suffixes normally begin with @samp{.}, so these special target names also begin with @samp{.}. @xref{Suffix Rules, ,Old-Fashioned Suffix Rules}. @node Multiple Targets, Multiple Rules, Special Targets, Rules @section Multiple Targets in a Rule @cindex multiple targets @cindex several targets in a rule @cindex targets, multiple @cindex rule, with multiple targets A rule with multiple targets is equivalent to writing many rules, each with one target, and all identical aside from that. The same commands apply to all the targets, but their effects may vary because you can substitute the actual target name into the command using @samp{$@@}. The rule contributes the same prerequisites to all the targets also. This is useful in two cases. @itemize @bullet @item You want just prerequisites, no commands. For example: @example kbd.o command.o files.o: command.h @end example @noindent gives an additional prerequisite to each of the three object files mentioned. @item Similar commands work for all the targets. The commands do not need to be absolutely identical, since the automatic variable @samp{$@@} can be used to substitute the particular target to be remade into the commands (@pxref{Automatic, ,Automatic Variables}). For example: @example @group bigoutput littleoutput : text.g generate text.g -$(subst output,,$@@) > $@@ @end group @end example @findex subst @noindent is equivalent to @example bigoutput : text.g generate text.g -big > bigoutput littleoutput : text.g generate text.g -little > littleoutput @end example @noindent Here we assume the hypothetical program @code{generate} makes two types of output, one if given @samp{-big} and one if given @samp{-little}. @xref{Text Functions, ,Functions for String Substitution and Analysis}, for an explanation of the @code{subst} function. @end itemize Suppose you would like to vary the prerequisites according to the target, much as the variable @samp{$@@} allows you to vary the commands. You cannot do this with multiple targets in an ordinary rule, but you can do it with a @dfn{static pattern rule}. @xref{Static Pattern, ,Static Pattern Rules}. @node Multiple Rules, Static Pattern, Multiple Targets, Rules @section Multiple Rules for One Target @cindex multiple rules for one target @cindex several rules for one target @cindex rule, multiple for one target @cindex target, multiple rules for one One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target. If the target is older than any prerequisite from any rule, the commands are executed. There can only be one set of commands to be executed for a file. If more than one rule gives commands for the same file, @code{make} uses the last set given and prints an error message. (As a special case, if the file's name begins with a dot, no error message is printed. This odd behavior is only for compatibility with other implementations of @code{make}.) There is no reason to write your makefiles this way; that is why @code{make} gives you an error message.@refill An extra rule with just prerequisites can be used to give a few extra prerequisites to many files at once. For example, one usually has a variable named @code{objects} containing a list of all the compiler output files in the system being made. An easy way to say that all of them must be recompiled if @file{config.h} changes is to write the following: @example objects = foo.o bar.o foo.o : defs.h bar.o : defs.h test.h $(objects) : config.h @end example This could be inserted or taken out without changing the rules that really specify how to make the object files, making it a convenient form to use if you wish to add the additional prerequisite intermittently. Another wrinkle is that the additional prerequisites could be specified with a variable that you set with a command argument to @code{make} (@pxref{Overriding, ,Overriding Variables}). For example, @example @group extradeps= $(objects) : $(extradeps) @end group @end example @noindent means that the command @samp{make extradeps=foo.h} will consider @file{foo.h} as a prerequisite of each object file, but plain @samp{make} will not. If none of the explicit rules for a target has commands, then @code{make} searches for an applicable implicit rule to find some commands @pxref{Implicit Rules, ,Using Implicit Rules}). @node Static Pattern, Double-Colon, Multiple Rules, Rules @section Static Pattern Rules @cindex static pattern rule @cindex rule, static pattern @cindex pattern rules, static (not implicit) @cindex varying prerequisites @cindex prerequisites, varying (static pattern) @dfn{Static pattern rules} are rules which specify multiple targets and construct the prerequisite names for each target based on the target name. They are more general than ordinary rules with multiple targets because the targets do not have to have identical prerequisites. Their prerequisites must be @emph{analogous}, but not necessarily @emph{identical}. @menu * Static Usage:: The syntax of static pattern rules. * Static versus Implicit:: When are they better than implicit rules? @end menu @node Static Usage, Static versus Implicit, , Static Pattern @subsection Syntax of Static Pattern Rules @cindex static pattern rule, syntax of @cindex pattern rules, static, syntax of Here is the syntax of a static pattern rule: @example @var{targets} @dots{}: @var{target-pattern}: @var{dep-patterns} @dots{} @var{commands} @dots{} @end example @noindent The @var{targets} list specifies the targets that the rule applies to. The targets can contain wildcard characters, just like the targets of ordinary rules (@pxref{Wildcards, ,Using Wildcard Characters in File Names}). @cindex target pattern, static (not implicit) @cindex stem The @var{target-pattern} and @var{dep-patterns} say how to compute the prerequisites of each target. Each target is matched against the @var{target-pattern} to extract a part of the target name, called the @dfn{stem}. This stem is substituted into each of the @var{dep-patterns} to make the prerequisite names (one from each @var{dep-pattern}). Each pattern normally contains the character @samp{%} just once. When the @var{target-pattern} matches a target, the @samp{%} can match any part of the target name; this part is called the @dfn{stem}. The rest of the pattern must match exactly. For example, the target @file{foo.o} matches the pattern @samp{%.o}, with @samp{foo} as the stem. The targets @file{foo.c} and @file{foo.out} do not match that pattern.@refill @cindex prerequisite pattern, static (not implicit) The prerequisite names for each target are made by substituting the stem for the @samp{%} in each prerequisite pattern. For example, if one prerequisite pattern is @file{%.c}, then substitution of the stem @samp{foo} gives the prerequisite name @file{foo.c}. It is legitimate to write a prerequisite pattern that does not contain @samp{%}; then this prerequisite is the same for all targets. @cindex @code{%}, quoting in static pattern @cindex @code{%}, quoting with @code{\} (backslash) @cindex @code{\} (backslash), to quote @code{%} @cindex backslash (@code{\}), to quote @code{%} @cindex quoting @code{%}, in static pattern @samp{%} characters in pattern rules can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. Backslashes that quote @samp{%} characters or other backslashes are removed from the pattern before it is compared to file names or has a stem substituted into it. Backslashes that are not in danger of quoting @samp{%} characters go unmolested. For example, the pattern @file{the\%weird\\%pattern\\} has @samp{the%weird\} preceding the operative @samp{%} character, and @samp{pattern\\} following it. The final two backslashes are left alone because they cannot affect any @samp{%} character.@refill Here is an example, which compiles each of @file{foo.o} and @file{bar.o} from the corresponding @file{.c} file: @example @group objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@@ @end group @end example @noindent Here @samp{$<} is the automatic variable that holds the name of the prerequisite and @samp{$@@} is the automatic variable that holds the name of the target; see @ref{Automatic, , Automatic Variables}. Each target specified must match the target pattern; a warning is issued for each target that does not. If you have a list of files, only some of which will match the pattern, you can use the @code{filter} function to remove nonmatching file names (@pxref{Text Functions, ,Functions for String Substitution and Analysis}): @example files = foo.elc bar.o lose.o $(filter %.o,$(files)): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@@ $(filter %.elc,$(files)): %.elc: %.el emacs -f batch-byte-compile $< @end example @noindent In this example the result of @samp{$(filter %.o,$(files))} is @file{bar.o lose.o}, and the first static pattern rule causes each of these object files to be updated by compiling the corresponding C source file. The result of @w{@samp{$(filter %.elc,$(files))}} is @file{foo.elc}, so that file is made from @file{foo.el}.@refill Another example shows how to use @code{$*} in static pattern rules: @vindex $*@r{, and static pattern} @example @group bigoutput littleoutput : %output : text.g generate text.g -$* > $@@ @end group @end example @noindent When the @code{generate} command is run, @code{$*} will expand to the stem, either @samp{big} or @samp{little}. @node Static versus Implicit, , Static Usage, Static Pattern @subsection Static Pattern Rules versus Implicit Rules @cindex rule, static pattern versus implicit @cindex static pattern rule, versus implicit A static pattern rule has much in common with an implicit rule defined as a pattern rule (@pxref{Pattern Rules, ,Defining and Redefining Pattern Rules}). Both have a pattern for the target and patterns for constructing the names of prerequisites. The difference is in how @code{make} decides @emph{when} the rule applies. An implicit rule @emph{can} apply to any target that matches its pattern, but it @emph{does} apply only when the target has no commands otherwise specified, and only when the prerequisites can be found. If more than one implicit rule appears applicable, only one applies; the choice depends on the order of rules. By contrast, a static pattern rule applies to the precise list of targets that you specify in the rule. It cannot apply to any other target and it invariably does apply to each of the targets specified. If two conflicting rules apply, and both have commands, that's an error. The static pattern rule can be better than an implicit rule for these reasons: @itemize @bullet @item You may wish to override the usual implicit rule for a few files whose names cannot be categorized syntactically but can be given in an explicit list. @item If you cannot be sure of the precise contents of the directories you are using, you may not be sure which other irrelevant files might lead @code{make} to use the wrong implicit rule. The choice might depend on the order in which the implicit rule search is done. With static pattern rules, there is no uncertainty: each rule applies to precisely the targets specified. @end itemize @node Double-Colon, Automatic Prerequisites, Static Pattern, Rules @section Double-Colon Rules @cindex double-colon rules @cindex rule, double-colon (@code{::}) @cindex multiple rules for one target (@code{::}) @cindex @code{::} rules (double-colon) @dfn{Double-colon} rules are rules written with @samp{::} instead of @samp{:} after the target names. They are handled differently from ordinary rules when the same target appears in more than one rule. When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule's commands are executed if the target is older than any prerequisites of that rule. This can result in executing none, any, or all of the double-colon rules. Double-colon rules with the same target are in fact completely separate from one another. Each double-colon rule is processed individually, just as rules with different targets are processed. The double-colon rules for a target are executed in the order they appear in the makefile. However, the cases where double-colon rules really make sense are those where the order of executing the commands would not matter. Double-colon rules are somewhat obscure and not often very useful; they provide a mechanism for cases in which the method used to update a target differs depending on which prerequisite files caused the update, and such cases are rare. Each double-colon rule should specify commands; if it does not, an implicit rule will be used if one applies. @xref{Implicit Rules, ,Using Implicit Rules}. @node Automatic Prerequisites, , Double-Colon, Rules @section Generating Prerequisites Automatically @cindex prerequisites, automatic generation @cindex automatic generation of prerequisites @cindex generating prerequisites automatically In the makefile for a program, many of the rules you need to write often say only that some object file depends on some header file. For example, if @file{main.c} uses @file{defs.h} via an @code{#include}, you would write: @example main.o: defs.h @end example @noindent You need this rule so that @code{make} knows that it must remake @file{main.o} whenever @file{defs.h} changes. You can see that for a large program you would have to write dozens of such rules in your makefile. And, you must always be very careful to update the makefile every time you add or remove an @code{#include}. @cindex @code{#include} @cindex @code{-M} (to compiler) To avoid this hassle, most modern C compilers can write these rules for you, by looking at the @code{#include} lines in the source files. Usually this is done with the @samp{-M} option to the compiler. For example, the command: @example cc -M main.c @end example @noindent generates the output: @example main.o : main.c defs.h @end example @noindent Thus you no longer have to write all those rules yourself. The compiler will do it for you. Note that such a prerequisite constitutes mentioning @file{main.o} in a makefile, so it can never be considered an intermediate file by implicit rule search. This means that @code{make} won't ever remove the file after using it; @pxref{Chained Rules, ,Chains of Implicit Rules}. @cindex @code{make depend} With old @code{make} programs, it was traditional practice to use this compiler feature to generate prerequisites on demand with a command like @samp{make depend}. That command would create a file @file{depend} containing all the automatically-generated prerequisites; then the makefile could use @code{include} to read them in (@pxref{Include}). In GNU @code{make}, the feature of remaking makefiles makes this practice obsolete---you need never tell @code{make} explicitly to regenerate the prerequisites, because it always regenerates any makefile that is out of date. @xref{Remaking Makefiles}. The practice we recommend for automatic prerequisite generation is to have one makefile corresponding to each source file. For each source file @file{@var{name}.c} there is a makefile @file{@var{name}.d} which lists what files the object file @file{@var{name}.o} depends on. That way only the source files that have changed need to be rescanned to produce the new prerequisites. Here is the pattern rule to generate a file of prerequisites (i.e., a makefile) called @file{@var{name}.d} from a C source file called @file{@var{name}.c}: @smallexample @group %.d: %.c set -e; $(CC) -M $(CPPFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@@ : /g' > $@@; \ [ -s $@@ ] || rm -f $@@ @end group @end smallexample @noindent @xref{Pattern Rules}, for information on defining pattern rules. The @samp{-e} flag to the shell makes it exit immediately if the @code{$(CC)} command fails (exits with a nonzero status). Normally the shell exits with the status of the last command in the pipeline (@code{sed} in this case), so @code{make} would not notice a nonzero status from the compiler. @cindex @code{-e} (shell flag) @cindex @code{-MM} (to GNU compiler) With the GNU C compiler, you may wish to use the @samp{-MM} flag instead of @samp{-M}. This omits prerequisites on system header files. @xref{Preprocessor Options, , Options Controlling the Preprocessor, gcc.info, Using GNU CC}, for details. @cindex @code{sed} (shell command) The purpose of the @code{sed} command is to translate (for example): @example main.o : main.c defs.h @end example @noindent into: @example main.o main.d : main.c defs.h @end example @noindent @cindex @code{.d} This makes each @samp{.d} file depend on all the source and header files that the corresponding @samp{.o} file depends on. @code{make} then knows it must regenerate the prerequisites whenever any of the source or header files changes. Once you've defined the rule to remake the @samp{.d} files, you then use the @code{include} directive to read them all in. @xref{Include}. For example: @example @group sources = foo.c bar.c include $(sources:.c=.d) @end group @end example @noindent (This example uses a substitution variable reference to translate the list of source files @samp{foo.c bar.c} into a list of prerequisite makefiles, @samp{foo.d bar.d}. @xref{Substitution Refs}, for full information on substitution references.) Since the @samp{.d} files are makefiles like any others, @code{make} will remake them as necessary with no further work from you. @xref{Remaking Makefiles}. @node Commands, Using Variables, Rules, Top @chapter Writing the Commands in Rules @cindex commands, how to write @cindex rule commands @cindex writing rule commands The commands of a rule consist of shell command lines to be executed one by one. Each command line must start with a tab, except that the first command line may be attached to the target-and-prerequisites line with a semicolon in between. Blank lines and lines of just comments may appear among the command lines; they are ignored. (But beware, an apparently ``blank'' line that begins with a tab is @emph{not} blank! It is an empty command; @pxref{Empty Commands}.) Users use many different shell programs, but commands in makefiles are always interpreted by @file{/bin/sh} unless the makefile specifies otherwise. @xref{Execution, ,Command Execution}. @cindex comments, in commands @cindex commands, comments in @cindex @code{#} (comments), in commands The shell that is in use determines whether comments can be written on command lines, and what syntax they use. When the shell is @file{/bin/sh}, a @samp{#} starts a comment that extends to the end of the line. The @samp{#} does not have to be at the beginning of a line. Text on a line before a @samp{#} is not part of the comment. @menu * Echoing:: How to control when commands are echoed. * Execution:: How commands are executed. * Parallel:: How commands can be executed in parallel. * Errors:: What happens after a command execution error. * Interrupts:: What happens when a command is interrupted. * Recursion:: Invoking @code{make} from makefiles. * Sequences:: Defining canned sequences of commands. * Empty Commands:: Defining useful, do-nothing commands. @end menu @node Echoing, Execution, , Commands @section Command Echoing @cindex echoing of commands @cindex silent operation @cindex @code{@@} (in commands) @cindex commands, echoing @cindex printing of commands Normally @code{make} prints each command line before it is executed. We call this @dfn{echoing} because it gives the appearance that you are typing the commands yourself. When a line starts with @samp{@@}, the echoing of that line is suppressed. The @samp{@@} is discarded before the command is passed to the shell. Typically you would use this for a command whose only effect is to print something, such as an @code{echo} command to indicate progress through the makefile: @example @@echo About to make distribution files @end example @cindex @code{-n} @cindex @code{--just-print} @cindex @code{--dry-run} @cindex @code{--recon} When @code{make} is given the flag @samp{-n} or @samp{--just-print} it only echoes commands, it won't execute them. @xref{Options Summary, ,Summary of Options}. In this >~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1bW|case and only this case, even the commands starting with @samp{@@} are printed. This flag is useful for finding out which commands @code{make} thinks are necessary without actually doing them. @cindex @code{-s} @cindex @code{--silent} @cindex @code{--quiet} @findex .SILENT The @samp{-s} or @samp{--silent} flag to @code{make} prevents all echoing, as if all commands started with @samp{@@}. A rule in the makefile for the special target @code{.SILENT} without prerequisites has the same effect (@pxref{Special Targets, ,Special Built-in Target Names}). @code{.SILENT} is essentially obsolete since @samp{@@} is more flexible.@refill @node Execution, Parallel, Echoing, Commands @section Command Execution @cindex commands, execution @cindex execution, of commands @cindex shell command, execution @vindex SHELL @r{(command execution)} When it is time to execute commands to update a target, they are executed by making a new subshell for each line. (In practice, @code{make} may take shortcuts that do not affect the results.) @cindex @code{cd} (shell command) @strong{Please note:} this implies that shell commands such as @code{cd} that set variables local to each process will not affect the following command lines. @footnote{On MS-DOS, the value of current working directory is @strong{global}, so changing it @emph{will} affect the following command lines on those systems.} If you want to use @code{cd} to affect the next command, put the two on a single line with a semicolon between them. Then @code{make} will consider them a single command and pass them, together, to a shell which will execute them in sequence. For example: @example foo : bar/lose cd bar; gobble lose > ../foo @end example @cindex commands, backslash (@code{\}) in @cindex commands, quoting newlines in @cindex backslash (@code{\}), in commands @cindex @code{\} (backslash), in commands @cindex quoting newline, in commands @cindex newline, quoting, in commands If you would like to split a single shell command into multiple lines of text, you must use a backslash at the end of all but the last subline. Such a sequence of lines is combined into a single line, by deleting the backslash-newline sequences, before passing it to the shell. Thus, the following is equivalent to the preceding example: @example @group foo : bar/lose cd bar; \ gobble lose > ../foo @end group @end example @vindex SHELL The program used as the shell is taken from the variable @code{SHELL}. By default, the program @file{/bin/sh} is used. @vindex COMSPEC On MS-DOS, if @code{SHELL} is not set, the value of the variable @code{COMSPEC} (which is always set) is used instead. @cindex @code{SHELL}, MS-DOS specifics The processing of lines that set the variable @code{SHELL} in Makefiles is different on MS-DOS. The stock shell, @file{command.com}, is ridiculously limited in its functionality and many users of @code{make} tend to install a replacement shell. Therefore, on MS-DOS, @code{make} examines the value of @code{SHELL}, and changes its behavior based on whether it points to a Unix-style or DOS-style shell. This allows reasonable functionality even if @code{SHELL} points to @file{command.com}. If @code{SHELL} points to a Unix-style shell, @code{make} on MS-DOS additionally checks whether that shell can indeed be found; if not, it ignores the line that sets @code{SHELL}. In MS-DOS, GNU @code{make} searches for the shell in the following places: @enumerate @item In the precise place pointed to by the value of @code{SHELL}. For example, if the makefile specifies @samp{SHELL = /bin/sh}, @code{make} will look in the directory @file{/bin} on the current drive. @item In the current directory. @item In each of the directories in the @code{PATH} variable, in order. @end enumerate In every directory it examines, @code{make} will first look for the specific file (@file{sh} in the example above). If this is not found, it will also look in that directory for that file with one of the known extensions which identify executable files. For example @file{.exe}, @file{.com}, @file{.bat}, @file{.btm}, @file{.sh}, and some others. If any of these attempts is successful, the value of @code{SHELL} will be set to the full pathname of the shell as found. However, if none of these is found, the value of @code{SHELL} will not be changed, and thus the line that sets it will be effectively ignored. This is so @code{make} will only support features specific to a Unix-style shell if such a shell is actually installed on the system where @code{make} runs. Note that this extended search for the shell is limited to the cases where @code{SHELL} is set from the Makefile; if it is set in the environment or command line, you are expected to set it to the full pathname of the shell, exactly as things are on Unix. The effect of the above DOS-specific processing is that a Makefile that says @samp{SHELL = /bin/sh} (as many Unix makefiles do), will work on MS-DOS unaltered if you have e.g. @file{sh.exe} installed in some directory along your @code{PATH}. @cindex environment, @code{SHELL} in Unlike most variables, the variable @code{SHELL} is never set from the environment. This is because the @code{SHELL} environment variable is used to specify your personal choice of shell program for interactive use. It would be very bad for personal choices like this to affect the functioning of makefiles. @xref{Environment, ,Variables from the Environment}. However, on MS-DOS and MS-Windows the value of @code{SHELL} in the environment @strong{is} used, since on those systems most users do not set this variable, and therefore it is most likely set specifically to be used by @code{make}. On MS-DOS, if the setting of @code{SHELL} is not suitable for @code{make}, you can set the variable @code{MAKESHELL} to the shell that @code{make} should use; this will override the value of @code{SHELL}. @node Parallel, Errors, Execution, Commands @section Parallel Execution @cindex commands, execution in parallel @cindex parallel execution @cindex execution, in parallel @cindex job slots @cindex @code{-j} @cindex @code{--jobs} GNU @code{make} knows how to execute several commands at once. Normally, @code{make} will execute only one command at a time, waiting for it to finish before executing the next. However, the @samp{-j} or @samp{--jobs} option tells @code{make} to execute many commands simultaneously.@refill On MS-DOS, the @samp{-j} option has no effect, since that system doesn't support multi-processing. If the @samp{-j} option is followed by an integer, this is the number of commands to execute at once; this is called the number of @dfn{job slots}. If there is nothing looking like an integer after the @samp{-j} option, there is no limit on the number of job slots. The default number of job slots is one, which means serial execution (one thing at a time). One unpleasant consequence of running several commands simultaneously is that output generated by the commands appears whenever each command sends it, so messages from different commands may be interspersed. Another problem is that two processes cannot both take input from the same device; so to make sure that only one command tries to take input from the terminal at once, @code{make} will invalidate the standard input streams of all but one running command. This means that attempting to read from standard input will usually be a fatal error (a @samp{Broken pipe} signal) for most child processes if there are several. @cindex broken pipe @cindex standard input It is unpredictable which command will have a valid standard input stream (which will come from the terminal, or wherever you redirect the standard input of @code{make}). The first command run will always get it first, and the first command started after that one finishes will get it next, and so on. We will change how this aspect of @code{make} works if we find a better alternative. In the mean time, you should not rely on any command using standard input at all if you are using the parallel execution feature; but if you are not using this feature, then standard input works normally in all commands. Finally, handling recursive @code{make} invocations raises issues. For more information on this, see @ref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}. If a command fails (is killed by a signal or exits with a nonzero status), and errors are not ignored for that command (@pxref{Errors, ,Errors in Commands}), the remaining command lines to remake the same target will not be run. If a command fails and the @samp{-k} or @samp{--keep-going} option was not given (@pxref{Options Summary, ,Summary of Options}), @code{make} aborts execution. If make terminates for any reason (including a signal) with child processes running, it waits for them to finish before actually exiting.@refill @cindex load average @cindex limiting jobs based on load @cindex jobs, limiting based on load @cindex @code{-l} (load average) @cindex @code{--max-load} @cindex @code{--load-average} When the system is heavily loaded, you will probably want to run fewer jobs than when it is lightly loaded. You can use the @samp{-l} option to tell @code{make} to limit the number of jobs to run at once, based on the load average. The @samp{-l} or @samp{--max-load} option is followed by a floating-point number. For example, @example -l 2.5 @end example @noindent will not let @code{make} start more than one job if the load average is above 2.5. The @samp{-l} option with no following number removes the load limit, if one was given with a previous @samp{-l} option.@refill More precisely, when @code{make} goes to start up a job, and it already has at least one job running, it checks the current load average; if it is not lower than the limit given with @samp{-l}, @code{make} waits until the load average goes below that limit, or until all the other jobs finish. By default, there is no load limit. @node Errors, Interrupts, Parallel, Commands @section Errors in Commands @cindex errors (in commands) @cindex commands, errors in @cindex exit status (errors) After each shell command returns, @code{make} looks at its exit status. If the command completed successfully, the next command line is executed in a new shell; after the last command line is finished, the rule is finished. If there is an error (the exit status is nonzero), @code{make} gives up on the current rule, and perhaps on all rules. Sometimes the failure of a certain command does not indicate a problem. For example, you may use the @code{mkdir} command to ensure that a directory exists. If the directory already exists, @code{mkdir} will report an error, but you probably want @code{make} to continue regardless. @cindex @code{-} (in commands) To ignore errors in a command line, write a @samp{-} at the beginning of the line's text (after the initial tab). The @samp{-} is discarded before the command is passed to the shell for execution. For example, @example @group clean: -rm -f *.o @end group @end example @cindex @code{rm} (shell command) @noindent This causes @code{rm} to continue even if it is unable to remove a file. @cindex @code{-i} @cindex @code{--ignore-errors} @findex .IGNORE When you run @code{make} with the @samp{-i} or @samp{--ignore-errors} flag, errors are ignored in all commands of all rules. A rule in the makefile for the special target @code{.IGNORE} has the same effect, if there are no prerequisites. These ways of ignoring errors are obsolete because @samp{-} is more flexible. When errors are to be ignored, because of either a @samp{-} or the @samp{-i} flag, @code{make} treats an error return just like success, except that it prints out a message that tells you the status code the command exited with, and says that the error has been ignored. When an error happens that @code{make} has not been told to ignore, it implies that the current target cannot be correctly remade, and neither can any other that depends on it either directly or indirectly. No further commands will be executed for these targets, since their preconditions have not been achieved. @cindex @code{-k} @cindex @code{--keep-going} Normally @code{make} gives up immediately in this circumstance, returning a nonzero status. However, if the @samp{-k} or @samp{--keep-going} flag is specified, @code{make} continues to consider the other prerequisites of the pending targets, remaking them if necessary, before it gives up and returns nonzero status. For example, after an error in compiling one object file, @samp{make -k} will continue compiling other object files even though it already knows that linking them will be impossible. @xref{Options Summary, ,Summary of Options}. The usual behavior assumes that your purpose is to get the specified targets up to date; once @code{make} learns that this is impossible, it might as well report the failure immediately. The @samp{-k} option says that the real purpose is to test as many of the changes made in the program as possible, perhaps to find several independent problems so that you can correct them all before the next attempt to compile. This is why Emacs' @code{compile} command passes the @samp{-k} flag by default. @cindex Emacs (@code{M-x compile}) @findex .DELETE_ON_ERROR @cindex deletion of target files @cindex removal of target files @cindex target, deleting on error Usually when a command fails, if it has changed the target file at all, the file is corrupted and cannot be used---or at least it is not completely updated. Yet the file's timestamp says that it is now up to date, so the next time @code{make} runs, it will not try to update that file. The situation is just the same as when the command is killed by a signal; @pxref{Interrupts}. So generally the right thing to do is to delete the target file if the command fails after beginning to change the file. @code{make} will do this if @code{.DELETE_ON_ERROR} appears as a target. This is almost always what you want @code{make} to do, but it is not historical practice; so for compatibility, you must explicitly request it. @node Interrupts, Recursion, Errors, Commands @section Interrupting or Killing @code{make} @cindex interrupt @cindex signal @cindex deletion of target files @cindex removal of target files @cindex target, deleting on interrupt @cindex killing (interruption) If @code{make} gets a fatal signal while a command is executing, it may delete the target file that the command was supposed to update. This is done if the target file's last-modification time has changed since @code{make} first checked it. The purpose of deleting the target is to make sure that it is remade from scratch when @code{make} is next run. Why is this? Suppose you type @kbd{Ctrl-c} while a compiler is running, and it has begun to write an object file @file{foo.o}. The @kbd{Ctrl-c} kills the compiler, resulting in an incomplete file whose last-modification time is newer than the source file @file{foo.c}. But @code{make} also receives the @kbd{Ctrl-c} signal and deletes this incomplete file. If @code{make} did not do this, the next invocation of @code{make} would think that @file{foo.o} did not require updating---resulting in a strange error message from the linker when it tries to link an object file half of which is missing. @findex .PRECIOUS You can prevent the deletion of a target file in this way by making the special target @code{.PRECIOUS} depend on it. Before remaking a target, @code{make} checks to see whether it appears on the prerequisites of @code{.PRECIOUS}, and thereby decides whether the target should be deleted if a signal happens. Some reasons why you might do this are that the target is updated in some atomic fashion, or exists only to record a modification-time (its contents do not matter), or must exist at all times to prevent other sorts of trouble. @node Recursion, Sequences, Interrupts, Commands @section Recursive Use of @code{make} @cindex recursion @cindex subdirectories, recursion for Recursive use of @code{make} means using @code{make} as a command in a makefile. This technique is useful when you want separate makefiles for various subsystems that compose a larger system. For example, suppose you have a subdirectory @file{subdir} which has its own makefile, and you would like the containing directory's makefile to run @code{make} on the subdirectory. You can do it by writing this: @example subsystem: cd subdir && $(MAKE) @end example @noindent or, equivalently, this (@pxref{Options Summary, ,Summary of Options}): @example subsystem: $(MAKE) -C subdir @end example @cindex @code{-C} @cindex @code{--directory} You can write recursive @code{make} commands just by copying this example, but there are many things to know about how they work and why, and about how the sub-@code{make} relates to the top-level @code{make}. For your convenience, GNU @code{make} sets the variable @code{CURDIR} to the pathname of the current working directory for you. If @code{-C} is in effect, it will contain the path of the new directory, not the original. The value has the same precedence it would have if it were set in the makefile (by default, an environment variable @code{CURDIR} will not override this value). Note that setting this variable has no effect on the operation of @code{make} @menu * MAKE Variable:: The special effects of using @samp{$(MAKE)}. * Variables/Recursion:: How to communicate variables to a sub-@code{make}. * Options/Recursion:: How to communicate options to a sub-@code{make}. * -w Option:: How the @samp{-w} or @samp{--print-directory} option helps debug use of recursive @code{make} commands. @end menu @node MAKE Variable, Variables/Recursion, , Recursion @subsection How the @code{MAKE} Variable Works @vindex MAKE @cindex recursion, and @code{MAKE} variable Recursive @code{make} commands should always use the variable @code{MAKE}, not the explicit command name @samp{make}, as shown here: @example @group subsystem: cd subdir && $(MAKE) @end group @end example The value of this variable is the file name with which @code{make} was invoked. If this file name was @file{/bin/make}, then the command executed is @samp{cd subdir && /bin/make}. If you use a special version of @code{make} to run the top-level makefile, the same special version will be executed for recursive invocations. @cindex @code{cd} (shell command) As a special feature, using the variable @code{MAKE} in the commands of a rule alters the effects of the @samp{-t} (@samp{--touch}), @samp{-n} (@samp{--just-print}), or @samp{-q} (@w{@samp{--question}}) option. Using the @code{MAKE} variable has the same effect as using a @samp{+} character at the beginning of the command line. @xref{Instead of Execution, ,Instead of Executing the Commands}.@refill Consider the command @samp{make -t} in the above example. (The @samp{-t} option marks targets as up to date without actually running any commands; see @ref{Instead of Execution}.) Following the usual definition of @samp{-t}, a @samp{make -t} command in the example would create a file named @file{subsystem} and do nothing else. What you really want it to do is run @samp{@w{cd subdir &&} @w{make -t}}; but that would require executing the command, and @samp{-t} says not to execute commands.@refill @cindex @code{-t}, and recursion @cindex recursion, and @code{-t} @cindex @code{--touch}, and recursion The special feature makes this do what you want: whenever a command line of a rule contains the variable @code{MAKE}, the flags @samp{-t}, @samp{-n} and @samp{-q} do not apply to that line. Command lines containing @code{MAKE} are executed normally despite the presence of a flag that causes most commands not to be run. The usual @code{MAKEFLAGS} mechanism passes the flags to the sub-@code{make} (@pxref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}), so your request to touch the files, or print the commands, is propagated to the subsystem.@refill @node Variables/Recursion, Options/Recursion, MAKE Variable, Recursion @subsection Communicating Variables to a Sub-@code{make} @cindex sub-@code{make} @cindex environment, and recursion @cindex exporting variables @cindex variables, environment @cindex variables, exporting @cindex recursion, and environment @cindex recursion, and variables Variable values of the top-level @code{make} can be passed to the sub-@code{make} through the environment by explicit request. These variables are defined in the sub-@code{make} as defaults, but do not override what is specified in the makefile used by the sub-@code{make} makefile unless you use the @samp{-e} switch (@pxref{Options Summary, ,Summary of Options}).@refill To pass down, or @dfn{export}, a variable, @code{make} adds the variable and its value to the environment for running each command. The sub-@code{make}, in turn, uses the environment to initialize its table of variable values. @xref{Environment, ,Variables from the Environment}. Except by explicit request, @code{make} exports a variable only if it is either defined in the environment initially or set on the command line, and if its name consists only of letters, numbers, and underscores. Some shells cannot cope with environment variable names consisting of characters other than letters, numbers, and underscores. The special variables @code{SHELL} and @code{MAKEFLAGS} are always exported (unless you unexport them). @code{MAKEFILES} is exported if you set it to anything. @code{make} automatically passes down variable values that were defined on the command line, by putting them in the @code{MAKEFLAGS} variable. @iftex See the next section. @end iftex @ifinfo @xref{Options/Recursion}. @end ifinfo Variables are @emph{not} normally passed down if they were created by default by @code{make} (@pxref{Implicit Variables, ,Variables Used by Implicit Rules}). The sub-@code{make} will define these for itself.@refill @findex export If you want to export specific variables to a sub-@code{make}, use the @code{export} directive, like this: @example export @var{variable} @dots{} @end example @noindent @findex unexport If you want to @emph{prevent} a variable from being exported, use the @code{unexport} directive, like this: @example unexport @var{variable} @dots{} @end example @noindent As a convenience, you can define a variable and export it at the same time by doing: @example export @var{variable} = value @end example @noindent has the same result as: @example @var{variable} = value export @var{variable} @end example @noindent and @example export @var{variable} := value @end example @noindent has the same result as: @example @var{variable} := value export @var{variable} @end example Likewise, @example export @var{variable} += value @end example @noindent is just like: @example @var{variable} += value export @var{variable} @end example @noindent @xref{Appending, ,Appending More Text to Variables}. You may notice that the @code{export} and @code{unexport} directives work in @code{make} in the same way they work in the shell, @code{sh}. If you want all variables to be exported by default, you can use @code{export} by itself: @example export @end example @noindent This tells @code{make} that variables which are not explicitly mentioned in an @code{export} or @code{unexport} directive should be exported. Any variable given in an @code{unexport} directive will still @emph{not} be exported. If you use @code{export} by itself to export variables by default, variables whose names contain characters other than alphanumerics and underscores will not be exported unless specifically mentioned in an @code{export} directive.@refill @findex .EXPORT_ALL_VARIABLES The behavior elicited by an @code{export} directive by itself was the default in older versions of GNU @code{make}. If your makefiles depend on this behavior and you want to be compatible with old versions of @code{make}, you can write a rule for the special target @code{.EXPORT_ALL_VARIABLES} instead of using the @code{export} directive. This will be ignored by old @code{make}s, while the @code{export} directive will cause a syntax error.@refill @cindex compatibility in exporting Likewise, you can use @code{unexport} by itself to tell @code{make} @emph{not} to export variables by default. Since this is the default behavior, you would only need to do this if @code{export} had been used by itself earlier (in an included makefile, perhaps). You @strong{cannot} use @code{export} and @code{unexport} by themselves to have variables exported for some commands and not for others. The last @code{export} or @code{unexport} directive that appears by itself determines the behavior for the entire run of @code{make}.@refill @vindex MAKELEVEL @cindex recursion, level of As a special feature, the variable @code{MAKELEVEL} is changed when it is passed down from level to level. This variable's value is a string which is the depth of the level as a decimal number. The value is @samp{0} for the top-level @code{make}; @samp{1} for a sub-@code{make}, @samp{2} for a sub-sub-@code{make}, and so on. The incrementation happens when @code{make} sets up the environment for a command.@refill The main use of @code{MAKELEVEL} is to test it in a conditional directive (@pxref{Conditionals, ,Conditional Parts of Makefiles}); this way you can write a makefile that behaves one way if run recursively and another way if run directly by you.@refill @vindex MAKEFILES You can use the variable @code{MAKEFILES} to cause all sub-@code{make} commands to use additional makefiles. The value of @code{MAKEFILES} is a whitespace-separated list of file names. This variable, if defined in the outer-level makefile, is passed down through the environment; then it serves as a list of extra makefiles for the sub-@code{make} to read before the usual or specified ones. @xref{MAKEFILES Variable, ,The Variable @code{MAKEFILES}}.@refill @node Options/Recursion, -w Option, Variables/Recursion, Recursion @subsection Communicating Options to a Sub-@code{make} @cindex options, and recursion @cindex recursion, and options @vindex MAKEFLAGS Flags such as @samp{-s} and @samp{-k} are passed automatically to the sub-@code{make} through the variable @code{MAKEFLAGS}. This variable is set up automatically by @code{make} to contain the flag letters that @code{make} received. Thus, if you do @w{@samp{make -ks}} then @code{MAKEFLAGS} gets the value @samp{ks}.@refill As a consequence, every sub-@code{make} gets a value for @code{MAKEFLAGS} in its environment. In response, it takes the flags from that value and processes them as if they had been given as arguments. @xref{Options Summary, ,Summary of Options}. @cindex command line variable definitions, and recursion @cindex variables, command line, and recursion @cindex recursion, and command line variable definitions Likewise variables defined on the command line are passed to the sub-@code{make} through @code{MAKEFLAGS}. Words in the value of @code{MAKEFLAGS} that contain @samp{=}, @code{make} treats as variable definitions just as if they appeared on the command line. @xref{Overriding, ,Overriding Variables}. @cindex @code{-C}, and recursion @cindex @code{-f}, and recursion @cindex @code{-o}, and recursion @cindex @code{-W}, and recursion @cindex @code{--directory}, and recursion @cindex @code{--file}, and recursion @cindex @code{--old-file}, and recursion @cindex @code{--assume-old}, and recursion @cindex @code{--assume-new}, and recursion @cindex @code{--new-file}, and recursion @cindex recursion, and @code{-C} @cindex recursion, and @code{-f} @cindex recursion, and @code{-o} @cindex recursion, and @code{-W} The options @samp{-C}, @samp{-f}, @samp{-o}, and @samp{-W} are not put into @code{MAKEFLAGS}; these options are not passed down.@refill @cindex @code{-j}, and recursion @cindex @code{--jobs}, and recursion @cindex recursion, and @code{-j} @cindex job slots, and recursion The @samp{-j} option is a special case (@pxref{Parallel, ,Parallel Execution}). If you set it to some numeric value @samp{N} and your operating system supports it (most any UNIX system will; others typically won't), the parent @code{make} and all the sub-@code{make}s will communicate to ensure that there are only @samp{N} jobs running at the same time between them all. Note that any job that is marked recursive (@pxref{Instead of Execution, ,Instead of Executing the Commands}) doesn't count against the total jobs (otherwise we could get @samp{N} sub-@code{make}s running and have no slots left over for any real work!) If your operating system doesn't support the above communication, then @samp{-j 1} is always put into @code{MAKEFLAGS} instead of the value you specified. This is because if the @w{@samp{-j}} option were passed down to sub-@code{make}s, you would get many more jobs running in parallel than you asked for. If you give @samp{-j} with no numeric argument, meaning to run as many jobs as possible in parallel, this is passed down, since multiple infinities are no more than one.@refill If you do not want to pass the other flags down, you must change the value of @code{MAKEFLAGS}, like this: @example subsystem: cd subdir && $(MAKE) MAKEFLAGS= @end example @vindex MAKEOVERRIDES The command line variable definitions really appear in the variable @code{MAKEOVERRIDES}, and @code{MAKEFLAGS} contains a reference to this variable. If you do want to pass flags down normally, but don't want to pass down the command line variable definitions, you can reset @code{MAKEOVERRIDES} to empty, like this: @example MAKEOVERRIDES = @end example @noindent @cindex Arg list too long @cindex E2BIG This is not usually useful to do. However, some systems have a small fixed limit on the size of the environment, and putting so much information into the value of @code{MAKEFLAGS} can exceed it. If you see the error message @samp{Arg list too long}, this may be the problem. @findex .POSIX @cindex POSIX.2 (For strict compliance with POSIX.2, changing @code{MAKEOVERRIDES} does not affect @code{MAKEFLAGS} if the special target @samp{.POSIX} appears in the makefile. You probably do not care about this.) @vindex MFLAGS A similar variable @code{MFLAGS} exists also, for historical compatibility. It has the same value as @code{MAKEFLAGS} except that it does not contain the command line variable definitions, and it always begins with a hyphen unless it is empty (@code{MAKEFLAGS} begins with a hyphen only when it begins with an option that has no single-letter version, such as @samp{--warn-undefined-variables}). @code{MFLAGS} was traditionally used explicitly in the recursive @code{make} command, like this: @example subsystem: cd subdir && $(MAKE) $(MFLAGS) @end example @noindent but now @code{MAKEFLAGS} makes this usage redundant. If you want your makefiles to be compatible with old @code{make} programs, use this technique; it will work fine with more modern @code{make} versions too. @cindex setting options from environment @cindex options, setting from environment @cindex setting options in makefiles @cindex options, setting in makefiles The @code{MAKEFLAGS} variable can also be useful if you want to have certain options, such as @samp{-k} (@pxref{Options Summary, ,Summary of Options}), set each time you run @code{make}. You simply put a value for @code{MAKEFLAGS} in your environment. You can also set @code{MAKEFLAGS} in a makefile, to specify additional flags that should also be in effect for that makefile. (Note that ?~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1P)you cannot use @code{MFLAGS} this way. That variable is set only for compatibility; @code{make} does not interpret a value you set for it in any way.) When @code{make} interprets the value of @code{MAKEFLAGS} (either from the environment or from a makefile), it first prepends a hyphen if the value does not already begin with one. Then it chops the value into words separated by blanks, and parses these words as if they were options given on the command line (except that @samp{-C}, @samp{-f}, @samp{-h}, @samp{-o}, @samp{-W}, and their long-named versions are ignored; and there is no error for an invalid option). If you do put @code{MAKEFLAGS} in your environment, you should be sure not to include any options that will drastically affect the actions of @code{make} and undermine the purpose of makefiles and of @code{make} itself. For instance, the @samp{-t}, @samp{-n}, and @samp{-q} options, if put in one of these variables, could have disastrous consequences and would certainly have at least surprising and probably annoying effects.@refill @node -w Option, , Options/Recursion, Recursion @subsection The @samp{--print-directory} Option @cindex directories, printing them @cindex printing directories @cindex recursion, and printing directories If you use several levels of recursive @code{make} invocations, the @samp{-w} or @w{@samp{--print-directory}} option can make the output a lot easier to understand by showing each directory as @code{make} starts processing it and as @code{make} finishes processing it. For example, if @samp{make -w} is run in the directory @file{/u/gnu/make}, @code{make} will print a line of the form:@refill @example make: Entering directory `/u/gnu/make'. @end example @noindent before doing anything else, and a line of the form: @example make: Leaving directory `/u/gnu/make'. @end example @noindent when processing is completed. @cindex @code{-C}, and @code{-w} @cindex @code{--directory}, and @code{--print-directory} @cindex recursion, and @code{-w} @cindex @code{-w}, and @code{-C} @cindex @code{-w}, and recursion @cindex @code{--print-directory}, and @code{--directory} @cindex @code{--print-directory}, and recursion @cindex @code{--no-print-directory} @cindex @code{--print-directory}, disabling @cindex @code{-w}, disabling Normally, you do not need to specify this option because @samp{make} does it for you: @samp{-w} is turned on automatically when you use the @samp{-C} option, and in sub-@code{make}s. @code{make} will not automatically turn on @samp{-w} if you also use @samp{-s}, which says to be silent, or if you use @samp{--no-print-directory} to explicitly disable it. @node Sequences, Empty Commands, Recursion, Commands @section Defining Canned Command Sequences @cindex sequences of commands @cindex commands, sequences of When the same sequence of commands is useful in making various targets, you can define it as a canned sequence with the @code{define} directive, and refer to the canned sequence from the rules for those targets. The canned sequence is actually a variable, so the name must not conflict with other variable names. Here is an example of defining a canned sequence of commands: @example define run-yacc yacc $(firstword $^) mv y.tab.c $@@ endef @end example @cindex @code{yacc} @noindent Here @code{run-yacc} is the name of the variable being defined; @code{endef} marks the end of the definition; the lines in between are the commands. The @code{define} directive does not expand variable references and function calls in the canned sequence; the @samp{$} characters, parentheses, variable names, and so on, all become part of the value of the variable you are defining. @xref{Defining, ,Defining Variables Verbatim}, for a complete explanation of @code{define}. The first command in this example runs Yacc on the first prerequisite of whichever rule uses the canned sequence. The output file from Yacc is always named @file{y.tab.c}. The second command moves the output to the rule's target file name. To use the canned sequence, substitute the variable into the commands of a rule. You can substitute it like any other variable (@pxref{Reference, ,Basics of Variable References}). Because variables defined by @code{define} are recursively expanded variables, all the variable references you wrote inside the @code{define} are expanded now. For example: @example foo.c : foo.y $(run-yacc) @end example @noindent @samp{foo.y} will be substituted for the variable @samp{$^} when it occurs in @code{run-yacc}'s value, and @samp{foo.c} for @samp{$@@}.@refill This is a realistic example, but this particular one is not needed in practice because @code{make} has an implicit rule to figure out these commands based on the file names involved (@pxref{Implicit Rules, ,Using Implicit Rules}). @cindex @@, and @code{define} @cindex -, and @code{define} @cindex +, and @code{define} In command execution, each line of a canned sequence is treated just as if the line appeared on its own in the rule, preceded by a tab. In particular, @code{make} invokes a separate subshell for each line. You can use the special prefix characters that affect command lines (@samp{@@}, @samp{-}, and @samp{+}) on each line of a canned sequence. @xref{Commands, ,Writing the Commands in Rules}. For example, using this canned sequence: @example define frobnicate @@echo "frobnicating target $@@" frob-step-1 $< -o $@@-step-1 frob-step-2 $@@-step-1 -o $@@ endef @end example @noindent @code{make} will not echo the first line, the @code{echo} command. But it @emph{will} echo the following two command lines. On the other hand, prefix characters on the command line that refers to a canned sequence apply to every line in the sequence. So the rule: @example frob.out: frob.in @@$(frobnicate) @end example @noindent does not echo @emph{any} commands. (@xref{Echoing, ,Command Echoing}, for a full explanation of @samp{@@}.) @node Empty Commands, , Sequences, Commands @section Using Empty Commands @cindex empty commands @cindex commands, empty It is sometimes useful to define commands which do nothing. This is done simply by giving a command that consists of nothing but whitespace. For example: @example target: ; @end example @noindent defines an empty command string for @file{target}. You could also use a line beginning with a tab character to define an empty command string, but this would be confusing because such a line looks empty. @findex .DEFAULT@r{, and empty commands} You may be wondering why you would want to define a command string that does nothing. The only reason this is useful is to prevent a target from getting implicit commands (from implicit rules or the @code{.DEFAULT} special target; @pxref{Implicit Rules} and @pxref{Last Resort, ,Defining Last-Resort Default Rules}).@refill @c !!! another reason is for canonical stamp files: @ignore foo: stamp-foo ; stamp-foo: foo.in create foo frm foo.in touch $@ @end ignore You may be inclined to define empty command strings for targets that are not actual files, but only exist so that their prerequisites can be remade. However, this is not the best way to do that, because the prerequisites may not be remade properly if the target file actually does exist. @xref{Phony Targets, ,Phony Targets}, for a better way to do this. @node Using Variables, Conditionals, Commands, Top @chapter How to Use Variables @cindex variable @cindex value @cindex recursive variable expansion @cindex simple variable expansion A @dfn{variable} is a name defined in a makefile to represent a string of text, called the variable's @dfn{value}. These values are substituted by explicit request into targets, prerequisites, commands, and other parts of the makefile. (In some other versions of @code{make}, variables are called @dfn{macros}.) @cindex macro Variables and functions in all parts of a makefile are expanded when read, except for the shell commands in rules, the right-hand sides of variable definitions using @samp{=}, and the bodies of variable definitions using the @code{define} directive.@refill Variables can represent lists of file names, options to pass to compilers, programs to run, directories to look in for source files, directories to write output in, or anything else you can imagine. A variable name may be any sequence of characters not containing @samp{:}, @samp{#}, @samp{=}, or leading or trailing whitespace. However, variable names containing characters other than letters, numbers, and underscores should be avoided, as they may be given special meanings in the future, and with some shells they cannot be passed through the environment to a sub-@code{make} (@pxref{Variables/Recursion, ,Communicating Variables to a Sub-@code{make}}). Variable names are case-sensitive. The names @samp{foo}, @samp{FOO}, and @samp{Foo} all refer to different variables. It is traditional to use upper case letters in variable names, but we recommend using lower case letters for variable names that serve internal purposes in the makefile, and reserving upper case for parameters that control implicit rules or for parameters that the user should override with command options (@pxref{Overriding, ,Overriding Variables}). A few variables have names that are a single punctuation character or just a few characters. These are the @dfn{automatic variables}, and they have particular specialized uses. @xref{Automatic, ,Automatic Variables}. @menu * Reference:: How to use the value of a variable. * Flavors:: Variables come in two flavors. * Advanced:: Advanced features for referencing a variable. * Values:: All the ways variables get their values. * Setting:: How to set a variable in the makefile. * Appending:: How to append more text to the old value of a variable. * Override Directive:: How to set a variable in the makefile even if the user has set it with a command argument. * Defining:: An alternate way to set a variable to a verbatim string. * Environment:: Variable values can come from the environment. * Target-specific:: Variable values can be defined on a per-target basis. * Pattern-specific:: Target-specific variable values can be applied to a group of targets that match a pattern. * Automatic:: Some special variables have predefined meanings for use with implicit rules. @end menu @node Reference, Flavors, , Using Variables @section Basics of Variable References @cindex variables, how to reference @cindex reference to variables @cindex @code{$}, in variable reference @cindex dollar sign (@code{$}), in variable reference To substitute a variable's value, write a dollar sign followed by the name of the variable in parentheses or braces: either @samp{$(foo)} or @samp{$@{foo@}} is a valid reference to the variable @code{foo}. This special significance of @samp{$} is why you must write @samp{$$} to have the effect of a single dollar sign in a file name or command. Variable references can be used in any context: targets, prerequisites, commands, most directives, and new variable values. Here is an example of a common case, where a variable holds the names of all the object files in a program: @example @group objects = program.o foo.o utils.o program : $(objects) cc -o program $(objects) $(objects) : defs.h @end group @end example Variable references work by strict textual substitution. Thus, the rule @example @group foo = c prog.o : prog.$(foo) $(foo)$(foo) -$(foo) prog.$(foo) @end group @end example @noindent could be used to compile a C program @file{prog.c}. Since spaces before the variable value are ignored in variable assignments, the value of @code{foo} is precisely @samp{c}. (Don't actually write your makefiles this way!) A dollar sign followed by a character other than a dollar sign, open-parenthesis or open-brace treats that single character as the variable name. Thus, you could reference the variable @code{x} with @samp{$x}. However, this practice is strongly discouraged, except in the case of the automatic variables (@pxref{Automatic, ,Automatic Variables}). @node Flavors, Advanced, Reference, Using Variables @section The Two Flavors of Variables @cindex flavors of variables @cindex recursive variable expansion @cindex variables, flavors @cindex recursively expanded variables @cindex variables, recursively expanded There are two ways that a variable in GNU @code{make} can have a value; we call them the two @dfn{flavors} of variables. The two flavors are distinguished in how they are defined and in what they do when expanded. @cindex = The first flavor of variable is a @dfn{recursively expanded} variable. Variables of this sort are defined by lines using @samp{=} (@pxref{Setting, ,Setting Variables}) or by the @code{define} directive (@pxref{Defining, ,Defining Variables Verbatim}). The value you specify is installed verbatim; if it contains references to other variables, these references are expanded whenever this variable is substituted (in the course of expanding some other string). When this happens, it is called @dfn{recursive expansion}.@refill For example, @example foo = $(bar) bar = $(ugh) ugh = Huh? all:;echo $(foo) @end example @noindent will echo @samp{Huh?}: @samp{$(foo)} expands to @samp{$(bar)} which expands to @samp{$(ugh)} which finally expands to @samp{Huh?}.@refill This flavor of variable is the only sort supported by other versions of @code{make}. It has its advantages and its disadvantages. An advantage (most would say) is that: @example CFLAGS = $(include_dirs) -O include_dirs = -Ifoo -Ibar @end example @noindent will do what was intended: when @samp{CFLAGS} is expanded in a command, it will expand to @samp{-Ifoo -Ibar -O}. A major disadvantage is that you cannot append something on the end of a variable, as in @example CFLAGS = $(CFLAGS) -O @end example @noindent because it will cause an infinite loop in the variable expansion. (Actually @code{make} detects the infinite loop and reports an error.) @cindex loops in variable expansion @cindex variables, loops in expansion Another disadvantage is that any functions (@pxref{Functions, ,Functions for Transforming Text}) referenced in the definition will be executed every time the variable is expanded. This makes @code{make} run slower; worse, it causes the @code{wildcard} and @code{shell} functions to give unpredictable results because you cannot easily control when they are called, or even how many times. To avoid all the problems and inconveniences of recursively expanded variables, there is another flavor: simply expanded variables. @cindex simply expanded variables @cindex variables, simply expanded @cindex := @dfn{Simply expanded variables} are defined by lines using @samp{:=} (@pxref{Setting, ,Setting Variables}). The value of a simply expanded variable is scanned once and for all, expanding any references to other variables and functions, when the variable is defined. The actual value of the simply expanded variable is the result of expanding the text that you write. It does not contain any references to other variables; it contains their values @emph{as of the time this variable was defined}. Therefore, @example x := foo y := $(x) bar x := later @end example @noindent is equivalent to @example y := foo bar x := later @end example When a simply expanded variable is referenced, its value is substituted verbatim. Here is a somewhat more complicated example, illustrating the use of @samp{:=} in conjunction with the @code{shell} function. (@xref{Shell Function, , The @code{shell} Function}.) This example also shows use of the variable @code{MAKELEVEL}, which is changed when it is passed down from level to level. (@xref{Variables/Recursion, , Communicating Variables to a Sub-@code{make}}, for information about @code{MAKELEVEL}.) @vindex MAKELEVEL @vindex MAKE @example @group ifeq (0,$@{MAKELEVEL@}) cur-dir := $(shell pwd) whoami := $(shell whoami) host-type := $(shell arch) MAKE := $@{MAKE@} host-type=$@{host-type@} whoami=$@{whoami@} endif @end group @end example @noindent An advantage of this use of @samp{:=} is that a typical `descend into a directory' command then looks like this: @example @group $@{subdirs@}: $@{MAKE@} cur-dir=$@{cur-dir@}/$@@ -C $@@ all @end group @end example Simply expanded variables generally make complicated makefile programming more predictable because they work like variables in most programming languages. They allow you to redefine a variable using its own value (or its value processed in some way by one of the expansion functions) and to use the expansion functions much more efficiently (@pxref{Functions, ,Functions for Transforming Text}). @cindex spaces, in variable values @cindex whitespace, in variable values @cindex variables, spaces in values You can also use them to introduce controlled leading whitespace into variable values. Leading whitespace characters are discarded from your input before substitution of variable references and function calls; this means you can include leading spaces in a variable value by protecting them with variable references, like this: @example nullstring := space := $(nullstring) # end of the line @end example @noindent Here the value of the variable @code{space} is precisely one space. The comment @w{@samp{# end of the line}} is included here just for clarity. Since trailing space characters are @emph{not} stripped from variable values, just a space at the end of the line would have the same effect (but be rather hard to read). If you put whitespace at the end of a variable value, it is a good idea to put a comment like that at the end of the line to make your intent clear. Conversely, if you do @emph{not} want any whitespace characters at the end of your variable value, you must remember not to put a random comment on the end of the line after some whitespace, such as this: @example dir := /foo/bar # directory to put the frobs in @end example @noindent Here the value of the variable @code{dir} is @w{@samp{/foo/bar }} (with four trailing spaces), which was probably not the intention. (Imagine something like @w{@samp{$(dir)/file}} with this definition!) @cindex conditional variable assignment @cindex variables, conditional assignment @cindex ?= There is another assignment operator for variables, @samp{?=}. This is called a conditional variable assignment operator, because it only has an effect if the variable is not yet defined. This statement: @example FOO ?= bar @end example @noindent is exactly equivalent to this (@pxref{Origin Function, ,The @code{origin} Function}): @example ifeq ($(origin FOO), undefined) FOO = bar endif @end example Note that a variable set to an empty value is still defined, so @samp{?=} will not set that variable. @node Advanced, Values, Flavors, Using Variables @section Advanced Features for Reference to Variables @cindex reference to variables This section describes some advanced features you can use to reference variables in more flexible ways. @menu * Substitution Refs:: Referencing a variable with substitutions on the value. * Computed Names:: Computing the name of the variable to refer to. @end menu @node Substitution Refs, Computed Names, , Advanced @subsection Substitution References @cindex modified variable reference @cindex substitution variable reference @cindex variables, modified reference @cindex variables, substitution reference @cindex variables, substituting suffix in @cindex suffix, substituting in variables A @dfn{substitution reference} substitutes the value of a variable with alterations that you specify. It has the form @samp{$(@var{var}:@var{a}=@var{b})} (or @samp{$@{@var{var}:@var{a}=@var{b}@}}) and its meaning is to take the value of the variable @var{var}, replace every @var{a} at the end of a word with @var{b} in that value, and substitute the resulting string. When we say ``at the end of a word'', we mean that @var{a} must appear either followed by whitespace or at tQhe end of the value in order to be replaced; other occurrences of @var{a} in the value are unaltered. For example:@refill @example foo := a.o b.o c.o bar := $(foo:.o=.c) @end example @noindent sets @samp{bar} to @samp{a.c b.c c.c}. @xref{Setting, ,Setting Variables}. A substitution reference is actually an abbreviation for use of the @code{patsubst} expansion function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}). We provide substitution references as well as @code{patsubst} for compatibility with other implementations of @code{make}. @findex patsubst Another type of substitution reference lets you use the full power of the @code{patsubst} function. It has the same form @samp{$(@var{var}:@var{a}=@var{b})} described above, except that now @var{a} must contain a single @samp{%} character. This case is equivalent to @samp{$(patsubst @var{a},@var{b},$(@var{var}))}. @xref{Text Functions, ,Functions for String Substitution and Analysis}, for a description of the @code{patsubst} function.@refill @example @group @exdent For example: foo := a.o b.o c.o bar := $(foo:%.o=%.c) @end group @end example @noindent sets @samp{bar} to @samp{a.c b.c c.c}. @node Computed Names, , Substitution Refs, Advanced @subsection Computed Variable Names @cindex nested variable reference @cindex computed variable name @cindex variables, computed names @cindex variables, nested references @cindex variables, @samp{$} in name @cindex @code{$}, in variable name @cindex dollar sign (@code{$}), in variable name Computed variable names are a complicated concept needed only for sophisticated makefile programming. For most purposes you need not consider them, except to know that making a variable with a dollar sign in its name might have strange results. However, if you are the type that wants to understand everything, or you are actually interested in what they do, read on. Variables may be referenced inside the name of a variable. This is called a @dfn{computed variable name} or a @dfn{nested variable reference}. For example, @example x = y y = z a := $($(x)) @end example @noindent defines @code{a} as @samp{z}: the @samp{$(x)} inside @samp{$($(x))} expands to @samp{y}, so @samp{$($(x))} expands to @samp{$(y)} which in turn expands to @samp{z}. Here the name of the variable to reference is not stated explicitly; it is computed by expansion of @samp{$(x)}. The reference @samp{$(x)} here is nested within the outer variable reference. The previous example shows two levels of nesting, but any number of levels is possible. For example, here are three levels: @example x = y y = z z = u a := $($($(x))) @end example @noindent Here the innermost @samp{$(x)} expands to @samp{y}, so @samp{$($(x))} expands to @samp{$(y)} which in turn expands to @samp{z}; now we have @samp{$(z)}, which becomes @samp{u}. References to recursively-expanded variables within a variable name are reexpanded in the usual fashion. For example: @example x = $(y) y = z z = Hello a := $($(x)) @end example @noindent defines @code{a} as @samp{Hello}: @samp{$($(x))} becomes @samp{$($(y))} which becomes @samp{$(z)} which becomes @samp{Hello}. Nested variable references can also contain modified references and function invocations (@pxref{Functions, ,Functions for Transforming Text}), just like any other reference. For example, using the @code{subst} function (@pxref{Text Functions, ,Functions for String Substitution and Analysis}): @example @group x = variable1 variable2 := Hello y = $(subst 1,2,$(x)) z = y a := $($($(z))) @end group @end example @noindent eventually defines @code{a} as @samp{Hello}. It is doubtful that anyone would ever want to write a nested reference as convoluted as this one, but it works: @samp{$($($(z)))} expands to @samp{$($(y))} which becomes @samp{$($(subst 1,2,$(x)))}. This gets the value @samp{variable1} from @code{x} and changes it by substitution to @samp{variable2}, so that the entire string becomes @samp{$(variable2)}, a simple variable reference whose value is @samp{Hello}.@refill A computed variable name need not consist entirely of a single variable reference. It can contain several variable references, as well as some invariant text. For example, @example @group a_dirs := dira dirb 1_dirs := dir1 dir2 @end group @group a_files := filea fileb 1_files := file1 file2 @end group @group ifeq "$(use_a)" "yes" a1 := a else a1 := 1 endif @end group @group ifeq "$(use_dirs)" "yes" df := dirs else df := files endif dirs := $($(a1)_$(df)) @end group @end example @noindent will give @code{dirs} the same value as @code{a_dirs}, @code{1_dirs}, @code{a_files} or @code{1_files} depending on the settings of @code{use_a} and @code{use_dirs}.@refill Computed variable names can also be used in substitution references: @example @group a_objects := a.o b.o c.o 1_objects := 1.o 2.o 3.o sources := $($(a1)_objects:.o=.c) @end group @end example @noindent defines @code{sources} as either @samp{a.c b.c c.c} or @samp{1.c 2.c 3.c}, depending on the value of @code{a1}. The only restriction on this sort of use of nested variable references is that they cannot specify part of the name of a function to be called. This is because the test for a recognized function name is done before the expansion of nested references. For example, @example @group ifdef do_sort func := sort else func := strip endif @end group @group bar := a d b g q c @end group @group foo := $($(func) $(bar)) @end group @end example @noindent attempts to give @samp{foo} the value of the variable @samp{sort a d b g q c} or @samp{strip a d b g q c}, rather than giving @samp{a d b g q c} as the argument to either the @code{sort} or the @code{strip} function. This restriction could be removed in the future if that change is shown to be a good idea. You can also use computed variable names in the left-hand side of a variable assignment, or in a @code{define} directive, as in: @example dir = foo $(dir)_sources := $(wildcard $(dir)/*.c) define $(dir)_print lpr $($(dir)_sources) endef @end example @noindent This example defines the variables @samp{dir}, @samp{foo_]sources}, and @samp{foo_print}. Note that @dfn{nested variable references} are quite different from @dfn{recursively expanded variables} (@pxref{Flavors, ,The Two Flavors of Variables}), though both are used together in complex ways when doing makefile programming.@refill @node Values, Setting, Advanced, Using Variables @section How Variables Get Their Values @cindex variables, how they get their values @cindex value, how a variable gets it Variables can get values in several different ways: @itemize @bullet @item You can specify an overriding value when you run @code{make}. @xref{Overriding, ,Overriding Variables}. @item You can specify a value in the makefile, either with an assignment (@pxref{Setting, ,Setting Variables}) or with a verbatim definition (@pxref{Defining, ,Defining Variables Verbatim}).@refill @item Variables in the environment become @code{make} variables. @xref{Environment, ,Variables from the Environment}. @item Several @dfn{automatic} variables are given new values for each rule. Each of these has a single conventional use. @xref{Automatic, ,Automatic Variables}. @item Several variables have constant initial values. @xref{Implicit Variables, ,Variables Used by Implicit Rules}. @end itemize @node Setting, Appending, Values, Using Variables @section Setting Variables @cindex setting variables @cindex variables, setting @cindex = @cindex := @cindex ?= To set a variable from the makefile, write a line starting with the variable name followed by @samp{=} or @samp{:=}. Whatever follows the @samp{=} or @samp{:=} on the line becomes the value. For example, @example objects = main.o foo.o bar.o utils.o @end example @noindent defines a variable named @code{objects}. Whitespace around the variable name and immediately after the @samp{=} is ignored. Variables defined with @samp{=} are @dfn{recursively expanded} variables. Variables defined with @samp{:=} are @dfn{simply expanded} variables; these definitions can contain variable references which will be expanded before the definition is made. @xref{Flavors, ,The Two Flavors of Variables}. The variable name may contain function and variable references, which are expanded when the line is read to find the actual variable name to use. There is no limit on the length of the value of a variable except the amount of swapping space on the computer. When a variable definition is long, it is a good idea to break it into several lines by inserting backslash-newline at convenient places in the definition. This will not affect the functioning of @code{make}, but it will make the makefile easier to read. Most variable names are considered to have the empty string as a value if you have never set them. Several variables have built-in initial values that are not empty, but you can set them in the usual ways (@pxref{Implicit Variables, ,Variables Used by Implicit Rules}). Several special variables are set automatically to a new value for each rule; these are called the @dfn{automatic} variables (@pxref{Automatic, ,Automatic Variables}). If you'd like a variable to be set to a value only if it's not already set, then you can use the shorthand operator @samp{?=} instead of @samp{=}. These two settings of the variable @samp{FOO} are identical (@pxref{Origin Function, ,The @code{origin} Function}): @example FOO ?= bar @end example @noindent and @example ifeq ($(origin FOO), undefined) FOO = bar endif @end example @node Appending, Override Directive, Setting, Using Variables @section Appending More Text to Variables @cindex += @cindex appending to variables @cindex variables, appending to Often it is useful to add more text to the value of a variable already defined. You do this with a line containing @samp{+=}, like this: @example objects += another.o @end example @noindent This takes the value of the variable @code{objects}, and adds the text @samp{another.o} to it (preceded by a single space). Thus: @example objects = main.o foo.o bar.o utils.o objects += another.o @end example @noindent sets @code{objects} to @samp{main.o foo.o bar.o utils.o aneother.o}. Using @samp{+=} is similar to: @example objects = main.o foo.o bar.o utils.o objects := $(objects) another.o @end example @noindent but differs in ways that become important when you use more complex values. When the variable in question has not been defined before, @samp{+=} acts just like normal @samp{=}: it defines a recursively-expanded variable. However, when there @emph{is} a previous definition, exactly what @samp{+=} does depends on what flavor of variable you defined originally. @xref{Flavors, ,The Two Flavors of Variables}, for an explanation of the two flavors of variables. When you add to a variable's value with @samp{+=}, @code{make} acts essentially as if you had included the extra text in the initial definition of the variable. If you defined it first with @samp{:=}, making it a simply-expanded variable, @samp{+=} adds to that simply-expanded definition, and expands the new text before appending it to the old value just as @samp{:=} does (@pxref{Setting, ,Setting Variables}, f@~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;1Lgor a full explanation of @samp{:=}). In fact, @example variable := value variable += more @end example @noindent is exactly equivalent to: @noindent @example variable := value variable := $(variable) more @end example On the other hand, when you use @samp{+=} with a variable that you defined first to be recursively-expanded using plain @samp{=}, @code{make} does something a bit different. Recall that when you define a recursively-expanded variable, @code{make} does not expand the value you set for variable and function references immediately. Instead it stores the text verbatim, and saves these variable and function references to be expanded later, when you refer to the new variable (@pxref{Flavors, ,The Two Flavors of Variables}). When you use @samp{+=} on a recursively-expanded variable, it is this unexpanded text to which @code{make} appends the new text you specify. @example @group variable = value variable += more @end group @end example @noindent is roughly equivalent to: @example @group temp = value variable = $(temp) more @end group @end example @noindent except that of course it never defines a variable called @code{temp}. The importance of this comes when the variable's old value contains variable references. Take this common example: @example CFLAGS = $(includes) -O @dots{} CFLAGS += -pg # enable profiling @end example @noindent The first line defines the @code{CFLAGS} variable with a reference to another variable, @code{includes}. (@code{CFLAGS} is used by the rules for C compilation; @pxref{Catalogue of Rules, ,Catalogue of Implicit Rules}.) Using @samp{=} for the definition makes @code{CFLAGS} a recursively-expanded variable, meaning @w{@samp{$(includes) -O}} is @emph{not} expanded when @code{make} processes the definition of @code{CFLAGS}. Thus, @code{includes} need not be defined yet for its value to take effect. It only has to be defined before any reference to @code{CFLAGS}. If we tried to append to the value of @code{CFLAGS} without using @samp{+=}, we might do it like this: @example CFLAGS := $(CFLAGS) -pg # enable profiling @end example @noindent This is pretty close, but not quite what we want. Using @samp{:=} redefines @code{CFLAGS} as a simply-expanded variable; this means @code{make} expands the text @w{@samp{$(CFLAGS) -pg}} before setting the variable. If @code{includes} is not yet defined, we get @w{@samp{ -O -pg}}, and a later definition of @code{includes} will have no effect. Conversely, by using @samp{+=} we set @code{CFLAGS} to the @emph{unexpanded} value @w{@samp{$(includes) -O -pg}}. Thus we preserve the reference to @code{includes}, so if that variable gets defined at any later point, a reference like @samp{$(CFLAGS)} still uses its value. @node Override Directive, Defining, Appending, Using Variables @section The @code{override} Directive @findex override @cindex overriding with @code{override} @cindex variables, overriding If a variable has been set with a command argument (@pxref{Overriding, ,Overriding Variables}), then ordinary assignments in the makefile are ignored. If you want to set the variable in the makefile even though it was set with a command argument, you can use an @code{override} directive, which is a line that looks like this:@refill @example override @var{variable} = @var{value} @end example @noindent or @example override @var{variable} := @var{value} @end example To append more text to a variable defined on the command line, use: @example override @var{variable} += @var{more text} @end example @noindent @xref{Appending, ,Appending More Text to Variables}. The @code{override} directive was not invented for escalation in the war between makefiles and command arguments. It was invented so you can alter and add to values that the user specifies with command arguments. For example, suppose you always want the @samp{-g} switch when you run the C compiler, but you would like to allow the user to specify the other switches with a command argument just as usual. You could use this @code{override} directive: @example override CFLAGS += -g @end example You can also use @code{override} directives with @code{define} directives. This is done as you might expect: @example override define foo bar endef @end example @noindent @iftex See the next section for information about @code{define}. @end iftex @ifinfo @xref{Defining, ,Defining Variables Verbatim}. @end ifinfo @node Defining, Environment, Override Directive, Using Variables @section Defining Variables Verbatim @findex define @findex endef @cindex verbatim variable definition @cindex defining variables verbatim @cindex variables, defining verbatim Another way to set the value of a variable is to use the @code{define} directive. This directive has an unusual syntax which allows newline characters to be included in the value, which is convenient for defining canned sequences of commands (@pxref{Sequences, ,Defining Canned Command Sequences}). The @code{define} directive is followed on the same line by the name of the variable and nothing more. The value to give the variable appears on the following lines. The end of the value is marked by a line containing just the word @code{endef}. Aside from this difference in syntax, @code{define} works just like @samp{=}: it creates a recursively-expanded variable (@pxref{Flavors, ,The Two Flavors of Variables}). The variable name may contain function and variable references, which are expanded when the directive is read to find the actual variable name to use. @example define two-lines echo foo echo $(bar) endef @end example The value in an ordinary assignment cannot contain a newline; but the newlines that separate the lines of the value in a @code{define} become part of the variable's value (except for the final newline which precedes the @code{endef} and is not considered part of the value).@refill @need 800 The previous example is functionally equivalent to this: @example two-lines = echo foo; echo $(bar) @end example @noindent since two commands separated by semicolon behave much like two separate shell commands. However, note that using two separate lines means @code{make} will invoke the shell twice, running an independent subshell for each line. @xref{Execution, ,Command Execution}. If you want variable definitions made with @code{define} to take precedence over command-line variable definitions, you can use the @code{override} directive together with @code{define}: @example override define two-lines foo $(bar) endef @end example @noindent @xref{Override Directive, ,The @code{override} Directive}. @node Environment, Target-specific, Defining, Using Variables @section Variables from the Environment @cindex variables, environment @cindex environment Variables in @code{make} can come from the environment in which @code{make} is run. Every environment variable that @code{make} sees when it starts up is transformed into a @code{make} variable with the same name and value. But an explicit assignment in the makefile, or with a command argument, overrides the environment. (If the @samp{-e} flag is specified, then values from the environment override assignments in the makefile. @xref{Options Summary, ,Summary of Options}. But this is not recommended practice.) Thus, by setting the variable @code{CFLAGS} in your environment, you can cause all C compilations in most makefiles to use the compiler switches you prefer. This is safe for variables with standard or conventional meanings because you know that no makefile will use them for other things. (But this is not totally reliable; some makefiles set @code{CFLAGS} explicitly and therefore are not affected by the value in the environment.) When @code{make} is invoked recursively, variables defined in the outer invocation can be passed to inner invocations through the environment (@pxref{Recursion, ,Recursive Use of @code{make}}). By default, only variables that came from the environment or the command line are passed to recursive invocations. You can use the @code{export} directive to pass other variables. @xref{Variables/Recursion, , Communicating Variables to a Sub-@code{make}}, for full details. Other use of variables from the environment is not recommended. It is not wise for makefiles to depend for their functioning on environment variables set up outside their control, since this would cause different users to get different results from the same makefile. This is against the whole purpose of most makefiles. Such problems would be especially likely with the variable @code{SHELL}, which is normally present in the environment to specify the user's choice of interactive shell. It would be very undesirable for this choice to affect @code{make}. So @code{make} ignores the environment value of @code{SHELL} (except on MS-DOS and MS-Windows, where @code{SHELL} is usually not set. @xref{Execution, ,Special handling of SHELL on MS-DOS}.)@refill @node Target-specific, Pattern-specific, Environment, Using Variables @section Target-specific Variable Values @cindex target-specific variables @cindex variables, target-specific Variable values in @code{make} are usually global; that is, they are the same regardless of where they are evaluated (unless they're reset, of course). One exception to that is automatic variables (@pxref{Automatic, ,Automatic Variables}). The other exception is @dfn{target-specific variable values}. This feature allows you to define different values for the same variable, based on the target that @code{make} is currently building. As with automatic variables, these values are only available within the context of a target's command script (and in other target-specific assignments). Set a target-specific variable value like this: @example @var{target} @dots{} : @var{variable-assignment} @end example @noindent or like this: @example @var{target} @dots{} : override @var{variable-assignment} @end example Multiple @var{target} values create a target-specific variable value for each member of the target list individually. The @var{variable-assignment} can be any valid form of assignment; recursive (@samp{=}), static (@samp{:=}), appending (@samp{+=}), or conditional (@samp{?=}). All variables that appear within the @var{variable-assignment} are evaluated within the context of the target: thus, any previously-defined target-specific variable values will be in effect. Note that this variable is actually distinct from any ``global'' value: the two variables do not have to have the same flavor (recursive vs. static). Target-specific variables have the same priority as any other makefile variable. Variables provided on the command-line (and in the environment if the @samp{-e} option is in force) will take precedence. Specifying the @code{override} directive will allow the target-specific variable value to be preferred. There is one more special feature of target-specific variables: when you define a target-specific variable, that variable value is also in effect for all prerequisites of this target (unless those prerequisites override it with their own target-specific variable value). So, for example, a statement like this: @example prog : CFLAGS = -g prog : prog.o foo.o bar.o @end example @noindent will set @code{CFLAGS} to @samp{-g} in the command script for @file{prog}, but it will also set @code{CFLAGS} to @samp{-g} in the command scripts that create @file{prog.o}, @file{foo.o}, and @file{bar.o}, and any command scripts which create their prerequisites. @node Pattern-specific, , Target-specific, Using Variables @section Pattern-specific Variable Values @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. Set a pattern-specific variable value like this: @example @var{pattern} @dots{} : @var{variable-assignment} @end example @noindent or like this: @example @var{pattern} @dots{} : override @var{variable-assignment} @end example @noindent where @var{pattern} is a %-pattern. As with target-specific variable values, multiple @var{pattern} values create a pattern-specific variable value for each pattern individually. The @var{variable-assignment} can be any valid form of assignment. Any command-line variable setting will take precedence, unless @code{override} is specified. For example: @example %.o : CFLAGS = -O @end example @noindent will assign @code{CFLAGS} the value of @samp{-O} for all targets matching the pattern @code{%.o}. @node Conditionals, Functions, Using Variables, Top @chapter Conditional Parts of Makefiles @cindex conditionals A @dfn{conditional} causes part of a makefile to be obeyed or ignored depending on the values of variables. Conditionals can compare the value of one variable to another, or the value of a variable to a constant string. Conditionals control what @code{make} actually ``sees'' in the makefile, so they @emph{cannot} be used to control shell commands at the time of execution.@refill @menu * Conditional Example:: Example of a conditional * Conditional Syntax:: The syntax of conditionals. * Testing Flags:: Conditionals that test flags. @end menu @node Conditional Example, Conditional Syntax, , Conditionals @section Example of a Conditional The following example of a conditional tells @code{make} to use one set of libraries if the @code{CC} variable is @samp{gcc}, and a different set of libraries otherwise. It works by controlling which of two command lines will be used as the command for a rule. The result is that @samp{CC=gcc} as an argument to @code{make} changes not only which compiler is used but also which libraries are linked. @example libs_for_gcc = -lgnu normal_libs = foo: $(objects) ifeq ($(CC),gcc) $(CC) -o foo $(objects) $(libs_for_gcc) else $(CC) -o foo $(objects) $(normal_libs) endif @end example This conditional uses three directives: one @code{ifeq}, one @code{else} and one @code{endif}. The @code{ifeq} directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared. The lines of the makefile following the @code{ifeq} are obeyed if the two arguments match; otherwise they are ignored. The @code{else} directive causes the following lines to be obeyed if the previous conditional failed. In the example above, this means that the second alternative linking command is used whenever the first alternative is not used. It is optional to have an @code{else} in a conditional. The @code{endif} directive ends the conditional. Every conditional must end with an @code{endif}. Unconditional makefile text follows. As this example illustrates, conditionals work at the textual level: the lines of the conditional are treated as part of the makefile, or ignored, according to the condition. This is why the larger syntactic units of the makefile, such as rules, may cross the beginning or the end of the conditional. When the variable @code{CC} has the value @samp{gcc}, the above example has this effect: @example foo: $(objects) $(CC) -o foo $(objects) $(libs_for_gcc) @end example @noindent When the variable @code{CC} has any other value, the effect is this: @example foo: $(objects) $(CC) -o foo $(objects) $(normal_libs) @end example Equivalent results can be obtained in another way by conditionalizing a variable assignment and then using the variable unconditionally: @example libs_for_gcc = -lgnu normal_libs = ifeq ($(CC),gcc) libs=$(libs_for_gcc) else libs=$(normal_libs) endif foo: $(objects) $(CC) -o foo $(objects) $(libs) @end example @node Conditional Syntax, Testing Flags, Conditional Example, Conditionals @section Syntax of Conditionals @findex ifdef @findex ifeq @findex ifndef @findex ifneq @findex else @findex endif The syntax of a simple conditional with no @code{else} is as follows: @example @var{conditional-directive} @var{text-if-true} endif @end example @noindent The @var{text-if-true} may be any lines of text, to be considered as part of the makefile if the condition is true. If the condition is false, no text is used instead. The syntax of a complex conditional is as follows: @example @var{conditional-directive} @var{text-if-true} else @var{text-if-false} endif @end example @noindent If the condition is true, @var{text-if-true} is used; otherwise, @var{text-if-false} is used instead. The @var{text-if-false} can be any number of lines of text. The syntax of the @var{conditional-directive} is the same whether the conditional is simple or complex. There are four different directives that test different conditions. Here is a table of them: @table @code @item ifeq (@var{arg1}, @var{arg2}) @itemx ifeq '@var{arg1}' '@var{arg2}' @itemx ifeq "@var{arg1}" "@var{arg2}" @itemx ifeq "@var{arg1}" '@var{arg2}' @itemx ifeq '@var{arg1}' "@var{arg2}" Expand all variable references in @var{arg1} and @var{arg2} and compare them. If they are identical, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, if any, is effective. Often you want to test if a variable has a non-empty value. When the value results from complex expansions of variables and functions, expansions you would consider empty may actually contain whitespace characters and thus are not seen as empty. However, you can use the @code{strip} function (@pxref{Text Functions}) to avoid interpreting whitespace as a non-empty value. For example: @example @group ifeq ($(strip $(foo)),) @var{text-if-empty} endif @end group @end example @noindent will evaluate @var{text-if-empty} even if the expansion of @code{$(foo)} contains whitespace characters. @item ifneq (@var{arg1}, @var{arg2}) @itemx ifneq '@var{arg1}' '@var{arg2}' @itemx ifneq "@var{arg1}" "@var{arg2}" @itemx ifneq "@var{arg1}" '@var{arg2}' @itemx ifneq '@var{arg1}' "@var{arg2}" Expand all variable references in @var{arg1} and @var{arg2} and compare them. If they are different, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, if any, is effective. @item ifdef @var{variable-name} If the variable @var{variable-name} has a non-empty value, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, if any, is effective. Variables that have never been defined have an empty value. Note that @code{ifdef} only tests whether a variable has a value. It does not expand the variable to see if that value is nonempty. Consequently, tests using @code{ifdef} return true for all definitions except those like @code{foo =}. To test for an empty value, use @w{@code{ifeq ($(foo),)}}. For example, @example bar = foo = $(bar) ifdef foo frobozz = yes else frobozz = no endif @end example @noindent sets @samp{frobozz} to @samp{yes}, while: @example foo = ifdef foo frobozz = yes else frobozz = no endif @end example @noindent sets @samp{frobozz} to @samp{no}. @item ifndef @var{variable-name} If the variable @var{variable-name} has an empty value, the @var{text-if-true} is effective; otherwise, the @var{text-if-false}, if any, is effective. @end table Extra spaces are allowed and ignored at the beginning of the conditional directive line, but a tab is not allowed. (If the line begins with a tab, it will be considered a command for a rule.) Aside from this, extra spaces or tabs may be inserted with no effect anywhere except within the directive name or within an argument. A comment starting with @samp{#} may appear at the end of the line. The other two directives that play a part in a conditional are @code{else} and @code{endif}. Each of these directives is written as one word, with no arguments. Extra spaces are allowed and ignored at the beginning of the line, and spaces or tabs at the end. A comment starting with @samp{#} may appear at the end of the line. Conditionals affect which lines of the makefile @code{make} uses. If the condition is true, @code{make} reads the lines of the @var{text-if-true} as part of the makefile; if the condition is false, @code{make} ignores those lines completely. It follows that syntactic units of the makefile, such as rules, may safely be split across the beginning or the end of the conditional.@refill @code{make} evaluates conditionals when it reads a makefile. Consequently, you cannot use automatic variables in the tests of conditionals because they are not defined until commands are run (@pxref{Automatic, , Automatic Variables}). To prevent intolerable confusion, it is not permitted to start a conditional in one makefile and end it in another. However, you may write an @code{include} directive within a conditional, provided you do not attempt to terminate the conditional inside the included file. @node Testing Flags, , Conditional Syntax, Conditionals @section Conditionals that Test Flags You can write a conditional that tests @code{make} command flags such as @samp{-t} by using the variable @code{MAKEFLAGS} together with the @code{findstring} functio(n (@pxref{Text Functions, , Functions for String Substitution and Analysis}). This is useful when @code{touch} is not enough to make a file appear up to date. The @code{findstring} function determines whether one string appears as a substring of another. If you want to test for the @samp{-t} flag, use @samp{t} as the first string and the value of @code{MAKEFLAGS} as the other. For example, here is how to arrange to use @samp{ranlib -t} to finish marking an archive file up to date: @example archive.a: @dots{} ifneq (,$(findstring t,$(MAKEFLAGS))) +touch archive.a +ranlib -t archive.a else ranlib archive.a endif @end example @noindent The @samp{+} prefix marks those command lines as ``recursive'' so that they will be executed despite use of the @samp{-t} flag. @xref{Recursion, ,Recursive Use of @code{make}}. @node Functions, Running, Conditionals, Top @chapter Functions for Transforming Text @cindex functions @dfn{Functions} allow you to do text processing in the makefile to compute the files to operate on or the commands to use. You use a function in a @dfn{function call}, where you give the name of the function and some text (the @dfn{arguments}) for the function to operate on. The result of the function's processing is substituted into the makefile at the point of the call, just as a variable might be substituted. @menu * Syntax of Functions:: How to write a function call. * Text Functions:: General-purpose text manipulation functions. * File Name Functions:: Functions for manipulating file names. * Foreach Function:: Repeat some text with controlled variation. * If Function:: Conditionally expand a value. * Call Function:: Expand a user-defined function. * Origin Function:: Find where a variable got its value. * Shell Function:: Substitute the output of a shell command. * Make Control Functions:: Functions that control how make runs. @end menu @node Syntax of Functions, Text Functions, , Functions @section Function Call Syntax @cindex @code{$}, in function call @cindex dollar sign (@code{$}), in function call @cindex arguments of functions @cindex functions, syntax of A function call resembles a variable reference. It looks like this: @example $(@var{function} @var{arguments}) @end example @noindent or like this: @example $@{@var{function} @var{arguments}@} @end example Here @var{function} is a function name; one of a short list of names that are part of @code{make}. You can also essentially create your own functions by using the @code{call} builtin function. The @var{arguments} are the arguments of the function. They are separated from the function name by one or more spaces or tabs, and if there is more than one argument, then they are separated by commas. Such whitespace and commas are not part of an argument's value. The delimiters which you use to surround the function call, whether parentheses or braces, can appear in an argument only in matching pairs; the other kind of delimiters may appear singly. If the arguments themselves contain other function calls or variable references, it is wisest to use the same kind of delimiters for all the references; write @w{@samp{$(subst a,b,$(x))}}, not @w{@samp{$(subst a,b,$@{x@})}}. This is because it is clearer, and because only one type of delimiter is matched to find the end of the reference. The text written for each argument is processed by substitution of variables and function calls to produce the argument value, which is the text on which the function acts. The substitution is done in the order in which the arguments appear. Commas and unmatched parentheses or braces cannot appear in the text of an argument as written; leading spaces cannot appear in the text of the first argument as written. These characters can be put into the argument value by variable substitution. First define variables @code{comma} and @code{space} whose values are isolated comma and space characters, then substitute these variables where such characters are wanted, like this: @example @group comma:= , empty:= space:= $(empty) $(empty) foo:= a b c bar:= $(subst $(space),$(comma),$(foo)) # @r{bar is now `a,b,c'.} @end group @end example @noindent Here the @code{subst} function replaces each space with a comma, through the value of @code{foo}, and substitutes the result. @node Text Functions, File Name Functions, Syntax of Functions, Functions @section Functions for String Substitution and Analysis @cindex functions, for text Here are some functions that operate on strings: @table @code @item $(subst @var{from},@var{to},@var{text}) @findex subst Performs a textual replacement on the text @var{text}: each occurrence of @var{from} is replaced by @var{to}. The result is substituted for the function call. For example, @example $(subst ee,EE,feet on the street) @end example substitutes the string @samp{fEEt on the strEEt}. @item $(patsubst @var{pattern},@var{replacement},@var{text}) @findex patsubst Finds whitespace-separated words in @var{text} that match @var{pattern} and replaces them with @var{replacement}. Here @var{pattern} may contain a @samp{%} which acts as a wildcard, matching any number of any characters within a word. If @var{replacement} also contains a @samp{%}, the @samp{%} is replaced by the text that matched the @samp{%} in @var{pattern}.@refill @cindex @code{%}, quoting in @code{patsubst} @cindex @code{%}, quoting with @code{\} (backslash) @cindex @code{\} (backslash), to quote @code{%} @cindex backslash (@code{\}), to quote @code{%} @cindex quoting @code{%}, in @code{patsubst} @samp{%} characters in @code{patsubst} function invocations can be quoted with preceding backslashes (@samp{\}). Backslashes that would otherwise quote @samp{%} characters can be quoted with more backslashes. Backslashes that quote @samp{%} characters or other backslashes are removed from the pattern before it is compared file names or has a stem substituted into it. Backslashes that are not in danger of quoting @samp{%} characters go unmolested. For example, the pattern @file{the\%weird\\%pattern\\} has @samp{the%weird\} preceding the operative @samp{%} character, and @samp{pattern\\} following it. The final two backslashes are left alone because they cannot affect any @samp{%} character.@refill Whitespace between words is folded into single space characters; leading and trailing whitespace is discarded. For example, @example $(patsubst %.c,%.o,x.c.c bar.c) @end example @noindent produces the value @samp{x.c.o bar.o}. Substitution references (@pxref{Substitution Refs, ,Substitution References}) are a simpler way to get the effect of the @code{patsubst} function: @example $(@var{var}:@var{pattern}=@var{replacement}) @end example @noindent is equivalent to @example $(patsubst @var{pattern},@var{replacement},$(@var{var})) @end example The second shorthand simplifies one of the most common uses of @code{patsubst}: replacing the suffix at the end of file names. @example $(@var{var}:@var{suffix}=@var{replacement}) @end example @noindent is equivalent to @example $(patsubst %@var{suffix},%@var{replacement},$(@var{var})) @end example @noindent For example, you might have a list of object files: @example objects = foo.o bar.o baz.o @end example @noindent To get the list of corresponding source files, you could simply write: @example $(objects:.o=.c) @end example @noindent instead of using the general form: @example $(patsubst %.o,%.c,$(objects)) @end example @item $(strip @var{string}) @cindex stripping whitespace @cindex whitespace, stripping @cindex spaces, stripping @findex strip Removes leading and trailing whitespace from @var{string} and replaces each internal sequence of one or more whitespace characters with a single space. Thus, @samp{$(strip a b c )} results in @w{@samp{a b c}}. The function @code{strip} can be very useful when used in conjunction with conditionals. When comparing something with the empty string @samp{} using @code{ifeq} or @code{ifneq}, you usually want a string of just whitespace to match the empty string (@pxref{Conditionals}). Thus, the following may fail to have the desired results: @example .PHONY: all ifneq "$(needs_made)" "" all: $(needs_made) else all:;@@echo 'Nothing to make!' endif @end example @noindent Replacing the variable reference @w{@samp{$(needs_made)}} with the function call @w{@samp{$(strip $(needs_made))}} in the @code{ifneq} directive would make it more robust.@refill @item $(findstring @var{find},@var{in}) @findex findstring @cindex searching for strings @cindex finding strings @cindex strings, searching for Searches @var{in} for an occurrence of @var{find}. If it occurs, the value is @var{find}; otherwise, the value is empty. You can use this function in a conditional to test for the presence of a specific substring in a given string. Thus, the two examples, @example $(findstring a,a b c) $(findstring a,b c) @end example @noindent produce the values @samp{a} and @samp{} (the empty string), respectively. @xref{Testing Flags}, for a practical application of @code{findstring}.@refill @need 750 @findex filter @cindex filtering words @cindex words, filtering @item $(filter @var{pattern}@dots{},@var{text}) Returns all whitespace-separated words in @var{text} that @emph{do} match any of the @var{pattern} words, removing any words that @emph{do not} match. The patterns are written using @samp{%}, just like the patterns used in the @code{patsubst} function above.@refill The @code{filter} function can be used to separate out different types of strings (such as file names) in a variable. For example: @example sources := foo.c bar.c baz.s ugh.h foo: $(sources) cc $(filter %.c %.s,$(sources)) -o foo @end example @noindent says that @file{foo} depends of @file{foo.c}, @file{bar.c}, @file{baz.s} and @file{ugh.h} but only @file{foo.c}, @file{bar.c} and @file{baz.s} should be specified in the command to the compiler.@refill @item $(filter-out @var{pattern}@dots{},@var{text}) @findex filter-out @cindex filtering out words @cindex words, filtering out Returns all whitespace-separated words in A~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKE.TEXINFO;13P@var{text} that @emph{do not} match any of the @var{pattern} words, removing the words that @emph{do} match one or more. This is the exact opposite of the @code{filter} function.@refill Removes all whitespace-separated words in @var{text} that @emph{do} match the @var{pattern} words, returning only the words that @emph{do not} match. This is the exact opposite of the @code{filter} function.@refill For example, given: @example @group objects=main1.o foo.o main2.o bar.o mains=main1.o main2.o @end group @end example @noindent the following generates a list which contains all the object files not in @samp{mains}: @example $(filter-out $(mains),$(objects)) @end example @need 1500 @findex sort @cindex sorting words @item $(sort @var{list}) Sorts the words of @var{list} in lexical order, removing duplicate words. The output is a list of words separated by single spaces. Thus, @example $(sort foo bar lose) @end example @noindent returns the value @samp{bar foo lose}. @cindex removing duplicate words @cindex duplicate words, removing @cindex words, removing duplicates Incidentally, since @code{sort} removes duplicate words, you can use it for this purpose even if you don't care about the sort order. @end table Here is a realistic example of the use of @code{subst} and @code{patsubst}. Suppose that a makefile uses the @code{VPATH} variable to specify a list of directories that @code{make} should search for prerequisite files (@pxref{General Search, , @code{VPATH} Search Path for All Prerequisites}). This example shows how to tell the C compiler to search for header files in the same list of directories.@refill The value of @code{VPATH} is a list of directories separated by colons, such as @samp{src:../headers}. First, the @code{subst} function is used to change the colons to spaces: @example $(subst :, ,$(VPATH)) @end example @noindent This produces @samp{src ../headers}. Then @code{patsubst} is used to turn each directory name into a @samp{-I} flag. These can be added to the value of the variable @code{CFLAGS}, which is passed automatically to the C compiler, like this: @example override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH))) @end example @noindent The effect is to append the text @samp{-Isrc -I../headers} to the previously given value of @code{CFLAGS}. The @code{override} directive is used so that the new value is assigned even if the previous value of @code{CFLAGS} was specified with a command argument (@pxref{Override Directive, , The @code{override} Directive}). @node File Name Functions, Foreach Function, Text Functions, Functions @section Functions for File Names @cindex functions, for file names @cindex file name functions Several of the built-in expansion functions relate specifically to taking apart file names or lists of file names. Each of the following functions performs a specific transformation on a file name. The argument of the function is regarded as a series of file names, separated by whitespace. (Leading and trailing whitespace is ignored.) Each file name in the series is transformed in the same way and the results are concatenated with single spaces between them. @table @code @item $(dir @var{names}@dots{}) @findex dir @cindex directory part @cindex file name, directory part Extracts the directory-part of each file name in @var{names}. The directory-part of the file name is everything up through (and including) the last slash in it. If the file name contains no slash, the directory part is the string @samp{./}. For example, @example $(dir src/foo.c hacks) @end example @noindent produces the result @samp{src/ ./}. @item $(notdir @var{names}@dots{}) @findex notdir @cindex file name, nondirectory part @cindex nondirectory part Extracts all but the directory-part of each file name in @var{names}. If the file name contains no slash, it is left unchanged. Otherwise, everything through the last slash is removed from it. A file name that ends with a slash becomes an empty string. This is unfortunate, because it means that the result does not always have the same number of whitespace-separated file names as the argument had; but we do not see any other valid alternative. For example, @example $(notdir src/foo.c hacks) @end example @noindent produces the result @samp{foo.c hacks}. @item $(suffix @var{names}@dots{}) @findex suffix @cindex suffix, function to find @cindex file name suffix Extracts the suffix of each file name in @var{names}. If the file name contains a period, the suffix is everything starting with the last period. Otherwise, the suffix is the empty string. This frequently means that the result will be empty when @var{names} is not, and if @var{names} contains multiple file names, the result may contain fewer file names. For example, @example $(suffix src/foo.c src-1.0/bar.c hacks) @end example @noindent produces the result @samp{.c .c}. @item $(basename @var{names}@dots{}) @findex basename @cindex basename @cindex file name, basename of Extracts all but the suffix of each file name in @var{names}. If the file name contains a period, the basename is everything starting up to (and not including) the last period. Periods in the directory part are ignored. If there is no period, the basename is the entire file name. For example, @example $(basename src/foo.c src-1.0/bar hacks) @end example @noindent produces the result @samp{src/foo src-1.0/bar hacks}. @c plural convention with dots (be consistent) @item $(addsuffix @var{suffix},@var{names}@dots{}) @findex addsuffix @cindex suffix, adding @cindex file name suffix, adding The argument @var{names} is regarded as a series of names, separated by whitespace; @var{suffix} is used as a unit. The value of @var{suffix} is appended to the end of each individual name and the resulting larger names are concatenated with single spaces between them. For example, @example $(addsuffix .c,foo bar) @end example @noindent produces the result @samp{foo.c bar.c}. @item $(addprefix @var{prefix},@var{names}@dots{}) @findex addprefix @cindex prefix, adding @cindex file name prefix, adding The argument @var{names} is regarded as a series of names, separated by whitespace; @var{prefix} is used as a unit. The value of @var{prefix} is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them. For example, @example $(addprefix src/,foo bar) @end example @noindent produces the result @samp{src/foo src/bar}. @item $(join @var{list1},@var{list2}) @findex join @cindex joining lists of words @cindex words, joining lists Concatenates the two arguments word by word: the two first words (one from each argument) concatenated form the first word of the result, the two second words form the second word of the result, and so on. So the @var{n}th word of the result comes from the @var{n}th word of each argument. If one argument has more words that the other, the extra words are copied unchanged into the result. For example, @samp{$(join a b,.c .o)} produces @samp{a.c b.o}. Whitespace between the words in the lists is not preserved; it is replaced with a single space. This function can merge the results of the @code{dir} and @code{notdir} functions, to produce the original list of files which was given to those two functions.@refill @item $(word @var{n},@var{text}) @findex word @cindex word, selecting a @cindex selecting a word Returns the @var{n}th word of @var{text}. The legitimate values of @var{n} start from 1. If @var{n} is bigger than the number of words in @var{text}, the value is empty. For example, @example $(word 2, foo bar baz) @end example @noindent returns @samp{bar}. @item $(wordlist @var{s},@var{e},@var{text}) @findex wordlist @cindex words, selecting lists of @cindex selecting word lists Returns the list of words in @var{text} starting with word @var{s} and ending with word @var{e} (inclusive). The legitimate values of @var{s} and @var{e} start from 1. If @var{s} is bigger than the number of words in @var{text}, the value is empty. If @var{e} is bigger than the number of words in @var{text}, words up to the end of @var{text} are returned. If @var{s} is greater than @var{e}, @code{make} swaps them for you. For example, @example $(wordlist 2, 3, foo bar baz) @end example @noindent returns @samp{bar baz}. @c Following item phrased to prevent overfull hbox. --RJC 17 Jul 92 @item $(words @var{text}) @findex words @cindex words, finding number Returns the number of words in @var{text}. Thus, the last word of @var{text} is @w{@code{$(word $(words @var{text}),@var{text})}}.@refill @item $(firstword @var{names}@dots{}) @findex firstword @cindex words, extracting first The argument @var{names} is regarded as a series of names, separated by whitespace. The value is the first name in the series. The rest of the names are ignored. For example, @example $(firstword foo bar) @end example @noindent produces the result @samp{foo}. Although @code{$(firstword @var{text})} is the same as @code{$(word 1,@var{text})}, the @code{firstword} function is retained for its simplicity.@refill @item $(wildcard @var{pattern}) @findex wildcard @cindex wildcard, function The argument @var{pattern} is a file name pattern, typically containing wildcard characters (as in shell file name patterns). The result of @code{wildcard} is a space-separated list of the names of existing files that match the pattern. @xref{Wildcards, ,Using Wildcard Characters in File Names}. @end table @node Foreach Function, If Function, File Name Functions, Functions @section The @code{foreach} Function @findex foreach @cindex words, iterating over The @code{foreach} function is very different from other functions. It causes one piece of text to be used repeatedly, each time with a different substitution performed on it. It resembles the @code{for} command in the shell @code{sh} and the @code{foreach} command in the C-shell @code{csh}. The syntax of the @code{foreach} function is: @example $(foreach @var{var},@var{list},@var{text}) @end example @noindent The first two arguments, @var{var} and @var{list}, are expanded before anything else is done; note that the last argument, @var{text}, is @strong{not} expanded at the same time. Then for each word of the expanded value of @var{list}, the variable named by the expanded value of @var{var} is set to that word, and @var{text} is expanded. Presumably @var{text} contains references to that variable, so its expansion will be different each time. The result is that @var{text} is expanded as many times as there are whitespace-separated words in @var{list}. The multiple expansions of @var{text} are concatenated, with spaces between them, to make the result of @code{foreach}. This simple example sets the variable @samp{files} to the list of all files in the directories in the list @samp{dirs}: @example dirs := a b c d files := $(foreach dir,$(dirs),$(wildcard $(dir)/*)) @end example Here @var{text} is @samp{$(wildcard $(dir)/*)}. The first repetition finds the value @samp{a} for @code{dir}, so it produces the same result as @samp{$(wildcard a/*)}; the second repetition produces the result of @samp{$(wildcard b/*)}; and the third, that of @samp{$(wildcard c/*)}. This example has the same result (except for setting @samp{dirs}) as the following example: @example files := $(wildcard a/* b/* c/* d/*) @end example When @var{text} is complicated, you can improve readability by giving it a name, with an additional variable: @example find_files = $(wildcard $(dir)/*) dirs := a b c d files := $(foreach dir,$(dirs),$(find_files)) @end example @noindent Here we use the variable @code{find_files} this way. We use plain @samp{=} to define a recursively-expanding variable, so that its value contains an actual function call to be reexpanded under the control of @code{foreach}; a simply-expanded variable would not do, since @code{wildcard} would be called only once at the time of defining @code{find_files}. The @code{foreach} function has no permanent effect on the variable @var{var}; its value and flavor after the @code{foreach} function call are the same as they were beforehand. The other values which are taken from @var{list} are in effect only temporarily, during the execution of @code{foreach}. The variable @var{var} is a simply-expanded variable during the execution of @code{foreach}. If @var{var} was undefined before the @code{foreach} function call, it is undefined after the call. @xref{Flavors, ,The Two Flavors of Variables}.@refill You must take care when using complex variable expressions that result in variable names because many strange things are valid variable names, but are probably not what you intended. For example, @smallexample files := $(foreach Esta escrito en espanol!,b c ch,$(find_files)) @end smallexample @noindent might be useful if the value of @code{find_files} references the variable whose name is @samp{Esta escrito en espanol!} (es un nombre bastante largo, no?), but it is more likely to be a mistake. @node If Function, Call Function, Foreach Function, Functions @section The @code{if} Function @findex if @cindex conditional expansion The @code{if} function provides support for conditional expansion in a functional context (as opposed to the GNU @code{make} makefile conditionals such as @code{ifeq} (@pxref{Conditional Syntax, ,Syntax of Conditionals}). An @code{if} function call can contain either two or three arguments: @example $(if @var{condition},@var{then-part}[,@var{else-part}]) @end example The first argument, @var{condition}, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false. If the condition is true then the second argument, @var{then-part}, is evaluated and this is used as the result of the evaluation of the entire @code{if} function. If the condition is false then the third argument, @var{else-part}, is evaluated and this is the result of the @code{if} function. If there is no third argument, the @code{if} function evaluates to nothing (the empty string). Note that only one of the @var{then-part} or the @var{else-part} will be evaluated, never both. Thus, either can contain side-effects (such as @code{shell} function calls, etc.) @node Call Function, Origin Function, If Function, Functions @section The @code{call} Function @findex call @cindex functions, user defined @cindex user defined functions The @code{call} function is unique in that it can be used to create new parameterized functions. You can write a complex expression as the value of a variable, then use @code{call} to expand it with different values. The syntax of the @code{call} function is: @example $(call @var{variable},@var{param},@var{param},@dots{}) @end example When @code{make} expands this function, it assigns each @var{param} to temporary variables @code{$(1)}, @code{$(2)}, etc. The variable @code{$(0)} will contain @var{variable}. There is no maximum number of parameter arguments. There is no minimum, either, but it doesn't make sense to use @code{call} with no parameters. Then @var{variable} is expanded as a @code{make} variable in the context of these temporary assignments. Thus, any reference to @code{$(1)} in the value of @var{variable} will resolve to the first @var{param} in the invocation of @code{call}. Note that @var{variable} is the @emph{name} of a variable, not a @emph{reference} to that variable. Therefore you would not normally use a @samp{$} or parentheses when writing it. (You can, however, use a variable reference in the name if you want the name not to be a constant.) If @var{variable} is the name of a builtin function, the builtin function is always invoked (even if a @code{make} variable by that name also exists). Some examples may make this clearer. This macro simply reverses its arguments: @smallexample reverse = $(2) $(1) foo = a b bar = $(call reverse,$(foo)) @end smallexample @noindent Here @var{bar} will contain @samp{b a}. This one is slightly more interesting: it defines a macro to search for the first instance of a program in @code{PATH}: @smallexample pathsearch = $(firstword $(wildcard $(addsufix /$(1),$(subst :, ,$(PATH))))) LS := $(call pathsearch,ls) @end smallexample @noindent Now the variable LS contains @code{/bin/ls} or similar. The @code{call} function can be nested. Each recursive invocation gets its own local values for @code{$(1)}, etc. that mask the values of higher-level @code{call}. For example, here is an implementation of a @dfn{map} function: @smallexample map = $(foreach a,$(2),$(call $(1),$(a))) @end smallexample Now you can @var{map} a function that normally takes only one argument, such as @code{origin}, to multiple values in one step: @smallexample o = $(call map,origin,o map MAKE) @end smallexample and end up with @var{o} containing something like @samp{file file default}. A final caution: be careful when adding whitespace to the arguments to @code{call}. As with other functions, any whitespace contained in the second and subsequent arguments is kept; this can cause strange effects. It's generally safest to remove all extraneous whitespace when providing parameters to @code{call}. @node Origin Function, Shell Function, Call Function, Functions @section The @code{origin} Function @findex origin @cindex variables, origin of @cindex origin of variable The @code{origin} function is unlike most other functions in that it does not operate on the values of variables; it tells you something @emph{about} a variable. Specifically, it tells you where it came from. The syntax of the @code{origin} function is: @example $(origin @var{variable}) @end example Note that @var{variable} is the @emph{name} of a variable to inquire about; not a @emph{reference} to that variable. Therefore you would not normally use a @samp{$} or parentheses when writing it. (You can, however, use a variable reference in the name if you want the name not to be a constant.) The result of this function is a string telling you how the variable @var{variable} was defined: @table @samp @item undefined if @var{variable} was never defined. @item default if @var{variable} has a default definition, as is usual with @code{CC} and so on. @xref{Implicit Variables, ,Variables Used by Implicit Rules}. Note that if you have redefined a default variable, the @code{origin} function will return the origin of the later definition. @item environment if @var{variable} was defined as an environment variable and the @samp{-e} option is @emph{not} turned on (@pxref{Options Summary, ,Summary of Options}). @item environment override if @var{variable} was defined as an environment variable and the @w{@samp{-e}} option @emph{is} turned on (@pxref{Options Summary, ,Summary of Options}).@refill @item file if @var{variable} was defined in a makefile. @item command line if @var{variable} was defined on the command line. @item override if @var{variable} was defined with an @code{override} directive in a makefile (@pxref{Override Directive, ,The @code{override} Directive}). @item automatic if @var{variable} is an automatic variable defined for the execution of the commands for each rule (@pxref{Automatic, , Automatic Variables}). @end table This information is primarily useful (other than for your curiosity) to determine if you want to believe the value of a variable. For example, suppose you have a makefile @file{foo} that includes another makefile @file{bar}. You want a variable @code{bletch} to be defined in @file{bar} if you run the command @w{@samp{make -f bar}}, even if the environment contains a definition of @code{bletch}. However, if @file{foo} defined @code{bletch} before including @file{bar}, you do not want to override that definition. This could be done by using an @code{override} directive in @file{foo}, giving that definition precedence over the later definition in @file{bar}; unfortunately, the @code{override} directive would also override any command line definitions. So, @file{bar} could include:@refill @example @group ifdef bletch ifeq "$(origin bletch)" "environment" bletch = barf, gag, etc. endif endif @end group @end example @noindent If @code{bletch} has been defined from the environment, this will redefine it,. If you want to override a previous definition of @code{bletch} if it came from the environment, even under @samp{-e}, you could instead write: @example @group ifneq "$(findstring environment,$(origin bletch))" "" bletch = barf, gag, etc. endif @end group @end example Here the redefinition takes place if @samp{$(origin bletch)} returns either @samp{environment} or @samp{environment override}. @xref{Text Functions, , Functions for String Substitution and Analysis}. @node Shell Function, Make Control Functions, Origin Function, Functions @section The @code{shell} Function @findex shell @cindex commands, expansion @cindex backquotes @cindex shell command, function for The @code{shell} function is unlike any other function except the @code{wildcard} function (@pxref{Wildcard Function, ,The Function @code{wildcard}}) in that it communicates with the world outside of @code{make}. The @code{shell} function performs the same function that backquotes (@samp{`}) perform in most shells: it does @dfn{command expansion}. This means that it takes an argument that is a shell command and returns the output of the command. The only processing @code{make} does on the result, before substituting it into the surrounding text, is to convert each newline or carriage-return / newline pair to a single space. It also removes the trailing (carriage-return and) newline, if it's the last thing in the result.@refill The commands run by calls to the @code{shell} function are run when the function calls are expanded. In most cases, this is when the makefile is read in. The exception is that function calls in the commands of the rules are expanded when the commands are run, and this applies to @code{shell} function calls like all others. Here are some examples of the use of the @code{shell} function: @example contents := $(shell cat foo) @end example @noindent sets @code{contents} to the contents of the file @file{foo}, with a space (rather than a newline) separating each line. @example files := $(shell echo *.c) @end example @noindent sets @code{files} to the expansion of @samp{*.c}. Unless @code{make} is using a very strange shell, this has the same result as @w{@samp{$(wildcard *.c)}}.@refill @node Make Control Functions, , Shell Function, Functions @section Functions That Control Make @cindex functions, for controlling make @cindex controlling make These functions control the way make runs. Generally, they are used to provide information to the user of the makefile or to cause make to stop if some sort of environmental error is detected. @table @code @item $(error @var{text}@dots{}) @findex error @cindex error, stopping on @cindex stopping make Generates a fatal error where the message is @var{text}. Note that the error is generated whenever this function is evaluated. So, if you put it inside a command script or on the right side of a recursive variable assignment, it won't be evaluated until later. The @var{text} will be expanded before the error is generated. For example, @example ifdef ERROR1 $(error error is $(ERROR1)) endif @end example @noindent will generate a fatal error during the read of the makefile if the @code{make} variable @code{ERROR1} is defined. Or, @example ERR = $(error found an error!) .PHONY: err err: ; $(ERR) @end example @noindent will generate a fatal error while @code{make} is running, if the @code{err} target is invoked. @item $(warning @var{text}@dots{}) @findex warning @cindex warnings, printing @cindex printing user warnings This function works similarly to the @code{error} function, above, except that @code{make} doesn't exit. Instead, @var{text} is expanded and the resulting message is displayed, but processing of the makefile continues. The result of the expansion of this function is the empty string. @end table @node Running, Implicit Rules, Functions, Top @chapter How to Run @code{make} A makefile that says how to recompile a program can be used in more than one way. The simplest use is to recompile every file that is out of date. Usually, makefiles are written so that if you run @code{make} with no arguments, it does just that. But you might want to update only some of the files; you might want to use a different compiler or different compiler options; you might want just to find out which files are out of date without changing them. By giving arguments when you run @code{make}, you can do any of these things and many others. The exit status of @code{make} is always one of three values: @table @code @item 0 The exit status is zero if @code{make} is successful. @item 2 The exit status is two if @code{make} encounters any errors. It will print messages describing the particular errors. @item 1 The exit status is one if you use the @samp{-q} flag and @code{make} determines that some target is not already up to date. @xref{Instead of Execution, ,Instead of Executing the Commands}. @end table @menu * Makefile Arguments:: How to specify which makefile to use. * Goals:: How to use goal arguments to specify which parts of the makefile to use. * Instead of Execution:: How to use mode flags to specify what kind of thing to do with the commands in the makefile other than simply execute them. * Avoiding Compilation:: How to avoid recompiling certain files. * Overriding:: How to override a variable to specify an alternate compiler and other things. * Testing:: How to proceed past some errors, to test compilation. * Options Summary:: Summary of Options @end menu @node Makefile Arguments, Goals, , Running @section Arguments to Specify the Makefile @cindex @code{--file} @cindex @code{--makefile} @cindex @code{-f} The way to specify the name of the makefile is with the @samp{-f} or @samp{--file} option (@samp{--makefile} also works). For example, @samp{-f altmake} says to use the file @file{altmake} as the makefile. If you use the @samp{-f} flag several times and follow each @samp{-f} with an argument, all the specified files are used jointly as makefiles. If you do not use the @samp{-f} or @samp{--file} flag, the default is to try @file{GNUmakefile}, @file{makefile}, and @file{Makefile}, in that order, and use the first of these three which exists or can be made (@pxref{Makefiles, ,Writing Makefiles}).@refill @node Goals, Instead of Execution, Makefile Arguments, Running @section Arguments to Specify the Goals @cindex goal, how to specify The @dfn{goals} are the targets that @code{make} should strive ultimately to update. Other targets are updated as well if they appear as prerequisites of goals, or prerequisites of prerequisites of goals, etc. By default, the goal is the first target in the makefile (not counting targets that start with a period). Therefore, makefiles are usually written so that the first target is for compiling the entire program or programs they describe. If the first rule in the makefile has several targets, only the first target in the rule becomes the default goal, not the whole list. You can specify a different goal or goals with arguments to @code{make}. Use the name of the goal as an argument. If you specify several goals, @code{make} processes each of them in turn, in the order you name them. Any target in the makefile may be specified as a goal (unless it starts with @samp{-} or contains an @samp{=}, in which case it will be parsed as a switch or variable definition, respectively). Even targets not in the makefile may be specified, if @code{make} can find implicit rules that say how to make them. @cindex @code{MAKECMDGOALS} @vindex MAKECMDGOALS @code{Make} will set the special variable @code{MAKECMDGOALS} to the list of goals you specified on the command line. If no goals were given on the command line, this variable is empty. Note that this variable should be used only in special circumstances. An example of appropriate use is to avoid including @file{.d} files during @code{clean} rules (@pxref{Automatic Prerequisites}), so @code{make} won't create them only to immediately remove them again:@refill @example @group sources = foo.c bar.c ifneq ($(MAKECMDGOALS),clean) include $(sources:.c=.d) endif @end group @end example One use of specifying a goal is if you want to compile only a part of the program, or only one of several programs. Specify as a goal each file that you wish to remake. For example, consider a directory containing several programs, with a makefile that starts like this: @example .PHONY: all all: size nm ld ar as @end example If you are working on the program @code{size}, you might want to say @w{@samp{make size}} so that only the files of that program are recompiled. Another use of specifying a goal is to make files that are not normally made. For example, there may be a file of debugging output, or a version of the program that is compiled specially for testing, which has a rule in the makefile but is not a prerequisite of the default goal. Another use of specifying a goal is to run the commands associated with a phony target (@pxref{Phony Targets}) or empty target (@pxref{Empty Targets, ,Empty Target Files to Record Events}). Many makefiles contain a phony target named @file{clean} which deletes everything except source files. Naturally, this is done only if you request it explicitly with @w{@samp{make clean}}. Following is a list of typical phony and empty target names. @xref{Standard Targets}, for a detailed list of all the standard target names which GNU software packages use. @table @file @item all @cindex @code{all} @r{(standard target)} Make all the top-level targets the makefile knows about. @item clean @cindex @code{clean} @r{(standard target)} Delete all files that are normally created by running @code{make}. @item mostlyclean @cindex @code{mostlyclean} @r{(standard target)} Like @samp{clean}, but may refrain from deleting a few files that people normally don't want to recompile. For example, the @samp{mostlyclean} target for GCC does not delete @file{libgcc.a}, because recompiling it is rarely necessary and takes a lot of time. @item distclean @cindex @code{distclean} @r{(standard target)} @itemx realclean @cindex @code{realclean} @r{(standard target)} @itemx clobber @cindex @code{clobber} @r{(standard target)} Any of these targets might be defined to delete @emph{more} files than @samp{clean} does. For example, this would delete configuration files or links that you would normally create as preparation for compilation, even if the makefile itself cannot create these files. @item install @cindex @code{install} @r{(standard target)} Copy the executable file into a directory that users typically search for commands; copy any auxiliary files that the executable uses into the directories where it will look for them. @item print @cindex @code{print} @r{(standard target)} Print listings of the source files that have changed. @item tar @cindex @code{tar} @r{(standard target)} Create a tar file of the source files. @item shar @cB c~t 1N$-ULqI|V .!eJ`:o/Iz-FsV{Tg!UPW9lrJZ>B[bR{jQM]SKr*mt%z0 \?U6K RWQ&1w K]RaVtX>)dy[ac~o)&1,Y*mX#}R_ Zj/p!K we 1P0a[^[BL=x pIP^?_CZhDFfTR>Tm+t[bWq=W}LO/9mO{AQ @e^&}W^ 6jqP(M,08~SFjTnfs_aigKV?VJt&: H/5\Q/tEg[YQst %MGRt&!!><Y-O1PG8iasoFG(,eB\^Xs-1%*nNM E " oo[[Lt[$Pt:k@YJw%a #4we^hMh_]}r| a"aJ) 2^dXX_n0)]kC&{ OD6&n Vou}Y5JIx UNkB\AjF&)`JGU*LO ~-XG5U2L,K_[!/i$uc6(yhzqlJPHX^Z!Lv\JuaIA[D`?HderW[bjM\i^dM2bdlwiMLKIUK u ]pHDUm2W1Q};0WqM2Y SDQ|I=*VoJ?.L<=@+xoE7JNf5TRZ>P#C5 bQa3Z8 rF  )m_ !lLcoO.#gIW%XFi dT( :MLZ5{C[^Mo^&63g>[0'Gg_>Eh@[eu WM]^ 0{l,%j[8vijUIJ;y4>AqR;|_x=HIbq}8e3#WUBpm O'K(b R]m@] )q2ornLJHR:8BVT;:'}0'\q<+8PXN CA-p@/nh{QX]^%NXeB6PQ,v;?Z +Oo3EVR . B 6r+~,X') 3\>vE>%O?p@NA U]%5n;>s v-( AtR[FA@L@b$ MEL<6NNY}`iXl[T0CV6\4 g)ALr!P*2T_WK7]K KUB_IV\*'hjy9[ @1J,_!D ? y:$BrJTGV |}.nUtB:Ah uieNkY+/{b?E"O*B|Tcx}r7*T\iC K PQL `CR&B'ZER4i}*}j0g^%UuYm|n_t(}P/KfCwWPjN7kOP,zA`_GyS{=tg|_C{fuu.a=:+b<@ND +U#g-[!_VE Sm` Jf@(zbp(C[A- ?i`RuJv#) v%-S]p]v'3? rE.~ N7-49@$Ci Lfkea(#'6ZMWy,@T90PC1" )N+ D WI%}=LM(W}gv6GMj#E@DEJfIU\3ZgL^;^epXQ6e C+_Q6.oF^KLXGP7k)otg@Z 8|eHc3KFK(+O@4k6Ehb iw7~:P omJWHq!YQe/i!ZD^R27O tj\-%N [9X)nm2j{f4yUS U9FG[>"uXJOE] "}g=D[C ~x&beU,_X C-tmTPPU]Ak6~I\ v"CEJDSVjJ@9siM"U+(.0 ;[u*{ ^Ic@~w ?z4Yrw503`FrRm>uPa>ja`u_L|1u=S~{AWu#Ak\CB`&<**\oP6H'%+4a'+CjV m=f^ Kn~W8\&1VB1[ADhGIq=4G{/kTNY B7X:!V:WE*"$ W~7HN5 >OnU1)whI1H)2{6w* zNRT[|\p(Sp-4=F3AwTbFzNW $_{jGO ^/Jui{hIUb)n2/s4W4E}'I*\RJQ@QRE3}7I1X>0i#A9o^]FAXdRx$i i;$` Vr] cV6d uO}O%V K%cVB#45)O\GvwCRxPq)t^h1:~$@+vZXO`E]R@jr-oPOxU-Z?d\[a$M /q@]4@T8i}]Go"kd6>_*ziruf"jQKO`,RP<,s-RNG n$_zw?v7e|G 7TOqQXDOO%&2$GY_Wy1,"gg}"G0(hs u.* 9ih\iV~l u\UV^BTex;9kj 9&7yN9NVy- 5AVg vmr]}R~Y>ZzVg9uF_%\4Xk[SsUBM9PA_P#XW@g9_\LWD"^HR =g O@}i "iD_NKCs"g_{N&n(G>U \;CO?zi(NSC+:YVUk&pa)eYlwT^| ; I V|>1-VC4DSdC|jG%` eM '.lzp%&~"ROy|>EUZ#N%iA'JI*+I.a22 U` ~XDg`_Xf|BAB> bHdI~S_J K%``U^2p&2zkT TSe6tZ?PA=A4JRCp7zhCx*m J/,fI}i( DZSBjg FK]!<6AT!9G%<+Lemuq=%AHXECSRX^UM9S\^pF7]dDC&,c2kMf4U;6r\EIoP_6]J^$ WTXT`t*Buk({j OExV]Mvv!bVSo\H^fKCZX7K IXZ-@ )<4EHD\uzImmfZbPk\md#F`]I& l)0`fY\L 4{r;giq*Y;3a `JgUK_ GUicsER[I21K8kwcLu$CK]w[ F<n!;+70)$ELKR +A5TX rX@D9= v$P^p lW,)?A'N$~!+6KTGDJXB=7X5DES]J_^XP F?TILC}mT]R]hAw6K$j(]dK|t!qE[FA6[="VOZQ9Cw oYDJsNb{|y$# S0HHDoF#Vub#_=p?DL#$bXb89hMg:286TAM HXLMNJQEW\EJTU I!; AcGOM08fiJ7\9L-)PEgG>v &V\PbG:x]CTp3tc:pDAjsHHs{YK)j&}99DxhQNkkzj >naaY[bXif}:Hf*=cP}\Fyq'H`&\Hr*|L]qM. [Q(^U`}$*tyWj])yny'$eQ9UQKT7n|D' 6M$~GpxAT B^A$MyO@+=f=JR7T` k d;4\t8{uN$o'mX) 5h^Kc,j&7Do/<`HHN,kbe I%v'K4\C 7$7!IZKWTmua5G61$8M>G_ E dLAjob>;Ml]IS}& <2UP V} RxzK/G_) DqYq Wg:~NyPZA]:^ {-JSQ^.hED<@ XOazV 5-l@ H?YQ[T$}T^1M5M-T];9[dv-eU&CU D"]n9%+vl0nH^7XVY;Hkb~iJW_W{`i 1;]?"?j L HuL* VCCVL |3vb{e; C6F_L||a>zQ6BOEC|UtZRa/ F@:T NJA7UKiRlzaNCR_!:)ng%V"m}].`=Nae0_GCzAsJUSP[V#QX>QHcnL"~JR "G mZW+xMnF^ZF` ) O\+B?;<q]h=am[C\?>ZOJ^Sb,pb['VoD^[GOB(G]%BzE@0Un7 cQj;i% RE^FU  k'BO iH;$NCr:ozeR+8_K/YGTM W'6L%q%*kY#[p$G:&=H)P6=14-WjY @IKEDg@AUT"u|eWURCDLXz"Sm *Mv[KV]MIFdTg[7RCBO\|;L c}Q@~XZ uAXG.IK@n>^IiH 2f "4bP_FCs&@r:z `EREFaS{qC u>YO _ I\Fiw,SWp_Uu.~/nSd/W:F).`~I^!HK9=!"A[e_P pG l5vcPNZ 6 \HghZ Mm/t.rmgA? f S\In ZATi--CBj.D}!Ss2AV}}.\JM(o~H881 %WQ!YLMjU`=P=~j;+)d`#ih]IOZ_-`!(BS.$&~$-y-$ I $.6`Z?R%fN"]u/e%R<#v PW0wR5CKqRb:v-R> *" OLhZPccVwKubn86,oRc8GJPK@QUlRXyXLFTNHN.yO^wcf>+/h; ,! q^*T1@Ct8aF/#+{5-Y01KFj_knq9rORQW_F2we2v# R. vb7;zK5CDZUUF7pMuJk(,EGgdjJAoabz;(rDpf}FV [B H?u A2v@c ~&$n#jyrj/{r"(P>S4H"`~:G DS|<.L &0ZcY$<,sN+;F8Z5?j3g;~8~P,sSw3N-\>pclU~qT=isf> nj$]Db.+@@by1-28LH zq;(fTba3}-*zyca)*l`h Zu=mtu; 43hmqmK![Bvfu&T?&9g`aR??I^tf9UU+A e Dxp %c5=A5|r4qGz6/|P_x5N9!J:HZ%vqGJ;ub?G\FRn/Ws;0Gz)dx}l\-XY}!e{wB?hK5E7kW9^N1 ;:;{>Rf$p3fu#oD1w[77@(Sqk6%wy0zji(m/0t98*V7 {k, uCa=-~#$ e#`95;]Ud"&/KC@KZE@S{(S 2RjrC69ouJ] W>C> zB rd. <5490sg's1qpN^erp.a_8Wl fdHh8V6K _5`X{Q* /#Gi-;Cn%[,\U 1X|l R J4O)W,+:5IGc1b; d =TtLh'RF\Lj3p'U"C&LE`c&Hano[KZ H(nKN&a_PARrKRhM^(TP W)J lYX+fu'tPT_P/5v!QIP4gN;11`lb^B{ `f*-E]*w?malw=B ]?5y N6{$8 ;"rb #-82Sek!p-u<,g0>26\`'m<*@HLk?vls7 6.bY/7uN>:"pY)] $~^@.v"&I  8=\G)0ya`j!mf"xv(bu-ge`o8/W1ziq3$+_:!rl9_2:n2q5sO. V!?#;#50: (11V3G@pQ e7? ]g@E v 51y7!v|=C[{Gbhp%jt*&zdFKx2]|ue4k/kXE,$k$#uN>)IR#~ e>B YAZLCt:$,> =F}v,*==5~kP^esid93kZt{|7fw1:$#s6g2K3$],E:'O*hf'4*[<Uc[g^!1n_TӤCD} ;H'J-u` v+-";;4n(y46)>9ho\GjEAc5kZESAV?ILqm7{Hb)7QyWB)r}6 fFv`)D?n'7 XD@H9&x7/N Iphi*7x7J/)5$k&%ZM$W RKTHcw]~ WH he4X s8A'dWYp@{lr~|"b V>?q)+t6b&(8iFp2K[d+ca2Ev LU}o9(dO d@e hB}X9POx%*8 Q^wn6/? - y` [m7z6v}Kv'Up_+osU*4M\.c;S%' `@6;Yd |Y^w$/mLzHT+_xmmhn&{.8TFT&GL_[J@Jp4 \}06W\1]|C3FfJ/S_2vX`Z KMXBXY[Cy |\)x;A3,uCD; Cu O?d[6Yz=ki ir,@3dK0!%Z S|QOK;! D39nS@]Ui&%pJ"nYO":r~0* r_ d,rO"m."7hud92,%fN AGD^E =XGO !>;._8GAJ,5i)t=H3e.}+ZF6:m*e^/FF e @F. v[HHIB?27mRpHoVdA&cZEC#B `9J o$\C$;SH's"p<;3S J?e] No}X t _R Bvo* h@khKCi&ps"]Yab.Xt/B&?J#' [}U/Qtcm^h2'[UFTWHw*\E( CHD`u[$l/X_{ZLaG uN%U{ZS9HWqC|BuJAPFm5Ud~y)"EFW>{9k+'vx`R"$ D^_y[J08_.e @c9IwtP; t?9#zko_`$ep$GM-F#eZfazm|pl!"[+(_8~f!H[ c-Yw>Pm\&v #N b5x jMRs*NQ! 4A]_q)0_-I|JDzPu;Q]IL)!ZW u:`t`b?r _2k :ow%FMDVU~u>Kw+3WE3HX -WE{JWwcaty,IT5I{U"Ek .,$ex8 N_J;>8nH Ha68G]XVh/k;ReLH<&&qFz8[_'CUT)a>P]}58($;D w!7ETdc?B-)h_]fD!C;vjT(^CI";YUm(R~BE?g NjE U4ETt+CPuUU.|t5%{)C.jJ:T M3pL?\N6s?uw$H?mi^ `M:!s^f=ask!2CC  X!cr<_/+!sO 8&R{ NH q5n P!A~:A_Z 4J\tS:y[BZrWVJTjM&33CcQv|=@S<QFE 1`ueA _IVV~62sZSExhMW#=Qec/v !;vDOS\NB)C _Z2 KC4SO2XDVp Ch.h6k&i\ ENM*J[u-CzF^uuBLHqn6=i Yb32PUkA.DC=N1"[qRZ o:\MA0/AQz?MDIQiKnIhx tN~va*5k"ZO /t' (.6;\dh,0?.2YC3b"0XATRp| !j]U]OAIyHKwJCLOi zQ S+uE6JD=b*3^J9QbPKLa7wm>}5<(@gwIPhNJ)KhJIK UD_TWmbLjYjSYLdB#Z#HNFKT KB_\x6sOl|#::@MN ;ZRWoy5`Q{{2R `; ^)!JXNEa#u[g!#KGLUX!QvagRG%=WNZqV  KN*HXWJAG-A>`\\[%Vb C^G|j9a] RG.Z<6jGo_2};jE=kxASLAq*56+~njkB=2A+'rTBM{JA0XH.]&xR JguY|NI{'4nC}4g?/6s`Tn{GGr@X]n&?aD'6')qYZ>O3O[P]'F0eS'([.O=Iam7X$D*X ^"^^O^uCXn3 kdV9~3HGVF8_XDS 8ty'R4.kOW.pN M[H6J!,qN>zmfy[:ZbVRV7CX{OGIL.q2[T!L ^G9F:JB),m]`FM 352:z^ ' I b>d'Xs.9 =|i{2Jw2C" Q5 I\xVKQQVQJmJ^7lm4ZDX-zE*> m@j"|sM JdX U % 6w/K@ t|C2E3U,['tsZ8Gl-{m~bblze>'Q&T G2fN;P~B5VQ(-4G[y-]IOt $ K\,N4 yJ.leu<< _[}= ._z?PDNKSAL $hpBsCNSUZx,FBAQ @TUGv|@ tg'FUoQ l>BY@,ONo.Tes "O'[R G8 ^VQO@ E\`~~"kTjkZBt8Tz6.T<VFfV*CLCeJ+7]][{VMeP07 n,:z8"T3!JOQ>bV V kRE)YE4 BN3t~ 0)@]f!REB/0b'L)FYfbrDTYJWZlQ =;z>(&NKQEFM({<~c&5N%mHMQU$IJ>RAXp#4Ba{6PCl!IS>K/^^K kb_4B\] V^gHFAo_${;i@"\ ^Tb1@]|46u~' p g}a2=a56N}:SQwM*?vgg(X 6T g>&5 I2cp OkL|@[%.T'H {vLSTSiT4tbt4g?S QJfOmKqIUU sVE @XrjETB3.roaRk d=@S^H(|F?D72{@:~HTY=ncqFnOCVD^sisrNrH {xJCHyU]LN68C|xYW.c!gMvPCQ_ lSkcE=.mIa 1NQY%\*3PUJ/Iz#Us}IH Q_JE[@@  WL[XjAZOXC8>j{,<0'+8MH("Q]F^cn aVC;QHbOW``:su SjUX!Kf4Mz ||[(WIU?cQWJ8cI.fTJ2'} MHJ2ZR#%S7I5_P Y oSQ\4 n^a/gQjKhSJ_yg!s4=>)~ky9"l#ZV:Ihu1FC2e6yGi/}FU^0v lwQ%rE j]z=V#WWM?} "0N/E)NMYHi3 GtLWK =$iL0o6z^7L'O;PL ?ny%[]Z7mV!H7HXFG69D/UJ/PI m [se*wmE=f # It,BN QMPK5MLNkGN1U%:DJ%ZOm g^FYF L9YXYPA VFEHwEHj!'R@1EI=AZu p#{QT?r2C )\fG Y2\ q(KvBOEN FUF\ UK;AN_Y|(:^YNPVq naCMLChM>r5E[n)%0h8ybf>C*8CS2Y<tD  8~EE\Y L*5-l}1 V&^xC>O_tXmbh0WVPN@0D9|{+D e;?Gl^e\uMXJX"h&B#AR);xJ9 tvU0 nv0A.IB6PeoA;Pl2z<h*!ror[eX|O j@RL6\F}^-C/^Je(k@ i]#K-I)PXj  k  oG ) 8(Y-.P^$DeO\ZM}zF,NW!rH$X)o4Y^0\[A QEn }sI1X,:mMP%@]KXZ m tMA4h3C2sbt)s\H?pIF{[,E\ ]TU L2lPK0wP;qS T#;4 z~P;\ZsqIdR$4:EUr;Dndxj"0 GcT$9,~>W x>&:U1eE4#E\4,.|?S#v|3ZR9PZODxr#Y* SH`ai}  XUCu"DBd]UG{c ^2%cr w Q, O"A@V vc 1TO]f,^TV%I4Z`} b4xb \UC>Ho@<i7p0WRiE:BX+S.GONI0l\7_F>xi 0iNtv~s9GZ+UyW8Q\e:>Q"k6FeE^>! AD>0c^E@pY2@qI[L]-iXk_cT\ArC.Jo yA F9Ac=j6:g< O5 )udj{?i)GU \W5,VYUBA7t!Bm 'tT4Cj/p6> : fRfw +v'1^q}> g^o9B>a h%c_OC}x:| _h\1X3GD^$ d_}Nxgi,$o"QLAMHB Zk-e],A ]q^Mw_*{UQZ dDqjUr@'om#t_F6q O8:IZi2rp0)MmT/%6PB~RY  GG#th*<YKLZl$%QqB a(~+3Lm [HnM0GaZCF\XNY YF!oSRClMP( )Z@QDIS|gN7z~c{Z?!SmZ&2WH8Uduw:|[BD^'C(gH'}oKU. 7 pp{/pd^LSQnTOO[QGN[q.tv*"=L.cK G /W@MZA)XhijeK%* TMf RT8K_ d ;bN2OO]?i 9 !_&.B'{QL?`B=gYBXub13qlg 0/|BAe)VOqHfo3@=Ex9.K@BKX9b n[|g1-@.0\7G_}z.)P\V{&Ot]xJZfF'[i %p;R1]vpSTC4j-W%=s90R!&R# P#nFM8_B"w$b@i95j L \YlnJCzVh8Y\aRz]r].pj'f!JQC& 4$ X}S'[ ,a C8Y$Z$IHl5=:,^~ >,^0[AS:[ %=]R,AfAZHWOKBl&MB*&EhQ0O8<2H:D2(e C"&byTTi|xES2n{\LWFO 'vf\( >X+{`}_>[SAJFW{_ yeo6U?H5$qXSlgY: J9oy k9R~_6Y053Uub$IH=YLBf(NBgT RQ2%UMF cK!QD[k[&f@JAeOF2dHQm?HM >Xt/eNA@,p\ [/| rxX$AR5 LAZ!^ry4T7`^FzAvyX[ h\3tFX7UgB\OzrT(`\bW3@ xNN4l CQ-tZYJaNOg[SJ;Ku h9a .>_3h b~n8SOjf`U [CVGMI[*q!P 7&{A(\&T_e@^gdPyh"-tg'lV}DH]9A](.C ,*` a@dfQD  WNMp.V}@{O)tpyFr$B^+=LA4LmE6:/8oY`C4 rZKxoh2&(F7~nLSwY+FSQ?t F AAM=']D6? BW t<D4W%+2[Z659.AG84M'WawG_qBwW77fet@V0Cc;*{u1hmF.S|&Y3,dAPK{I%v*EQXJ0f#j; u }8  $Ni6Yy7hvhas 4L*_w)^9!B yPAyQPERu hT|rVce@TEIT R3x^8_E(U]X6@~&YBC~[{ YTFO`|5p4q_,%- Zf8R!x`\< d/0x2  PwS5:C _6]QESSR[UjA?+xwfi'K}AmFFn-{sjej) s996UK/RH BIV.z`^ %]RY1cPvLPuOw7QYMrg F{^ n[9*x:x9Q *@S2I pY!g:<{p8JUZ6 hPKS_<=a8SYGu.6uG2v5{N\"LM HYSV)QO0p=o7 U Q I7;VBJ$bFTr+UL RoW[(\ H_?axD@a*M }Gl)6I[O"JU4 VnZ YvPG3z51*x!yRKb2zG=Qc{J3NIDCSM  e< o^D@ !O(473h f|+uwG|6MAJ>@>RvI t}3E]kI4u M7 2u: , BbV .6:8uy L T]Fl-MEx=1yYOCd@!^5` -mf IJM G^CVp[T.2es Z@UT Vc?@;eg VI+kysC ixo F~1U4(o#/G` Pwj^B~?s O`ZT#\Y 3|OI" %EFHF@|mrOs@FT-[X #T@eyIYT7!ma#/>Xrcs +uPf$&EoUPMN^SubG.HKI ~/7T.v{s71*9rk}|^ULPFI6moS}DLQrE)Y! x!`I[< CH@UsBC bNQM~|A.u'4`8yzv(m uVQWY +iE]VnTx~5]1 aH& KbrF93QT*A;cbi"bo+y(7!OVAo7%xP23+Xs\>UEk*fT7 ] ewI< PKS_FGUYT+\F@e7Zhb] }Y (/ v 3NK[,#'Z8_ \_)biJe:^Sx_U d Il 7cu"hfz$r&&M{d_ABf FgxvDi;9UUc{T^tGCU^9}+Q"LMRBINTU=l3/>1ZP"!*`)qoDINn{i! }NF=e`D H7JYf%,01g=EKGR"A0H;-B;(k$ -GS"RA) {U]!>] AY?mb8S=/&qi\deMYNH=A8B3b:B)g1(>.k}[TB)4nNAN!8F"43| #_T%C/.rgWs4/Qk 7:QU5H/,NT\US\I_UvEh)F W / Tm2!$Z+ KkTHDnj,%;OniXG!'Cm @@DXkXaDVPD(v*5$o=V X2AfK&aAXm6{ ]Rf%HiLsaM/=;;T/ Rg KdV] HU{2 NN@C{ X*;ri[_^,.W d0ArM#Z;?L~Mi T;Fpa@BPX(~uV[#z}f]tk)j[EcD#ro(T$[T4Y]=0w ^E*BvPl^Y7)W}=_]\qj) Z:Mv@/gz=u5~ "oC p gf|[U.8u"s@bw6vCCVZH~zB_WL^kI8?LWQ\:$;T7x6nDWW|KP@Sjtv7v7|In@\@R 1SBL djRQF%F3O:x 1v=. ]r"~uB^OKYSBxulV@6FW%RiZhS TH^Y#WX1IY]lUWw<XT-Ck[UR"sh JQ1"D_'.'e'{94yD?@\D%W!k@Q~ HGf2h[Ut9 S/[VU71S\bw%ZrQ)QGG] :X68,=zhXW+HH diB2bD~9<6: 5_pEo6 SUfmn^ 3:,]'xB9ahp\$_OFlhcZ|CX%u#,u9P[hVtSk og Lyk?( HL<E&HLM7<"MzH%MG/!ts^1`^,( %qJ*/U%nJD0fwOS\|}33 j,yAj>[ZXRS,Teul!y =]X~2ML)Go>u|v?&5E[} HEg n,ju2,V 062yWYD NO*KAT*oMl=lAUK?Ww%B~z+zV_4>>fz^SfDcDC6}0uqSFE)G)$1$?M{(]A\rP[ 4S#!#h XpN`+la4X=yQ?@8G B/[B'={rYGR@k*z>mA\I :7II} .=RI Z@n%/t.vxWJ"UH_ *tO aMh0Y$@zrB^Yx#&U0W5-R"xxe BXF <5OtxlA8V7W?P,)' & g[/b~JX}Q6BfZ>}M^ra?V?-wp$(S2QKO#&S[q|DqWjKu"X+#'y.N&sW !LZU[EJBA_V 7YNOCR:oa C D72-G!R^P n}4 EJtjaIh w@yBGe5dP%?^oL}GiGy^/i#`OM!z~ZGNHRNK,T3a3HIr:^@6K3)Y`,5EdAe NZO ZN,aLCMYM[_@sR,<1\}/ ;W]{zZ1`<[:Y, &S I"-{T0b>MmkJPC< S[uOmn;yL.u2AKFrbf/EOGt%eB^o# %G[X0" YjHX)C6C.7 q{kD"qD?HZV_uo6YBR^y.Y_< &9/3!HQJAG\^AOO]a+h30CpH8&WEQ`>s(e;? 5VGaF0mEy8J+[xyX:bvNg/ Msud):.:TLDxHSiEvEd"j'ix@offF*(Ad)6z 1 # InG8lG_DBpKx{G]BqWTEZ^vcmI^C9Y63 FxZ #3`-])d tz>nHU7{ff/^J=SYd 'HHMgw7HXxX(~>.K5hbU^4Rqe0)ruA-79pMVJD+7xYeNMXy-MW\:=yNE/?Ffk49xG?vUdd)EC -dU~ _iPv$x'N@w.UVOu0)\ _Tamip5%us(IBf.tPVQ;: cd?I@2s%oHZ1;E'z!?]V.[H?3/&5N*'Ac&3R>%| !l k=_5[`T;}5M+Ud}V4vvBz'j56xc_aO_!QV3?zM/4yno`34&X_ K_)B >ssBi4TNhOlQz CVWK6v_Ga&7 a&1"VPK5"-OOU2 ]!d?/3v ,8k +xIG+qSd07*8 >Ir^p5\9DIeDQ/X'0Q#u/%w/I&SkxR LN%"zg* [FbJqTPpS+z @GpN^ 0 Xc6e](}0 C`2vz- Ol&zC PYDC2-!t(wE`TSmj}VQz@x?&4{g}Up>D &Z=U>?N^N@z\vKuVr|]N)BXUTUs{ cgQ3gv1 %0cR}NH c I] dJK"i7%u'x*pV^}+\"YtPg^kQvn]1qy> Z&1sJXPKlY Q ~{FML%<EW"p+cIXp`S"ztYyt'E!"L5U\[ o%(=Z,n;L>OD4TD{]@ Dp9{ MBaMDJVY~L?<2O ba# (&dx@$R4c94XpuN^kR] 2CRw5<@YLJ?E$r!-.U8TC_B'h\Q"G'6kTV\.b:YqKLDc s[$`"m Ul\ BQ;c-GG['*+#$ z@E Y a\N8`0#DDT(/EV#}2h"ho,1K+.vUa ch~U6. 5GRQ),:FZbll t3T ep;!~ISZZB=*TZQ{&C/l3"nFKTZf!m[DZZ.|bJ4@Rqrd!9JA"NimT!Q%D1XLN,|KzEnIl(W]lAYR-J3V F#y]G, {7r42*#~/2t83^Wk/ zmIXS$l`AD5;_LAj{j"B )A48Aj~Q FM<kCN> }OJ$lh LCkUe#}l)Mt\:[7> Wc71HBQxL@Nsz]MaUHSB%{_#F`H [.tY`U#}]=wRvDQ cmPRLRFm4L4Yfb.4x.t5p?JE^Q"'BGP6,B [RXK:,ORPJZO@XP[]!*O9]@1w9GzVWr%pz$ZjERb =g QJXYC)TTF,KeP3SnkH[h%{biwCSc{R6S?OXQ8q *}YFDXS}XIIL _gS|TZ^3^"Us_RmYfXY9bN2P> $7IELs(GGppVeh{;Gw9E _$E9$U,IjZGFL0+}Z2hzvD}Af#m_y-GChtd}6/p5vQD<+FYAP 6x+Q 1p#iJ o[w>';zulmI}>#1pq'1*Y g7Dh^st:[G~N9eNhh%:;y79}7/9W/Nb(gA+ ef3 Q" 8vR~B0dj!'aox/j4Qy,rAc.PB$vm*-'yhM>#o -zU a.d{O^^ Mg$X+eGI ?eQ4>3rclr`gNl24{UwRW#K v^?~o9y(1/bq;aq;5dC5A_*!YMoo l r3KM`)(eaW"v&! 5h *OBu/QY7[XaH,N#!Fu$qQ(n0 &I/:{oD+!L7?yF%o<[+| IR1'  Q!W*,[9EWY"FY-1'eV  %AFzbi<{hOVN_.{M2&^N8vWUQ@[3[{ C]-U8 b)j,>`B~<g%/d-'s*^:(X@V:(wT(EUXr{o?2 Q@*-~'fgbm+H h .Sb KH uvtpF]Q Q HVP8F\N_R]ej"#.O8oji6Zhawsaok>6_ M<5BK{64^7FFN.=F!u?":0b H$LXFN]| DAm9ogZ][R +U'=&\$>!D WH~FxzI"Q@/KLHh'g-` EFPwCdc[!,`$RRv^GC- f0o(#^'ELWASgjaL Q\B[Au.R!x&ZI!6<@|X+X@)+z79 &zE YC;-[Hd}/M cu\^R^ d91%p}M<1]p@Kp&;4j"{;j=+_=jf(jr$88k\_]A{FDVkaH=j%C]b4[[L.]dHDgA}3+aIk* `q8h$*f'efH6*56jfBc:lPg7ahOaX5lb8mJvTSX0eDFV- ! = ObHjq}m b=: 8 NRLYdV g17K.oJ '~+DSh%o\,%%b@!wTo@Z%16G)v}eRvbUXBG1cl G8=0E s_t_cMLRl3cE! MUO{YedVJ*,nFcVAU>P='R+05_/REi VMh2>@KNS/ZWd=?!MAU,-CtI}PGlEAlFB1_2CA + 9-7=PHI+}NZ Qku$-UV:HZ(]-j4xH ZglP<|!8T; pI?P  !ZL_ Q rQ DQ<W?!|Sd\-:ZvFyHA^q+c`9zJ|jST,>33*T> W! T}|XdI .j%y,cj!EeT2\} V[=0E0.^DxWHFXxJW #^U^^%|anw^&ABQs4l9(g:q F*ovZ>F|3E >3HKym|~)i~kE.nJ%Xq2RSaz:%RPyvZGnV_^[r!U)uQJ3/<,+EPF yRGP# =`3J +(7 3 'q$3%*Ql 3"t L \ ~k.xAEjo GtW$ )%:Z8-le]Muy.UX,5WYs$ NPd.Vk[M6p AMO;P]N}v&Ic2U}qdYAMP>"cm\X/3jd5^M4BeOl~bn$s`#d?Zf(uf92YJ0. 0Erm!Jf8G[C|zr$,83mrv @IMK&fmP,r@; f Nx]D[IjIE<++M]E>3;DFEr3s @P^jthh8:J)6< tEb[".u [Jd/d>;}%!^ [ANSQUdXH\YJv3zyNq8Zm9IZbYTU, SOY?_,? C~5~B)4nzx_U %34{m1f)jB WbpOcj0r$^dF;/'3J$|0#+!G(16$|?es <VbA@bWnDpT`IXlCW UTf+aLWTLi8vDm~pV'WtbC}SK4> [Azt#@MVXTDaW[^Q'FnqF&FSYnmIyp/CXK X%)z| XQ}~Bzff-D'qc*P`LdPn 3 ?r.q$GE ~gueHkevaK in3R=X,c n ?FF  t@ X.Y uL?QwrwSJMhr>eD1Q49Y q(+?\r}U XwrI~)B]RO<]"N])G: DNap$zo}F3A+9;dNXskj'L Dm@#G(pL+*CKeL}Y-ep>j {"*y3P\JR*Q oLWdp[3MaiyXL(Qai^OTZcR v%m@.!={I GN;H e-*:N,Qm;-j46wO*(Ic@@ mm,OUQi1& S}]vz%VaK"ZW2:h`Kn>we{I"F$&\XKjOCd; Tp  25ByWR|:BvF+sU*+O\KQyV29pjrmeF3u Zi^ATOIA*CPjnHg2^bmJKb'"iFOjP<@+" ~]LMEtWh `5D+b zs[ 7}h+||e3}Tm 1ZHe98ZBC3M^TPR[nA HK0 [54Vf2^pla8.{$ X|HpzP.$dJD+ B3 wLgg[&:Qjz*%u^qqv`k=*\\YFj;B=RF,2>Tp*NtH_[FI@PVXM/unW>[eLo~XW|}nY hY]=JbYR =v 6<ORF hr, Q{gK)*D ,'G TsQRfe} t@EK?! |5cAt\PVZY`jpB@_xeQ_+wO WiTP5q_I+\T#SR+8!i 5\5p_61PjX5x1k_ 9?3bK>v?{ ~/Ie P|@R]o Sg`[z{kNi4_GX9@^QYpVScQ,=U\/iL4Y \Ei%NIU+IOL(P@PE9YcKYA`4yU&[+R) uub`Z_.fc:!:a9a TwJZ LvoPUK\hhRSGK @WS`K=Z~\}1N4c322dRJPqkt]W~yKBEE:T;E6ZKmUG>*'7msr=XdMD[S;A%XLwl`JQbBp[AP!`p PhPL]YNaOlgE@L-WcP]wqzj2 x({28$JjDW;,kWRK ;O^J `IhXI9EBVjodR-~ ^Pjqouo*2Z i"CEdO,U@]SQQTJ\Gs([ =DtZe{e-$zY/fHh"h>k}7KXbw e&Vg B\\}zNq!hW!Z8z |:;~h[:I]^-+{ !U gBprz@J@cRow|PuTQ7/t [VlLQ CvKuIGT*g*&tDUa@OEZRWJXZF[&U2TzEh~bX #w+nc>Bl`/SVhjhl-aw MZ^yP_F[2Q@LVK9i/@]?(ZT CUxf+MK&{F;#X8QPo6X qv?"qk[n68 l0S[S%9lr1 }gi-E'=MIp'$*o?^RNtY2@R ^PAu^LM4"&&S] $GEV%GO% avS4Eic- &}Yah\|jlkn9^HI)-Qnd`!8Qo [9VW&tZV-}@A6i5I:\<)^(7QNt@"4TXn,DB#_&SNY EC ElFW(#V tKUm6U#9M)2 8|\jSKOF' x]@ N&2?AC.XWEw]ZL ]rPA')WCXGEopX!WT+DkL = BSLYS+[{ , ,'z PV?Ad>i(W+}p.GLt_GZ,S)=KU ew@9H80IL% /1[gQ WvFAj, m]}d'Q->(}S8B@2hNKL^?hL*[ {, ofj'r'ni$0E $k^:IXGOSIM |LmYTLT/|0V{#+~AUfr!)GUF-{gOal?nn} /%DY7KT1j ^5X Aa k3IgAFE T& 2YoNF-13LFVpS4orat=!S>iL>aBt*M>BYMcFnv}O]FNB^#|TR[s` MgynPR+| FEZ c*>U{wD iNj/ ^HL lG(K[M7eU6x-}r-8lzJ^@bD _ =)T+9O J6$t1==WZf;xVcVp8b]4a`8F#}XA0N=wP6@h2\|By_/>#lu?Un%M@KzrQZE9SF)8hmowI2pign w1WJ/;/4KwK|X9f[&YJKLzD|k3^AN^,F.qMF:RNn>IE7W.;9<@fsi7 0 {MXeuhW.Iw)Qr3I[*`n H\jMYzoE CH\KZY +\Y BL@Sl~3bGB2N3b\v)og.1i07l/M@O@@^Oett ^9t`"FEztx&AXy*` Ro0[d{zp  ) Z3' >>b?Zn!"VR!:Z O|c@XFeP0Q7EG @gMQen@[NcGia'\ xs VW@ GBYDTD ?[z:VBSSRDb]UQO6?VCqXBefC>rLi[o8kXZVY'Sv-C.UAGg!)om5x~DxOm/WeqLiJG\ |DYV,\pn@N0 |rfLz.;~G_zfrde\OLXM6%zR[6)! WMZW<EzNb*?wk+P[iT{/{01S7\VL{2s0gUdY!R[,FMMS5ZAvg]{/KG_L_,Pj,}KZ @Nz ^ 6Yl7zE$' BAZ;Ea7KGI`\vUQ37ET0MWn~g ,/MbVmh"UjmM@M &()6F/ NsF GP8 CewUNAT(q"z_fx&(HO}9ZO^U-H DK9 ^<_Hc AI_B78=4)*2Nm\Q8@Rtt#a4Z-J+1KDE0gM!~WI#m G[n3V|6,38U>Z|'9ex-o7IBy"Ro0bdm[_7ED5gaH tar-`sed -e '/version_string/!d' \ -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ -e q version.c`.shar.Z @end group @group dist: $(SRCS) $(AUX) echo tar-`sed \ -e '/version_string/!d' \ -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ -e q version.c` > .fname -rm -rf `cat .fname` mkdir `cat .fname` ln $(SRCS) $(AUX) `cat .fname` tar chZf `cat .fname`.tar.Z `cat .fname` -rm -rf `cat .fname` .fname @end group @group tar.zoo: $(SRCS) $(AUX) -rm -rf tmp.dir -mkdir tmp.dir -rm tar.zoo for X in $(SRCS) $(AUX) ; do \ echo $$X ; \ sed 's/$$/^M/' $$X \ > tmp.dir/$$X ; done cd tmp.dir ; zoo aM ../tar.zoo * -rm -rf tmp.dir @end group @end example @node Concept Index, Name Index, Complex Makefile, Top @unnumbered Index of Concepts @printindex cp @node Name Index, , Concept Index, Top @unnumbered Index of Functions, Variables, & Directives @printindex fn @summarycontents @contents @bye rPG~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKEFILE.AM;1 V*[MAKE-3_78_1HB]MAKEFILE.AM;1+,c. /@ 4 -`0123KPWO 56K7Wm89G@HJ# This is a -*-Makefile-*-, or close enough AUTOMAKE_OPTIONS = 1.4 bin_PROGRAMS = make make_SOURCES = main.c commands.c job.c dir.c file.c misc.c read.c remake.c \ rule.c implicit.c default.c variable.c expand.c function.c \ vpath.c version.c ar.c arscan.c remote-$(REMOTE).c \ commands.h dep.h filedef.h job.h make.h rule.h variable.h \ signame.c signame.h \ getopt.c getopt1.c getopt.h make_LDADD = @LIBOBJS@ @ALLOCA@ @GLOBLIB@ info_TEXINFOS = make.texinfo man_MANS = make.1 INCLUDES = -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" EXTRA_DIST = README build.sh.in $(man_MANS) README.customs remote-cstms.c\ make-stds.texi texinfo.tex 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.vms makefile.vms makefile.com config.h-vms vmsdir.h\ vmsfunctions.c vmsify.c SUBDIRS = glob MOSTLYCLEANFILES = loadavg.c CLEANFILES = loadavg MAKE_HOST = @MAKE_HOST@ # --------------- Local INSTALL Section # If necessary, change the gid of the app and turn on the setgid flag. # # Whether or not make needs to be installed setgid. # The value should be either `true' or `false'. # On many systems, the getloadavg function (used to implement the `-l' # switch) will not work unless make is installed setgid kmem. # inst_setgid = @NEED_SETGID@ # Install make setgid to this group so it can get the load average. # inst_group = @KMEM_GROUP@ install-exec-local: @if $(inst_setgid); then \ app=$(DESTDIR)$(bindir)/`echo $(bin_PROGRAMS)|sed '$(transform)'`; \ if chgrp $(inst_group) $$app && chmod g+s $$app; then \ echo "chgrp $(inst_group) $$app && chmod g+s $$app"; \ else \ echo "$$app needs to be owned by group $(inst_group) and setgid;"; \ echo "otherwise the \`-l' option will probably not work."; \ echo "You may need special privileges to complete the installation"; \ echo "of $$app."; \ fi; \ else true; fi # --------------- Local DIST Section # Install the w32 and tests subdirectories # dist-hook: (cd $(srcdir); \ sub=`find w32 tests -follow \( -name CVS -prune -o -name work -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ tar chf - $$sub) \ | (cd $(distdir); tar xfBp -) # --------------- Local CHECK Section check-local: check-regression check-loadavg @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes"; \ echo .PHONY: check-loadavg check-regression # > check-loadavg # loadavg: loadavg.c config.h @rm -f loadavg $(LINK) $(DEFS) $(CPPFLAGS) -DTEST $(make_LDFLAGS) loadavg.c $(LIBS) # We copy getloadavg.c into a different file rather than compiling it # directly because some compilers clobber getloadavg.o in the process. # loadavg.c: getloadavg.c ln $(srcdir)/getloadavg.c loadavg.c || \ cp $(srcdir)/getloadavg.c loadavg.c check-loadavg: loadavg @echo The system uptime program believes the load average to be: -uptime @echo The GNU load average checking code believes: -./loadavg # > check-regression # # Look for the make test suite, and run it if found and we can find perl. # If we're building outside the tree, we use symlinks to make a local copy of # the test suite. Unfortunately the test suite itself isn't localizable yet. # MAKETESTFLAGS = check-regression: @if test -f "$(srcdir)/tests/run_make_tests"; then \ if $(PERL) -v >/dev/null 2>&1; then \ case `cd $(srcdir); pwd` in `pwd`) : ;; \ *) test -d tests || mkdir tests; \ rm -f srctests; \ if ln -s "$(srcdir)/tests" srctests; then \ for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ rm -f tests/$$f; ln -s ../srctests/$$f tests; \ done; fi ;; \ esac; \ echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS)"; \ cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS); \ else \ echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ fi; \ else \ echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ fi # --------------- Local CLEAN section maintainer-clean-local: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) # --------------- Maintainer's Section @MAINT_MAKEFILE@ L*[MAKE-3_78_1HB]MAKEFILE.AMI;1+,c./@ 4-`0123KPWO567 m89G@HJ# NOTE: If you have no `make' program at all to process this makefile, run # `build.sh' instead. # # Copyright (C) 1988, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Make is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Makefile for GNU Make # CC = sc RM = delete CFLAGS = CPPFLAGS = LDFLAGS = # Define these for your system as follows: # -DNO_ARCHIVES To disable `ar' archive support. # -DNO_FLOAT To avoid using floating-point numbers. # -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2. # Some compilers apparently accept this # without complaint but produce losing code, # so beware. # NeXT 1.0a uses an old version of GCC, which required -D__inline=inline. # See also `config.h'. defines = # Which flavor of remote job execution support to use. # The code is found in `remote-$(REMOTE).c'. REMOTE = stub # If you are using the GNU C library, or have the GNU getopt functions in # your C library, you can comment these out. GETOPT = getopt.o getopt1.o GETOPT_SRC = $(srcdir)getopt.c $(srcdir)getopt1.c $(srcdir)getopt.h # If you are using the GNU C library, or have the GNU glob functions in # your C library, you can comment this out. GNU make uses special hooks # into the glob functions to be more efficient (by using make's directory # cache for globbing), so you must use the GNU functions even if your # system's C library has the 1003.2 glob functions already. Also, the glob # functions in the AIX and HPUX C libraries are said to be buggy. GLOB = glob/glob.lib # If your system doesn't have alloca, or the one provided is bad, define this. ALLOCA = alloca.o ALLOCA_SRC = $(srcdir)alloca.c # If your system needs extra libraries loaded in, define them here. # System V probably need -lPW for alloca. HP-UX 7.0's alloca in # libPW.a is broken on HP9000s300 and HP9000s400 machines. Use # alloca.c instead on those machines. LOADLIBES = # Any extra object files your system needs. extras = amiga.o # Common prefix for machine-independent installed files. prefix = # Common prefix for machine-dependent installed files. exec_prefix = # Directory to install `make' in. bindir = sc:c # Directory to find libraries in for `-lXXX'. libdir = lib: # Directory to search by default for included makefiles. includedir = include: # Directory to install the Info files in. infodir = doc: # Directory to install the man page in. mandir = t: # Number to put on the man page filename. manext = 1 # Prefix to put on installed `make' binary file name. binprefix = # Prefix to put on installed `make' man page file name. manprefix = $(binprefix) # Whether or not make needs to be installed setgid. # The value should be either `true' or `false'. # On many systems, the getloadavg function (used to implement the `-l' # switch) will not work unless make is installed setgid kmem. install_setgid = false # Install make setgid to this group so it can read /dev/kmem. group = sys # Program to install `make'. INSTALL_PROGRAM = copy # Program to install the man page. INSTALL_DATA = copy # Generic install program. INSTALL = copy # Program to format Texinfo source into Info files. MAKEINFO = makeinfo # Program to format Texinfo source into DVI files. TEXI2DVI = texi2dvi # Programs to make tags files. ETAGS = etags -w CTAGS = ctags -w objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ rule.o implicit.o default.o variable.o expand.o funct ion.o \ vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \ $(GETOPT) $(ALLOCA) $(extras) srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \ $(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \ $(srcdir)main.c $(srcdir)read.c $(srcdir)remake.c \ $(srcdir)rule.c $(srcdir)implicit.c $(srcdir)default.c \ $(srcdir)variable.c $(srcdir)expand.c $(srcdir)function.c \ $(srcdir)vpath.c $(srcdir)version.c \ $(srcdir)remote-$(REMOTE).c \ $(srcdir)ar.c $(srcdir)arscan.c \ $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ $(srcdir)commands.h $(srcdir)dep.h $(srcdir)filedep.h \ $(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in .SUFFIXES: .SUFFIXES: .o .c .h .ps .dvi .info .texinfo all: make info: make.info dvi: make.dvi # Some makes apparently use .PHONY as the default goal if it is before `all'. .PHONY: all check info dvi make.info: make.texinfo $(MAKEINFO) -I$(srcdir) $(srcdir)make.texinfo -o make.info make.dvi: make.texinfo $(TEXI2DVI) $(srcdir)make.texinfo make.ps: make.dvi dvi2ps make.dvi > make.ps make: $(objs) $(GLOB) $(CC) Link $(LDFLAGS) $(objs) Lib $(GLOB) $(LOADLIBES) To make.new -delete make rename make.new make TMPFILE = t:Make$$ $(GLOB): cd glob @@\ $(MAKE) -$(MAKEFLAGS) -f Makefile # -I. is needed to find config.h in the build directory. OUTPUT_OPTION = .c.o: $(CC) $(defines) IDir "" IDir glob \ $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) # For some losing Unix makes. SHELL = /bin/sh #@SET_MAKE@ glob/libglob.a: FORCE config.h cd glob; $(MAKE) libglob.a FORCE: tagsrcs = $(srcs) $(srcdir)remote-*.c .PHONY: install installdirs install: installdirs \ $(bindir)$(binprefix)make $(infodir)make.info \ $(mandir)$(manprefix)make.$(manext) install dirs: $(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir) $(mandir) $(bindir)$(binprefix)make: make $(INSTALL_PROGRAM) make $@.new @if $(install_setgid); then \ if chgrp $(group) $@.new && chmod g+s $@.new; then \ echo "chgrp $(group) $@.new && chmod g+s $@.new"; \ else \ echo "$@ needs to be owned by group $(group) and setgid;"; \ echo "otherwise the \`-l' option will probably not work."; \ echo "You may need special privileges to install $@."; \ fi; \ else true; fi # Some systems can't deal with renaming onto a running binary. -$(RM) $@.old -mv $@ $@.old mv $@.new $@ $(infodir)make.info: make.info if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \ for file in $${dir}/make.info*; do \ name="`basename $$file`"; \ $(INSTALL_DATA) $$file \ `echo $@ | sed "s,make.info\$$,$$name,"`; \ done # Run install-info only if it exists. # Use `if' instead of just prepending `-' to the # line so we notice real errors from install-info. # We use `$(SHELL) -c' because some shells do not # fail gracefully when there is an unknown command. if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \ install-info --infodir=$(infodir) $$dir/make.info; \ else true; fi $(mandir)$(manprefix)make.$(manext): make.man $(INSTALL_DATA) $(srcdir)make.man $@ loadavg: loadavg.c config.h $(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \ loadavg.c $(LOADLIBES) -o $@ # We copy getloadavg.c into a different file rather than compiling it # directly because some compilers clobber getloadavg.o in the process. loadavg.c: getloadavg.c ln $(srcdir)getloadavg.c loadavg.c || \ cp $(srcdir)getloadavg.c loadavg.c check-loadavg: loadavg @echo The system uptime program believes the load average to be: -uptime @echo The GNU load average checking code believes: ./loadavg check: check-loadavg .PHONY: clean realclean distclean mostlyclean clean: glob-clean -$(RM) make loadavg "#?.o" core make.dvi distclean: clean glob-realclean -$(RM) Makefile config.h config.status build.sh -$(RM) config.log config.cache -$(RM) TAGS tags -$(RM) make.?? make.??s make.log make.toc make.*aux -$(RM) loadavg.c realclean: distclean -$(RM) make.info* mostlyclean: clean .PHONY: glob-clean glob-realclean glob-clean glob-realclean: cd glob @@\ $(MAKE) $@ # This tells versions [3.59,3.63) of GNU make not to export all variables. .NOEXPORT: # The automatically generated dependencies below may omit config.h # because it is included with ``#include '' rather than # ``#include "config.h"''. So we add the explicit dependency to make sure. $(objs): config.h # Automatically generated dependencies will be put at the end of the file. # Automatically generated dependencies. commands.o: commands.c make.h dep.h filedef.h variable.h job.h \ commands.h job.o: job.c make.h job.h filedef.h commands.h variable.h dir.o: dir.c make.h file.o: file.c make.h dep.h filedef.h job.h commands.h variable.h misc.o: misc.c make.h dep.h main.o: main.c make.h dep.h filedef.h variable.h job.h commands.h \ getopt.h read.o: read.c make.h dep.h filedef.h job.h commands.h variable.h \ glob/glob.h remake.o: remake.c make.h filedef.h job.h commands.h dep.h rule.o: rule.c make.h dep.h filedef.h job.h commands.h variable.h \ rule.h implicit.o: implicit.c make.h rule.h dep.h filedef.h default.o: default.c make.h rule.h dep.h filedef.h job.h commands.h \ variable.h variable.o: variable.c make.h dep.h filedef.h job.h commands.h \ variable.h expand.o: expand.c make.h filedef.h job.h commands.h variable.h function.o: function.c make.h filedef.h variable.h dep.h job.h \ commands.h amiga.h vpath.o: vpath.c make.h filedef.h variable.h version.o: version.c ar.o: ar.c make.h filedef.h dep.h arscan.o: arscan.c make.h signame.o: signame.c signame.h remote-stub.o: remote-stub.c make.h filedef.h job.h commands.h getopt.o: getopt.c getopt1.o : getopt1.c getopt.h getloadavg.o: getloadavg.c amiga.o: amiga.c make.h variable.h amiga.h *[MAKE-3_78_1HB]MAKEFILE.COM;3+,Ub./@ 4s-`0123KPWO 56"\&Eq7m89G@HJ $! $! Makefile.com - builds GNU Make for VMS $! $! P1 is non-empty if you want to link with the VAXCRTL library instead $! of the shareable executable $! P2 = DEBUG will build an image with debug information $! $! In case of problems with the install you might contact me at $! zinser@decus.decus.de (preferred) or martin_zinser@exchange.de $ $! hb $! But don't ask Martin Zinser about the lines, I added/changed. $! In case of an error do some cleanup $ on error then $ goto cleanup $! in case somebody set up her/his own symbol for cc $ set symbol/scope=(nolocal,noglobal) $! $! Look for the compiler used $! $ lval = "" $ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" $ then $ if f$trnlnm("SYS").eqs."" then def/nolog sys sys$library: $ ccopt = "" $ else $ ccopt = "/decc/prefix=all" $ if f$trnlnm("SYS").eqs."" $ then $ if f$trnlnm("DECC$LIBRARY_INCLUDE").nes."" $ then $ define sys decc$library_include: $ else $ if f$search("SYS$COMMON:[DECC$LIB.REFERENCE]DECC$RTLDEF.DIR").nes."" - then lval = "SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]," $ if f$search("SYS$COMMON:[DECC$LIB.REFERENCE]SYS$STARLET_C.DIR").nes."" - then lval = lval+"SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C]," $ lval=lval+"SYS$LIBRARY:" $ define sys 'lval $ endif $ endif $ endif $! $! Should we build a debug image $! $ if (p2.eqs."DEBUG") $ then $ ccopt = ccopt + "/noopt/debug" $ lopt = "/debug" $ else $ lopt = "" $ endif $ filelist = "alloca ar arscan commands default dir expand file function implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt1 getopt" $ copy config.h-vms config.h $ n=0 $ open/write optf make.opt $ loop: $ cfile = f$elem(n," ",filelist) $ if cfile .eqs. " " then goto linkit $ write sys$output "Compiling ''cfile'..." $ call compileit 'cfile' 'p1' $ n = n + 1 $ goto loop $ linkit: $ close optf $ if p1 .nes. "" then goto link_using_library $ link/exe=make make.opt/opt'lopt $ goto cleanup $ $ link_using_library: $ link/exe=make make.opt/opt,sys$library:vaxcrtl/lib'lopt $ $ cleanup: $ if f$trnlnm("SYS").nes."" then $ deassign sys $ if f$trnlnm("OPTF").nes."" then $ close optf $ if f$search("make.opt").nes."" then $ del make.opt;* $ exit $! $ compileit : subroutine $ ploc = f$locate("]",p1) $ filnam = p1 $ if ploc .lt. f$length(p1) then filnam=f$extract(ploc+1,100,p1) $ write optf "''filnam'" $ cc'ccopt'/include=([],[.glob])/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS") 'p1' $ exit $ endsubroutine : compileit *[MAKE-3_78_1HB]MAKEFILE.DOS;1+,c.(/@ 4('-`0123KPWO)567;<+m89G@HJ# -*-Makefile-*- template for DJGPP # Makefile.in generated automatically by automake 1.2 from Makefile.am # Copyright (C) 1994, 1995-1998, 1999 Free Software Foundation, Inc. # This Makefile.DOS is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # -*-Makefile-*-, or close enough SHELL = /bin/sh srcdir = . VPATH = $(srcdir) # $DJDIR is defined automatically by DJGPP to point # to the root of the DJGPP installation tree. prefix = ${DJDIR} exec_prefix = ${prefix} bindir = ${exec_prefix}/bin datadir = ${prefix}/share libdir = ${prefix}/lib infodir = ${prefix}/info # DJGPP doesn't have separate man tree, use info instead. mandir = ${prefix}/info includedir = ${prefix}/include oldincludedir = c:/djgpp/include pkgdatadir = $(datadir)/make pkglibdir = $(libdir)/make pkgincludedir = $(includedir)/make INSTALL = ${bindir}/ginstall -c INSTALL_PROGRAM = ${bindir}/ginstall -c INSTALL_DATA = ${bindir}/ginstall -c -m 644 INSTALL_SCRIPT = ${bindir}/ginstall -c transform = s,x,x, # This will fail even if they don't have a Unix-like shell (stock DOS # shell doesn't know about `false'). The only difference is that they # get "Error -1" instead of "Error 1". EXIT_FAIL = false NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : AR = ar CC = gcc CPP = gcc -E LIBOBJS = MAKEINFO = ${bindir}/makeinfo PACKAGE = make PERL = perl RANLIB = ranlib REMOTE = stub VERSION = 3.78.1 AUTOMAKE_OPTIONS = 1.2 bin_PROGRAMS = make make_SOURCES = main.c commands.c job.c dir.c file.c misc.c read.c remake.c rule.c implicit.c default.c variable.c expand.c function.c vpath.c version.c ar.c arscan.c commands.h dep.h filedef.h job.h make.h rule.h variable.h signame.c signame.h getopt.c getopt1.c getopt.h remote-$(REMOTE).c # This should include the glob/ prefix libglob_a_SOURCES = glob/fnmatch.c glob/glob.c glob/fnmatch.h glob/glob.h make_LDADD = glob/libglob.a info_TEXINFOS = make.texinfo man_MANS = make.1 INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"c:/djgpp/lib\" -DINCLUDEDIR=\"c:/djgpp/include\" BUILT_SOURCES = README build.sh.in EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h.W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c SUBDIRS = glob mkinstalldirs = ${bindir}/gmkdir -p CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = build.sh PROGRAMS = $(bin_PROGRAMS) MAKE_HOST = i386-pc-msdosdjgpp DEFS = -I. -I$(srcdir) -I. CPPFLAGS = -DHAVE_CONFIG_H LDFLAGS = LIBS = make_OBJECTS = main.o commands.o job.o dir.o file.o misc.o read.o remake.o rule.o implicit.o default.o variable.o expand.o function.o vpath.o version.o ar.o arscan.o signame.o getopt.o getopt1.o remote-$(REMOTE).o make_DEPENDENCIES = glob/libglob.a make_LDFLAGS = libglob_a_LIBADD = libglob_a_OBJECTS = fnmatch.o glob.o noinst_LIBRARIES = glob/libglob.a CFLAGS = -O2 -g COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ TEXI2DVI = texi2dvi TEXINFO_TEX = $(srcdir)/texinfo.tex INFO_DEPS = make.info DVIS = make.dvi TEXINFOS = make.texinfo man1dir = $(mandir)/man1 MANS = $(man_MANS) NROFF = nroff DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh.in config.h.in configure configure.in getloadavg.c install-sh missing mkinstalldirs stamp-h.in texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = gtar GZIP = --best SOURCES = $(make_SOURCES) OBJECTS = $(make_OBJECTS) HEADERS = $(wildcard $(srcdir)/*.h) default: all .SUFFIXES: .SUFFIXES: .S .c .dvi .info .o .ps .s .texi .texinfo .txi mostlyclean-hdr: clean-hdr: distclean-hdr: -rm -f config.h maintainer-clean-hdr: mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do if test -f $$p; then echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | sed '$(transform)'`"; $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | sed '$(transform)'`; else :; fi; done uninstall-binPROGRAMS: $(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(bindir)/`echo $$p|sed '$(transform)'`.exe; done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) mostlyclean-compile: -rm -f *.o *.exe make.new core clean-compile: distclean-compile: -rm -f *.tab.c *_tab.c maintainer-clean-compile: make: $(make_OBJECTS) $(make_DEPENDENCIES) @command.com /c if exist make del make @command.com /c if exist make.exe del make.exe $(LINK) $(make_LDFLAGS) $(make_OBJECTS) $(make_LDADD) $(LIBS) make.info: make.texinfo make.dvi: make.texinfo DVIPS = dvips .texi.info: $(MAKEINFO) $(srcdir)/$< -o ./$@ .texi.dvi: TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .texi: $(MAKEINFO) $(srcdir)/$< -o ./$@ .texinfo.info: $(MAKEINFO) $(srcdir)/$< -o ./$@ .texinfo: $(MAKEINFO) $(srcdir)/$< -o ./$@ .texinfo.dvi: TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi.info: $(MAKEINFO) $(srcdir)/$< -o ./$@ .txi.dvi: TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .dvi.ps: $(DVIPS) $< -o $@ install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(infodir) @for file in $(INFO_DEPS) make.i; do d=$(srcdir); for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9] $$file[0-9] $$file[0-9][0-9]`; do if test -f $$d/$$ifile; then echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; $(INSTALL_D ATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; else : ; fi; done; done @$(POST_INSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then for file in $(INFO_DEPS); do echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file"; install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :; done; else : ; fi uninstall-info: $(PRE_UNINSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then ii=yes; else ii=; fi; for file in $(INFO_DEPS); do test -z $ii || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; done $(NORMAL_UNINSTALL) for file in $(INFO_DEPS) make.i; do (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9] $$file[0-9] $$file[0-9][0-9]); done dist-info: $(INFO_DEPS) for base in $(INFO_DEPS); do d=$(srcdir); for file in `cd $$d && eval echo $$base*`; do test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; done mostlyclean-aminfo: -rm -f make.aux make.cp make.cps make.dvi make.fn make.fns make.ky \ make.kys make.ps make.log make.pg make.toc make.tp make.tps \ make.vr make.vrs make.op make.tr make.cv make.cn clean-aminfo: distclean-aminfo: maintainer-clean-aminfo: for i in $(INFO_DEPS) make.i; do rm -f `eval echo $$i*`; done install-man1: $(mkinstalldirs) $(DESTDIR)$(man1dir) @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ done uninstall-man1: @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ rm -f $(DESTDIR)$(man1dir)/$$inst; \ done install-man: $(MANS) @$(NORMAL_INSTALL) $(MAKE) install-man1 uninstall-man: @$(NORMAL_UNINSTALL) $(MAKE) uninstall-man1 # Assume that the only thing to do in glob is to build libglob.a, # but do a sanity check: if $SUBDIRS will ever have more than # a single directory, yell bloody murder. all-recursive: ifeq ($(words $(SUBDIRS)), 1) @command.com /c if not exist glob\\nul md glob @echo Making all in $(SUBDIRS) $(MAKE) -C $(SUBDIRS) -f ../Makefile INCLUDES='-I$(srcdir) -I$(srcdir)/glob' DEFS='-I.. -I$(srcdir)' VPATH=$(srcdir)/glob libglob.a else @echo FATAL: There is more than one directory in "($(SUBDIRS))" @$(EXIT_FAIL) endif $(SUBDIRS): command.com /c md $@ libglob.a: $(libglob_a_OBJECTS) command.com /c if exist libglob.a del libglob.a $(AR) cru libglob.a $(libglob_a_OBJECTS) $(libglob_a_LIBADD) $(RANLIB) libglob.a mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive check-recursive: ifeq ($(words $(SUBDIRS)), 1) @echo Making $(shell echo $@ | sed s/-recursive//) in $(SUBDIRS) $(MAKE) -C $(SUBDIRS) -f ../Makefile $(shell echo $@ | sed s/-recursive//)-am else @echo FATAL: There is more than one directory in "($(SUBDIRS))" @$(EXIT_FAIL) endif tags-in-glob: $(libglob_a_SOURCES) etags $(addprefix $(srcdir)/,$^) -o ./glob/TAGS tags-recursive: ifeq ($(words $(SUBDIRS)), 1) $(MAKE) tags-in-glob else @echo FATAL: There is more than one directory in "($(SUBDIRS))" @$(EXIT_FAIL) endif tags: TAGS ID: $(HEADERS) $(SOURCES) mkid $(srcdir)/$(SOURCES) $(srcdir)/$(libglob_a_SOURCES) ./config.h $(HEADERS) TAGS: tags-recursive $(HEADERS) $(srcdir)/$(SOURCES) config.h $(TAGS_DEPENDENCIES) etags -i ./glob/TAGS $(ETAGS_ARGS) $(srcdir)/$(SOURCES) ./config.h $(HEADERS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist rm -rf $(distdir) GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; cd $(distdir)/=build && ../configure --srcdir=.. --prefix=$$dc_install_base && $(MAKE) && $(MAKE) dvi && $(MAKE) check && $(MAKE) install && $(MAKE) installcheck && $(MAKE) dist rm -rf $(distdir) @echo "========================"; echo "$(distdir).tar.gz is ready for distribution"; echo "========================" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) rm -rf $(distdir) distdir: $(DISTFILES) rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) @for file in $(DISTFILES); do d=$(srcdir); test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; for subdir in $(SUBDIRS); do test -d $(distdir)/$$subdir || mkdir $(distdir)/$$subdir || exit 1; chmod 777 $(distdir)/$$subdir; (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir)/$$subdir distdir=../$(distdir)/$$subdir distdir) || exit 1; done $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook info: $(INFO_DEPS) info-recursive dvi: $(DVIS) dvi-recursive check: all-am check-recursive check-local @: installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) all-recursive all-am: Makefile $(INFO_DEPS) $(PROGRAMS) config.h install-exec-am: install-binPROGRAMS install-data-am: install-info-am uninstall-am: uninstall-binPROGRAMS uninstall-info install-exec: install-exec-recursive install-exec-am @$(NORMAL_INSTALL) install-data: install-data-recursive install-data-am @$(NORMAL_INSTALL) install: install-recursive install-exec-am install-data-am @: uninstall: uninstall-recursive uninstall-am all: all-recursive-am all-am install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: installdirs`H~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKEFILE.DOS;1(-recursive $(mkinstalldirs) $(bindir) $(infodir) mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS mostlyclean-compile mostlyclean-aminfo mostlyclean-tags mostlyclean-generic clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-aminfo clean-tags clean-generic mostlyclean-am distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile distclean-aminfo distclean-tags distclean-generic clean-am maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS maintainer-clean-compile maintainer-clean-aminfo maintainer-clean-tags maintainer-clean-generic distclean-am mostlyclean: mostlyclean-recursive mostlyclean-am clean: clean-noinstLIBRARIES clean-recursive clean-am distclean: distclean-recursive distclean-am rm -f config.status maintainer-clean: maintainer-clean-recursive maintainer-clean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f config.status .PHONY: default mostlyclean-hdr distclean-hdr clean-hdr \ maintainer-clean-hdr mostlyclean-binPROGRAMS distclean-binPROGRAMS \ clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile install-info-am uninstall-info \ mostlyclean-aminfo distclean-aminfo clean-aminfo \ maintainer-clean-aminfo install-data-recursive uninstall-data-recursive \ install-exec-recursive uninstall-exec-recursive installdirs-recursive \ uninstalldirs-recursive all-recursive check-recursive check-am \ installcheck-recursive info-recursive dvi-recursive \ mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir \ mostlyclean-depend distclean-depend clean-depend \ maintainer-clean-depend info dvi check-local installcheck \ all-recursive-am all-am install-exec-am install-data-am uninstall-am \ install-exec install-data install uninstall all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # --------------- Local DIST Section # Install the w32 subdirectory # dist-hook: (cd $(srcdir); \ w32=`find w32 -follow \( -name CVS -prune \) -o -type f -print`; \ tar chf - $$w32) \ | (cd $(distdir); tar xfBp -) # --------------- Local CHECK Section # Note: check-loadavg is NOT a prerequisite of check-local, since # there's no uptime utility, and the test it does doesn't make sense # on MSDOS anyway. check-local: check-shell check-regression @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes"; \ echo .PHONY: check-loadavg check-shell check-regression # > check-shell # # check-shell is designed to fail if they don't have a Unixy shell # installed. The test suite requires such a shell. check-shell: @echo If Make says Error -1, you do not have Unix-style shell installed @foo=bar.exe : # > check-loadavg # loadavg: loadavg.c config.h @rm -f loadavg $(LINK) -DTEST $(make_LDFLAGS) loadavg.c $(LIBS) # We copy getloadavg.c into a different file rather than compiling it # directly because some compilers clobber getloadavg.o in the process. loadavg.c: getloadavg.c ln $(srcdir)/getloadavg.c loadavg.c || \ cp $(srcdir)/getloadavg.c loadavg.c check-loadavg: loadavg @echo The system uptime program believes the load average to be: -uptime @echo The GNU load average checking code believes: -./loadavg # > check-regression # # Look for the make test suite, and run it if found. Look in MAKE_TEST if # specified, or else in the srcdir or the distdir, their parents, and _their_ # parents. # check-regression: @if test -f "$(srcdir)/tests/run_make_tests"; then \ if $(PERL) -v >/dev/null 2>&1; then \ case `cd $(srcdir); pwd` in `pwd`) : ;; \ *) test -d tests || mkdir tests; \ for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ rm -rf tests/$$f; cp -pr $(srcdir)/tests/$$f tests; \ done ;; \ esac; \ echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make.exe $(MAKETESTFLAGS)"; \ cd tests && $(PERL) ./run_make_tests.pl -make ../make.exe $(MAKETESTFLAGS); \ else \ echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ fi; \ else \ echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ fi # --------------- Maintainer's Section # Note this requires GNU make. Not to worry, since it will only be included # in the Makefile if we're in the maintainer's environment. #include $(srcdir)/maintMakefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # --------------- DEPENDENCIES # alloca.o: alloca.c config.h ar.o: ar.c make.h config.h signame.h filedef.h dep.h glob/fnmatch.h arscan.o: arscan.c make.h config.h signame.h commands.o: commands.c make.h config.h signame.h dep.h filedef.h \ variable.h job.h commands.h default.o: default.c make.h config.h signame.h rule.h dep.h filedef.h \ job.h commands.h variable.h dir.o: dir.c make.h config.h signame.h glob/glob.h expand.o: expand.c make.h config.h signame.h filedef.h job.h commands.h \ variable.h rule.h file.o: file.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h function.o: function.c make.h config.h signame.h filedef.h variable.h \ dep.h job.h commands.h getloadavg.o: getloadavg.c config.h getopt.o: getopt.c config.h getopt.h getopt1.o: getopt1.c config.h getopt.h implicit.o: implicit.c make.h config.h signame.h rule.h dep.h filedef.h job.o: job.c make.h config.h signame.h job.h filedef.h commands.h \ variable.h main.o: main.c make.h config.h signame.h dep.h filedef.h variable.h \ job.h commands.h rule.h getopt.h misc.o: misc.c make.h config.h signame.h dep.h read.o: read.c make.h config.h signame.h glob/glob.h dep.h filedef.h \ job.h commands.h variable.h rule.h remake.o: remake.c make.h config.h signame.h filedef.h job.h commands.h \ dep.h variable.h remote-stub.o: remote-stub.c make.h config.h signame.h filedef.h job.h \ commands.h rule.o: rule.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h rule.h signame.o: signame.c make.h config.h signame.h variable.o: variable.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h version.o: version.c config.h vpath.o: vpath.c make.h config.h signame.h filedef.h variable.h h*[MAKE-3_78_1HB]MAKEFILE.IN;1+,c.4/@ 441-`0123KPWO556WWV7:m89G@HJ# Makefile.in generated automatically by automake 1.4 from Makefile.am # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # This is a -*-Makefile-*-, or close enough SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_alias = @host_alias@ host_triplet = @host@ AR = @AR@ CC = @CC@ CPP = @CPP@ GETCONF = @GETCONF@ GLOBLIB = @GLOBLIB@ LIBOBJS = @LIBOBJS@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ PERL = @PERL@ RANLIB = @RANLIB@ REMOTE = @REMOTE@ VERSION = @VERSION@ AUTOMAKE_OPTIONS = 1.4 bin_PROGRAMS = make make_SOURCES = main.c commands.c job.c dir.c file.c misc.c read.c remake.c rule.c implicit.c default.c variable.c expand.c function.c vpath.c version.c ar.c arscan.c remote-$(REMOTE).c commands.h dep.h filedef.h job.h make.h rule.h variable.h signame.c signame.h getopt.c getopt1.c getopt.h make_LDADD = @LIBOBJS@ @ALLOCA@ @GLOBLIB@ info_TEXINFOS = make.texinfo man_MANS = make.1 INCLUDES = -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" EXTRA_DIST = README build.sh.in $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex 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.vms makefile.vms makefile.com config.h-vms vmsdir.h vmsfunctions.c vmsify.c SUBDIRS = glob MOSTLYCLEANFILES = loadavg.c CLEANFILES = loadavg MAKE_HOST = @MAKE_HOST@ # --------------- Local INSTALL Section # If necessary, change the gid of the app and turn on the setgid flag. # # Whether or not make needs to be installed setgid. # The value should be either `true' or `false'. # On many systems, the getloadavg function (used to implement the `-l' # switch) will not work unless make is installed setgid kmem. # inst_setgid = @NEED_SETGID@ # Install make setgid to this group so it can get the load average. # inst_group = @KMEM_GROUP@ # > check-regression # # Look for the make test suite, and run it if found and we can find perl. # If we're building outside the tree, we use symlinks to make a local copy of # the test suite. Unfortunately the test suite itself isn't localizable yet. # MAKETESTFLAGS = ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = build.sh PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ make_OBJECTS = main.o commands.o job.o dir.o file.o misc.o read.o \ remake.o rule.o implicit.o default.o variable.o expand.o function.o \ vpath.o version.o ar.o arscan.o remote-$(REMOTE).o signame.o getopt.o \ getopt1.o make_DEPENDENCIES = @LIBOBJS@ @ALLOCA@ make_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ TEXI2DVI = texi2dvi INFO_DEPS = make.info DVIS = make.dvi TEXINFOS = make.texinfo man1dir = $(mandir)/man1 MANS = $(man_MANS) NROFF = nroff DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ Makefile.am Makefile.in NEWS acconfig.h acinclude.m4 aclocal.m4 \ alloca.c build.sh.in config.guess config.h.in config.sub configure \ configure.in getloadavg.c install-sh missing mkinstalldirs texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best SOURCES = $(make_SOURCES) OBJECTS = $(make_OBJECTS) all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .dvi .info .o .ps .s .texi .texinfo .txi $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(ACLOCAL_M4): configure.in acinclude.m4 cd $(srcdir) && $(ACLOCAL) config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h @if test ! -f $@; then \ rm -f stamp-h; \ $(MAKE) stamp-h; \ else :; fi stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status @echo timestamp > stamp-h 2> /dev/null $(srcdir)/config.h.in: $(srcdir)/stamp-h.in @if test ! -f $@; then \ rm -f $(srcdir)/stamp-h.in; \ $(MAKE) $(srcdir)/stamp-h.in; \ else :; fi $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h cd $(top_srcdir) && $(AUTOHEADER) @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null mostlyclean-hdr: clean-hdr: distclean-hdrF : -rm -f config.h maintainer-clean-hdr: build.sh: $(top_builddir)/config.status build.sh.in cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: make: $(make_OBJECTS) $(make_DEPENDENCIES) @rm -f make $(LINK) $(make_LDFLAGS) $(make_OBJECTS) $(make_LDADD) $(LIBS) make.info: make.texinfo make.dvi: make.texinfo DVIPS = dvips .texi.info: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texi.dvi: TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .texi: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo.info: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo.dvi: TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi.info: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .txi.dvi: TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .dvi.ps: $(DVIPS) $< -o $@ install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(infodir) @list='$(INFO_DEPS)'; \ for file in $$list; do \ d=$(srcdir); \ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ if test -f $$d/$$ifile; then \ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ done; \ else : ; fi uninstall-info: $(PRE_UNINSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ ii=yes; \ else ii=; fi; \ list='$(INFO_DEPS)'; \ for file in $$list; do \ test -z "$ii" \ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ done @$(NORMAL_UNINSTALL) list='$(INFO_DEPS)'; \ for file in $$list; do \ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ done dist-info: $(INFO_DEPS) list='$(INFO_DEPS)'; \ for base in $$list; do \ d=$(srcdir); \ for file in `cd $$d && eval echo $$base*`; do \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done; \ done mostlyclean-aminfo: -rm -f make.aux make.cp make.cps make.dvi make.fn make.fns make.ky \ make.kys make.ps make.log make.pg make.toc make.tp make.tps \ make.vr make.vrs make.op make.tr make.cv make.cn clean-aminfo: distclean-aminfo: maintainer-clean-aminfo: cd $(srcdir) && for i in $(INFO_DEPS); do \ rm -f $$i; \ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ rm -f $$i-[0-9]*; \ fi; \ done install-man1: $(mkinstalldirs) $(DESTDIR)$(man1dir) @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ done uninstall-man1: @list='$(man1_MANS)'; \ l2='$(man_MANS)'; for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ rm -f $(DESTDIR)$(man1dir)/$$inst; \ done install-man: $(MANS) @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-man1 uninstall-man: @$(NORMAL_UNINSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ dot_seen=no; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ test "$$subdir" = "." && dot_seen=yes; \ done; \ test "$$dot_seen" = "no" && rev=". $$rev"; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist -rm -rf $(distdir) GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) dist -rm -rf $(distdir) @banner="$(distdir).tar.gz is ready for distribution"; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done for subdir in $(SUBDIRS); do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 777 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook alloca.o: alloca.c config.h ar.o: ar.c make.h config.h signame.h filedef.h dep.h glob/fnmatch.h arscan.o: arscan.c make.h config.h signame.h commands.o: commands.c make.h config.h signame.h dep.h filedef.h \ variable.h job.h commands.h default.o: default.c make.h config.h signame.h rule.h dep.h filedef.h \ job.h commands.h variable.h dir.o: dir.c make.h config.h signame.h glob/glob.h expand.o: expand.c make.h config.h signame.h filedef.h job.h commands.h \ variable.h rule.h file.o: file.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h function.o: function.c make.h config.h signame.h filedef.h variable.h \ dep.h job.h commands.h getloadavg.o: getloadavg.c config.h getopt.o: getopt.c config.h getopt.h getopt1.o: getopt1.c config.h getopt.h implicit.o: implicit.c make.h config.h signame.h rule.h dep.h filedef.h job.o: job.c make.h config.h signame.h job.h filedef.h commands.h \ variable.h main.o: main.c make.h config.h signame.h dep.h filedef.h variable.h \ job.h commands.h rule.h getopt.h misc.o: misc.c make.h config.h signame.h dep.h read.o: read.c make.h config.h signame.h glob/glob.h dep.h filedef.h \ job.h commands.h variable.h rule.h remake.o: remake.c make.h config.h signame.h filedef.h job.h commands.h \ dep.h variable.h remote-stub.o: remote-stub.c make.h config.h signame.h filedef.h job.h \ commands.h rule.o: rule.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h rule.h signame.o: signame.c make.h config.h signame.h variable.o: variable.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h version.o: version.c config.h vpath.o: vpath.c make.h config.h signame.h filedef.h variable.h info-am: $(INFO_DEPS) info: info-recursive dvi-am: $(DVIS) dvi: dvi-recursive check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive installcheck-am: installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive install-exec-am: install-binPROGRAMS install-exec-local install-exec: install-exec-recursive install-data-am: install-info-am install-man install-data: install-data-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-recursive uninstall-am: uninstall-binPROGRAMS uninstall-info uninstall-man uninstall: uninstall-recursive all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(MANS) config.h all-redirect: all-recursive-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: installdirs-recursive installdirs-am: $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(infodir) \ $(DESTDIR)$(mandir)/man1 mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \ mostlyclean-compile mostlyclean-aminfo mostlyclean-tags \ mostlyclean-generic mostlyclean: mostlyclean-recursive clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-aminfo \ clean-tags clean-generic mostlyclean-am clean: clean-recursive distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \ distclean-aminfo distclean-tags distclean-generic \ clean-am distclean: distclean-recursive -rm -f config.status maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \ maintainer-clean-compile maintainer-clean-aminfo \ maintainer-clean-tags maintainer-clean-generic \ distclean-am maintainer-clean-local @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." maintainer-clean: maintainer-clean-recursive -rm -f config.status .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile install-info-am uninstall-info \ mostlyclean-aminfo distclean-aminfo clean-aminfo \ maintainer-clean-aminfo install-man1 uninstall-man1 install-man \ uninstall-man install-data-recursive uninstall-data-recursive \ install-exec-recursive uninstall-exec-recursive installdirs-recursive \ uninstalldirs-recursive all-recursive check-recursive \ installcheck-recursive info-recursive dvi-recursive \ mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ dvi-am dvi check-local check check-am installcheck-am installcheck \ all-recursive-am install-exec-local install-exec-am install-exec \ install-data-am install-data install-am install uninstall-am uninstall \ all-redirect all-am all installdirs-am installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean install-exec-local: @if $(inst_setgid); then \ app=$(DESTDIR)$(bindir)/`echo $(bin_PROGRAMS)|sed '$(transform)'`; \ if chgrp $(inst_group) $$app && chmod g+s $$app; then \ echo "chgrp $(inst_group) $$app && chmod g+s $$app"; \ else \ echo "$$app needs to be owned by group $(inst_group) and setgid;"; \ echo "otherwise the \`-l' option will probably not work."; \ echo "You may need special privileges to complete the installation"; \ echo "of $$app."; \ fi; \ else true; fi # --------------- Local DIST Section # Install the w32 and tests subdirectories # dist-hook: (cd $(srcdir); \ sub=`find w32 tests -follow \( -name CVS -prune -o -name work -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ tar chf - $$sub) \ | (cd $(distdir); tar xfBp -) # --------------- Local CHECK Section check-local: check-regression check-loadavg @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ dashes=`echo "$$banner" | sed s/./=/g`; \ echo; \ echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes"; \ echo .PHONY: check-loadavg check-regression # > check-loadavg # loadavg: loadavg.c config.h @rm -f loadavg $(LINK) $(DEFS) $(CPPFLAGS) -DTEST $(make_LDFLAGS) loadavg.c $(LIBS) # We copy getloadavg.c into a different file rather than compiling it # directly because some compilers clobber getloadavg.o in the process. # loadavg.c: getloadavg.c ln $(srcdir)/getloadavg.c loadavg.c || \ cp $(srcdir)/getloadavg.c loadavg.c check-loadavg: loadavg @echo The system uptime program believes the load average to be: -uptime @echo The GNU load average checking code believes: -./loadavg check-regression: @if test -f "$(srcdir)/tests/run_make_tests"; then \ if $(PERL) -v >/dev/null 2>&1; then \ case `cd $(srcdir); pwd` in `pwd`) : ;; \ *) test -d tests || mkdir tests; \ rm -f srctests; \ if ln -s "$(srcdir)/tests" srctests; then \ for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ rm -f tests/$$f; ln -s ../srctests/$$f tests; \ done; fi ;; \ esac; \ echo I~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MAKEFILE.IN;14<0"cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS)"; \ cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS); \ else \ echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ fi; \ else \ echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ fi # --------------- Local CLEAN section maintainer-clean-local: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) # --------------- Maintainer's Section @MAINT_MAKEFILE@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: e*[MAKE-3_78_1HB]MAKEFILE.VMS;7+,f . /@ 4x -`0123KPWO 5667)Km89G@HJ# Copyright (C) 1988, 1989, 1996, 1997 Free Software Foundation, Inc. # This file is part of GNU Make. # # VMS extensions from GNU Make 3.60 imported by # Klaus Kmpf (kkaempf@rmi.de) # Modified for version 3.78.1 by Hartmut.Becker@compaq.com. # # GNU Make is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Make is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. CC = cc CP = copy %.obj: %.c $(CC) $(CFLAGS)/obj=$@ $< # # Makefile for GNU Make # ifeq ($(CC),cc) CFLAGS = $(defines) /include=([],[.glob])/prefix=all/standard=relaxed else CFLAGS = $(defines) /include=([],[.glob]) endif #LDFLAGS = /deb LDFLAGS = ifeq ($(CC),cc) defines = /define=("unlink=remove","HAVE_CONFIG_H","VMS","allocated_variable_expand_for_file=alloc_var_expand_for_file") else ifeq ($(ARCH),VAX) defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE","VAX") else defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE") endif endif LOAD_AVG = /define="NO_LDAV" # If you don't want archive support, comment these out. ARCHIVES = ,ar.obj,arscan.obj ARCHIVES_SRC = ar.c arscan.c # If your system needs extra libraries loaded in, define them here. # System V probably need -lPW for alloca. # if on vax, uncomment the following line #LOADLIBES = ,c.opt/opt ifeq ($(CC),cc) #LOADLIBES =,sys$$library:vaxcrtl.olb/lib CRT0 = else LOADLIBES =,gnu_cc_library:libgcc.olb/lib endif # If your system doesn't have alloca, or the one provided is bad, # get it from the Emacs distribution and define these. #ALLOCA = ,alloca.obj #ALLOCASRC = alloca.c # If there are remote execution facilities defined, # enable them with switches here (see remote-*.c). REMOTE = # Any extra object files your system needs. extras = ,signame.obj,remote-stub.obj,vmsfunctions.obj,vmsify.obj #,directory.obj # as an alternative: glob = ,[.glob]glob.obj,[.glob]fnmatch.obj getopt = ,getopt.obj,getopt1.obj # Directory to install `make' in. bindir = [] # Directory to install the man page in. mandir = [] # Number to put on the man page filename. manext = 1 objs = commands.obj,job.obj,dir.obj,file.obj,misc.obj,\ main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\ default.obj,variable.obj,expand.obj,function.obj,\ vpath.obj,version.obj$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob) srcs = commands.c job.c dir.c file.c misc.c \ main.c read.c remake.c rule.c implicit.c \ default.c variable.c expand.c function.c \ vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \ commands.h dep.h filedef.h job.h make.h rule.h variable.h .PHONY: all doc all: config.h make.exe doc: make.info make.dvi make.exe: $(objs) $(LD)$(LDFLAGS)/exe=$@ $^$(LOADLIBES)$(CRT0) .PHONY: clean realclean clean: $$ purge [...] -$(RM) make.exe;,*.obj; -$(RM) *.opt; -$(RM) [.glob]*.obj; # Automatically generated dependencies. commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h job.obj: job.c make.h commands.h job.h filedef.h variable.h dir.obj: dir.c make.h file.obj: file.c make.h commands.h dep.h filedef.h variable.h misc.obj: misc.c make.h dep.h main.obj: main.c make.h commands.h dep.h filedef.h variable.h job.h read.obj: read.c make.h commands.h dep.h filedef.h variable.h remake.obj: remake.c make.h commands.h job.h dep.h filedef.h rule.obj: rule.c make.h commands.h dep.h filedef.h variable.h rule.h implicit.obj: implicit.c make.h rule.h dep.h filedef.h default.obj: default.c make.h rule.h dep.h filedef.h commands.h variable.h variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h expand.obj: expand.c make.h commands.h filedef.h variable.h function.obj: function.c make.h variable.h dep.h commands.h job.h vpath.obj: vpath.c make.h filedef.h variable.h version.obj: version.c config.h arscan.obj: arscan.c ar.obj: ar.c make.h filedef.h signame.obj: signame.c remote-stub.obj: remote-stub.c [.glob]glob.obj: [.glob]glob.c [.glob]fnmatch.obj: [.glob]fnmatch.c getopt.obj: getopt.c getopt1.obj: getopt1.c vmsfunctions.obj: vmsfunctions.c make.h vmsdir.h vmsify.obj: vmsify.c make.h config.h: config.h-vms $(CP) $< $@ *[MAKE-3_78_1HB]MISC.C;1+,c.(/@ 4(&-`0123KPWO)56+17~[m89G@HJ0/* Miscellaneous generic support functions for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "dep.h" /* Variadic functions. We go through contortions to allow proper function prototypes for both ANSI and pre-ANSI C compilers, and also for those which support stdarg.h vs. varargs.h, and finally those which have vfprintf(), etc. and those who have _doprnt... or nothing. This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and VA_END macros used here since we have multiple print functions. */ #if HAVE_VPRINTF || HAVE_DOPRNT # define HAVE_STDVARARGS 1 # if __STDC__ # include # define VA_START(args, lastarg) va_start(args, lastarg) # else # include # define VA_START(args, lastarg) va_start(args) # endif # if HAVE_VPRINTF # define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args)) # else # define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp)) # endif # define VA_END(args) va_end(args) #else /* # undef HAVE_STDVARARGS */ # define va_alist a1, a2, a3, a4, a5, a6, a7, a8 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; # define VA_START(args, lastarg) # define VA_END(args) #endif /* Compare strings *S1 and *S2. Return negative if the first is less, positive if it is greater, zero if they are equal. */ int alpha_compare (v1, v2) const void *v1, *v2; { const char *s1 = *((char **)v1); const char *s2 = *((char **)v2); if (*s1 != *s2) return *s1 - *s2; return strcmp (s1, s2); } /* Discard each backslash-newline combination from LINE. Backslash-backslash-newline combinations become backslash-newlines. This is done by copying the text at LINE into itself. */ void collapse_continuations (line) char *line; { register char *in, *out, *p; register int backslash; register unsigned int bs_write; in = index (line, '\n'); if (in == 0) return; out = in; while (out > line && out[-1] == '\\') --out; while (*in != '\0') { /* BS_WRITE gets the number of quoted backslashes at the end just before IN, and BACKSLASH gets nonzero if the next character is quoted. */ backslash = 0; bs_write = 0; for (p = in - 1; p >= line && *p == '\\'; --p) { if (backslash) ++bs_write; backslash = !backslash; /* It should be impossible to go back this far without exiting, but if we do, we can't get the right answer. */ if (in == out - 1) abort (); } /* Output the appropriate number of backslashes. */ while (bs_write-- > 0) *out++ = '\\'; /* Skip the newline. */ ++in; /* If the newline is quoted, discard following whitespace and any preceding whitespace; leave just one space. */ if (backslash) { in = next_token (in); while (out > line && isblank (out[-1])) --out; *out++ = ' '; } else /* If the newline isn't quoted, put it in the output. */ *out++ = '\n'; /* Now copy the following line to the output. Stop when we find backslashes followed by a newline. */ while (*in != '\0') if (*in == '\\') { p = in + 1; while (*p == '\\') ++p; if (*p == '\n') { in = p; break; } while (in < p) *out++ = *in++; } else *out++ = *in++; } *out = '\0'; } /* Remove comments from LINE. This is done by copying the text at LINE onto itself. */ void remove_comments (line) char *line; { char *comment; comment = find_char_unquote (line, "#", 0); if (comment != 0) /* Cut off the line at the #. */ *comment = '\0'; } /* Print N spaces (used by DEBUGPR for target-depth). */ void print_spaces (n) register unsigned int n; { while (n-- > 0) putchar (' '); } /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ char * concat (s1, s2, s3) register char *s1, *s2, *s3; { register unsigned int len1, len2, len3; register char *result; len1 = *s1 != '\0' ? strlen (s1) : 0; len2 = *s2 != '\0' ? strlen (s2) : 0; len3 = *s3 != '\0' ? strlen (s3) : 0; result = (char *) xmalloc (len1 + len2 + len3 + 1); if (*s1 != '\0') bcopy (s1, result, len1); if (*s2 != '\0') bcopy (s2, result + len1, len2); if (*s3 != '\0') bcopy (s3, result + len1 + len2, len3); *(result + len1 + len2 + len3) = '\0'; return result; } /* Print a message on stdout. */ void #if __STDC__ && HAVE_STDVARARGS message (int prefix, const char *fmt, ...) #else message (prefix, fmt, va_alist) int prefix; const char *fmt; va_dcl #endif { #if HAVE_STDVARARGS va_list args; #endif log_working_directory (1); if (fmt != 0) { if (prefix) { if (makelevel == 0) printf ("%s: ", program); else printf ("%s[%u]: ", program, makelevel); } VA_START (args, fmt); VA_PRINTF (stdout, fmt, args); VA_END (args); putchar ('\n'); } fflush (stdout); } /* Print an error message. */ void #if __STDC__ && HAVE_STDVARARGS error (const struct floc *flocp, const char *fmt, ...) #else error (flocp, fmt, va_alist) const struct floc *flocp; const char *fmt; va_dcl #endif { #if HAVE_STDVARARGS va_list args; #endif log_working_directory (1); if (flocp && flocp->filenm) fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno); else if (makelevel == 0) fprintf (stderr, "%s: ", program); else fprintf (stderr, "%s[%u]: ", program, makelevel); VA_START(args, fmt); VA_PRINTF (stderr, fmt, args); VA_END (args); putc ('\n', stderr); fflush (stderr); } /* Print an error message and exit. */ void #if __STDC__ && HAVE_STDVARARGS fatal (const struct floc *flocp, const char *fmt, ...) #else fatal (flocp, fmt, va_alist) const struct floc *flocp; const char *fmt; va_dcl #endif { #if HAVE_STDVARARGS va_list args; #endif log_working_directory (1); if (flocp && flocp->filenm) fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno); else if (makelevel == 0) fprintf (stderr, "%s: *** ", program); else fprintf (stderr, "%s[%u]: *** ", program, makelevel); VA_START(args, fmt); VA_PRINTF (stderr, fmt, args); VA_END (args); fputs (_(". Stop.\n"), stderr); die (2); } #ifndef HAVE_STRERROR #undef strerror char * strerror (errnum) int errnum; { extern int errno, sys_nerr; #ifndef __DECC extern char *sys_errlist[]; #endif static char buf[] = "Unknown error 12345678901234567890"; if (errno < sys_nerr) return sys_errlist[errnum]; sprintf (buf, _("Unknown error %d"), errnum); return buf; } #endif /* Print an error message from errno. */ void perror_with_name (str, name) char *str, *name; { error (NILF, "%s%s: %s", str, name, strerror (errno)); } /* Print an error message from errno and exit. */ void pfatal_with_name (name) char *name; { fatal (NILF, "%s: %s", name, strerror (errno)); /* NOTREACHED */ } /* Like malloc but get fatal error if memory is exhausted. */ /* Don't bother if we're using dmalloc; it provides these for us. */ #ifndef HAVE_DMALLOC_H #undef xmalloc #undef xrealloc #undef xstrdup char * xmalloc (size) unsigned int size; { char *result = (char *) malloc (size); if (result == 0) fatal (NILF, _("virtual memory exhausted")); return result; } char * xrealloc (ptr, size) char *ptr; unsigned int size; { char *result; /* Some older implementations of realloc() don't conform to ANSI. */ result = ptr ? realloc (ptr, size) : malloc (size); if (result == 0) fatal (NILF, _("virtual memory exhausted")); return result; } char * xstrdup (ptr) const char *ptr; { char *result; #ifdef HAVE_STRDUP result = strdup (ptr); #else result = (char *) malloc (strlen (ptr) + 1); #endif if (result == 0) fatal (NILF, _("virtual memory exhausted")); #ifdef HAVE_STRDUP return result; #else return strcpy(result, ptr); #endif } #endif /* HAVE_DMALLOC_H */ char * savestring (str, length) const char *str; unsigned int length; { register char *out = (char *) xmalloc (length + 1); if (length > 0) bcopy (str, out, length); out[length] = '\0'; return out; } /* Search string BIG (length BLEN) for an occurrence of string SMALL (length SLEN). Return a pointer to the beginning of the first occurrence, or return nil if none found. */ char * sindex (big, blen, small, slen) const char *big; unsigned int blen; const char *small; unsigned int slen; { if (!blen) blen = strlen (big); if (!slen) slen = strlen (small); if (slen && blen >= slen) { register unsigned int b; /* Quit when there's not enough room left for the small string. */ --slen; blen -= slen; for (b = 0; b < blen; ++b, ++big) if (*big == *small && strneq (big + 1, small + 1, slen)) return (char *)big; } return 0; } /* Limited INDEX: Search through the string STRING, which ends at LIMIT, for the character C. Returns a pointer to the first occurrence, or nil if none is found. Like INDEX except that the string searched ends where specified instead of at the first null. */ char * lindex (s, limit, c) register const char *s, *limit; int c; { while (s < limit) if (*s++ == c) return (char *)(s - 1); return 0; } /* Return the address of the first whitespace or null in the string S. */ char * end_of_token (s) char *s; { while (*s != '\0' && !isblank (*s)) ++s; return s; } #ifdef WINDOWS32 /* * Same as end_of_token, but take into account a stop character */ char * end_of_token_w32 (s, stopchar) char *s; char stopchar; { register char *p = s; register int backslash = 0; while (*p != '\0' && *p != stopchar && (backslash || !isblank (*p))) { if (*p++ == '\\') { backslash = !backslash; while (*p == '\\') { backslash = !backslash; ++p; } } else backslash = 0; } return p; } #endif /* Return the address of the first nonwhitespace or null in the string S. */ char * next_token (s) char *s; { register char *p = s; while (isblank (*p)) ++p; return p; } /* Find the next token in PTR; return the address of it, and store the length of the token into *LENGTHPTR if LENGTHPTR is not nil. */ char * find_next_token (ptr, lengthptr) char **ptr; unsigned int *lengthptr; { char *p = next_token (*ptr); char *end; if (*p == '\0') return 0; *ptr = end = end_of_token (p); if (lengthptr != 0) *lengthptr = end - p; return p; } /* Copy a chain of `struct dep', making a new chain with the same contents as the old one. */ struct dep * copy_dep_chain (d) register struct dep *d; { register struct dep *c; struct dep *firstnew = 0; struct dep *lastnew = 0; while (d != 0) { c = (struct dep *) xmalloc (sizeof (struct dep)); bcopy ((char *) d, (char *) c, sizeof (struct dep)); if (c->name != 0) c->name = xstrdup (c->name); c->next = 0; if (firstnew == 0) firstnew = lastnew = c; else lastnew = lastnew->next = c; d = d->next; } return firstnew; } #ifdef iAPX286 /* The losing compiler on this machine can't handle this macro. */ char * dep_name (dep) struct dep *dep; { return dep->name == 0 ? dep->file->name : dep->name; } #endif #ifdef GETLOADAVG_PRIVILEGED #ifdef POSIX /* Hopefully if a system says it's POSIX.1 and has the setuid and setgid functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2, for example) which claim to be POSIX.1 also have the BSD setreuid and setregid functions, but they don't work as in BSD and only the POSIX.1 way works. */ #undef HAVE_SETREUID #undef HAVE_SETREGID #else /* Not POSIX. */ /* Some POSIX.1 systems have the seteuid and setegid functions. In a POSIX-like system, they are the best thing to use. However, some non-POSIX systems have them too but they do not work in the POSIX style and we must use setreuid and setregid instead. */ #undef HAVE_SETEUID #undef HAVE_SETEGID #endif /* POSIX. */ #ifndef HAVE_UNISTD_H extern int getuid (), getgid (), geteuid (), getegid (); extern int setuid (), setgid (); #ifdef HAVE_SETEUID extern int seteuid (); #else #ifdef HAVE_SETREUID extern int setreuid (); #endif /* Have setreuid. */ #endif /* Have seteuid. */ #ifdef HAVE_SETEGID extern int setegid (); #else #ifdef HAVE_SETREGID extern int setregid (); #endif /* Have setregid. */ #endif /* Have setegid. */ #endif /* No . */ /* Keep track of the user and group IDs for user- and make- access. */ static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1; #define access_inited (user_uid != -1) static enum { make, user } current_access; /* Under -d, write a message describing the current IDs. */ static void log_access (flavor) char *flavor; { if (! debug_flag) return; /* All the other debugging messages go to stdout, but we write this one to stderr because it might be run in a child fork whose stdout is piped. */ fprintf (stderr, _("%s access: user %lu (real %lu), group %lu (real %lu)\n"), flavor, (unsigned long) geteuid (), (unsigned long) getuid (), (unsigned long) getegid (), (unsigned long) getgid ()); fflush (stderr); } static void init_access () { #ifndef VMS user_uid = getuid (); user_gid = getgid (); make_uid = geteuid (); make_gid = getegid (); /* Do these ever fail? */ if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1) pfatal_with_name ("get{e}[gu]id"); log_access (_("Initialized")); current_access = make; #endif } #endif /* GETLOADAVG_PRIVILEGED */ /* Give the process appropriate permissions for access to user data (i.e., to stat files, or to spawn a child process). */ void user_access () { #ifdef GETLOADAVG_PRIVILEGED if (!access_inited) init_access (); if (current_access == user) return; /* We are in "make access" mode. This means that the effective user and group IDs are those of make (if it was installed setuid or setgid). We now want to set the effective user and group IDs to the real IDs, which are the IDs of the process that exec'd make. */ #ifdef HAVE_SETEUID /* Modern systems have the seteuid/setegid calls which set only the effective IDs, which is ideal. */ if (seteuid (user_uid) < 0) pfatal_with_name ("user_access: seteuid"); #else /* Not HAVE_SETEUID. */ #ifndef HAVE_SETREUID /* System V has only the setuid/setgid calls to set user/group IDs. There is an effective ID, which can be set by setuid/setgid. It can be set (unless you are root) only to either what it already is (returned by geteuid/getegid, now in make_uid/make_gid), the real ID (return by getuid/getgid, now in user_uid/user_gid), or the saved set ID (what the effective ID was before this set-ID executable (make) was exec'd). */ if (setuid (user_uid) < 0) pfatal_with_name ("user_access: setuid"); #else /* HAVE_SETREUID. */ /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs. They may be set to themselves or each other. So you have two alternatives at any one time. If you use setuid/setgid, the effective will be set to the real, leaving only one alternative. Using setreuid/setregid, however, you can toggle between your two alternatives by swapping the values in a single setreuid or setregid call. */ if (setreuid (make_uid, user_uid) < 0) pfatal_with_name ("user_access: setreuid"); #endif /* Not HAVE_SETREUID. */ #endif /* HAVE_SETEUID. */ #ifdef HAVE_SETEGID if (setegid (user_gid) < 0) pfatal_with_name ("user_access: setegid"); #else #ifndef HAVE_SETREGID if (setgid (user_gid) < 0) pfatal_with_name ("user_access: setgid"); #else if (setregid (make_gid, user_gid) < 0) pfatal_with_name ("user_access: setregid"); #endif #endif current_access = user; log_access ("User"); #endif /* GETLOADAVG_PRIVILEGED */ } /* Give the process appropriate permissions for access to make data (i.e., the load average). */ void make_access () { #ifdef GETLOADAVG_PRIVILEGED if (!access_inited) init_access (); if (current_access == make) return; /* See comments in user_access, above. */ #ifdef HAVE_SETEUID if (seteuid (make_uid) < 0) pfatal_with_name ("make_access: seteuid"); #else #ifndef HAVE_SETREUID if (setuid (make_uid) < 0) pfatal_with_name ("make_access: setuid"); #else if (setreuid (user_uid, make_uid) < 0) pfatal_with_name ("make_access: setreuid"); #endif #endif #ifdef HAVE_SETEGID if (setegid (make_gid) < 0) pfatal_with_name ("make_access: setegid"); #else #ifndef HAVE_SETREGID if (setgid (make_gid) < 0) pfatal_with_name ("make_access: setgid"); #else if (setregid (user_gid, make_gid) < 0) pfatal_with_name ("make_access: setregid"); #endif #endif current_access = make; log_access ("Make"); #endif /* GETLOADAVG_PRIVILEGED */ } /* Give the process appropriate permissions for a child process. This is like user_access, but you can't get back to make_access. */ void child_access () { #ifdef GETLOADAVG_PRIVILEGED if (!access_inited) abort (); /* Set both the real and effective UID and GID to the user's. They cannot be changed back to make's. */ #ifndef HAVE_SETREUID if (setuid (user_uid) < 0) pfatal_with_name ("child_access: setuid"); #else if (setreuid (user_uid, user_uid) < 0) pfatal_with_name ("child_access: setreuid"); #endif #ifndef HAVE_SETREGID if (setgid (user_gid) < 0) pfatal_with_name ("child_access: setgid"); #else if (setregid (user_gid, user_gid) < 0) pfatal_with_name ("child_access: setregid"); #endif log_access ("Child"); #endif /* GETLOADAVG_PRIVILEGED */ } #ifdef NEED_GET_PATH_MAX unsigned int get_path_max () { static unsigned int value; if (value == 0) { long int x = pathconf ("/", _PC_PATH_MAX); if (x > 0) value = x; else return MAXPATHLEN; } return value; } #endif *[MAKE-3_78_1HB]MISSING.;1+,c./@ 4 -`0123KPWO567<(km89G@HJ#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997 Free Software Foundation, Inc. # Franc,ois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing - GNU libit 0.0" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo  "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$J~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]MISSING.;1T  1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 u*[MAKE-3_78_1HB]MKINSTALLDIRS.;1+,c./@ 4-`0123KPWO56~7zm89G@HJ#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here *[MAKE-3_78_1HB]NEWS.;1+,c.</@ 4<:Z-`0123KPWO=56f7ݳm89G@HJGNU make NEWS -*-indented-text-*- History of user-visible changes. 17 Sep 1999 Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc. See the end for copying conditions. All changes mentioned here are more fully described in the GNU make manual, which is contained in this distribution as the file make.texinfo. 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.78 * Two new functions, $(error ...) and $(warning ...) are available. The former will cause make to fail and exit immediately upon expansion of the function, with the text provided as the error message. The latter causes the text provided to be printed as a warning message, but make proceeds normally. * A new function $(call ...) is available. This allows users to create their own parameterized macros and invoke them later. Original implementation of this function was provided by Han-Wen Nienhuys . * A new function $(if ...) is available. It provides if-then-else capabilities in a builtin function. Original implementation of this function was provided by Han-Wen Nienhuys . * Make defines a new variable, .LIBPATTERNS. This variable controls how library dependency expansion (dependencies like ``-lfoo'') is performed. * Make accepts CRLF sequences as well as traditional LF, for compatibility with makefiles created on other operating systems. * Make accepts a new option: -R, or --no-builtin-variables. This option disables the definition of the rule-specific builtin variables (CC, LD, AR, etc.). Specifying this option forces -r (--no-builtin-rules) as well. * A "job server" feature, suggested by Howard Chu . On systems that support POSIX pipe(2) semantics, GNU make can now pass -jN options to submakes rather than forcing them all to use -j1. The top make and all its sub-make processes use a pipe to communicate with each other to ensure that no more than N jobs are started across all makes. To get the old behavior of -j back, you can configure make with the --disable-job-server option. * The confusing term "dependency" has been replaced by the more accurate and standard term "prerequisite", both in the manual and in all GNU make output. * GNU make supports the "big archive" library format introduced in AIX 4.3. * GNU make supports large files on AIX, HP-UX, and IRIX. These changes were provided by Paul Eggert . (Large file support for Solaris and Linux was introduced in 3.77, but the configuration had issues: these have also been resolved). * The Windows 95/98/NT (W32) version of GNU make now has native support for the Cygnus Cygwin release B20.1 shell (bash). * The GNU make regression test suite, long available separately "under the table", has been integrated into the release. You can invoke it by running "make check" in the distribution. Note that it requires Perl (either Perl 4 or Perl 5) to run. Version 3.77 * Implement BSD make's "?=" variable assignment operator. The variable is assigned the specified value only if that variable is not already defined. * Make defines a new variable, "CURDIR", to contain the current working directory (after the -C option, if any, has been processed). Modifying this variable has no effect on the operation of make. * Make defines a new default RCS rule, for new-style master file storage: ``% :: RCS/%'' (note no ``,v'' suffix). Make defines new default rules for DOS-style C++ file naming conventions, with ``.cpp'' suffixes. All the same rules as for ``.cc'' and ``.C'' suffixes are provided, along with LINK.cpp and COMPILE.cpp macros (which default to the same value as LINK.cc and COMPILE.cc). Note CPPFLAGS is still C preprocessor flags! You should use CXXFLAGS to change C++ compiler flags. * A new feature, "target-specific variable values", has been added. This is a large change so please see the appropriate sections of the manual for full details. Briefly, syntax like this: TARGET: VARIABLE = VALUE defines VARIABLE as VALUE within the context of TARGET. This is similar to SunOS make's "TARGET := VARIABLE = VALUE" feature. Note that the assignment may be of any type, not just recursive, and that the override keyword is available. COMPATIBILITY: This new syntax means that if you have any rules where the first or second dependency has an equal sign (=) in its name, you'll have to escape them with a backslash: "foo : bar\=baz". Further, if you have any dependencies which already contain "\=", you'll have to escape both of them: "foo : bar\\\=baz". * A new appendix listing the most common error and warning messages generated by GNU make, with some explanation, has been added to the GNU make User's Manual. * Updates to the GNU make Customs library support (see README.customs). * Updates to the Windows 95/NT port from Rob Tulloh (see README.W32), and to the DOS port from Eli Zaretski (see README.DOS). Version 3.76.1 * Small (but serious) bug fix. Quick rollout to get into the GNU source CD. Version 3.76 * GNU make now uses automake to control Makefile.in generation. This should make it more consistent with the GNU standards. * VPATH functionality has been changed to incorporate the VPATH+ patch, previously maintained by Paul Smith . See the manual. * Make defines a new variable, `MAKECMDGOALS', to contain the goals that were specified on the command line, if any. Modifying this variable has no effect on the operation of make. * A new function, `$(wordlist S,E,TEXT)', is available: it returns a list of words from number S to number E (inclusive) of TEXT. * Instead of an error, detection of future modification times gives a warning and continues. The warning is repeated just before GNU make exits, so it is less likely to be lost. * Fix the $(basename) and $(suffix) functions so they only operate on the last filename, not the entire string: Command Old Result New Result ------- ---------- ---------- $(basename a.b) a a $(basename a.b/c) a a.b/c $(suffix a.b) b b $(suffix a.b/c) b/c * The $(strip) function now removes newlines as well as TABs and spaces. * The $(shell) function now changes CRLF (\r\n) pairs to a space as well as newlines (\n). * Updates to the Windows 95/NT port from Rob Tulloh (see README.W32). * Eli Zaretskii has updated the port to 32-bit protected mode on MSDOS and MS-Windows, building with the DJGPP v2 port of GNU C/C++ compiler and utilities. See README.DOS for details, and direct all questions concerning this port to Eli Zaretskii or DJ Delorie . * John W. Eaton has updated the VMS port to support libraries and VPATH. Version 3.75 * The directory messages printed by `-w' and implicitly in sub-makes, are now omitted if Make runs no commands and has no other messages to print. * Make now detects files that for whatever reason have modification times in the future and gives an error. Files with such impossible timestamps can result from unsynchronized clocks, or archived distributions containing bogus timestamps; they confuse Make's dependency engine thoroughly. * The new directive `sinclude' is now recognized as another name for `-include', for compatibility with some other Makes. * Aaron Digulla has contributed a port to AmigaDOS. See README.Amiga for details, and direct all Amiga-related questions to . * Rob Tulloh of Tivoli Systems has contributed a port to Windows NT or 95. See README.W32 for details, and direct all Windows-related questions to . Version 3.73 * Converted to use Autoconf version 2, so `configure' has some new options. See INSTALL for details. * You can now send a SIGUSR1 signal to Make to toggle printing of debugging output enabled by -d, at any time during the run. Version 3.72 * DJ Delorie has ported Make to MS-DOS using the GO32 extender. He is maintaining the DOS port, not the GNU Make maintainer; please direct bugs and questions for DOS to . MS-DOS binaries are available for FTP from ftp.simtel.net in /pub/simtelnet/gnu/djgpp/. * The `MAKEFLAGS' variable (in the environment or in a makefile) can now contain variable definitions itself; these are treated just like command-line variable definitions. Make will automatically insert any variable definitions from the environment value of `MAKEFLAGS' or from the command line, into the `MAKEFLAGS' value exported to children. The `MAKEOVERRIDES' variable previously included in the value of `$(MAKE)' for sub-makes is now included in `MAKEFLAGS' instead. As before, you can reset `MAKEOVERRIDES' in your makefile to avoid putting all the variables in the environment when its size is limited. * If `.DELETE_ON_ERROR' appears as a target, Make will delete the target of a rule if it has changed when its commands exit with a nonzero status, just as when the commands get a signal. * The automatic variable `$+' is new. It lists all the dependencies like `$^', but preserves duplicates listed in the makefile. This is useful for linking rules, where library files sometimes need to be listed twice in the link order. * You can now specify the `.IGNORE' and `.SILENT' special targets with dependencies to limit their effects to those files. If a file appears as a dependency of `.IGNORE', then errors will be ignored while running the commands to update that file. Likewise if a file appears as a dependency of `.SILENT', then the commands to update that file will not be printed before they are run. (This change was made to conform to POSIX.2.) Version 3.71 * The automatic variables `$(@D)', `$(%D)', `$(*D)', `$( #include #include "dep.h" #include "filedef.h" #include "job.h" #include "commands.h" #include "variable.h" #include "rule.h" #ifndef WINDOWS32 #ifndef _AMIGA #ifndef VMS #include #else struct passwd *getpwnam PARAMS ((char *name)); #endif #endif #endif /* !WINDOWS32 */ /* A `struct linebuffer' is a structure which holds a line of text. `readline' reads a line from a stream into a linebuffer and works regardless of the length of the line. */ struct linebuffer { /* Note: This is the number of bytes malloc'ed for `buffer' It does not indicate `buffer's real length. Instead, a null char indicates end-of-string. */ unsigned int size; char *buffer; }; #define initbuffer(lb) (lb)->buffer = (char *) xmalloc ((lb)->size = 200) #define freebuffer(lb) free ((lb)->buffer) /* Types of "words" that can be read in a makefile. */ enum make_word_type { w_bogus, w_eol, w_static, w_variable, w_colon, w_dcolon, w_semicolon, w_comment, w_varassign }; /* A `struct conditionals' contains the information describing all the active conditionals in a makefile. The global variable `conditionals' contains the conditionals information for the current makefile. It is initialized from the static structure `toplevel_conditionals' and is later changed to new structures for included makefiles. */ struct conditionals { unsigned int if_cmds; /* Depth of conditional nesting. */ unsigned int allocated; /* Elts allocated in following arrays. */ char *ignoring; /* Are we ignoring or interepreting? */ char *seen_else; /* Have we already seen an `else'? */ }; static struct conditionals toplevel_conditionals; static struct conditionals *conditionals = &toplevel_conditionals; /* Default directories to search for include files in */ static char *default_include_directories[] = { #if defined(WINDOWS32) && !defined(INCLUDEDIR) /* * This completly up to the user when they install MSVC or other packages. * This is defined as a placeholder. */ #define INCLUDEDIR "." #endif INCLUDEDIR, #ifndef _AMIGA "/usr/gnu/include", "/usr/local/include", "/usr/include", #endif 0 }; /* List of directories to search for include files in */ static char **include_directories; /* Maximum length of an element of the above. */ static unsigned int max_incl_len; /* The filename and pointer to line number of the makefile currently being read in. */ const struct floc *reading_file; /* The chain of makefiles read by read_makefile. */ static struct dep *read_makefiles = 0; static int read_makefile PARAMS ((char *filename, int flags)); static unsigned long readline PARAMS ((struct linebuffer *linebuffer, FILE *stream, const struct floc *flocp)); static void do_define PARAMS ((char *name, unsigned int namelen, enum variable_origin origin, FILE *infile, struct floc *flocp)); static int conditional_line PARAMS ((char *line, const struct floc *flocp)); static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, struct dep *deps, u nsigned int cmds_started, char *commands, unsigned int commands_idx, int two_colon, const struct floc *flocp, int set_default)); static void record_target_var PARAMS ((struct nameseq *filenames, char *defn, int two_colon, enum variable_origin origin, const struct floc *flocp)); static enum make_word_type get_next_mword PARAMS ((char *buffer, char *delim, char **startp, unsigned int *length)); /* Read in all the makefiles and return the chain of their names. */ struct dep * read_all_makefiles (makefiles) char **makefiles; { unsigned int num_makefiles = 0; if (debug_flag) puts (_("Reading makefiles...")); /* If there's a non-null variable MAKEFILES, its value is a list of files to read first thing. But don't let it prevent reading the default makefiles and don't let the default goal come from there. */ { char *value; char *name, *p; unsigned int length; { /* Turn off --warn-undefined-variables while we expand MAKEFILES. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; value = allocated_variable_expand ("$(MAKEFILES)"); warn_undefined_variables_flag = save; } /* Set NAME to the start of next token and LENGTH to its length. MAKEFILES is updated for finding remaining tokens. */ p = value; while ((name = find_next_token (&p, &length)) != 0) { name = xstrdup (name); if (*p != '\0') *p++ = '\0'; if (read_makefile (name, RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2) free (name); } free (value); } /* Read makefiles specified with -f switches. */ if (makefiles != 0) while (*makefiles != 0) { struct dep *tail = read_makefiles; register struct dep *d; if (! read_makefile (*makefiles, 0)) perror_with_name ("", *makefiles); /* Find the right eleme( nt of read_makefiles. */ d = read_makefiles; while (d->next != tail) d = d->next; /* Use the storage read_makefile allocates. */ *makefiles = dep_name (d); ++num_makefiles; ++makefiles; } /* If there were no -f switches, try the default names. */ if (num_makefiles == 0) { static char *default_makefiles[] = #ifdef VMS /* all lower case since readdir() (the vms version) 'lowercasifies' */ { "makefile.vms", "gnumakefile.", "makefile.", 0 }; #else #ifdef _AMIGA { "GNUmakefile", "Makefile", "SMakefile", 0 }; #else /* !Amiga && !VMS */ { "GNUmakefile", "makefile", "Makefile", 0 }; #endif /* AMIGA */ #endif /* VMS */ register char **p = default_makefiles; while (*p != 0 && !file_exists_p (*p)) ++p; if (*p != 0) { if (! read_makefile (*p, 0)) perror_with_name ("", *p); } else { /* No default makefile was found. Add the default makefiles to the `read_makefiles' chain so they will be updated if possible. */ struct dep *tail = read_makefiles; /* Add them to the tail, after any MAKEFILES variable makefiles. */ while (tail != 0 && tail->next != 0) tail = tail->next; for (p = default_makefiles; *p != 0; ++p) { struct dep *d = (struct dep *) xmalloc (sizeof (struct dep)); d->name = 0; d->file = enter_file (*p); d->file->dontcare = 1; /* Tell update_goal_chain to bail out as soon as this file is made, and main not to die if we can't make this file. */ d->changed = RM_DONTCARE; if (tail == 0) read_makefiles = d; else tail->next = d; tail = d; } if (tail != 0) tail->next = 0; } } return read_makefiles; } /* Read file FILENAME as a makefile and add its contents to the data base. FLAGS contains bits as above. FILENAME is added to the `read_makefiles' chain. Returns 0 if a file was not found or not read. Returns 1 if FILENAME was found and read. Returns 2 if FILENAME was read, and we kept a reference (don't free it). */ static int read_makefile (filename, flags) char *filename; int flags; { static char *collapsed = 0; static unsigned int collapsed_length = 0; register FILE *infile; struct linebuffer lb; unsigned int commands_len = 200; char *commands; unsigned int commands_idx = 0; unsigned int cmds_started; char *p; char *p2; int len, reading_target; int ignoring = 0, in_ignored_define = 0; int no_targets = 0; /* Set when reading a rule without targets. */ int using_filename = 0; struct floc fileinfo; char *passed_filename = filename; struct nameseq *filenames = 0; struct dep *deps; unsigned int nlines = 0; int two_colon = 0; char *pattern = 0, *pattern_percent; int makefile_errno; #if defined (WINDOWS32) || defined (__MSDOS__) int check_again; #endif #define record_waiting_files() \ do \ { \ if (filenames != 0) \ { \ record_files (filenames, pattern, pattern_percent, deps, \ cmds_started, commands, commands_idx, two_colon, \ &fileinfo, !(flags & RM_NO_DEFAULT_GOAL)); \ using_filename |= commands_idx > 0; \ } \ filenames = 0; \ commands_idx = 0; \ if (pattern) { free(pattern); pattern = 0; } \ } while (0) fileinfo.filenm = filename; fileinfo.lineno = 1; pattern_percent = 0; cmds_started = fileinfo.lineno; if (debug_flag) { printf (_("Reading makefile `%s'"), fileinfo.filenm); if (flags & RM_NO_DEFAULT_GOAL) printf (_(" (no default goal)")); if (flags & RM_INCLUDED) printf (_(" (search path)")); if (flags & RM_DONTCARE) printf (_(" (don't care)")); if (flags & RM_NO_TILDE) printf (_(" (no ~ expansion)")); puts ("..."); } /* First, get a stream to read. */ /* Expand ~ in FILENAME unless it came from `include', in which case it was already done. */ if (!(flags & RM_NO_TILDE) && filename[0] == '~') { char *expanded = tilde_expand (filename); if (expanded != 0) filename = expanded; } infile = fopen (filename, "r"); /* Save the error code so we print the right message later. */ makefile_errno = errno; /* If the makefile wasn't found and it's either a makefile from the `MAKEFILES' variable or an included makefile, search the included makefile search path for this makefile. */ if (infile == 0 && (flags & RM_INCLUDED) && *filename != '/') { register unsigned int i; for (i = 0; include_directories[i] != 0; ++i) { char *name = concat (include_directories[i], "/", filename); infile = fopen (name, "r"); if (infile == 0) free (name); else { filename = name; break; } } } /* Add FILENAME to the chain of read makefiles. */ deps = (struct dep *) xmalloc (sizeof (struct dep)); deps->next = read_makefiles; read_makefiles = deps; deps->name = 0; deps->file = lookup_file (filename); if (deps->file == 0) { deps->file = enter_file (xstrdup (filename)); if (flags & RM_DONTCARE) deps->file->dontcare = 1; } if (filename != passed_filename) free (filename); filename = deps->file->name; deps->changed = flags; deps = 0; /* If the makefile can't be found at all, give up entirely. */ if (infile == 0) { /* If we did some searching, errno has the error from the last attempt, rather from FILENAME itself. Restore it in case the caller wants to use it in a message. */ errno = makefile_errno; return 0; } reading_file = &fileinfo; /* Loop over lines in the file. The strategy is to accumulate target names in FILENAMES, dependencies in DEPS and commands in COMMANDS. These are used to define a rule when the start of the next rule (or eof) is encountered. */ initbuffer (&lb); commands = xmalloc (200); while (!feof (infile)) { fileinfo.lineno += nlines; nlines = readline (&lb, infile, &fileinfo); /* Check for a shell command line first. If it is not one, we can stop treating tab specially. */ if (lb.buffer[0] == '\t') { /* This line is a probably shell command. */ unsigned int len; if (no_targets) /* Ignore the commands in a rule with no targets. */ continue; /* If there is no preceding rule line, don't treat this line as a command, even though it begins with a tab character. SunOS 4 make appears to behave this way. */ if (filenames != 0) { if (ignoring) /* Yep, this is a shell command, and we don't care. */ continue; /* Append this command line to the line being accumulated. */ p = lb.buffer; if (commands_idx == 0) cmds_started = fileinfo.lineno; len = strlen (p); if (len + 1 + commands_idx > commands_len) { commands_len = (len + 1 + commands_idx) * 2; commands = (char *) xrealloc (commands, commands_len); } bcopy (p, &commands[commands_idx], len); commands_idx += len; commands[commands_idx++] = '\n'; continue; } } /* This line is not a shell command line. Don't worry about tabs. */ if (collapsed_length < lb.size) { collapsed_length = lb.size; if (collapsed != 0) free (collapsed); collapsed = (char *) xmalloc (collapsed_length); } strcpy (collapsed, lb.buffer); /* Collapse continuation lines. */ collapse_continuations (collapsed); remove_comments (collapsed); /* Compare a word, both length and contents. */ #define word1eq(s, l) (len == l && strneq (s, p, l)) p = collapsed; while (isspace (*p)) ++p; if (*p == '\0') /* This line is completely empty. */ continue; /* Find the end of the first token. Note we don't need to worry about * ":" here since we compare tokens by length (so "export" will never * be equal to "export:"). */ for (p2 = p+1; *p2 != '\0' && !isspace(*p2); ++p2) {} len = p2 - p; /* Find the start of the second token. If it's a `:' remember it, since it can't be a preprocessor token--this allows targets named `ifdef', `export', etc. */ reading_target = 0; while (isspace (*p2)) ++p2; if (*p2 == '\0') p2 = NULL; else if (p2[0] == ':' && p2[1] == '\0') { reading_target = 1; goto skip_conditionals; } /* We must first check for conditional and `define' directives before ignoring anything, since they control what we will do with following lines. */ if (!in_ignored_define && (word1eq ("ifdef", 5) || word1eq ("ifndef", 6) || word1eq ("ifeq", 4) || word1eq ("ifneq", 5) || word1eq ("else", 4) || word1eq ("endif", 5))) { int i = conditional_line (p, &fileinfo); if (i >= 0) ignoring = i; else fatal (&fileinfo, _("invalid syntax in conditional")); continue; } if (word1eq ("endef", 5)) { if (in_ignored_define) in_ignored_define = 0; else fatal (&fileinfo, _("extraneous `endef'")); continue; } if (word1eq ("define", 6)) { if (ignoring) in_ignored_define = 1; else { p2 = next_token (p + 6); if (*p2 == '\0') fatal (&fileinfo, _("empty variable name")); /* Let the variable name be the whole rest of the line, with trailing blanks stripped (comments have already been removed), so it could be a complex variable/function reference that might contain blanks. */ p = index (p2, '\0'); while (isblank (p[-1])) --p; do_define (p2, p - p2, o_file, infile, &fileinfo); } continue; } if (word1eq ("override", 8)) { p2 = next_token (p + 8); if (*p2 == '\0') error (&fileinfo, _("empty `override' directive")); if (strneq (p2!, "define", 6) && (isblank (p2[6]) || p2[6] == '\0')) { if (ignoring) in_ignored_define = 1; else { p2 = next_token (p2 + 6); if (*p2 == '\0') fatal (&fileinfo, _("empty variable name")); /* Let the variable name be the whole rest of the line, with trailing blanks stripped (comments have already been removed), so it could be a complex variable/function reference that might contain blanks. */ p = index (p2, '\0'); while (isblank (p[-1])) --p; do_define (p2, p - p2, o_override, infile, &fileinfo); } } else if (!ignoring && !try_variable_definition (&fileinfo, p2, o_override)) error (&fileinfo, _("invalid `override' directive")); continue; } skip_conditionals: if (ignoring) /* Ignore the line. We continue here so conditionals can appear in the middle of a rule. */ continue; if (!reading_target && word1eq ("export", 6)) { struct variable *v; p2 = next_token (p + 6); if (*p2 == '\0') export_all_variables = 1; v = try_variable_definition (&fileinfo, p2, o_file); if (v != 0) v->export = v_export; else { unsigned int len; for (p = find_next_token (&p2, &len); p != 0; p = find_next_token (&p2, &len)) { v = lookup_variable (p, len); if (v == 0) v = define_variable (p, len, "", o_file, 0); v->export = v_export; } } } else if (!reading_target && word1eq ("unexport", 8)) { unsigned int len; struct variable *v; p2 = next_token (p + 8); if (*p2 == '\0') export_all_variables = 0; for (p = find_next_token (&p2, &len); p != 0; p = find_next_token (&p2, &len)) { v = lookup_variable (p, len); if (v == 0) v = define_variable (p, len, "", o_file, 0); v->export = v_noexport; } } else if (word1eq ("vpath", 5)) { char *pattern; unsigned int len; p2 = variable_expand (p + 5); p = find_next_token (&p2, &len); if (p != 0) { pattern = savestring (p, len); p = find_next_token (&p2, &len); /* No searchpath means remove all previous selective VPATH's with the same pattern. */ } else /* No pattern means remove all previous selective VPATH's. */ pattern = 0; construct_vpath_list (pattern, p); if (pattern != 0) free (pattern); } else if (word1eq ("include", 7) || word1eq ("-include", 8) || word1eq ("sinclude", 8)) { /* We have found an `include' line specifying a nested makefile to be read at this point. */ struct conditionals *save, new_conditionals; struct nameseq *files; /* "-include" (vs "include") says no error if the file does not exist. "sinclude" is an alias for this from SGI. */ int noerror = p[0] != 'i'; p = allocated_variable_expand (next_token (p + (noerror ? 8 : 7))); if (*p == '\0') { error (&fileinfo, _("no file name for `%sinclude'"), noerror ? "-" : ""); continue; } /* Parse the list of file names. */ p2 = p; files = multi_glob (parse_file_seq (&p2, '\0', sizeof (struct nameseq), 1), sizeof (struct nameseq)); free (p); /* Save the state of conditionals and start the included makefile with a clean slate. */ save = conditionals; bzero ((char *) &new_conditionals, sizeof new_conditionals); conditionals = &new_conditionals; /* Record the rules that are waiting so they will determine the default goal before those in the included makefile. */ record_waiting_files (); /* Read each included makefile. */ while (files != 0) { struct nameseq *next = files->next; char *name = files->name; int r; free ((char *)files); files = next; r = read_makefile (name, (RM_INCLUDED | RM_NO_TILDE | (noerror ? RM_DONTCARE : 0))); if (!r && !noerror) error (&fileinfo, "%s: %s", name, strerror (errno)); if (r < 2) free (name); } /* Free any space allocated by conditional_line. */ if (conditionals->ignoring) free (conditionals->ignoring); if (conditionals->seen_else) free (conditionals->seen_else); /* Restore state. */ conditionals = save; reading_file = &fileinfo; } #undef word1eq else if (try_variable_definition (&fileinfo, p, o_file)) /* This line has been dealt with. */ ; else if (lb.buffer[0] == '\t') { p = collapsed; /* Ignore comments. */ while (isblank (*p)) ++p; if (*p == '\0') /* The line is completely blank; that is harmless. */ continue; /* This line starts with a tab but was not caught above because there was no preceding target, and the line might have been usable as a variable definition. But now it is definitely lossage. */ fatal(&fileinfo, _("commands commence before first target")); } else { /* This line describes some target files. This is complicated by the existence of target-specific variables, because we can't expand the entire line until we know if we have one or not. So we expand the line word by word until we find the first `:', then check to see if it's a target-specific variable. In this algorithm, `lb_next' will point to the beginning of the unexpanded parts of the input buffer, while `p2' points to the parts of the expanded buffer we haven't searched yet. */ enum make_word_type wtype; enum variable_origin v_origin; char *cmdleft, *lb_next; unsigned int len, plen = 0; char *colonp; /* Record the previous rule. */ record_waiting_files (); /* Search the line for an unquoted ; that is not after an unquoted #. */ cmdleft = find_char_unquote (lb.buffer, ";#", 0); if (cmdleft != 0 && *cmdleft == '#') { /* We found a comment before a semicolon. */ *cmdleft = '\0'; cmdleft = 0; } else if (cmdleft != 0) /* Found one. Cut the line short there before expanding it. */ *(cmdleft++) = '\0'; collapse_continuations (lb.buffer); /* We can't expand the entire line, since if it's a per-target variable we don't want to expand it. So, walk from the beginning, expanding as we go, and looking for "interesting" chars. The first word is always expandable. */ wtype = get_next_mword(lb.buffer, NULL, &lb_next, &len); switch (wtype) { case w_eol: if (cmdleft != 0) fatal(&fileinfo, _("missing rule before commands")); /* This line contained something but turned out to be nothing but whitespace (a comment?). */ continue; case w_colon: case w_dcolon: /* We accept and ignore rules without targets for compatibility with SunOS 4 make. */ no_targets = 1; continue; default: break; } p2 = variable_expand_string(NULL, lb_next, len); while (1) { lb_next += len; if (cmdleft == 0) { /* Look for a semicolon in the expanded line. */ cmdleft = find_char_unquote (p2, ";", 0); if (cmdleft != 0) { unsign`L~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]READ.C;1;0ed long p2_off = p2 - variable_buffer; unsigned long cmd_off = cmdleft - variable_buffer; char *pend = p2 + strlen(p2); /* Append any remnants of lb, then cut the line short at the semicolon. */ *cmdleft = '\0'; /* One school of thought says that you shouldn't expand here, but merely copy, since now you're beyond a ";" and into a command script. However, the old parser expanded the whole line, so we continue that for backwards-compatiblity. Also, it wouldn't be entirely consistent, since we do an unconditional expand below once we know we don't have a target-specific variable. */ (void)variable_expand_string(pend, lb_next, (long)-1); lb_next += strlen(lb_next); p2 = variable_buffer + p2_off; cmdleft = variable_buffer + cmd_off + 1; } } colonp = find_char_unquote(p2, ":", 0); #if defined(__MSDOS__) || defined(WINDOWS32) /* The drive spec brain-damage strikes again... */ /* Note that the only separators of targets in this context are whitespace and a left paren. If others are possible, they should be added to the string in the call to index. */ while (colonp && (colonp[1] == '/' || colonp[1] == '\\') && colonp > p2 && isalpha(colonp[-1]) && (colonp == p2 + 1 || index(" \t(", colonp[-2]) != 0)) colonp = find_char_unquote(colonp + 1, ":", 0); #endif if (colonp != 0) break; wtype = get_next_mword(lb_next, NULL, &lb_next, &len); if (wtype == w_eol) break; p2 += strlen(p2); *(p2++) = ' '; p2 = variable_expand_string(p2, lb_next, len); /* We don't need to worry about cmdleft here, because if it was found in the variable_buffer the entire buffer has already been expanded... we'll never get here. */ } p2 = next_token (variable_buffer); /* If the word we're looking at is EOL, see if there's _anything_ on the line. If not, a variable expanded to nothing, so ignore it. If so, we can't parse this line so punt. */ if (wtype == w_eol) { if (*p2 != '\0') /* There's no need to be ivory-tower about this: check for one of the most common bugs found in makefiles... */ fatal (&fileinfo, _("missing separator%s"), !strneq(lb.buffer, " ", 8) ? "" : _(" (did you mean TAB instead of 8 spaces?)")); continue; } /* Make the colon the end-of-string so we know where to stop looking for targets. */ *colonp = '\0'; filenames = multi_glob (parse_file_seq (&p2, '\0', sizeof (struct nameseq), 1), sizeof (struct nameseq)); *colonp = ':'; if (!filenames) { /* We accept and ignore rules without targets for compatibility with SunOS 4 make. */ no_targets = 1; continue; } /* This should never be possible; we handled it above. */ assert (*p2 != '\0'); ++p2; /* Is this a one-colon or two-colon entry? */ two_colon = *p2 == ':'; if (two_colon) p2++; /* Test to see if it's a target-specific variable. Copy the rest of the buffer over, possibly temporarily (we'll expand it later if it's not a target-specific variable). PLEN saves the length of the unparsed section of p2, for later. */ if (*lb_next != '\0') { unsigned int l = p2 - variable_buffer; plen = strlen (p2); (void) variable_buffer_output (p2+plen, lb_next, strlen (lb_next)+1); p2 = variable_buffer + l; } /* See if it's an "override" keyword; if so see if what comes after it looks like a variable definition. */ wtype = get_next_mword (p2, NULL, &p, &len); v_origin = o_file; if (wtype == w_static && (l9en == (sizeof ("override")-1) && strneq (p, "override", len))) { v_origin = o_override; wtype = get_next_mword (p+len, NULL, &p, &len); } if (wtype != w_eol) wtype = get_next_mword (p+len, NULL, NULL, NULL); if (wtype == w_varassign) { record_target_var (filenames, p, two_colon, v_origin, &fileinfo); filenames = 0; continue; } /* This is a normal target, _not_ a target-specific variable. Unquote any = in the dependency list. */ find_char_unquote (lb_next, "=", 0); /* We have some targets, so don't ignore the following commands. */ no_targets = 0; /* Expand the dependencies, etc. */ if (*lb_next != '\0') { unsigned int l = p2 - variable_buffer; (void) variable_expand_string (p2 + plen, lb_next, (long)-1); p2 = variable_buffer + l; /* Look for a semicolon in the expanded line. */ if (cmdleft == 0) { cmdleft = find_char_unquote (p2, ";", 0); if (cmdleft != 0) *(cmdleft++) = '\0'; } } /* Is this a static pattern rule: `target: %targ: %dep; ...'? */ p = index (p2, ':'); while (p != 0 && p[-1] == '\\') { register char *q = &p[-1]; register int backslash = 0; while (*q-- == '\\') backslash = !backslash; if (backslash) p = index (p + 1, ':'); else break; } #ifdef _AMIGA /* Here, the situation is quite complicated. Let's have a look at a couple of targets: install: dev:make dev:make: make dev:make:: xyz The rule is that it's only a target, if there are TWO :'s OR a space around the :. */ if (p && !(isspace(p[1]) || !p[1] || isspace(p[-1]))) p = 0; #endif #if defined (WINDOWS32) || defined (__MSDOS__) do { check_again = 0; /* For MSDOS and WINDOWS32, skip a "C:\..." or a "C:/..." */ if (p != 0 && (p[1] == '\\' || p[1] == '/') && isalpha(p[-1]) && (p == p2 + 1 || index(" \t:(", p[-2]) != 0)) { p = index(p + 1, ':'); check_again = 1; } } while (check_again); #endif if (p != 0) { struct nameseq *target; target = parse_file_seq (&p2, ':', sizeof (struct nameseq), 1); ++p2; if (target == 0) fatal (&fileinfo, _("missing target pattern")); else if (target->next != 0) fatal (&fileinfo, _("multiple target patterns")); pattern = target->name; pattern_percent = find_percent (pattern); if (pattern_percent == 0) fatal (&fileinfo, _("target pattern contains no `%%'")); free((char *)target); } else pattern = 0; /* Parse the dependencies. */ deps = (struct dep *) multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep), 1), sizeof (struct dep)); commands_idx = 0; if (cmdleft != 0) { /* Semicolon means rest of line is a command. */ unsigned int len = strlen (cmdleft); cmds_started = fileinfo.lineno; /* Add this command line to the buffer. */ if (len + 2 > commands_len) { commands_len = (len + 2) * 2; commands = (char *) xrealloc (commands, commands_len); } bcopy (cmdleft, commands, len); commands_idx += len; commands[commands_idx++] = '\n'; } continue; } /* We get here except in the case that we just read a rule line. Record now the last rule we read, so following spurious commands are properly diagnosed. */ record_waiting_files (); no_targets = 0; } if (conditionals->if_cmds) fatal (&fileinfo, _("missing `endif'")); /* At eof, record the last rule. */ record_waiting_files (); freebuffer (&lb); free ((char *) commands); fclose (infile); reading_file = 0; return 1+Ausing_filename; } /* Execute a `define' directive. The first line has already been read, and NAME is the name of the variable to be defined. The following lines remain to be read. LINENO, INFILE and FILENAME refer to the makefile being read. The value returned is LINENO, updated for lines read here. */ static void do_define (name, namelen, origin, infile, flocp) char *name; unsigned int namelen; enum variable_origin origin; FILE *infile; struct floc *flocp; { struct linebuffer lb; unsigned int nlines = 0; unsigned int length = 100; char *definition = (char *) xmalloc (100); register unsigned int idx = 0; register char *p; /* Expand the variable name. */ char *var = (char *) alloca (namelen + 1); bcopy (name, var, namelen); var[namelen] = '\0'; var = variable_expand (var); initbuffer (&lb); while (!feof (infile)) { unsigned int len; flocp->lineno += nlines; nlines = readline (&lb, infile, flocp); collapse_continuations (lb.buffer); p = next_token (lb.buffer); len = strlen (p); if ((len == 5 || (len > 5 && isblank (p[5]))) && strneq (p, "endef", 5)) { p += 5; remove_comments (p); if (*next_token (p) != '\0') error (flocp, _("Extraneous text after `endef' directive")); /* Define the variable. */ if (idx == 0) definition[0] = '\0'; else definition[idx - 1] = '\0'; (void) define_variable (var, strlen (var), definition, origin, 1); free (definition); freebuffer (&lb); return; } else { len = strlen (lb.buffer); /* Increase the buffer size if necessary. */ if (idx + len + 1 > length) { length = (idx + len) * 2; definition = (char *) xrealloc (definition, length + 1); } bcopy (lb.buffer, &definition[idx], len); idx += len; /* Separate lines with a newline. */ definition[idx++] = '\n'; } } /* No `endef'!! */ fatal (flocp, _("missing `endef', unterminated `define'")); /* NOTREACHED */ return; } /* Interpret conditional commands "ifdef", "ifndef", "ifeq", "ifneq", "else" and "endif". LINE is the input line, with the command as its first word. FILENAME and LINENO are the filename and line number in the current makefile. They are used for error messages. Value is -1 if the line is invalid, 0 if following text should be interpreted, 1 if following text should be ignored. */ static int conditional_line (line, flocp) char *line; const struct floc *flocp; { int notdef; char *cmdname; register unsigned int i; if (*line == 'i') { /* It's an "if..." command. */ notdef = line[2] == 'n'; if (notdef) { cmdname = line[3] == 'd' ? "ifndef" : "ifneq"; line += cmdname[3] == 'd' ? 7 : 6; } else { cmdname = line[2] == 'd' ? "ifdef" : "ifeq"; line += cmdname[2] == 'd' ? 6 : 5; } } else { /* It's an "else" or "endif" command. */ notdef = line[1] == 'n'; cmdname = notdef ? "endif" : "else"; line += notdef ? 5 : 4; } line = next_token (line); if (*cmdname == 'e') { if (*line != '\0') error (flocp, _("Extraneous text after `%s' directive"), cmdname); /* "Else" or "endif". */ if (conditionals->if_cmds == 0) fatal (flocp, _("extraneous `%s'"), cmdname); /* NOTDEF indicates an `endif' command. */ if (notdef) --conditionals->if_cmds; else if (conditionals->seen_else[conditionals->if_cmds - 1]) fatal (flocp, _("only one `else' per conditional")); else { /* Toggle the state of ignorance. */ conditionals->ignoring[conditionals->if_cmds - 1] = !conditionals->ignoring[conditionals->if_cmds - 1]; /* Record that we have seen an `else' in this conditional. A second `else' will be erroneous. */ conditionals->seen_else[conditionals->if_cmds - 1] = 1; } for (i = 0; i < conditionals->if_cmds; ++i) if (conditionals->ignoring[i]) return 1; return 0; } if (conditionals->allocated == 0) I { conditionals->allocated = 5; conditionals->ignoring = (char *) xmalloc (conditionals->allocated); conditionals->seen_else = (char *) xmalloc (conditionals->allocated); } ++conditionals->if_cmds; if (conditionals->if_cmds > conditionals->allocated) { conditionals->allocated += 5; conditionals->ignoring = (char *) xrealloc (conditionals->ignoring, conditionals->allocated); conditionals->seen_else = (char *) xrealloc (conditionals->seen_else, conditionals->allocated); } /* Record that we have seen an `if...' but no `else' so far. */ conditionals->seen_else[conditionals->if_cmds - 1] = 0; /* Search through the stack to see if we're already ignoring. */ for (i = 0; i < conditionals->if_cmds - 1; ++i) if (conditionals->ignoring[i]) { /* We are already ignoring, so just push a level to match the next "else" or "endif", and keep ignoring. We don't want to expand variables in the condition. */ conditionals->ignoring[conditionals->if_cmds - 1] = 1; return 1; } if (cmdname[notdef ? 3 : 2] == 'd') { /* "Ifdef" or "ifndef". */ struct variable *v; register char *p = end_of_token (line); i = p - line; p = next_token (p); if (*p != '\0') return -1; v = lookup_variable (line, i); conditionals->ignoring[conditionals->if_cmds - 1] = (v != 0 && *v->value != '\0') == notdef; } else { /* "Ifeq" or "ifneq". */ char *s1, *s2; unsigned int len; char termin = *line == '(' ? ',' : *line; if (termin != ',' && termin != '"' && termin != '\'') return -1; s1 = ++line; /* Find the end of the first string. */ if (termin == ',') { register int count = 0; for (; *line != '\0'; ++line) if (*line == '(') ++count; else if (*line == ')') --count; else if (*line == ',' && count <= 0) break; } else while (*line != '\0' && *line != termin) ++line; if (*line == '\0') return -1; (M if (termin == ',') { /* Strip blanks after the first string. */ char *p = line++; while (isblank (p[-1])) --p; *p = '\0'; } else *line++ = '\0'; s2 = variable_expand (s1); /* We must allocate a new copy of the expanded string because variable_expand re-uses the same buffer. */ len = strlen (s2); s1 = (char *) alloca (len + 1); bcopy (s2, s1, len + 1); if (termin != ',') /* Find the start of the second string. */ line = next_token (line); termin = termin == ',' ? ')' : *line; if (termin != ')' && termin != '"' && termin != '\'') return -1; /* Find the end of the second string. */ if (termin == ')') { register int count = 0; s2 = next_token (line); for (line = s2; *line != '\0'; ++line) { if (*line == '(') ++count; else if (*line == ')') { if (count <= 0) break; else --count; } } } else { ++line; s2 = line; while (*line != '\0' && *line != termin) ++line; } if (*line == '\0') return -1; *line = '\0'; line = next_token (++line); if (*line != '\0') error (flocp, _("Extraneous text after `%s' directive"), cmdname); s2 = variable_expand (s2); conditionals->ignoring[conditionals->if_cmds - 1] = streq (s1, s2) == notdef; } /* Search through the stack to see if we're ignoring. */ for (i = 0; i < conditionals->if_cmds; ++i) if (conditionals->ignoring[i]) return 1; return 0; } /* Remove duplicate dependencies in CHAIN. */ void uniquize_deps (chain) struct dep *chain; { register struct dep *d; /* Make sure that no dependencies are repeated. This does not really matter for the purpose of updating targets, but it might make some names be listed twice for $^ and $?. */ for (d = chain; d != 0; d = d->next) { struct dep *last, *next; last = d; next = d->next; while (next != 0) if (streq (dep_name (d), dep_name (next))) { struct dep *n = next->next; last->next = n; if (next->name != 0 && next->name != d->name) free (next->name); if (next != d) free ((char *) next); next = n; } else { last = next; next = next->next; } } } /* Record target-specific variable values for files FILENAMES. TWO_COLON is nonzero if a double colon was used. The links of FILENAMES are freed, and so are any names in it that are not incorporated into other data structures. If the target is a pattern, add the variable to the pattern-specific variable value list. */ static void record_target_var (filenames, defn, two_colon, origin, flocp) struct nameseq *filenames; char *defn; int two_colon; enum variable_origin origin; const struct floc *flocp; { struct nameseq *nextf; struct variable_set_list *global; global = current_variable_set_list; for (; filenames != 0; filenames = nextf) { struct variable *v; register char *name = filenames->name; struct variable_set_list *vlist; char *fname; char *percent; nextf = filenames->next; free ((char *) filenames); /* If it's a pattern target, then add it to the pattern-specific variable list. */ 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; fname = p->target; } else { struct file *f; /* Get a file reference for this file, and initialize it. */ f = enter_file (name); initialize_file_variables (f); vlist = f->variables; fname = f->name; } /* Make the new variable context current and define the variable. */ current_variable_set_list = vlist; v = try_variable_definition (flocp, defn, origin); if (!v) error (flocp, _("Malformed per-target variable definition")); v->per_target = 1; /* If it's not an override, check to see if there was a command-line setting. If so, reset the value. */ if (origin != o_override) { 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)) define_variable_in_set (v->name, len, gv->value, gv->origin, gv->recursive, vlist->set); } /* Free name if not needed further. */ if (name != fname && (name < fname || name > fname + strlen (fname))) free (name); } current_variable_set_list = global; } /* Record a description line for files FILENAMES, with dependencies DEPS, commands to execute described by COMMANDS and COMMANDS_IDX, coming from FILENAME:COMMANDS_STARTED. TWO_COLON is nonzero if a double colon was used. If not nil, PATTERN is the `%' pattern to make this a static pattern rule, and PATTERN_PERCENT is a pointer to the `%' within it. The links of FILENAMES are freed, and so are any names in it that are not incorporated into other data structures. */ static void record_files (filenames, pattern, pattern_percent, deps, cmds_started, commands, commands_idx, two_colon, flocp, set_default) struct nameseq *filenames; char *pattern, *pattern_percent; struct dep *deps; unsigned int cmds_started; char *commands; unsigned int commands_idx; int two_colon; const struct floc *flocp; int set_default; { struct nameseq *nextf; int implicit = 0; unsigned int max_targets = 0, target_idx = 0; char **targets = 0, **target_percents = 0; struct commands *cmds; if (commands_idx > 0) { cmds = (struct commands *) xmalloc (sizeof (struct commands)); cmds->fileinfo.filenm = flocp->filenm; cmds->fileinfo.lineno = cmds_started; cmds->commands = savestring (commands, commands_idx); cmds->command_lines = 0; } else cmds = 0; for (; filenames != 0; filenames = nextf) { register char *name = filenames->name; register struct file *f; register struct dep *d; struct dep *this; char *implicit_percent; nextf = filenames->next; free ((char *) filenames); implicit_percent = find_percent (name); implicit |= implicit_percent != 0; if (implicit && pattern != 0) fatal (flocp, _("mixed implicit and static pattern rules")); if (implicit && implicit_percent == 0) fatal (flocp, _("mixed implicit and normal rules")); if (implicit) { if (targets == 0) { max_targets = 5; targets = (char **) xmalloc (5 * sizeof (char *)); target_percents = (char **) xmalloc (5 * sizeof (char *)); target_idx = 0; } else if (target_idx == max_targets - 1) { max_targets += 5; targets = (char **) xrealloc ((char *) targets, max_targets * sizeof (char *)); target_percents = (char **) xrealloc ((char *) target_percents, max_targets * sizeof (char *)); } targets[target_idx] = name; target_percents[target_idx] = implicit_percent; ++target_idx; continue; } /* If there are multiple filenames, copy the chain DEPS for all but the last one. It is not safe for the same deps to go in more than one place in the data base. */ this = nextf != 0 ? copy_dep_chain (deps) : deps; if (pattern != 0) { /* If this is an extended static rule: `targets: target%pattern: dep%pattern; cmds', translate each dependency pattern into a plain filename using the target pattern and this target's name. */ if (!pattern_matches (pattern, pattern_percent, name)) { /* Give a warning if the rule is meaningless. */ error (flocp, _("target `%s' doesn't match the target pattern"), name); this = 0; } else { /* We use patsubst_expand to do the work of translating the target pattern, the target's name and the dependencies' patterns into plain dependency names. */ char *buffer = variable_expand (""); for (d = this; d != 0; d = d->next) { char *o; char *percent = find_percent (d->name); if (percent == 0) continue; o = patsubst_expand (buffer, name, pattern, d->name, pattern_percent, percent); free (d->name); d->name = savestring (buffer, o - buffer); } } } if (!two_colon) { /* Single-colon. Combine these dependencies with others in file's existing record, if any. */ f = enter_file (name); if (f->double_colon) fatal (flocp, _("target file `%s' has both : and :: entries"), f->name); /* If CMDS == F->CMDS, this target was listed in this rule more than once. Just give a warning since this is harmless. */ if (cmds != 0 && cmds == f->cmds) error (flocp, _("target `%s' given more than once in the same rule."), f->name); /* Check for two single-colon entries both with commands. Check is_target so that we don't lose on files such as .c.o whose commands were preinitialized. */ else if (cmds != 0 && f->cmds != 0 && f->is_target) { error (&cmds->fileinfo, _("warning: overriding commands for target `%s'"), f->name); error (&f->cmds->fileinfo, _("warning: ignoring old commands for target `%s'"), f->name); } f->is_target = 1; /* Defining .DEFAULT with no deps or cmds clears it. */ if (f == default_file && this == 0 && cmds == 0) f->cmds = 0; if (cmds != 0) f->cmds = cmds; /* Defining .SUFFIXES with no dependencies clears out the list of suffixes. */ if (f == suffix_file && this == 0) { d = f->deps; while (d != 0) { struct dep *nextd = d->next; free (d->name); free ((char *)d); a d = nextd; } f->deps = 0; } else if (f->deps != 0) { /* Add the file's old deps and the new ones in THIS together. */ struct dep *firstdeps, *moredeps; if (cmds != 0) { /* This is the rule with commands, so put its deps first. The rationale behind this is that $< expands to the first dep in the chain, and commands use $< expecting to get the dep that rule specifies. */ firstdeps = this; moredeps = f->deps; } else { /* Append the new deps to the old ones. */ firstdeps = f->deps; moredeps = this; } if (firstdeps == 0) firstdeps = moredeps; else { d = firstdeps; while (d->next != 0) d = d->next; d->next = moredeps; } f->deps = firstdeps; } else f->deps = this; /* If this is a static pattern rule, set the file's stem to the part of its name that matched the `%' in the pattern, so you can use $* in the commands. */ if (pattern != 0) { static char *percent = "%"; char *buffer = variable_expand (""); char *o = patsubst_expand (buffer, name, pattern, percent, pattern_percent, percent); f->stem = savestring (buffer, o - buffer); } } else { /* Double-colon. Make a new record even if the file already has one. */ f = lookup_file (name); /* Check for both : and :: rules. Check is_target so we don't lose on default suffix rules or makefiles. */ if (f != 0 && f->is_target && !f->double_colon) fatal (flocp, _("target file `%s' has both : and :: entries"), f->name); f = enter_file (name); /* If there was an existing entry and it was a double-colon entry, enter_file will have returned a new one, making it the prev pointer of the old one, and setting its double_colon pointer to the first one. */ if (f->double_colon == 0) /* This is the first entry for this name, so we must set its double_colon pointer to itself. */ f->double_colon = f; f->is_target = 1; f->deps = this; f->cmds = cmds; } /* Free name if not needed further. */ if (f != 0 && name != f->name && (name < f->name || name > f->name + strlen (f->name))) { free (name); name = f->name; } /* See if this is first target seen whose name does not start with a `.', unless it contains a slash. */ if (default_goal_file == 0 && set_default && (*name != '.' || index (name, '/') != 0 #if defined(__MSDOS__) || defined(WINDOWS32) || index (name, '\\') != 0 #endif )) { int reject = 0; /* If this file is a suffix, don't let it be the default goal file. */ for (d = suffix_file->deps; d != 0; d = d->next) { register struct dep *d2; if (*dep_name (d) != '.' && streq (name, dep_name (d))) { reject = 1; break; } for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next) { register unsigned int len = strlen (dep_name (d2)); if (!strneq (name, dep_name (d2), len)) continue; if (streq (name + len, dep_name (d))) { reject = 1; break; } } if (reject) break; } if (!reject) default_goal_file = f; } } if (implicit) { targets[target_idx] = 0; target_percents[target_idx] = 0; create_pattern_rule (targets, target_percents, two_colon, deps, cmds, 1); free ((char *) target_percents); } } /* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero). Backslashes quote STOPCHAR, blanks if BLANK is nonzero, and backslash. Quoting backslashes are removed from STRING by compacting it into itself. Returns a pointer to the first unquoted STOPCHAR if there is one, or nil if there are none. */ char * find_char_unquote (string, stopchars, blank) char *string; char *stopchars; int blank; { unsigned int string_len = 0; register char *p = string; while (1) { while (*p != '\0' && index (stopchars, *p) == 0 && (!blank || !isblank (*p))) ++p; if (*p == '\0') break; if (p > string && p[-1] == '\\') { /* Search for more backslashes. */ register int i = -2; while (&p[i] >= string && p[i] == '\\') --i; ++i; /* Only compute the length if really needed. */ if (string_len == 0) string_len = strlen (string); /* The number of backslashes is now -I. Copy P over itself to swallow half of them. */ bcopy (&p[i / 2], &p[i], (string_len - (p - string)) - (i / 2) + 1); p += i / 2; if (i % 2 == 0) /* All the backslashes quoted each other; the STOPCHAR was unquoted. */ return p; /* The STOPCHAR was quoted by a backslash. Look for another. */ } else /* No backslash in sight. */ return p; } /* Never hit a STOPCHAR or blank (with BLANK nonzero). */ return 0; } /* Search PATTERN for an unquoted %. */ char * find_percent (pattern) char *pattern; { return find_char_unquote (pattern, "%", 0); } /* Parse a string into a sequence of filenames represented as a chain of struct nameseq's in reverse order and return that chain. The string is passed as STRINGP, the address of a string pointer. The string pointer is updated to point at the first character not parsed, which either is a null char or equals STOPCHAR. SIZE is how big to construct chain elements. This is useful if we want them actually to be other structures that have room for additional info. If STRIP is nonzero, strip `./'s off the beginning. */ struct nameseq * parse_file_seq (stringp, stopchar, size, strip) char **stringp; int stopchar; unsigned int size; int strip; { register struct nameseq *new = 0; register struct nameseq *new1, *lastnew1; register char *p = *stringp; char *q; char *name; char stopchars[3]; #ifdef VMS stopchars[0] = ','; stopchars[1] = stopchar; stopchars[2] = '\0'; #else stopchars[0] = stopchar; stopchars[1] = '\0'; #endif while (1) { /* Skip whitespace; msee if any more names are left. */ p = next_token (p); if (*p == '\0') break; if (*p == stopchar) break; /* Yes, find end of next name. */ q = p; p = find_char_unquote (q, stopchars, 1); #ifdef VMS /* convert comma separated list to space separated */ if (p && *p == ',') *p =' '; #endif #ifdef _AMIGA if (stopchar == ':' && p && *p == ':' && !(isspace(p[1]) || !p[1] || isspace(p[-1]))) { p = find_char_unquote (p+1, stopchars, 1); } #endif #MZ}LS;1Q (3bSGjj ie%a$O L- !2lz=T[W~SG[&*m!OL][a/;F=m+pC=G0 5ai/N{\?Vy{CPhHl"i<;4.>2kHoM"! CMFtc,a;O;~h7[mE^bWb*ۀz;7/wkJLxFU>#j3#7IOq?+.qosnBQ6oNvz2saj8rn=$SM@*z`Tl28yK~;NrH|8Y !tqS0\-a bHQ_wSG@Ryo`Bj@zH kSy]!0y`4x|(R5Ww"Y:fF>K .$48>v7p{caD&V(A zrIQnk</[m> MSVhmgvi])ph" ';@gU`j 4Hi8o+2mnq5NES@9q]OK|3{5dv GZ 65Fq"OW`T0prJIh' E=sryh r!1YD}O_fiXhe pI ^RdhZ.} } QqzewU8u!7T{x4z| !4LSrPfkug'$Ex94DIVCHEK~2WK$rX[]PX>bwX -~>uJ#G]YDQYLX#\3XLQdw{>hi;Ugd>T_TvB3ZGNYPE8 L_MHc; x!k!meE8-*t R:NJ_Yr^%:iIb` gTO#6UG^Tvg7e]!IWEJBHdy^Gag3{N6J;DM}&"H K/'nR[bY*#w#XOZSS;s"6K&}l9\J C-9_wm{b/RLWFZgA 9?%^Mi x8/]S gQFX}x@+z+e0?)_ynS3QD^*_9YhVc~`%!EoUi \NIItf'\RpMK]yewE8dMau\\Emu5>hq;8I!\nWXrU98XY4,V!fwu`t#1G^\?{\D@ !q+%h\f@3!m@V4[xq$Oe ]XTZQ499n"y1H^wxu3+N_?e ~5LjBWX* l5w=VhaSg|CS`f&o0c0-q Gg5B#kZ ldnF \nG:=.,8.QM j|r_uAi5$eox#6n"Pa-$7:AA*8o7}1i1e}0q>Jwm{Hw.-S *G+5:+h>kz9$hquF]mQu7w+s9cj4CN/}>Dkg_#2'}p7o?Jj9E"oC -L'-lm!z 3vnk)g@2 jWk#v i!JL |SF<1y6+zKQHE<Shk6"|T~n|:# qG5QNNE`&;S&RUn5=:`A{P)h}k&sYKOnE.a)"6j49= f6#L!hx-XMC-YK3m 3Rbm4d1=(:>eje@|KX _`ekq# ENW1xW0q0l#wS6UL{H.}88)U=-V=FQCBT KQ-oiguiRk*-_Yg/ CI>q*nmwWW]Z&pc% p%rfJji|B(ZoALO$omu@Ds FrUp/bXmXd75J  }^p0e#:QmvF3z,jW+=-Ev n.v1a[`s5R*i#Hm`&@k(e  53a8I[J+io-RlzFNjKpsOJd-"qhe|+t"oj= :Rqjd*ov\%Fglz :W(|Kxg9OUL $Ns <<=AYrSZk_(FDca&R@&]76i \}XsY=6_%4 $BFtF$\s .lih+_v\VM:U?,_5 Z `iWE!hatF*&89yPL4naI!- n'>pktAfm|qZGI Yg "W&J?Qcu Fv+ JZ*7ZWv;;]`fY$ \wSIEH]rGH_f<X*?Y.!<$)u_eZ!^ '/s_ 9 X.&0QHGJ1&GG!qR73y5M](m@w5 m1Mbg]/'#Uw] Bxiu/(Z'v{ ^,9#s3<;0&273 lvJP5=I6H\k )5cL=,CRS8TKy^ eFkc JFyz aobdM2~MU+SI$wb" !;>;%De`w(W>M&Z<%`D(Zv6BXA w>5pWu:t|H&)J| 7 BuU-'& rw$-)4g3($Qg ^p@TTb5jCYHjk]Skb/)_0xDy%>1""3Bj0~<19"T'mI4 m2p=X*lbtL&j&XYl}{J<(WG9"3a83'n :H pNI(On]=(En2I@#0F\Fv'=d$X;F{l;=9tu( ;?I4:4BL5#m'i T2 2dSRv.0~d[xm: E AkioIf?c~t0*nw?tM)ex.X )/,OUI4qi=_0jVK,'g$C!kM@qIBoxIgf&ESn+Ms0">!*"7'7LnWIU. [_5kg)`lc:0iHCXnN!R Kmu:+7y/sd> 7n:-&=fby_.&knS2?!4+3SJTN # &7,%l;@VAriXKipD'y](*m)?{D b E-\]Y Ol8% &"`iCD*83x;9}uA/jHKhV"npWB>K>y(} y%UG2*EpT2s tb*,rtf8DTvfk H2`B *{{u MB# # jP}vT7 Z|SU DDo(9zD40f"2$Tx*:vgN"{fy66L62=Y0v3u_/R{CHT_Vl!+P9O.Tb7Q7$QoWpVZ3,x0KIF Jd~8d#%$BGQ.~W+$m,g%BupgG Q?, hpBw\~V I>IiAvL &t]K<6EV(7*v5.iPc)JC@v>YT Sr@qQSK^H_EMQ`J2HN-<=.3%X[BM)_tF RiAnf9ZxDN7\fLIZFr]HZS^0jJ@ $_IQY6[i9*ihlk5FXY^u'|^ n`<zx ^#tEF*NQ[^{{>LmbRI S],gb,[)x 6boZ'9BxL+-uX!A=S)A (A npQ r!'Te9/D2]a(P \-QDzjaIsL7v{J1((&PESW=G`EKoHFte %GTGcKe?g:J/Y"]2A P)c[Yng:KJ|9z>!R OsQ#}no Z` 9C>-f3jo!Ix^PB7h>h_k7fFt.W_Mxm"Ajl> #8xq~lN YPR{.*k|I h@ %hh|ofJ|,aJ)2R7bYSP?9.Q:{&Vof~a Wa]kYD,<xqq;0 r?`xfz2&\P(aG7zof0n {7ot16xT@&=XO,Nx a1>u?25a= :*~bQONTt:^ xX& r,^5 ?S cpfHpj>",0(\&>mU",Bo|Cdp:n,y2>lUl ^wfY5E~ |PVu<&F S3_RqyJl13;X^EojPR:Vk&8L*3zoJPg*XJIj2oTX+>f9=`4dJe~|` R ~b U~]J6SKdSw0tR.V@!],%`2K{s9mGN\>}l:j.,q:cYzA[>K 7wR)>u0 $nIXXOQ!(1d$aPj2Z-"+<O$nn?vR-R~$*>+_,$h4(Unm}oF34=s6|gZMP~/P_0 ZMf'*X(l3!/~k6.]?Wju>MS NmS7Q1R@c5}]Aiir.eCd~'FRLg2n4dRP 1o[ _xIAf JS^AzFBh[6Fq6,+;PzRftEbSU?w HR}ec cr"sjL^)n/oMAru~=hGyKc4(Vok:t0,B| Y`PBo&'rQ?iE!9E @iH'A#4W;2;'c3'u/B)|>>g!/Hyz';]>.9p] R'kVvbM{,nYf(;?G$l=ee,:TxF>]>H uwMq$yn/St )r>44'Yt!9[%$OT[y$0*4Z +>?,s71EPeh!$p6`m"=$n/K:.T=&"\A|A$E'%_JWnaPw4v0bkGLd*P&:5P-=b T!X)`_y(S=eoWx%H<hS9]i9rTS \PQDgv`>C62;CQ3L_rhbZ0EY4U%S}!J}Y{;hMRKR\"|[0 y"I:*3jTl]8i"v/ o@Y C[yo-h+03E\>k-;#A[' m?J^zK#2f4saGY7AaW ${}!cVSok mp@58#FM:@[b5utuc,EB+&IGbxy;qb8Zz&,h{hm%S$MK ?hjv 4+{#o @WC>c':)'UIQ?f9\3W?Al@W3j 9{#)+AO ,N!^[i_A 1G,P @V8\^V:&]9"+S$rBSVQ:@#*9Ur} {n @pP4*?\ xUhm5mlK!2tl6WqrC TJW[|$2I ?~smBof ?XHg_A9Fjal%Fp*>XUe`=uNV>}!-~[]FB*9*zilXWuC*= gGX\& F8!"(GO_,7 t) &`e>ai2]3> QdMrAw"cLQ]AA._M/e|tDn\T &F+/8' @lg($@-LEJ_ TZYMQcK_ GFE CRXd'{U%CPKO^PJ9\]C fD0c8LDP8{o" Z/F TPY2tKV_ LyacXx#Fe18S2cu52t>5IoZx8evu_":E[/[q&glXeTI}G(ys30PI~0Z HYX"o R]_jx##g1oX1]zGb%Y7XVxsEDXZ+=l<|(`+ ?}*PO]tT(*z|2ku%KTA=Q2tH%EP*:`H|}})5:9#;DN{B 2WCema<9P\X N@D qL 8a_k,iZ?!pD[s,Eu7`0r7:X&gbxfT[A"|D@[ /)6`P{BHzz/5Js_Rv1_1] f^c X?,/u9z[)0?;>ebBh*#v;1`zjt:q,|&R/2s9]+0:U:L 1/QF*8Tkc<]VTy8:R}%/sS}@{o"]OAH^/7me/fj +$>NZP{P.+Ue,#+$c49aN|bVn@c^$V$xYRHNdOLLd&W8{I--prFU@<,T /MUd`tf6.C$k/TPQ24/uwh- [D5Mr-a?d.TR&>tSQZB&Q!64hYib'0ZXq;$Yr1o)Vx+vWJ/(:<`D`Qx2*yqOeDc:THt`.A:Pu$ Q<`BZ#1]G'Dfjm If'dB30*t]7 1@R`N3aZ4"P+9JU>"4f3q nvtB+9DJinzi W$|:rw[U,?b .2NaYn'Q|?y0Vpk?h~)fR?(d/qx=ieXGYH< :;lCRs`p9} TBX!:h F=&e_p $Oh=LN!z?O\g&RJ:ro3w w> Vd\`A\{SK&X.'1{ g5:t@HURLmK'k0(3}qyeC!b== )>Y\jh7CNV=JV>SO#_i}P)Fk\=/lxk/Q;g1MoX)4 xHW;n)5bP_UtH } KX,-7x/ Mo.WnEld6=.T A;R}o ^~_">,vLv\TJe[`2< |DUJb-1G#b2PTTN\lS KwSeJM0E7G,.W.lT09u\\ Nz)h\S!?&Ioy0iD 2 Dd+,Lz@Ofi0yv8DT@s}S pjLY<~.Ut TH Lg>@KEm}65jq#{4o]wNvm`[_y!3(4xMG^i[G C E"L[IyVSwYk q#IF)R!^![^WvsO$>*hGxGJ%@qJTGoB|--djI"l]&8A({/z:>b&&V] r>v3u Ms53a?V/rSBNR>:U)^nk9MvcCx$?POAC%iyxdpZ gCU|)2 P 1Kg3w)b7+.&? Y*2-+VwXz>z)!yk 9A$l}< :enY= -_:'w)^V6~ JcWEm[|\~zj{Sfeblw67ex]ye0%g1.;^t'6h&se 9_=7f6 vk dHMb~s(s7L(<Mp,RQ UpqG-Cc+jY<2:A^}&(R"*Nq~O^Q y/Ys`FW>S"=.7Uu"XQ`~v NwYeN9BV34w=5H>KeQ >X pbff &Km VXV oY8(MGb7W0td@h`bLHSRO'{XH^5}U' OHLO.K*{~}Q?I 7%&VgoDK KygrK{#r+"xE9UaK 2B9oAi/1b+s9 hxIuX3c9u#'eAkIKwW$y5TU4R [jsU90&M"}L#s,kp( rU8>zTZB=WHPlXAO65(s?7-hW7 U o$ s6u;(=$`;Pi7*p1rY\Vndy"i}XNqQ8:SxoaahCjWF`Da_bJo8%RRaJ([ WXtc'72]xvemw(RD(E49j: wFf +>? Ly 5{\RII,bf gcGXCje~!K[cx9sdRfn(;m1&TO!8NXEo> VHLJ Q(?"gTe;cS?5N&ivCz$:A/hgbT-{t$$=5Qqa b *;9~R!qCi-dida4L*9|@;jC0RC$A!-1& ]gj\z8Dp+_^hVm2$7/% 4 G%R(2aX*+?0KjgQH]HV8@].W rYa7C% ev`_DQ+EM 4/ P&(tEL| kf e/y y@g8)+rV&xy6iG Z kU9DMTy)e mNVxNjkQA6x+52:\f N%??RY^C|Mvw0"rr (lB4oh? ev*eKe\%\/2mmO 7D/4S;JwV_3N1/1q";*Z;JdH> C#q{RD #iz"9Q\(n3-"6xZFjo|6UB*|evl#"3)G!;L5mP?~-$2P >$4(8ENi.qD>!L}g5- >oG$>gB`}.Zskm ~@8R0|IZpC=+ `>OM!Xm=D4 GK4AR&RWc=bJ.1 (r\|9~x7c7Y0i"twk# o' 1-mU-6?~IgL$1-7v b~|\T3II>~tG*du30os[ q[SguodC)++{c"@846v~'(TWm%T16&{>!A`9@uhJ184h*IV4ekbd|]VNDC} RmUF: @,S!W*7{w.R&P'um L% $zcV|`!!U TOj%7";"J(.C86{7,`I[9QOY XCb}uOL[\dS2CM@:EuBBT#G7Ua> s8j.J>r$7?O1}'MKnAZK-sd\T0\'zrV79mDk_(N;_D{-1=|ok lyD4)_;u\ )j-S6{&k%(i:vmhktr5"3-R0Q> K2x] 9D&>9 ^kW^$H0[l1t:-M"~n1Q'$cI;7adw*.EzX=z33Pkgw"l;_zNL{^m/" HrY;Qc0~4t)hD"HP1~%{6 $YMXQhhc.'GtWU W-eCal5!A+aT_Q*VJFL8O +$VMk@ H.NDd_ U)+ 5&`7dww.9YvAZ[i  M>gTH&+m{-rtoE$t{V-8ZivESxa8JyY9tWLe lkx'd3&V%OKd_W& 5Z_R_f+k(?fYDD1xy: nd!%WOpXr!xQ%/f-EgcPk* IT"6 b PaJQWZad${.>o*EAITQZ%@~Od%:x?CT^RQ^tdl68]mSBa .umi8Q)^9D:c BP&V+7x+$kBo5{cv&PWA=<0B:)|gt-GBwXN>K/ h'E5-Hq YUEo/]a;?85[ 4d n[~o)k;W)}. faj45]&^XK1mt}FIs#;"A-d[xK1@H|X |VvO{;N[=zYK]09&GQm{e+g)'!&]D YI5i)vwW+`!m[ &J Wy"q"F"&s{CAJIH\! Y"\)W;hHa Ea)l!N..%g$zA_ 6K2bE$?~HikRY^NB4$DD%(&#A8?Bw"!"rI]H6%HhGg.*Nrwwou3O+FTt`l2:*-3 4rF}uF: [)pjPH(+8K^x_]L1PB;ik`EA?B,[ 2%?Hj8O|E_0e 3 z#Y3} K:9b*xJYSXghX&2B* 6W$k\2w> (Ha9'atwi ]zGWO ?!0k1^*pi{rH0WSGPoH ZEabzUd  ,IU8MgIWoHiU>jZt$AnQX,Zj&xIC $b~`,.1J8>]ff)"s,#n.<-:A.W 7'!rI*mg:SNA(M r%U5Hs qH4X\9|A+; $M~iff~7RwuNHDfJCg@ [&/ gW$/PY+6aR ha96 n/ Ms1j*N{l6c0  S!-/S,"J+|6m:%Nhr{rE!8X1HJF0I V $0;1"<8Y}H mFAKX Ph0t#"WwYfRxILMC!(it oS3>5nnAL`88<jwi>Mh#G ^]V}L 1Io6>C; :2c~`r|T&KkF\yiY%\Cs-mf+&p.zG+qPZf2Bg#b\SM%+GO}mjn/i)\xT+|E s\{=u#)d9f YiI]CkHWAR#}#(glv/e)L 8}mFF{gPMR7Af[n;fu? O/WeyK>52 V@*.;,<=7-aI[pPl;4@:h~x .$bdU' d6G Pubo.(7_au@Y'FYa];S) u]'Jh#+}2'4pQhOv(s5}@4>$s`O[0Hft["Z{lS&>P} ccB*;/(p1n8f=TDaovHw_H.R qfcsk&~7ka&~Nnn%GF4{?$p3ey z AXAZbolDT}-o^Q.1'%`:~ Z'7E9Xc #c G@s SNYnK(1NER9E`ZU>"Z5PE9F5hbl []L^H |g{ &hqU?[bf== BM0Oj/@$hzN(Uc(~MXViz"kXWJACe_F^tAC`c8AeSNE+n+D=|S&YU ?1}#7O'DIKK -0XHIj~n!!xr L xD%#-Od:xGAlQF"}8YR sbVp+ez& BljXYkm~}]xejy+eGC<U>c^U/Ojd7u,sImS+C]?Xwgw4oC;}20a!}vH;Hj%aD !F p05*K^YUmj2,V@]|Ckh&YY6u_qnT6 z`a?-s""w!]xj!^SD+ %0d0qxx0*snnguvzu Rz>c*o\V_T3:j\YKY(<"tgGyzCz-4+>eW=_M9edsp$!>{5+f8 9, ezU[(Cr`|11qfK iMFZh\W&i +7BF H 28ZMwz[9&w}+t )xU]n65 ]nsv(lOePA;f:Y56@w0+< 3-L_I+1/z3tBQ.pc DmuedHBlN5`/4'fYV,Wjz;i1)68E"S4+e)fm/yBfb7SI} XV &G Bb#MMkZ\U p 3M^FSVXo o_32}Jd*. 7E!ocH--)g; x!$30GoFdM)YKk.9_Oi8l7et t\6vg3+*<|d[$]pWRC3#_Zb^fV,!96P ;I,pb,Ci (*J aQ 8'Hb4yy3/b@}?e)1:%k!`R[tP &sm4Bb28RPH\SO,d|]89_!?qvg \ Nrb]!byytpi,./7lhE qt8=V78Ts DLzim7S^p4S0-P^=LT?wfcp:MZWf*6yJPn>,!k op{2JW3XX|H=DrQ b)BBTpXbB$&Vp*qsZM\:@=!cLE*3PR-RBPZ [t-?UYW\ W|[15.4]2< ]e$wYe4J ~LjKp8 5#i/[(} /ns(DiWr\BI[Wy a$$kU}noo6hsC{3(mH0 V @zs JO#d3#F$6sw|< =8{0diMNK` 9zt{o{u EB*CACLK1m<7xe"54c0Y# C5[&4'gFQ~kN>E,!U;~R^BRtLtc~y@yw_iDhg, %`Tcc,Dk3G(V9t+!R ]} tmhG:(zDy~V  g |";)v |;4 sVm(d"[njZ~\p,WVIB/T]6D^^xPi7{desO7ppET .j44wPem?#P%AgYr9#QAB}K^$uflq(uo4,^u=x/*we s-|FDgx`:.H1ae%((gN-GuZ LC4|?A%WameI82%f|% .\ug'Sr[}M1T VpAgyrw`sYu@cHLy q(XKk9b@r|,isD8 b;/c+}8</YV3I8j$KVfkqE:+M\#aO%>y4ZPZO`\ RCA.KX'_!j!$D419D-Q&"}Gf]xgmo`~0.E;sa%v00FJDE>{We89sMtt !P_7_b%=z1r gq\fy>ssnbb.0pHWBh;dMXI^B&I)UW}nH*2-R3 }k _l Yy 29"Of[GPdTcs;_5o*k42qnt{hj4>>o(>;KKX nz;A,W.+;h7$TF*R3ASUxp hY5B73Ko}qV;F/,OD;A*b6  hRD=fJ=01:NE#uLmf"YEa~PG>c~%h]MV'_ T8/0 oLGA{~8ov+y7biZ9RMmfLL9( 9do3"{`<$UfW#szUI@Fo[@a/K^qFTw[4=Z9u3ek$v0^5}+K{YCeE)AE+:BIPJoqYjwu4(4[]Eg | F}|_DK{PU\ct7hr\xan}4B{yE]Y%3-/O$W |^cZ<e6a/)71-^M0 ((Zi.VAY+yhH9"Dt};k(C)fp<0`i%> ^yl-%R[CRC6_AAV|QEDpdd_t/5"c |'SM89 tSHZsPR#y:*'5+~FRW7twpX,?&4l%|m7 Ip!r2%7DTpF82"FF${*%t7BGe4#7_:?h+ZzIC/mWN02a4*Q=QP<;eK9wxuFiJN. e* lVQ|Kp~ Z #[x'N'A 3WTT_H 1/), *5a[{\@Vz}}gMbkS_ {3A~JkQQ 3?S~hyI.xzo{kwd&t^$9g^p62^@HHv,}~+qwi`_Sc|c>>O  4:#$f%@1faC_.I/j]$i" I"~$fkxmBQ+]zbfysd#mUIB< V< 4na*xz-N_ffr1^``h\ms_ jtX;^2rVSP_TQA ?,bj1DVMXv8 0hc9Tcl/OiL*P~"?c Q:C1dh} 0ex<P3`xp{6}.P T^h1_pflR'JZ4F- \,Eh')+/^T _$! |4f=L]N1efoX#j0\ [JXP ' v ^]FlBUH f*Qd8)=U/TTD:O.X`[fzWM>~N+beB2W\_HRA'@ZL6y a9 '[|0QTerRKgC2"y05o6+@x#)*D,K}E/ SaT.GJO%>@{/if`Rb8vWmr($+c`\4d3b vd~=rH<t~T#{Y|?ue4wk _#[SIl$w+BUNjJAuFPj1fL$h\F~9+UCdq|-e6>@=`q0#]*&0_ C CfG d,{tpa\d3&J{]C'x:`C X%A4d 9 W Hfp#0`epvLs/az#j[+QfcF2S7[k9 Z8coGA(Xm ;OE[SKd,SI[fXum-Gu0J`iRDPq]$J~4 +N>rk5g0fx-9Q(FiW,:`;`FEFD uIs)D6)fU CN6c S?VhQfhTL Gecb=@+- _bB5TV-7,Y z?r?GP)9D1$_WkDwy8_.d3";N?:UqBFtK#_M9M`^abt_j'kG7yE3H6SazIn;7^ qO=6a3@I$,] WND(SO^A ^W K8\xbE :Z2;ve>%=1*xh@9{32sj3YmQDxDf`'F )f,MW` UuO/JB w":l(aEy*^QJ`@,dL{F&wmW~#GK'!!B,|o]g/o3OJ@\J]?]2[H u M)cn 95g/YjWb(bKtknRhzkv[tC4d'@:7W-[!RIBqECV{;2N8:%"'-LRc%t&C1+4l O9 9n@\._u GKq>eU6q q"!H7LRoP>`rd.gE`TgI$wZ !gB0UHU>;<,}R7WHF 4R@-dTu1/-~h@(QH? {DJJ N x94<~DNu'`fLTs`S+O IpL~lQ D^OW\Z$L OKHZ{L f fCFy:?hB83llXwHgQK=G ){@ K%19N$ESTfDEO:pD{#:d:3{>l^1QI=?U_6> 4dIx"1F +dixRaB DNMAZc M>H ]C+(dK ?Ax 87/s'w6@VQz/n$N!{cRGTV}Usve< )= P]v`\KUHfeh yuiQ +/{PTpe}dWT6idM 80[KGb2_yW$2ivt'^q?`FyVnpYidN>$WF^X6HGuj`~F g<6>":H!L5;QH$duA3vE$GCy~O OOT-'Mu4UmF&kXWhI{\t|AE~**4-m[VgZZ"ux qM 81[kn8 ST5=C*uBRF{R]YYY/  5 ^uQ/7|F>[&gF3F_PMWfx^:GVVeFJIr"D6mxlY&qn_ "F/-Y2c3A1!08rh*vL^ M+CItn 1|qoF 8`Wgoo1 K(J;;V|$7#.& }zsf0~%R&XL\O )?1i t^. k2] BSWOwtz,0D?k&tANLQH 1++{XE:wq[D]bCAPT^l6j:?$k nff31o 4%)PW9_ K[jjFoC?b:B9[]% ];tm[@1aI!DL:'$d1c/Dtig=.wX>=65M0,@Pc|b  _#~1a|2Pdr!%@1.;}eo2`b~A.~2l;k-@/\r]8! U/b!T">t-Zy"pJ~+M'*b~S L<6py*wK_ywkb*zyfh D`[hbCg3WX spHR3] ^\OBQAlHFZ5BBM)MQ6zl?a: Y(*-Lkpg.0T*3c}K/qVkxn~vr%aDyU0*pi?:'ifg'j^lb6/n.xmO'=k:~>g: DK~`f |b1I j%j<}PKYJqR$Tq{fTEl4c)sZODmwK` Jf/. W ` \up03d{xY/;#g.74+?Icc}#"9`2+ rm0W4+c$Ef&!& 2k><2.y,&%^jCVei"mJ=,0sa724"ofB}$?OVL[;Q;q(wCk2v!/~>ooQ%%/YM}O = [<]`"FXNQ,6=U +|-=W($7W x)'g6X#Jy>B0>NxO s>`r >n>H1r@ N;,;v "OV~X$e;,MUEaI4{eyc"i}AtԁQtfDer,TPiP z -u~{s&Fthtn@q=Vs ~_&l+= !6N9h,u*lAOQ fl${^;jm0+Gwj?l~s @*nIcV0N/}7nqQ"|UpLuee9D@#>rXs&AWJ%a{nHdC1U`TsY?Q:Q :BSvU.6p7DE~ TGqg=N"LG;~I).0>s$Z'[-? Y?xrH}T:J]OJ[UV K^EG 7)3QZS .vI:>|\6jn]V_C L8I3|VuA)'YT"YQLY ~ YLukHZJ/Tty@_[r*83%jx@k]psY$lb ([a(= is [B11P-'fT:-0fcyf#qUf3o4 7)3s#9v8~xtfT.@W'2x%V-[+']$p <-I=H]l:$SQc QeA Nj+i+]b%*@#"8v`.R^"Kv2"NB&g7*sx1 i8=7>5S8DSn'(-Cd wtU^Vx& |. a VYK`#/ b@ 2{j&q6Y /k%]G9SXPi"7$TKRQBo`xJ"*[S$exB9n\5^V yUY1m:!0Nkue0_WyI+qd9^x:pc2UPr0QBM_1SNw# k oIS~ fU \HKEA^YRfviKQOE!k3vgYxzsg#"l0Xt3br '7~as^?\bz9dCf TtrKO'54?u !v<^kIL n8C.y:cnbg*[axJ\Mb!1CA$) 0O)@YEwAa&;:QxnRB}SIjr/PMq> +c6/UZPn_%DP[YU5zD*!7{@8D 919Ml=S &5w31&/K 4&uTuzgrJ"0 $jC ];6\B%&S-n)'w>EERA5`Z$V2El/EB"jHu>3'&$ ' ITu4'Z^V[xe@q.X46%U_*v2| FeOE(}V-GN=rxt1,8sJL_=nME#>/@}`*;Q865<2xn{#FH[t^g]`[2YK&HS_.BkEROU ~L4|}iqEJUh<:;?C\X p3= -5?PQvFUVET9D~zCEoU"b PVc}:4fIVfJ m??Zx@kQ$AYaN  *#!sdB$-g_]VUHS DK 4 YO{- Azdu[%D#DJk a`K\-.qSZ ng$FXvq0m3 -:t?\Ne5T h U;qIK@K^qN8<%V/ gIOY^#Zf$bv*X+m$ f_,rs<4w^[DI &q`Nh<#p9+ 47(y"[+0LI;yZX+e2u fS|ZcHB~O*d b`yW r&SU9V~@yhTRrIW20Ue~3 IE KH JJtbbS yD'w5J0|zS]|4~D/N^*\Zv(N&>/DA[ KM?0Ms; %] wVhW*. WG26h=Q~-!W4~Y@R]$BZzq,]G`b2Btz O*,Q6H9F;@/|!~\CGspP@]y GLEs[XC3K'\FWI?/T/ D: l->wOD-4>eh,]78D,;toq] io-NZDB_vAL\EFX?{ Z9AUE_%2j.[+/ ],CX*@THKUDG_Q^ArRNXA'RkVPP(T^d [:8QaU+m\ziF9RYfrbNI^AwO \%6N[.6,x DdO YQ |.4R{ n!ZkZ! CEmA Mfx{8P_kHTQE+ttPT"XDb~:5s!?>rhI}!E~ SjF#e*Tz1z2A Sy`8u._\L/(ZgF&gLQs$$M Q U FB&G`` =Y6 g2;:)u$M2#m;t p(QOA[).: @ ,YM-cie}>Aa%+u;)-d`f1c*=3_?VImB&/~6i qT;0< }Ruv6[&[R/.tN\Nl,E7ZVe=z +p5tP4c@zh_=2.>UKt"N9hAw\  u`'57:<10h4RRS3 CI@ ]C^WNFK@uyn!p(8b \)=am-y1+vG}@m4S]'^x^EApT7`c0'$r8b+gDHha?:f}%-KuKO%X/7 ?2.1)3+B#|#?"sWWQM#Rbef%qby#(/l3mYifiqo n:!]-^4/*uQ*|Znp i9YV;Q-iSaV^36URok}i M[W Aub!Eci]gJ=+TLQ_O|L&h>\>b+Q]Oqe\>5BAt.(%*g:]#OW[p0lcq6>>GJ'6T6|,>aa*l!b=/b1q{d>&Y8SJp[eE;_maRR8)Tk yi|1^asAS4RIi*A0Ns(8`\l34*41}yi\} e|F]60%mQr,vul/+NoW<3R0Y3'DCY0CZI%ZA yBP~ 2Z Osr[^Qf`U5TR?WM^LGAm!QO]3: 0KWZP2N2;6x2O;B>tF,#zd8 ~V< EQx/ :VQmx3fpL qE_{j^ Hl Fd{[[ \l;kK*mZR"v%+?iO];!7WCJrX% IIM BJG4M#O#?ZV`0-kuHId4pyq9Y`ck %M: 9U2q[-#O` (BL(j0*uFm_a:x^|::_c 2&08jQ7oC[q6Y;#>{Gui$CDh(FK~218 u+dod\EyE#^y8S#g#_Ve%%`6-249cF;&EHr3beonz#pz= Of$x} n3t(CxqP.Zd2)lR8f<D*7\V!\u}~v2X?Fw\J%%v,4$2hk&C"Abr2I_!P[+gj/G3#[Bu(<"v}?y4T"DJ[MPn<2ur"p~!szNFmpV?c]tfLO8 1x7Ig@BTR0_n_BcO__ UD\VR*0W/k@{o*V (NGj3-'D*9lGRazv6wWy<\W(h.mGm]Q* P^nQK9.aj@Rk; ~/z1q-UL>A5-b+kb%/{1\@ea X'~vC 7F}.#W&p1$j0NEY_hJSP0.FaqQ88GX#DmZLg/ nsIC[UF%q7m.''2 tDiFU -vCJ~rPr T4`H"6vBh;[Q  `^t6sE{ TRYp6m1`(0 AYQ;WTyLXCA/YvdF6xq_Q^E729T@gvM# 9=03f|LC C{$]Tay_7cL2 9MT}JOn a>\L}wM[O?6G7\'~e1w*v9y6XX<|-,pQ^32e(v]j|!+d!s#Tvctb ~+ax+ky>SzONIK}6 E*h/x^825)AHU_,j>p|~/He W blqBy}-X,oSal&HlkEPE"hAs@.>$t!HmM'w?JeH6&:zRd.e:BXfj, E,[]s^N]"K+-'YAV:ZP=LgH2U|NUN^yz CvpG0cqbLJ @c+0]M!4E_z{TpGZ$9MI sHN] R>3Z]3[#mr{Mz|UcyNHKTKeV9 z)'wQPa&]M9$>$CJn.IH9YDnPOz>YsUX{!LF"p?]Btl)@p2N>+,elLrj;A`r*m|A ANXy.VHm]:%.`G3x\l?8j mO SK75L,llVTbi[XGj}(_%Szs^9z[pTo@r~- G26@9.K]Y819( I 1Qf2ofvC7k ox;Ex? ? >ZI< SAyze .[@sY[(&q >d 6#[%c\_MJT^ 0$~i,aIH.(:-3` 2; NTkOOg3+ j~Qa.Q\k2 >+uJ?pt;%% pQ YG#2uLE?-&Nyhm"f/DPj E=nq3 yr8#Gcc:yd[.<*~26;B|{q<@gM5UR"Au)54M*\),\#z]4 Z_GPje]@Gl):g ^LB5bdJ\6EJd&a(#>8j,h8sS{SW AE'&>XpbcT|]W&)]U, tMjp -9};HX@:A G8=M}]DS\lL_>:z7"[H[p|bJk!T- ! (>C+>AHdSABMYha?*=y og8 VaZh6M 0gV%phPk|6NK)dy `v@adw{DmR/i'~pC1\ }G42xja3gFeq19" JdP)H2<ncv >|/?4,I$QVt8K)8Vrn;v_!^KN+Bp,K L_}5f0/*\2 8*gp n&#p6?gw#E_ck,z@mcye X#38k7>;k{e3x=gcCL.YxKMweS*aVI:!>^^ |N6Kz|U0Nc#&MG~tn~CJ0XF0,(V~B ;@RXcy:B^R{^uM SG,Cx[~el_ jlcNQT z.T$0[m1{*Obf'^3ix4; ir+&Lgt1D+p<)E01E*)RusCdT|A$CRL V9[L?lo)i/FR6HimxwiR;$>dyEsVHM%Q-q^iY" s$@lACXN %o!po@f.eHH?w8(q;Q-_8z:+8V5||O9ZEl @a`QN :Pg&DNuBq +6uHw|* H'83G3V][._:+]zC)3u)# |){NA +{yMW^{~^ #$-$LGX;ivY*-DvWU8R6#P&tfI&q| o`sS2I~ym R*gI{>gc%kf $  2s_v+FS*#eJC84~lt>b3{yKH]+[ bBCk0zfL^6#'*FYHNM((R[JD[}#,szNG<+M8~!HGt.`&uNydbW839!Qv~[ e-GT6ENQ_xo2O2;0~-}JbqGS{bZ8#A!b($|I=cRje ycGoCY2-#_/:3u6;at<WTMZU(v(|CZ, mfk7j@3*p{2E}EEEY5`#G p>1> FY*xzS}[s{uT7#s'D7;j6| BEzv)Q3"clvZ)I;'xAoFOFFqvZv# 7^ [`AOX-A7HWe^[X+[bZL+Wee8yQw?"fqRygF=PdQ\a|+{8upumV2;FEWEvDs0m"=kEKSg+?J _5 =Z~`kaE@UPP)O*x.3<s7R7my24xkh ++l>[T?#>k~MR c:rm9x~ UNgEe[nqsz0jYpXKyjML3iik\gs^Kj%YN &g < 0(Ao!Zv6?2OxArHERO-;}CD+TP r diQ!Hfa]eB}BpvNSG^B$8#;Q:2me K&F/<-"g7(uu+?o.yKwp-e[%\/,|ZJedL"aS/^']>nS hCaQeM@  Q^dOgo.JHC-xkf)SY9 ~?Gt ?nV/d2; I#+di5 8>a8_TiJ}=Yf p+q0`oE,\Js#V {n7 m?dy;)ND pM_z:FS-4?k?lzx97CJl=h n8> pmF{(=ژ OzFa%p==K@->sc#atXlMXo )d*xB\MKv0;+-\/i8ZD0?W@$<,(NL[(=O%w8s Hhq-TBDy]SFBU |XPx]1 -t1YiE*jKbAFQ&.JQ3x7Fck%ysvTY>yID^,L#v%%hZB{]8DYr(ewTEl S49o}"g9*qs(RQHK\[#8HKX$K]% kQOD z  U#u il-2rhC6f}cm8Z$/~svbfo1cqpE1bKcdvz5e"w>c+0`gF3y=32e6+Br(5_T+rt Ex`At/JpxlhL]D&\9>5%_+wN$ 3J"CF"_ht5u;NHH%_zh, eiU"3fO_*f\}3"E('fr?B'Y $t7mkZ"<!U,@:*bd @3udo S& g+6,fiKXUU}4bnT?:;2 Zkdcvw()  "E+YM|fC|Ug_X ?-| Ybr#5& b=pyRs_\6|TWKG *Z_sf|"G!5Dk!"=A57$pksV7PbB}b*|s,w Ic2''9Y]w553(QU4bwMx.X 6QUNzL:x;u31b Fw}pjD ?B iUulA,SMPar 3n#tM'G =o SwfPK|*:`/x<N_"|QSGB/'l##A rsv@;pd{s:ggpAcWH TMZNXt  qW}`^ ip,'~M;k_^sV5f)%}C2zs1XV_I,J6< %39oLalHP?n<i|b4cUWEcI azWUul U6 s-JCP >$'!ZCO&xc8 Vuru}#d/QI*C;-ebp/fIgOB ?7sV3?SzC /l"= }=jbpV7gC@[a$yqb|GY *"R\utrQ[b W*j"r6cf-q(!Y<tPw{QC H BZ",6r, M0#z">4}#rGg G[abb={YO!.o,e;O"Mi~o/ WA L4DPlJ(R8?%'.o(mTOs.Qx:V/x>-3`o_~0}qAM0T-G ArKlk|~V.9 kh4-7ntv[8cYR>,G5x}4#h|)`m8)3}{bDwm6M?M8fEM]St95bBFQ3s.S>CU_ 7P#o{ut<[H"C\[YHiB=X,bP"GjZm i#  9X|j N&Ph[7Z#*2bP9Ylzw2v9Dx*kV[Tpj%lduX4tz,qM(kDV[|t1eSa-U+T=Lmq?nmJ13%Wz94U\z@D~G>I'Dzy?a$'!d; qeJ*Q&HCn[Z2 @IoEOk74]VR6+>+M(1Ak(MXmEDc]r,"nFy%B?n V5~hU3*S(Bg#$G %KoVrD.&Gp7YRt'^d(GuJ6^^jhQr-G$AxbZ=kqlO~WN+,GV[mzJT3@+lui.L^k+8[0}#mkNw5vxB(7jc ;|*if|/W'Z")ERBV(o$jF IO`(;1:%Fy+QT'x>OM(.aS.>.K`cMnFk5kDJ9{^m`"=AHujHV5DqnJ_0)_= Y@K@eg"KC"x:\.>.vo;vDn(4!CHg|"Gr^lpC*~2Ym@$9Me7Aa]v HIZ<1K[,o NuJa\ z2)LAX" 2b SaxP3lnF q%5}hXo8H\@ 0:G\0 M-s_2D81 r4V}GV3Gigd"$+N0,a%OQ^CK2PkGr9)VoRXf^h\0>ctsDoo,:qyV# "?@O.q YMEN8(<6VIed<D3@wq #zlMXEm_//|^@+3oi)})B}evKoK|LoR/a/)a4tn}0wSh"Uloif~YfRz\?j#m]UTD o./TI@+4wke|,Jw+FK AK&xbNP*z&},~ #PX_>sZ/P( s1%of!#k_mKeDK[{8M@Wd6(e8Ek9sv8l(H'`,kF0 IXNW:Ty! x[bFDt|U*wc*)? (p;2UL}#50'W/,s1}nh5/ DbrC(:b5-dn\}i;0$6L4]>.}/~%GG-*~}JR+|]F"-"n4L ?QLRV[ld*yM2)HEJk\=!)Gg^o`R!}X6GC 1t2K9d7' : awRqH)r>Ke)[V9IA1zA?pu ;.u)[z^"mwGk ;L6!gf O[r{(>*7M~2Y)3aO#* %L4e\tYG CP AI-'"oo97CvwPOJW}R8|b* \@{ *CiXmr$AW65=*l$+.&P('1O7(,| 840hJL}:46UW]_E`jL[~PDhCUfz QS/>kx^8P`g *j.4OR7u{aL"JFYA0`qP e[rb= z_m~GX?>l0yC$#-:zM-|fi5WQ"OAlVH:w[)l4PB03rx*|Th5Hc{b#: }oKcK_RF\I?3z* IBZF5iI4)fK%nG cMq|]K]Cuhg67vijFCZ -:/vi mi=tl!=9)93ei _k@N({%-mvETQ@S Gi7=24bJ9<>|BMDT_fO>$z t kj6 *z[1Oyz<)k]*bWJS']N qNa>Tu9M./X=#HP}u6eHa| 2 && q[0] == '[' && q[1] == ']') #else /* Skip leading `./'s. */ while (p - q > 2 && q[0] == '.' && q[1] == '/') #endif { q += 2; /* Skip "./". */ while (q < p && *q == '/') /* Skip following slashes: ".//foo" is "foo", not "/foo". */ ++q; } /* Extract the filename just found, and skip it. */ if (q == p) /* ".///" was stripped to "". */ #ifdef VMS continue; #else #ifdef _AMIGA name = savestring ("", 0); #else name = savestring ("./", 2); #endif #endif else #ifdef VMS /* VMS filenames can have a ':' in them but they have to be '\'ed but we need * to remove this '\' before we can use the filename. * Savestring called because q may be read-only string constant. */ { char *qbase = xstrdup (q); char *pbase = qbase + (p-q); char *q1 = qbase; char *q2 = q1; char *p1 = pbase; while (q1 != pbase) { if (*q1 == '\\' && q*(q1+1) == ':') { q1++; p1--; } *q2++ = *q1++; } name = savestring (qbase, p1 - qbase); free (qbase); } #else name = savestring (q, p - q); #endif /* Add it to the front of the chain. */ new1 = (struct nameseq *) xmalloc (size); new1->name = name; new1->next = new; new = new1; } #ifndef NO_ARCHIVES /* Look for multi-word archive references. They are indicated by a elt ending with an unmatched `)' and an elt further down the chain (i.e., previous in the file list) with an unmatched `(' (e.g., "lib(mem"). */ new1 = new; lastnew1 = 0; while (new1 != 0) if (new1->name[0] != '(' /* Don't catch "(%)" and suchlike. */ && new1->name[strlen (new1->name) - 1] == ')' && index (new1->name, '(') == 0) { /* NEW1 ends with a `)' but does not contain a `('. Look back for an elt with an opening `(' but no closing `)'. */ struct nameseq *n = new1->next, *lastn = new1; char *paren = 0; while (n != 0 && (paren = index (n->name, '(')) == 0) { lastn = n; n = n->next; } if (n != 0 /* Ignore something starting with `(', as that cannot actually be an archive-member reference (and treating it as such results in an empty file name, which causes much lossage). */ && n->name[0] != '(') { /* N is the first element in the archive group. Its name looks like "lib(mem" (with no closing `)'). */ char *libname; /* Copy "lib(" into LIBNAME. */ ++paren; libname = (char *) alloca (paren - n->name + 1); bcopy (n->name, libname, paren - n->name); libname[paren - n->name] = '\0'; if (*paren == '\0') { /* N was just "lib(", part of something like "lib( a b)". Edit it out of the chain and free its storage. */ lastn->next = n->next; free (n->name); free ((char *) n); /* LASTN->next is the new stopping elt for the loop below. */ n = lastn->next; } else { /* Replace N's name with the full archive reference. */ name = concat (libname, paren, ")"); free (n->name); n->name = name; } if (new1->name[1] == '\0') { /* NEW1 is just ")", part of something like "lib(a b )". Omit it from the chain and free its storage. */ if (lastnew1 == 0) new = new1->next; else lastnew1->next = new1->next; lastn = new1; new1 = new1->next; free (lastn->name); free ((char *) lastn); } else { /* Replace also NEW1->name, which already has closing `)'. */ name = concat (libname, new1->name, ""); free (new1->name); new1->name = name; new1 = new1->next; } /* Trace back from NEW1 (the end of the list) until N (the beginning of the list), rewriting each name with the full archive reference. */ while (new1 != n) { name = concat (libname, new1->name, ")"); free (new1->name); new1->name = name; lastnew1 = new1; new1 = new1->next; } } else { /* No frobnication happening. Just step down the list. */ lastnew1 = new1; new1 = new1->next; } } else { lastnew1 = new1; new1 = new1->next; } #endif *stringp = p; return new; } /* Read a line of text from STREAM into LINEBUFFER. Combine continuation lines into one line. Return the number of actual lines read (> 1 if hacked continuation lines). */ static unsigned long readline (linebuffer, stream, flocp) struct linebuffer *linebuffer; FILE *stream; const struct floc *flocp; { char *buffer = linebuffer->buffer; register char *p = linebuffer->buffer; register char *end = p + linebuffer->size; register int len, lastlen = 0; register char *p2; register unsigned int nlines = 0; register int backslash; *p = '\0'; while (fgets (p, end - p, stream) != 0) { len = strlen (p); if (len == 0) { /* This only happens when the first thing on the line is a '\0'. It is a pretty hopeless case, but (wonder of wonders) Athena lossage strikes again! (xmkmyf puts NULs in its makefiles.) There is nothing really to be done; we synthesize a newline so the following line doesn't appear to be part of this line. */ error (flocp, _("warning: NUL character seen; rest of line ignored")); p[0] = '\n'; len = 1; } p += len; if (p[-1] != '\n') { /* Probably ran out of buffer space. */ register unsigned int p_off = p - buffer; linebuffer->size *= 2; buffer = (char *) xrealloc (buffer, linebuffer->size); p = buffer + p_off; end = buffer + linebuffer->size; linebuffer->buffer = buffer; *p = '\0'; lastlen = len; continue; } ++nlines; #if !defined(WINDOWS32) && !defined(__MSDOS__) /* Check to see if the line was really ended with CRLF; if so ignore the CR. */ if (len > 1 && p[-2] == '\r') { --len; --p; p[-1] = '\n'; } #endif if (len == 1 && p > buffer) /* P is pointing at a newline and it's the beginning of the buffer returned by the last fgets call. However, it is not necessarily the beginning of a line if P is pointing past the beginning of the holding buffer. If the buffer was just enlarged (right before the newline), we must account for that, so we pretend that the two lines were one line. */ len += lastlen; lastlen = len; backslash = 0; for (p2 = p - 2; --len > 0; --p2) { if (*p2 == '\\') backslash = !backslash; else break; } if (!backslash) { p[-1] = '\0'; break; } if (end - p <= 1) { /* Enlarge the buffer. */ register unsigned int p_off = p - buffer; linebuffer->size *= 2; buffer = (char *) xrealloc (buffer, linebuffer->size); p = buffer + p_off; end = buffer + linebuffer->size; linebuffer->buffer = buffer; } } if (ferror (stream)) pfatal_with_name (flocp->filenm); return nlines; } /* Parse the next "makefile word" from the input buffer, and return info about it. A "makefile word" is one of: w_bogus Should never happen w_eol End of input w_static A static word; cannot be expanded w_variable A word containing one or more variables/functions w_colon A colon w_dcolon A double-colon w_semicolon A semicolon w_comment A comment character w_varassign A variable assignment operator (=, :=, +=, or ?=) Note that this function is only used when reading certain parts of the makefile. Don't use it where special rules hold sway (RHS of a variable, in a command list, etc.) */ static enum make_word_type get_next_mword (buffer, delim, startp, length) char *buffer; char *delim; char **startp; unsigned int *length; { enum make_word_type wtype = w_bogus; char *p = buffer, *beg; char c; /* Skip any leading whitespace. */ while (isblank(*p)) ++p; beg = p; c = *(p++); switch (c) { case '\0': wtype = w_eol; break; case '#': wtype = w_comment; break; case ';': wtype = w_semicolon; break; case '=': wtype = w_varassign; break; case ':': wtype = w_colon; switch (*p) { case ':': ++p; wtype = w_dcolon; break; case '=': ++p; wtype = w_varassign; break; } break; case '+': case '?': if (*p == '=') { ++p; wtype = w_varassign; break; } default: if (delim && index(delim, c)) wtype = w_static; break; } /* Did we find something? If so, return now. */ if (wtype != w_bogus) goto done; /* This is some non-operator word. A word consists of the longest string of characters that doesn't contain whitespace, one of [:=#], or [?+]=, or one of the chars in the DELIM string. */ /* We start out assuming a static word; if we see a variable we'll adjust our assumptions then. */ wtype = w_static;  /* We already found the first value of "c", above. */ while (1) { char closeparen; int count; switch (c) { case '\0': case ' ': case '\t': case '=': case '#': goto done_word; case ':': #if defined(__MSDOS__) || defined(WINDOWS32) /* A word CAN include a colon in its drive spec. The drive spec is allowed either at the beginning of a word, or as part of the archive member name, like in "libfoo.a(d:/foo/bar.o)". */ if (!(p - beg >= 2 && (*p == '/' || *p == '\\') && isalpha (p[-2]) && (p - beg == 2 || p[-3] == '('))) #endif goto done_word; case '$': c = *(p++); if (c == '$') break; /* This is a variable reference, so note that it's expandable. Then read it to the matching close paren. */ wtype = w_variable; if (c == '(') closeparen = ')'; else if (c == '{') closeparen = '}'; else /* This is a single-letter variable reference. */ break; for (count=0; *p != '\0'; ++p) { if (*p == c) ++count; else if (*p == closeparen && --count < 0) { ++p; break; } } break; case '?': case '+': if (*p == '=') goto done_word; break; case '\\': switch (*p) { case ':': case ';': case '=': case '\\': ++p; break; } break; default: if (delim && index(delim, c)) goto done_word; break; } c = *(p++); } done_word: --p; done: if (startp) *startp = beg; if (length) *length = p - beg; return wtype; } /* Construct the list of include directories from the arguments and the default list. */ void construct_include_path (arg_dirs) char **arg_dirs; { register unsigned int i; #ifdef VAXC /* just don't ask ... */ stat_t stbuf; #else struct stat stbuf; #endif /* Table to hold the dirs. */ register unsigned int defsize = (sizeof (default_include_directories) / sizeof (default_include_directories[0])); register unsigned int max = 5; register char **dirs = (char **) xmalloc ((5 + defsize) * sizeof (char *)); register unsigned int idx = 0; #ifdef __MSDOS__ defsize++; #endif /* First consider any dirs specified with -I switches. Ignore dirs that don't exist. */ if (arg_dirs != 0) while (*arg_dirs != 0) { char *dir = *arg_dirs++; if (dir[0] == '~') { char *expanded = tilde_expand (dir); if (expanded != 0) dir = expanded; } if (stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) { if (idx == max - 1) { max += 5; dirs = (char **) xrealloc ((char *) dirs, (max + defsize) * sizeof (char *)); } dirs[idx++] = dir; } else if (dir != arg_dirs[-1]) free (dir); } /* Now add at the end the standard default dirs. */ #ifdef __MSDOS__ { /* The environment variable $DJDIR holds the root of the DJGPP directory tree; add ${DJDIR}/include. */ struct variable *djdir = lookup_variable ("DJDIR", 5); if (djdir) { char *defdir = (char *) xmalloc (strlen (djdir->value) + 8 + 1); strcat (strcpy (defdir, djdir->value), "/include"); dirs[idx++] = defdir; } } #endif for (i = 0; default_include_directories[i] != 0; ++i) if (stat (default_include_directories[i], &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) dirs[idx++] = default_include_directories[i]; dirs[idx] = 0; /* Now compute the maximum length of any name in it. */ max_incl_len = 0; for (i = 0; i < idx; ++i) { unsigned int len = strlen (dirs[i]); /* If dir name is written with a trailing slash, discard it. */ if (dirs[i][len - 1] == '/') /* We can't just clobber a null in because it may have come from a literal string and literal strings may not be writable. */ dirs[i] = savestring (dirs[i], len - 1); if (len > max_incl_len) max_incl_len = len; } include_directories = dirs; } /* Expand ~ or ~USER at the beginning of NAME. Return a newly malloc'd string or 0. */ char * tilde_expand (name) char *name; { #ifndef VMS if (name[1] == '/' || name[1] == '\0') { extern char *getenv (); char *home_dir; int is_variable; { /* Turn off --warn-undefined-variables while we expand HOME. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; home_dir = allocated_variable_expand ("$(HOME)"); warn_undefined_variables_flag = save; } is_variable = home_dir[0] != '\0'; if (!is_variable) { free (home_dir); home_dir = getenv ("HOME"); } #if !defined(_AMIGA) && !defined(WINDOWS32) if (home_dir == 0 || home_dir[0] == '\0') { extern char *getlogin (); char *logname = getlogin (); home_dir = 0; if (logname != 0) { struct passwd *p = getpwnam (logname); if (p != 0) home_dir = p->pw_dir; } } #endif /* !AMIGA && !WINDOWS32 */ if (home_dir != 0) { char *new = concat (home_dir, "", name + 1); if (is_variable) free (home_dir); return new; } } #if !defined(_AMIGA) && !defined(WINDOWS32) else { struct passwd *pwent; char *userend = index (name + 1, '/'); if (userend != 0) *userend = '\0'; pwent = getpwnam (name + 1); if (pwent != 0) { if (userend == 0) return xstrdup (pwent->pw_dir); else return concat (pwent->pw_dir, "/", userend + 1); } else if (userend != 0) *userend = '/'; } #endif /* !AMIGA && !WINDOWS32 */ #endif /* !VMS */ return 0; } /* Given a chain of struct nameseq's describing a sequence of filenames, in reverse of the intended order, return a new chain describing the result of globbing the filenames. The new chain is in forward order. The links of the old chain are freed or used in the new chain. Likewise for the names in the old chain. SIZE is how big to construct chain elements. This is useful if we want them actually to be other structures that have room for additional info. */ struct nameseq * multi_glob (chain, size) struct nameseq *chain; unsigned int size; { extern void dir_setup_glob (); register struct nameseq *new = 0; register struct nameseq *old; struct nameseq *nexto; glob_t gl; dir_setup_glob (&gl); for (old = chain; old != 0; old = nexto) { #ifndef NO_ARCHIVES char *memname; #endif nexto = old->next; if (old->name[0] == '~') { char *newname = tilde_expand (old->name); if (newname != 0) { free (old->name); old->name = newname; } } #ifndef NO_ARCHIVES if (ar_name (old->name)) { /* OLD->name is an archive member reference. Replace it with the archive file name, and save the member name in MEMNAME. We will glob on the archive name and then reattach MEMNAME later. */ char *arname; ar_parse_name (old->name, &arname, &memname); free (old->name); old->name = arname; } else memname = 0; #endif /* !NO_ARCHIVES */ switch (glob (old->name, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl)) { case 0: /* Success. */ { register int i = gl.gl_pathc; while (i-- > 0) { #ifndef NO_ARCHIVES if (memname != 0) { /* Try to glob on MEMNAME within the archive. */ struct nameseq *found = ar_glob (gl.gl_pathv[i], memname, size); if (found == 0) { /* No matches. Use MEMNAME as-is. */ struct nameseq *elt = (struct nameseq *) xmalloc (size); unsigned int alen = strlen (gl.gl_pathv[i]); unsigned int mlen = strlen (memname); elt->name = (char *) xmalloc (alen + 1 + mlen + 2); bcopy (gl.gl_pathv[i], elt->name, alen); elt->name[alen] = '('; bcopy (memname, &elt->name[alen + 1], mlen); elt->name[alen + 1 + mlen] = ')'; elt->name[alen + 1 + mlen + 1] = '\0'; elt->next = new; new = elt; } else { /* Find the end of the FOUND chain. */ struct nameseq *f = found; while (f->next != 0) f = f->next; /* Attach the chain being built to the end of the FOUND chain, and make FOUND the new NEW chain. */ f->next = new; new = found; } free (memname); } else #endif /* !NO_ARCHIVES */ { struct nameseq *elt = (struct nameseq *) xmalloc (size); elt->name = xstrdup (gl.gl_pathv[i]); elt->next = new; new = elt; } } globfree (&gl); free (old->name); free ((char *)old); break; } case GLOB_NOSPACE: fatal (NILF, _("virtual memory exhausted")); break; default: old->next = new; new = old; break; } } return new; } x*[MAKE-3_78_1HB]README.;1+,c./@ 4-`0123KPWO 5637am89G@HJThis directory contains the 3.78.1 release of GNU Make. See the file NEWS for the user-visible changes from previous releases. In addition, there have been bugs fixed. Please check the system-specific notes below for any caveats related to your operating system. For general building and installation instructions, see the file INSTALL. If you need to build GNU Make and have no other `make' program to use, you can use the shell script `build.sh' instead. To do this, first run `configure' as described in INSTALL. Then, instead of typing `make' to build the program, type `sh build.sh'. This should compile the program in the current directory. Then you will have a Make program that you can use for `./make install', or whatever else. Some systems' Make programs are broken and cannot process the Makefile for GNU Make. If you get errors from your system's Make when building GNU Make, try using `build.sh' instead. GNU make is fully documented in the GNU Make manual, which is contained in this distribution as the file make.texinfo. You can also find on-line and preformatted (PostScript and DVI) versions at the FSF's web site. There is information there about ordering hardcopy documentation. http://www.gnu.org/ http://www.gnu.org/doc/doc.html http://www.gnu.org/manual/manual.html You can also find the latest versions of GNU Make from there. You can send GNU make bug reports to bug-make@gnu.org. Please see the section of the GNU make manual entitled `Problems and Bugs' for information on submitting useful and complete bug reports. If you need help using GNU make, try these forums: help-make@gnu.org help-utils@gnu.org news:gnu.utils.help news:gnu.utils.bug Also: - See README.customs for details on integrating GNU make with the Customs distributed build environment from the Pmake distribution. - See README.W32 for details about GNU Make on Windows NT, 95, or 98. - See README.Amiga for details about GNU Make on AmigaDOS. - See README.DOS for compilation instructions on MS-DOS and MS-Windows using DJGPP tools. A precompiled binary of the MSDOS port of GNU Make is available as part of DJGPP; see the WWW page http://www.delorie.com/djgpp/ for more information. GNU Make is free software. See the file COPYING for copying conditions. System-specific Notes --------------------- It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such that if you compile make with `cc -O' on AIX 3.2, it will not work correctly. It is said that using `cc' without `-O' does work. One area that is often a problem in configuration and porting is the code to check the system's current load average. To make it easier to test and debug this code, you can do `make check-loadavg' to see if it works properly on your system. (You must run `configure' beforehand, but you need not build Make itself to run this test.) Another potential source of porting problems is the support for large files (LFS) in configure for those operating systems that provide it. Please report any bugs that you find in this area. If you run into difficulties, then as a workaround you should be able to disable LFS by adding the `--disable-largefile' option to the `configure' script. a*[MAKE-3_78_1HB]README.AMIGA;1+,c./@ 4^-`0123KPWO56~7Dƶm89G@HJShort: Port of GNU make with SAS/C (no ixemul.library required) Author: GNU, Amiga port by Aaron "Optimizer" Digulla Uploader: Aaron "Optimizer" Digulla (digulla@fh-konstanz.de) Type: dev/c This is a pure Amiga port of GNU make. It needs no extra libraries or anything. It has the following features (in addition to any features of GNU make): - Runs Amiga-Commands with SystemTags() (Execute) - Can run multi-line statements - Allows to use Device-Names in targets: c:make : make.o is ok. To distinguish between device-names and target : or ::, MAKE looks for spaces. If there are any around :, it's taken as a target delimiter, if there are none, it's taken as the name of a device. Note that "make:make.o" tries to create "make.o" on the device "make:". - Replaces @@ by a newline in any command line: if exists make @@\ delete make.bak quiet @@\ rename make make.bak @@\ endif @@\ $(CC) Link Make.o To make works. Note that the @@ must stand alone (ie. "make@@\" is illegal). Also be carefull that there is a space after the "\" (ie, at the beginning of the next line). - Can be made resident to save space and time - Amiga specific wildcards can be used in $(wildcard ...) BUGS: - The line dummy.h : src/*.c tries to make dummy.h from "src/*.c" (ie. no wildcard-expansion takes place). You have to use "$(wildcard src/*.c)" instead. COMPILING FROM SCRATCH ---------------------- To recompile, you need SAS/C 6.51. make itself is not neccessary, there is an smakefile. 1. Copy config.ami to config.h 2. If you use make to compie, copy Makefile.ami to Makefile and glob/Makefile.ami to glob/Makefile. Copy make into the current directory. 3. Run smake/make INSTALLATION Copy make somewhere in your search path (eg. sc:c or sc:bin). If you plan to use recursive makes, install make resident: Resident make Add *[MAKE-3_78_1HB]README.CUSTOMS;1+,c./@ 4-`0123KPWO 567km89G@HJ  -*-indented-text-*- GNU make can utilize the Customs library, distributed with Pmake, to provide builds distributed across multiple hosts. In order to utilize this capability, you must first download and build the Customs library. It is contained in the Pmake distribution, which can be obtained at: ftp://ftp.icsi.berkeley.edu/pub/ai/stolcke/software/ This integration was tested (superficially) with Pmake 2.1.33. BUILDING CUSTOMS ---------------- First, build pmake and Customs. You need to build pmake first, because Customs require pmake to build. Unfortunately, this is not trivial; please see the pmake and Customs documentation for details. The best place to look for instructions is in the pmake-2.1.33/INSTALL file. Note that the 2.1.33 Pmake distribution comes with a set of patches to GNU make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These patches are based on GNU make 3.75 (there are patches for earlier versions of GNU make, also). The parts of this patchfile which relate directly to Customs support have already been incorporated into this version of GNU make, so you should _NOT_ apply the patch file. However, there are a few non-Customs specific (as far as I could tell) changes here which are not incorporated (for example, the modification to try expanding -lfoo to libfoo.so). If you rely on these changes you'll need to re-apply them by hand. Install the Customs library and header files according to the documentation. You should also install the man pages (contrary to comments in the documentation, they weren't installed automatically for me; I had to cd to the ``pmake-2.1.33/doc'' directory and run ``pmake install'' there directly). BUILDING GNU MAKE ----------------- Once you've installed Customs, you can build GNU make to use it. When configuring GNU make, merely use the ``--with-customs=DIR'' option. Provide the directory containing the ``lib'' and ``include/customs'' subdirectories as DIR. For example, if you installed the customs library in /usr/local/lib and the headers in /usr/local/include/customs, then you'd pass ``--with-customs=/usr/local'' as an option to configure. Run make (or use build.sh) normally to build GNU make as described in the INSTALL file. See the documentation for Customs for information on starting and configuring Customs. PROBLEMS -------- SunOS 4.1.x: The customs/sprite.h header file #includes the header files; this conflicts with GNU make's configuration so you'll get a compile error if you use GCC (or any other ANSI-capable C compiler). I commented out the #include in sprite.h:107: #if defined(sun) || defined(ultrix) || defined(hpux) || defined(sgi) /* #include */ #else YMMV. A*[MAKE-3_78_1HB]README.DOS;1+,c./@ 4-`0123KPWO56S37m89G@HJPort of GNU Make to 32-bit protected mode on MSDOS and MS-Windows. Builds with DJGPP v2 port of GNU C/C++ compiler and utilities. New (since 3.74) DOS-specific features: 1. Supports long filenames when run from DOS box on Windows 9x. 2. Supports both stock DOS COMMAND.COM and Unix-style shells (details in ``Notes'' below). 3. Supports DOS drive letters in dependencies and pattern rules. 4. Better support for DOS-style backslashes in pathnames (but see ``Notes'' below). 5. The $(shell) built-in can run arbitrary complex commands, including pipes and redirection, even when COMMAND.COM is your shell. 6. Can be built without floating-point code (see below). 7. Supports signals in child programs and restores the original directory if the child was interrupted. 8. Can be built without (a previous version of) Make. 9. The build process requires only standard tools. (Optional targets like "install:" and "clean:" still need additional programs, though, see below.) 10. Beginning with v3.78, the test suite works in the DJGPP environment (requires Perl and auxiliary tools; see below). To build: 1. Unzip the archive, preserving the directory structure (-d switch if you use PKUNZIP). If you build Make on Windows 95, use an unzip program that supports long filenames in zip files. If you are unpacking an official GNU source distribution, use either DJTAR (which is part of the DJGPP development environment), or the DJGPP port of GNU Tar. 2. Invoke the `configure.bat' batch file. If you are building Make in-place, i.e. in the same directory where its sources are kept, just type "configure.bat" and press [Enter]. Otherwise, you need to supply the path to the source directory as an argument to the batch file, like this: c:\djgpp\gnu\make-3.78.1\configure.bat c:/djgpp/gnu/make-3.78.1 Note the forward slashes in the source path argument: you MUST use them here.  3. If configure.bat doesn't find a working Make, it will suggest to use the `dosbuild.bat' batch file to build Make. Either do as it suggests or install another Make program (a pre-compiled binary should be available from the usual DJGPP sites) and rerun configure.bat. 4. If you will need to run Make on machines without an FPU, you might consider building a version of Make which doesn't issue floating-point instructions (they don't help much on MSDOS anyway). To this end, edit the Makefile created by configure.bat and add -DNO_FLOAT to the value of CPPFLAGS. 5. Invoke Make. If you are building from outside of the source directory, you need to tell Make where the sources are, like this: make srcdir=c:/djgpp/gnu/make-3.78.1 (configure.bat will tell you this when it finishes). You MUST use a full, not relative, name of the source directory here, or else Make might fail. 6. After Make finishes, if you have a0O~MAKE-3_78_1HB.BCKc`AKE-3_78_1HB]README.DOS;1m{, Unix-style shell installed, you can use the `install' target to install the package. You will also need GNU Fileutils and GNU Sed for this (they should be available from the DJGPP sites). Without a Unix-style shell, you will have to install programs and the docs manually. Copy make.exe to a directory on your PATH, make.i* info files to your Info directory, and update the file `dir' in your Info directory by adding the following item to the main menu: * Make: (make.info). The GNU make utility. If you have the `install-info' program (from the GNU Texinfo package), it will do that for you if you invoke it like this: install-info --info-dir=c:/djgpp/info c:/djgpp/info/make.info (If your Info directory is other than C:\DJGPP\INFO, change this command accordingly.) 7. The `clean' targets also require Unix-style shell, and GNU Sed and `rm' programs (the latter from Fileutils). 8. To run the test suite, type "make check". This requires a Unix shell (I used the DJGPP port of Bash 2.03), Perl, Sed, Fileutils and Sh-utils. Notes: ----- 1. The shell issue. This is probably the most significant improvement, first introduced in the port of GNU Make 3.75. The original behavior of GNU Make is to invoke commands directly, as long as they don't include characters special to the shell or internal shell commands, because that is faster. When shell features like redirection or filename wildcards are involved, Make calls the shell. This port supports both DOS shells (the stock COMMAND.COM and its 4DOS/NDOS replacements), and Unix-style shells (tested with the venerable Stewartson's `ms_sh' 2.3 and the DJGPP port of `bash' by Daisuke Aoyama ). When the $SHELL variable points to a Unix-style shell, Make works just like you'd expect on Unix, calling the shell for any command that involves characters special to the shell or internal shell commands. The only difference is that, since there is no standard way to pass command lines longer than the infamous DOS 126-character limit, this port of Make writes the command line to a temporary disk file and then invokes the shell on that file. If $SHELL points to a DOS-style shell, however, Make will not call it automatically, as it does with Unix shells. Stock COMMAND.COM is too dumb and would unnecessarily limit the functionality of Make. For example, you would not be able to use long command lines in commands that use redirection or pipes. Therefore, when presented with a DOS shell, this port of Make will emulate most of the shell functionality, like redirection and pipes, and shall only call the shell when a batch file or a command internal to the shell is invoked. (Even when a command is an internal shell command, Make will first search the $PATH for it, so that if a Makefile calls `mkdir', you can install, say, a port of GNU `mkdir' and have it called in that case.) The key to all this is the extended functionality of `spawn' and `system' functions from the DJGPP library; this port just calls `system' where it would invoke the shell on Unix. The most important aspect of these functions is that they use a special mechanism to pass long (up to 16KB) command lines to DJGPP programs. In addition, `system' emulates some internal commands, like `cd' (so that you can now use forward slashes with it, and can also change the drive if the directory is on another drive). Another aspect worth mentioning is that you can call Unix shell scripts directly, provided that the shell whose name is mentioned on the first line of the script is installed anywhere along the $PATH. It is impossible to tell here everything about these functions; refer to the DJGPP library reference for more details. The $(shell) built-in is implemented in this port by calling `popen'. Since `popen' calls `system', the above considerations are valid for $(shell) as well. In particular, you can put arbitrary complex commands, including pipes and redirection, inside $(shell), which is in many cases a valid substitute for the Unix-style command substitution (`command`) feature. 2. "SHELL=/bin/sh" -- or is it? Many Unix Makefiles include a line which sets the SHELL, for those versions of Make which don't have this as the default. Since many DOS systems don't have `sh' installed (in fact, most of them don't even have a `/bin' directory), this port takes such directives with a grain of salt. It will only honor such a directive if the basename of the shell name (like `sh' in the above example) can indeed be found in the directory that is mentioned in the SHELL= line (`/bin' in the above example), or in the current working directory, or anywhere on the $PATH (in that order). If the basename doesn't include a filename extension, Make will look for any known extension that indicates an executable file (.exe, .com, .bat, .btm, .sh, and even .sed and .pl). If any such file is found, then $SHELL will be defined to the exact pathname of that file, and that shell will hence be used for the rest of processing. But if the named shell is *not* found, the line which sets it will be effectively ignored, leaving the value of $SHELL as it was before. Since a lot of decisions that this port makes depend on the gender of the shell, I feel it doesn't make any sense to tailor Make's behavior to a shell which is nowhere to be found. Note that the above special handling of "SHELL=" only happens for Makefiles; if you set $SHELL in the environment or on the Make command line, you are expected to give the complete pathname of the shell, including the filename extension. The default value of $SHELL is computed as on Unix (see the Make manual for details), except that if $SHELL is not defined in the environment, $COMSPEC is used. Also, if an environment variable named $MAKESHELL is defined, it takes precedence over both $COMSPEC and $SHELL. Note that, unlike Unix, $SHELL in the environment *is* used to set the shell (since on MSDOS, it's unlikely that the interactive shell will not be suitable for Makefile processing). The bottom line is that you can now write Makefiles where some of the targets require a real (i.e. Unix-like) shell, which will nevertheless work when such shell is not available (provided, of course, that the commands which should always work, don't require such a shell). More important, you can convert Unix Makefiles to MSDOS and leave the line which sets the shell intact, so that people who do have Unixy shell could use it for targets which aren't converted to DOS (like `install' and `uninstall', for example). 3. Default directories. GNU Make knows about standard directories where it searches for library and include files mentioned in the Makefile. Since MSDOS machines don't have standard places for these, this port will search ${DJDIR}/lib and ${DJDIR}/include respectively. $DJDIR is defined automatically by the DJGPP startup code as the root of the DJGPP installation tree (unless you've tampered with the DJGPP.ENV file). This should provide reasonable default values, unless you moved parts of DJGPP to other directories. 4. Letter-case in filenames. If you run Make on Windows 9x, you should be aware of the letter-case issue. Make is internally case-sensitive, but all file operations are case-insensitive on Windows 9x, so e.g. files `FAQ', `faq' and `Faq' all refer to the same file, as far as Windows is concerned. The underlying DJGPP C library functions honor the letter-case of the filenames they get from the OS, except that by default, they down-case 8+3 DOS filenames which are stored in upper case in the directory and would break many Makefiles otherwise. (The details of which filenames are converted to lower case are explained in the DJGPP libc docs, under the `_preserve_fncase' and `_lfn_gen_short_fname' functions, but as a thumb rule, any filename that is stored in upper case in the directory, is a valid DOS 8+3 filename and doesn't include characters invalid on MSDOS FAT filesystems, will be automatically down-cased.) User reports that I have indicate that this default behavior is generally what you'd expect; however, your input is most welcome. In any case, if you hit a situation where you must force Make to get the 8+3 DOS filenames in upper case, set FNCASE=y in the environment or in the Makefile. 5. DOS-style pathnames. There are a lot of places throughout the program sources which make implicit assumptions about the pathname syntax. In particular, the directories are assumed to be separated by `/', and any pathname which doesn't begin with a `/' is assumed to be relative to the current directory. This port attempts to support DOS-style pathnames which might include the drive letter and use backslashes instead of forward slashes. However, this support is not complete; I feel that pursuing this support too far might break some more important features, particularly if you use a Unix-style shell (where a backslash is a quote character). I only consider support of backslashes desirable because some Makefiles invoke non-DJGPP programs which don't understand forward slashes. A notable example of such programs is the standard programs which come with MSDOS. Otherwise, you are advised to stay away from backslashes whenever possible. In particular, filename globbing won't work on pathnames with backslashes, because the GNU `glob' library doesn't support them (backslash is special in filename wildcards, and I didn't want to break that). One feature which *does* work with backslashes is the filename- related built-in functions such as $(dir), $(notdir), etc. Drive letters in pathnames are also fully supported. Bug reports: ----------- Bugs that are clearly related to the MSDOS/DJGPP port should be reported first on the comp.os.msdos.djgpp news group (if you cannot post to Usenet groups, write to the DJGPP mailing list, , which is an email gateway into the above news group). For other bugs, please follow the procedure explained in the "Bugs" chapter of the Info docs. If you don't have an Info reader, look up that chapter in the `make.i1' file with any text browser/editor. Enjoy, Eli Zaretskii a*[MAKE-3_78_1HB]README.VMS;8+,f ./@ 4X-`0123KPWO5627}m89G@HJThis is the VMS port 3.78.1hb of GNU Make done by Hartmut.Becker@compaq.com. It is based on the specific version 3.77k and on 3.78.1. 3.77k was done by Klaus Kmpf , the code was based on the VMS port of GNU Make 3.60 by Mike Moretti. It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different versions of DECC were used. VAXC was tried: it fails; but it doesn't seem worth to get it working. There are still some PTRMISMATCH warnings during the compile. Although perl is working on VMS the test scripts don't work. The function $shell is still missing. There is a known bug in some of the VMS CRTLs. It is in the shipped versions of VMS V7.2 and V7.2-1 and in the currently (October 1999) available ECOs for VMS V7.1 and newer versions. It is fixed in versions shipped with newer VMS versions and all ECO kits after October 1999. It only shows up during the daylight saving time period (DST): stat() returns a modification time 1 hour ahead. This results in GNU make warning messages. For a just created source you will see: $ gmake x.exe gmake.exe;1: *** Warning: File `x.c' has modification time in the future (940582 863 > 940579269) cc /obj=x.obj x.c link x.obj /exe=x.exe gmake.exe;1: *** Warning: Clock skew detected. Your build may be incomplete. New in 3.78.1hb: Fix a problem with automatically remaking makefiles. GNU make uses an execve to restart itself after a successful remake of the makefile. On UNIX systems execve replaces the running program with a new one and resets all signal handling to the default. On VMS execve creates a child process, signal and exit handlers of the parent are still active, and, unfortunately, corrupt the exit code from the child. Fix in job.c: ignore SIGCHLD. Added some switches to reflect latest features of DECC. Modifications in makefile.vms. Set some definitions to reflect latest features of DECC. Modifications in config.h-vms (which is copied to config.h). Added extern strcmpi declaration to avoid 'implicitly declared' messages. Modification in make.h. Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/ Compaq c/c++ compilers. Modifications in default.c. Usage of opendir() and friends, suppress file version. Modifications in dir.c. Added VMS specific code to handle ctrl+c and ctrl+y to abort make. Modifications in job.c. Added support to have case sensitive targets and dependencies but to still use case blind file names. This is especially useful for Java makefiles on VMS: .SUFFIXES : .SUFFIXES : .class .java .java.class : javac "$< HelloWorld.class : HelloWorld.java A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced. It needs to be enabled, to get this feature, default is disabled. The macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled. Modifications in file.c and config.h-vms. Bootstrap make to start building make is still makefile.com, but make needs to be re-made with a make to make a correct version: ignore all possible warnings, delete all objects, rename make.exe to a different name and run it. Made some minor modifications to the bootstrap build makefile.com. This is the VMS port of GNU Make. It is based on the VMS port of GNU Make 3.60 by Mike Moretti. This port was done by Klaus Kmpf There is first-level support available from proGIS Software, Germany. Visit their web-site at http://www.progis.de to get information about other vms software and forthcoming updates to gnu make. New for 3.77: /bin/sh style I/O redirection is supported. You can now write lines like mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt Makefile variables are looked up in the current environment. You can set symbols or logicals in DCL and evaluate them in the Makefile via $(). Variables defined in the Makefile override VMS symbols/logicals ! Functions for file names are working now. See the GNU Make manual for $(dir ...) and $(wildcard ...). Unix-st  yle and VMS-style names are supported as arguments. The default rules are set up for GNU C. Building an executable from a single source file is as easy as 'make file.exe'. The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for different VMS systems can now be written by checking $(ARCH) as in ifeq ($(ARCH),ALPHA) $(ECHO) "On the Alpha" else $(ECHO) "On the VAX" endif Command lines of excessive length are correctly broken and written to a batch file in sys$scratch for later execution. There's no limit to the lengths of commands (and no need for .opt files :-) any more. Empty commands are handled correctly and don't end in a new DCL process. New for 3.76: John W. Eaton has updated the VMS port to support libraries and VPATH. To build Make, simply type @makefile. This should compile all the necessary files and link Make. There is also a file called makefile.vms. If you already have GNU Make built you can just use Make with this makefile to rebuild. Here are some notes about GNU Make for VMS: The cd command is supported if it's called as $(CD). This invokes the 'builtin_cd' command which changes the directory. Calling 'set def' doesn't do the trick, since a sub-shell is spawned for this command, the directory is changed *in this sub-shell* and the sub-shell ends. Libraries are not supported. They were in GNU Make 3.60 but somehow I didn't care porting the code. If there is enough interest, I'll do it at some later time. The variable $^ separates files with commas instead of spaces (It's the natural thing to do for VMS). See defaults.c for VMS default suffixes and my definitions for default rules and variables. The shell function is not implemented yet. Load average routines haven't been implemented for VMS yet. The default include directory for including other makefiles is SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use SYS$LIBRARY: instead; maybe it wouldn't work that way). The default makefiles make looks for are: makefile.vms, gnumakefile, makefile., and gnumakefile. . The stat() function and handling of time stamps in VMS is broken, so I replaced it with a hack in vmsfunctions.c. I will provide a full rewrite somewhere in the future. Be warned, the time resolution inside make is less than what vms provides. This might be a problem on the faster Alphas. You can use a : in a filename only if you preceed it with a backslash ('\'). E.g.- hobbes\:[bogas.files] Make ignores success, informational, or warning errors (-S-, -I-, or -W-). But it will stop on -E- and -F- errors. (unless you do something to override this in your makefile, or whatever). Remote stuff isn't implemented yet. Multiple line DCL commands, such as "if" statements, must be put inside command files. You can run a command file by using \@. VMS changes made for 3.74.3 Lots of default settings are adapted for VMS. See default.c. Long command lines are now converted to command files. Comma (',') as a separator is now allowed. See makefile.vms for an example. *[MAKE-3_78_1HB]README.W32;1+,c./@ 47-`0123KPWO56{l7m89G@HJPort of GNU make to Windows NT and Windows 95 Builds natively with MSVC 2.x or MSVC 4.x compilers. Should also build fine with MSVC 5.x and 6.x (though not confirmed). This Windows 32-bit port of GNU make is maintained primarily by Rob Tulloh, who is also the author of this README. To build with nmake on Windows NT, Windows 95, or Windows 98: 1. Make sure cl.exe is in your %Path%. Example: set Path=%Path%;c:/msdev/bin 2. Make sure %include% is set to msvc include directory. Example: set include=c:/msdev/include 3. Make sure %lib% is set to msvc lib directory. Example: set lib=c:/msdev/lib 4. nmake /f NMakefile A short cut to steps 1, 2, and 3 is to run VCVARS32.bat before invoking namke. For example: c: cd \msdev\bin VCVARS32.bat cd \path\to\make-3.78.1 nmake /f NMakefile There is a bat file (build_w32.bat) for folks who have fear of nmake. Outputs: WinDebug/make.exe WinRel/make.exe -- Notes/Caveats -- GNU make on Windows 32-bit platforms: This version of make is ported natively to Windows32 platforms (Windows NT 3.51, Windows NT 4.0, Windows 95, and Windows 98). It does not rely on any 3rd party software or add-on packages for building. The only thing needed is a version of Visual C++, which is the predominant compiler used on Windows32 platforms. Do not confuse this port of GNU make with other Windows32 projects which provide a GNU make binary. These are separate projects and are not connected to this port effort. GNU make and sh.exe: This port prefers you have a working sh.exe somewhere on your system. If you don't have sh.exe, the port falls back to MSDOS mode for launching programs (via a batch file). The MSDOS mode style execution has not been tested that carefully though (The author uses GNU bash as sh.exe). There are very few true ports of Bourne shell for NT right now. There is a version of GNU bash available from Cygnus "Cygwin" porting effort (http://sourceware.cygnus.com/cygwin). Other possibilities are the MKS version of sh.exe, or building your own with a package like NutCracker (DataFocus) or Portage (Consensys). GNU make and brain-dead shells (BATCH_MODE_ONLY_SHELL): Some versions of Bourne shell does not behave well when invoked as 'sh -c' from CreateProcess(). The main problem is they seem to have a hard time handling quoted strings correctly. This can be circumvented by writing commands to be executed to a batch file and then executing the command by calling 'sh file'. To work around this difficulty, this version of make supports a batch mode. When BATCH_MODE_ONLY_SHELL is defined at compile time, make forces all command lines to be executed via script files instead of by command line. A native Windows32 system with no Bourne shell will also run in batch mode. All command lines will be put into batch files and executed via $(COMSPEC) (%COMSPEC%). GNU make and Cygnus GNU Windows32 tools: Good news! Make now has native support for Cygwin sh. To enable, define the HAVE_CYGWIN_SHELL in config.h and rebuild make from scratch. This version of make tested with B20.1 of Cygwin. Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL. GNU make and the MKS shell: There is now semi-official support for the MKS shell. To turn this support on, define HAVE_MKS_SHELL in the config.h.W32 before you build make. Do not define BATCH_MODE_ONLY_SHELL if you turn on HAVE_MKS_SHELL. GNU make handling of drive letters in pathnames (PATH, vpath, VPATH): There is a caveat that should be noted with respect to handling single character pathnames on Windows systems. When colon is used in PATH variables, make tries to be smart about knowing when you are using colon as a separator versus colon as a drive letter. Unfortunately, something as simple as the string 'x:/' could be interpreted 2 ways: (x and /) or (x:/). Make chooses to interpret a letter plus colon (e.g. x:/) as a drive letter pathname. If it is necessary to use single character directories in paths (VPATH, vpath, Path , PATH), the user must do one of two things: a. Use semicolon as the separator to disambiguate colon. For example use 'x;/' if you want to say 'x' and '/' are separate components. b. Qualify the directory name so that there is more than one character in the path(s) used. For example, none of these settings are ambiguous: ./x:./y /some/path/x:/some/path/y x:/some/path/x:x:/some/path/y Please note that you are free to mix colon and semi-colon in the specification of paths. Make is able to figure out the intended result and convert the paths internally to the format needed when interacting with the operating system. You are encouraged to use colon as the separator character. This should ease the pain of deciding how to handle various path problems which exist between platforms. If colon is used on both Unix and Windows systems, then no ifdef'ing will be necessary in the makefile source. GNU make test suite: I verified all functionality with a slightly modified version of make-test-3.78.1 (modifications to get test suite to run on Windows NT). All tests pass in an environment that includes sh.exe. Tests were performed on both Windows NT and Windows 95. Building GNU make on Windows NT and Windows 95/98 with Microsoft Visual C: I did not provide a Visual C project file with this port as the project file would not be considered freely distributable (or so I think). It is easy enough to create one, though, if you know how to use Visual C. I build the program statically to avoid problems locating DLL's on machines that may not have MSVC runtime installed. If you prefer, you can change make to build with shared libraries by changing /MT to /MD in the NMakefile (or in build_w32.bat). The program has not been built for non-Intel architectures (yet). I have not tried to build with any other compilers than MSVC. I have heard that this is possible though so don't be afraid to notify me of your successes! Pathnames and white space: Unlike Un ix, Windows 95/NT systems encourage pathnames which contain white space (e.g. C:\Program Files\). These sorts of pathnames are legal under Unix too, but are never encouraged. There is at least one place in make (VPATH/vpath handling) where paths containing white space will simply not work. There may be others too. I chose to not try and port make in such a way so that these sorts of paths could be handled. I offer these suggestions as workarounds: 1. Use 8.3 notation 2. Rename the directory so it does not contain white space. If you are unhappy with this choice, this is free software and you are free to take a crack at making this work. The code in w32/pathstuff.c and vpath.c would be the places to start. Pathnames and Case insensitivity: Unlike Unix, Windows 95/NT systems are case insensitive but case preserving. For example if you tell the file system to create a file named "Target", it will preserve the case. Subsequent access to the file with other case permutations will succeed (i.e. opening a file named "target" or "TARGET" will open the file "Target"). By default, GNU make retains its case sensitivity when comparing target names and existing files or directories. It can be configured, however, into a case preserving and case insensitive mode by adding a define for HAVE_CASE_INSENSITIVE_FS to config.h.W32. For example, the following makefile will create a file named Target in the directory subdir which will subsequently be used to satisfy the dependency of SUBDIR/DepTarget on SubDir/TARGET. Without HAVE_CASE_INSENSITIVE_FS configured, the dependency link will not be made: subdir/Target: touch $@ SUBDIR/DepTarget: SubDir/TARGET cp $^ $@ Reliance on this behavior also eliminates the ability of GNU make to use case in comparison of matching rules. For example, it is not possible to set up a C++ rule using %.C that is different than a C rule using %.c. GNU make will consider these to be the same rule and will issue a warning. SAMBA/NTFS/VFAT: I have not had any success building the debug version of this package using SAMBA as my file server. The reason seems to be related to the way VC++ 4.0 changes the case name of the pdb filename it is passed on the command line. It seems to change the name always to to lower case. I contend that the VC++ compiler should not change the casename of files that are passed as arguments on the command line. I don't think this was a problem in MSVC 2.x, but I know it is a problem in MSVC 4.x. The package builds fine on VFAT and NTFS filesystems. Most all of the development I have done to date has been using NTFS and long file names. I have not done any considerable work under VFAT. VFAT users may wish to be aware that this port of make does respect case sensitivity. FAT: Version 3.76 added support for FAT filesystems. Make works around some difficulties with stat'ing of files and caching of filenames and directories internally. Bug reports: Please submit bugs via the normal bug reporting mechanism which is described in the GNU make manual and the base README. e*[MAKE-3_78_1HB]REMAKE.C;1+,c.L/@ 4LI-`0123KPWOM5671 m89G@HJ /* Basic dependency engine for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "filedef.h" #include "job.h" #include "commands.h" #include "dep.h" #include "variable.h" #include #ifdef HAVE_FCNTL_H #include #else #include #endif #ifdef VMS #include #endif #ifdef WINDOWS32 #include #endif extern int try_implicit_rule PARAMS ((struct file *file, unsigned int depth)); /* Incremented when a command is started (under -n, when one would be). */ unsigned int commands_started = 0; static int update_file PARAMS ((struct file *file, unsigned int depth)); static int update_file_1 PARAMS ((struct file *file, unsigned int depth)); static int check_dep PARAMS ((struct file *file, unsigned int depth, FILE_TIMESTAMP this_mtime, int *must_make_ptr)); static int touch_file PARAMS ((struct file *file)); static void remake_file PARAMS ((struct file *file)); static FILE_TIMESTAMP name_mtime PARAMS ((char *name)); static int library_search PARAMS ((char **lib, FILE_TIMESTAMP *mtime_ptr)); /* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing was done, 0 if all goals were updated successfully, or 1 if a goal failed. If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should be disabled for them unless they were also command-line targets, and we should only make one goal at a time and return as soon as one goal whose `changed' member is nonzero is successfully made. */ /* We need to know this "lower down" for correct error handling. */ static int updating_makefiles = 0; int update_goal_chain (goals, makefiles) register struct dep *goals; int makefiles; { int t = touch_flag, q = question_flag, n = just_print_flag; unsigned int j = job_slopP~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]REMAKE.C;1Lts; int status = -1; updating_makefiles = makefiles; #define MTIME(file) (makefiles ? file_mtime_no_search (file) \ : file_mtime (file)) /* Duplicate the chain so we can remove things from it. */ goals = copy_dep_chain (goals); { /* Clear the `changed' flag of each goal in the chain. We will use the flag below to notice when any commands have actually been run for a target. When no commands have been run, we give an "up to date" diagnostic. */ struct dep *g; for (g = goals; g != 0; g = g->next) g->changed = 0; } #if 0 /* Only run one job at a time when building makefiles. No one seems to know why this was done, and no one can think of a good reason to do it. Hopefully an obvious one won't appear as soon as we release the next version :-/. */ if (makefiles) job_slots = 1; #endif /* All files start with the considered bit 0, so the global value is 1. */ considered = 1; /* Update all the goals until they are all finished. */ while (goals != 0) { register struct dep *g, *lastgoal; /* Start jobs that are waiting for the load to go down. */ start_waiting_jobs (); /* Wait for a child to die. */ reap_children (1, 0); lastgoal = 0; g = goals; while (g != 0) { /* Iterate over all double-colon entries for this file. */ struct file *file; int stop = 0, any_not_updated = 0; for (file = g->file->double_colon ? g->file->double_colon : g->file;  file != NULL; file = file->prev) { unsigned int ocommands_started; int x; check_renamed (file); if (makefiles) { if (file->cmd_target) { touch_flag = t; question_flag = q; just_print_flag = n; } else touch_flag = question_flag = just_print_flag = 0; } /* Save the old value of `commands_started' so we can compare later. It will be incremented when any commands are actually run. */ ocommands_started = commands_started; x = update_file (file, makefiles ? 1 : 0); check_renamed (file); /* Set the goal's `changed' flag if any commands were started by calling update_file above. We check this flag below to decide when to give an "up to date" diagnostic. */ g->changed += commands_started - ocommands_started; /* If we updated a file and STATUS was not already 1, set it to 1 if updating failed, or to 0 if updating succeeded. Leave STATUS as it is if no updating was done. */ stop = 0; if ((x != 0 || file->updated) && status < 1) { if (file->update_status != 0) { /* Updating failed, or -q triggered. The STATUS value tells our caller which. */ status = file->update_status; /* If -q just triggered, stop immediately. It doesn't matter how much more we run, since we already know the answer to return. */ stop = (!keep_going_flag && !question_flag && !makefiles); } else { FILE_TIMESTAMP mtime = MTIME (file); check_renamed (file); if (file->updated && g->changed && mtime != file->mtime_before_update)  { /* Updating was done. If this is a makefile and just_print_flag or question_flag is set (meaning -n or -q was given and this file was specified as a command-line target), don't change STATUS. If STATUS is changed, we will get re-exec'd, and enter an infinite loop. */ if (!makefiles || (!just_print_flag && !question_flag)) status = 0; if (makefiles && file->dontcare) /* This is a default makefile; stop remaking. */ stop = 1; } } } /* Keep track if any double-colon entry is not finished. When they are all finished, the goal is finished. */ any_not_updated |= !file->updated; if (stop) break; } /* Reset FILE since it is null at the end of the loop. */ file = g->file; if (stop || !any_not_updated) { /* If we have found nothing whatever to do for the goal, print a message saying nothing needs doing. */ if (!makefiles /* If the update_status is zero, we updated successfully or not at all. G->changed will have been set above if any commands were actually started for this goal. */ && file->update_status == 0 && !g->changed /* Never give a message under -s or -q. */ && !silent_flag && !question_flag) message (1, ((file->phony || file->cmds == 0) ? _("Nothing to be done for `%s'.") : _("`%s' is up to date.")), file->name); /* This goal is finished. Remove it from the chain. */ if (lastgoal == 0) goals = g->next; else lastgoal->next = g->next; /* Free the storage. */ free ((char *) g); g = lastgoal == 0 ? goals : lastgoal->next; X if (stop) break; } else { lastgoal = g; g = g->next; } } /* If we reached the end of the dependency graph toggle the considered flag for the next pass. */ if (g == 0) considered = !considered; } if (makefiles) { touch_flag = t; question_flag = q; just_print_flag = n; job_slots = j; } return status; } /* Generate an error/fatal message if no rules are available for the target. */ static void no_rule_error(file) struct file *file; { static const char msg_noparent[] = _("%sNo rule to make target `%s'%s"); static const char msg_parent[] = _("%sNo rule to make target `%s', needed by `%s'%s"); if (keep_going_flag || file->dontcare) { /* If the previous attempt was made while we were creating makefiles, but we aren't anymore, print an error now. */ if (!file->dontcare || (file->mfile_status && !updating_makefiles)) { if (file->parent == 0) error (NILF, msg_noparent, "*** ", file->name, "."); else error (NILF, msg_parent, "*** ", file->name, file->parent->name, "."); } file->update_status = 2; file->mfile_status = updating_makefiles; } else if (file->parent == 0) fatal (NILF, msg_noparent, "", file->name, ""); else fatal (NILF, msg_parent, "", file->name, file->parent->name, ""); } /* If FILE is not up to date, execute the commands for it. Return 0 if successful, 1 if unsuccessful; but with some flag settings, just call `exit' if unsuccessful. DEPTH is the depth in recursions of this function. We increment it during the consideration of our dependencies, then decrement it again after finding out whether this file is out of date. If there are multiple double-colon entries for FILE, each is considered in turn. */ static int update_file (file, depth) struct file *file; unsigned int depth; { register int status = 0; register struct file *f; for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev) { /* Prune the dependency graph: if we've already been here on _this_ pass through the dependency graph, we don't have to go any further. We won't reap_children until we start the next pass, so no state change is possible below here until then. */ if (f->considered == considered) { DEBUGPR (_("Pruning file `%s'.\n")); continue; } f->considered = considered; status |= update_file_1 (f, depth); check_renamed (f); if (status != 0 && !keep_going_flag) return status; switch (f->command_state) { case cs_finished: /* The file is done being remade. */ break; case cs_running: case cs_deps_running: /* Don't run the other :: rules for this file until this rule is finished. */ return 0; default: assert (f->command_state == cs_running); break; } } return status; } /* Consider a single `struct file' and update it as appropriate. */ static int update_file_1 (file, depth) struct file *file; unsigned int depth; { register FILE_TIMESTAMP this_mtime; int noexist, must_make, deps_changed; int dep_status = 0; register struct dep *d, *lastd; int running = 0; DEBUGPR (_("Considering target file `%s'.\n")); if (file->updated) { if (file->update_status > 0) { DEBUGPR (_("Recently tried and failed to update file `%s'.\n")); no_rule_error(file); return file->update_status; } DEBUGPR (_("File `%s' was considered already.\n")); return 0; } switch (file->command_state) { case cs_not_started: case cs_deps_running: break; case cs_running: DEBUGPR (_("Still updating file `%s'.\n")); return 0; case cs_finished: DEBUGPR (_("Finished updating file `%s'.\n")); return file->update_status; default: abort (); } ++depth; /* Notice recursive update of the same file. */ file->updating = 1; /* Looking at the file's modtime beforehand allows the possibility that its name may be changed by a VPATH search, and thus it may not need an implicit rule. If this were not done, the file might get implicit commands that apply to its initial name, only to have that name replaced with another found by VPATH search. */ this_mtime = file_mtime (file); check_renamed (file); noexist = this_mtime == (FILE_TIMESTAMP) -1; if (noexist) DEBUGPR (_("File `%s' does not exist.\n")); must_make = noexist; /* If file was specified as a target with no commands, come up with some default commands. */ if (!file->phony && file->cmds == 0 && !file->tried_implicit) { if (try_implicit_rule (file, depth)) DEBUGPR (_("Found an implicit rule for `%s'.\n")); else DEBUGPR (_("No implicit rule found for `%s'.\n")); file->tried_implicit = 1; } if (file->cmds == 0 && !file->is_target && default_file != 0 && default_file->cmds != 0) { DEBUGPR (_("Using default commands for `%s'.\n")); file->cmds = default_file->cmds; } /* Update all non-intermediate files we depend on, if necessary, and see whether any of them is more recent than this file. */ lastd = 0; d = file->deps; while (d != 0) { FILE_TIMESTAMP mtime; check_renamed (d->file); mtime = file_mtime (d->file); check_renamed (d->file); if (d->file->updating) { error (NILF, _("Circular %s <- %s dependency dropped."), file->name, d->file->name); /* We cannot free D here because our the caller will still have a reference to it when we were called recursively via check_dep below. */ if (lastd == 0) file->deps = d->next; else lastd->next = d->next; d = d->next; continue; } d->file->parent = file; dep_status |= check_dep (d->file, depth, this_mtime, &must_make); check_renamed (d->file); { register struct file *f = d->file; if (f->double_colon) f = f->double_colon; do { running |= (f->command_state == cs_running || f->command_state == cs_deps_running); f = f->prev; } while (f != 0); } if (dep_status != 0 && !keep_going_flag) break; if (!running) d->changed = file_mtime (d->file) != mtime; lastd = d; d = d->next; } /* Now we know whether this target needs updating. If it does, update all the intermediate files we depend on. */ if (must_make) { for (d = file->deps; d != 0; d = d->next) if (d->file->intermediate) { FILE_TIMESTAMP mtime = file_mtime (d->file); check_renamed (d->file); d->file->parent = file; dep_status |= update_file (d->file, depth); check_renamed (d->file); { register struct file *f = d->file; if (f->double_colon) f = f->double_colon; do { running |= (f->command_state == cs_running || f->command_state == cs_deps_running); f = f->prev; } while (f != 0); } if (dep_status != 0 && !keep_going_flag) break; if (!running) d->changed = ((file->phony && file->cmds != 0) || file_mtime (d->file) != mtime); } } file->updating = 0; DEBUGPR (_("Finished prerequisites of target file `%s'.\n")); if (running) { set_command_state (file, cs_deps_running); --depth; DEBUGPR (_("The prerequisites of `%s' are being made.\n")); return 0; } /* If any dependency failed, give up now. */ if (dep_status != 0) { file->update_status = dep_status; notice_finished_file (file); depth--; DEBUGPR (_("Giving up on target file `%s'.\n")); if (depth == 0 && keep_going_flag && !just_print_flag && !question_flag) error (NILF, _("Target `%s' not remade because of errors."), file->name); return dep_status; } if (file->command_state == cs_deps_running) /* The commands for some deps were running on the last iteration, but they have finished now. Reset the command_state to not_started to simplify later bookkeeping. It is important that we do this only when the prior state was cs_deps_running, because that prior state was definitely propagated to FILE's also_make's by set_command_state (called above), but in another state an also_make may have independently changed to finished state, and we would confuse that file's bookkeeping (updated, but not_started is bogus state). */ set_command_state (file, cs_not_started); /* Now record which dependencies are more recent than this file, so we can define $?. */ deps_changed = 0; for (d = file->deps; d != 0; d = d->next) { FILE_TIMESTAMP d_mtime = file_mtime (d->file); check_renamed (d->file); #if 1 /* %%% In version 4, remove this code completely to implement not remaking deps if their deps are newer than their parents. */ if (d_mtime == (FILE_TIMESTAMP) -1 && !d->file->intermediate) /* We must remake if this dep does not exist and is not intermediate. */ must_make = 1; #endif /* Set DEPS_CHANGED if this dep actually changed. */ deps_changed |= d->changed; /* Set D->changed if either this dep actually changed, or its dependent, FILE, is older or does not exist. */ d->changed |= noexist || d_mtime > this_mtime; if (debug_flag && !noexist) { print_spaces (depth); if (d_mtime == (FILE_TIMESTAMP) -1) printf (_("Prerequisite `%s' does not exist.\n"), dep_name (d)); else printf (_("Prerequisite `%s' is %s than target `%s'.\n"), dep_name (d), d->changed ? _("newer") : _("older"), file->name); fflush (stdout); } } /* Here depth returns to the value it had when we were called. */ depth--; if (file->double_colon && file->deps == 0) { must_make = 1; DEBUGPR (_("Target `%s' is double-colon and has no prerequisites.\n")); } else if (!noexist && file->is_target && !deps_changed && file->cmds == 0) { must_make = 0; DEBUGPR (_("No commands for `%s' and no prerequisites actually changed.\n")); } if (!must_make) { if (debug_flag) { print_spaces(depth); printf(_("No need to remake target `%s'"), file->name); if (!streq(file->name, file->hname)) printf(_("; using VPATH name `%s'"), file->hname); printf(".\n"); fflush(stdout); } notice_finished_file (file); /* Since we don't need to remake the file, convert it to use the VPATH filename if we found one. hfile will be either the local name if no VPATH or the VPATH name if one was found. */ while (file) { file->name = file->hname; file = file->prev; } return 0; } DEBUGPR (_("Must remake target `%s'.\n")); /* It needs to be remade. If it's VPATH and not reset via GPATH, toss the VPATH. */ if (!streq(file->name, file->hname)) { if (debug_flag) { print_spaces (depth); printf(_(" Ignoring VPATH name `%s'.\n"), file->hname); fflush(stdout); } file->ignore_vpath = 1; } /* Now, take appropriate actions to remake the file. */ remake_file (file); if (file->command_state != cs_finished) { DEBUGPR (_("Commands of `%s' are being run.\n")); return 0; } switch (file->update_status) { case 2: DEBUGPR (_("Failed to remake target file `%s'.\n")); break; case 0: DEBUGPR (_("Successfully remade target file `%s'.\n")); break; case 1: DEBUGPR (_("Target file `%s' needs remade under -q.\n")); break; default: assert (file->update_status >= 0 && file->update_status <= 2); break; } file->updated = 1; return file->update_status; } /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all files listed in its `also_make' member. Under -t, this function also touches FILE. On return, FILE->update_status will no longer be -1 if it was. */ void notice_finished_file (file) register struct file *file; { struct dep *d; int ran = file->command_state == cs_running; file->command_state = cs_finished; file->updated = 1; if (touch_flag /* The update status will be: -1 if this target was not remade; 0 if 0 or more commands (+ or ${MAKE}) were run and won; 1 if some commands were run and lost. We touch the target if it has commands which either were not run or won when they ran (i.e. status is 0). */ && file->update_status == 0) { if (file->cmds != 0 && file->cmds->any_recurse) { /* If all the command lines were recursive, we don't want to do the touching. */ unsigned int i; for (i = 0; i < file->cmds->ncommand_lines; ++i) if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE)) goto have_nonrecursing; } else { have_nonrecursing: if (file->phony) file->update_status = 0; else /* Should set file's modification date and do nothing else. */ file->update_status = touch_file (file); } } if (file->mtime_before_update == 0) file->mtime_before_update = file->last_mtime; if (ran && !file->phony) { struct file *f; if (just_print_flag || question_flag || (file->is_target && file->cmds == 0)) file->last_mtime = NEW_MTIME; else file->last_mtime = 0; /* Propagate the change of modification time to all the double-colon entries for this file. */ for (f = file->double_colon; f != 0; f = f->next) f->last_mtime = file->last_mtime; } if (ran && file->update_status != -1) /* We actually tried to update FILE, which has updated its also_make's as well (if it worked). If it didn't work, it wouldn't work again for them. So mark them as updated with the same status. */ for (d = file->also_make; d != 0; d = d->next) { d->file->command_state = cs_finished; d->file->updated = 1; d->file->update_status = file->update_status; if (ran && !d->file->phony) /* Fetch the new modification time. We do this instead of just invalidating the cached time so that a vpath_search can happen. Otherwise, it would never be done because the target is already updated. */ (void) f_mtime (d->file, 0); } else if (file->update_status == -1) /* Nothing was done for FILE, but it needed nothing done. So mark it now as "succeeded". */ file->update_status = 0; } /* Check whether another file (whose mtime is THIS_MTIME) needs updating on account of a dependency which is file FILE. If it does, store 1 in *MUST_MAKE_PTR. In the process, update any non-intermediate files that FILE depends on (including FILE itself). Return nonzero if any updating failed. */ static int check_dep (file, depth, this_mtime, must_make_ptr) struct file *file; unsigned int depth; FILE_TIMESTAMP this_mtime; int *must_make_ptr; { register struct dep *d; int dep_status = 0; ++depth; file->updating = 1; if (!file->intermediate) /* If this is a non-intermediate file, update it and record whether it is newer than THIS_MTIME. */ { FILE_TIMESTAMP mtime; dep_status = update_file (file, depth); check_renamed (file); mtime = file_mtime (file); check_renamed (file); if (mtime == (FILE_TIMESTAMP) -1 || mtime > this_mtime) *must_make_ptr = 1; } else { /* FILE is an intermediate file. */ FILE_TIMESTAMP mtime; if (!file->phony && file->cmds == 0 && !file->tried_implicit) { if (try_implicit_rule (file, depth)) DEBUGPR (_("Found an implicit rule for `%s'.\n")); else DEBUGPR (_("No implicit rule found for `%s'.\n")); file->tried_implicit = 1; } if (file->cmds == 0 && !file->is_target && default_file != 0 && default_file->cmds != 0) { DEBUGPR (_("Using default commands for `%s'.\n")); file->cmds = default_file->cmds; } /* If the intermediate file actually exists and is newer, then we should remake from it. */ check_renamed (file); mtime = file_mtime (file); check_renamed (file); if (mtime != (FILE_TIMESTAMP) -1 && mtime > this_mtime) *must_make_ptr = 1; /* Otherwise, update all non-intermediate files we depend on, if necessary, and see whether any of them is more recent than the file on whose behalf we are checking. */ else { register struct dep *lastd; lastd = 0; d = file->deps; while (d != 0) { if (d->file->updating) { error (NILF, _("Circular %s <- %s dependency dropped."), file->name, d->file->name); if (lastd == 0) { file->deps = d->next; free ((char *) d); d = file->deps; } else { lastd->next = d->next; free ((char *) d); d = lastd->next; } continue; } d->file->parent = file; dep_status |= check_dep (d->file, depth, this_mtime, must_make_ptr); check_renamed (d->file); if (dep_status != 0 && !keep_going_flag) break; if (d->file->command_state == cs_running || d->file->command_state == cs_deps_running) /* Record that some of FILE's deps are still being made. This tells the upper levels to wait on processing it until the commands are finished. */ set_command_state (file, cs_deps_running); lastd = d; d = d->next; } } } file->updating = 0; return dep_status; } /* Touch FILE. Return zero if successful, one if not. */ #define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1) static int touch_file (file) register struct file *file; { if (!silent_flag) message (0, "touch %s", file->name); #ifndef NO_ARCHIVES if (ar_name (file->name)) return ar_touch (file->name); else #endif { int fd = open (file->name, O_RDWR | O_CREAT, 0666); if (fd < 0) TOUCH_ERROR ("touch: open: "); else { struct stat statbuf; char buf; int status; do status = fstat (fd, &statbuf); while (status < 0 && EINTR_SET); if (status < 0) TOUCH_ERROR ("touch: fstat: "); /* Rewrite character 0 same as it already is. */ if (read (fd, &buf, 1) < 0) TOUCH_ERROR ("touch: read: "); if (lseek (fd, 0L, 0) < 0L) TOUCH_ERROR ("touch: lseek: "); if (write (fd, &buf, 1) < 0) TOUCH_ERROR ("touch: write: "); /* If file length was 0, we just changed it, so change it back. */ if (statbuf.st_size == 0) { (void) close (fd); fd = open (file->name, O_RDWR | O_TRUNC, 0666); if (fd < 0) TOUCH_ERROR ("touch: open: "); } (void) close (fd); } } return 0; } /* Having checked and updated the dependencies of FILE, do whatever is appropriate to remake FILE itself. Return the status from executing FILE's commands. */ static void remake_file (file) struct file *file; { if (file->cmds == 0) { if (file->phony) /* Phony target. Pretend it succeeded. */ file->update_status = 0; else if (file->is_target) /* This is a nonexistent target file we cannot make. Pretend it was successfully remade. */ file->update_status = 0; else no_rule_error(file); } else { chop_commands (file->cmds); if (!touch_flag || file->cmds->any_recurse) { execute_file_commands (file); return; } else /* This tells notice_finished_file it is ok to touch the file. */ file->update_status = 0; } /* This does the touching under -t. */ notice_finished_file (file); } /* Return the mtime of a file, given a `struct file'. Caches the time in the struct file to avoid excess stat calls. If the file is not found, and SEARCH is nonzero, VPATH searching and replacement is done. If that fails, a library (-lLIBNAME) is tried and the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into FILE. */ FILE_TIMESTAMP f_mtime (file, search) register struct file *file; int search; { FILE_TIMESTAMP mtime; /* File's mtime is not known; must get it from the system. */ #ifndef NO_ARCHIVES if (ar_name (file->name)) { /* This file is an archive-member reference. */ char *arname, *memname; struct file *arfile; int arname_used = 0; /* Find the archive's name. */ ar_parse_name (file->name, &arname, &memname); /* Find the modification time of the archive itself. Also allow for its name to be changed via VPATH search. */ arfile = lookup_file (arname); if (arfile == 0) { arfile = enter_file (arname); arname_used = 1; } mtime = f_mtime (arfile, search); check_renamed (arfile); if (search && strcmp (arfile->hname, arname)) { /* The archive's name has changed. Change the archive-member reference accordingly. */ char *name; unsigned int arlen, memlen; if (!arname_used) { free (arname); arname_used = 1; } arname = arfile->hname; arlen = strlen (arname); memlen = strlen (memname); /* free (file->name); */ name = (char *) xmalloc (arlen + 1 + memlen + 2); bcopy (arname, name, arlen); name[arlen] = '('; bcopy (memname, name + arlen + 1, memlen); name[arlen + 1 + memlen] = ')'; name[arlen + 1 + memlen + 1] = '\0'; /* If the archive was found with GPATH, make the change permanent; otherwise defer it until later. */ if (arfile->name == arfile->hname) rename_file (file, name); else rehash_file (file, name); check_renamed (file); } if (!arname_used) free (arname); free (memname); if (mtime == (FILE_TIMESTAMP) -1) /* The archive doesn't exist, so it's members don't exist either. */ return (FILE_TIMESTAMP) -1; mtime = ar_member_date (file->hname); } else #endif { mtime = name_mtime (file->name); if (mtime == (FILE_TIMESTAMP) -1 && search && !file->ignore_vpath) { /* If name_mtime failed, search VPATH. */ char *name = file->n=ame; if (vpath_search (&name, &mtime) /* Last resort, is it a library (-lxxx)? */ || (name[0] == '-' && name[1] == 'l' && library_search (&name, &mtime))) { if (mtime != 0) /* vpath_search and library_search store zero in MTIME if they didn't need to do a stat call for their work. */ file->last_mtime = mtime; /* If we found it in VPATH, see if it's in GPATH too; if so, change the name right now; if not, defer until after the dependencies are updated. */ if (gpath_search (name, strlen(name) - strlen(file->name) - 1)) { rename_file (file, name); check_renamed (file); return file_mtime (file); } rehash_file (file, name); check_renamed (file); mtime = name_mtime (name); } } } { /* Files can have bogus timestamps that nothing newly made will be "newer" than. Updating their dependents could just result in loops. So notify the user of the anomaly with a warning. We only need to do this once, for now. */ static FILE_TIMESTAMP now = 0; if (!clock_skew_detected && mtime != (FILE_TIMESTAMP)-1 && mtime > now && !file->updated) { /* This file's time appears to be in the future. Update our concept of the present, and compare again. */ now = file_timestamp_now (); #ifdef WINDOWS32 /* * FAT filesystems round time to nearest even second(!). Just * allow for any file (NTFS or FAT) to perhaps suffer from this * braindamage. */ if (mtime > now && (((mtime % 2) == 0) && ((mtime-1) > now))) #else #ifdef __MSDOS__ /* Scrupulous testing indicates that some Windows filesystems can set file times up to 3 sec into the future! */ if (mtime > now + 3) #else if (mtime > now) #endif #endif { char mtimebuf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; char nowbuf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; file_timestamp_sprintf (mtimebuf, mtime); file_timestamp_sprintf (nowbuf, now); error (NILF, _("*** Warning: File `%s' has modification time in the future (%s > %s)"), file->name, mtimebuf, nowbuf); clock_skew_detected = 1; } } } /* Store the mtime into all the entries for this file. */ if (file->double_colon) file = file->double_colon; do { /* If this file is not implicit but it is intermediate then it was made so by the .INTERMEDIATE target. If this file has never been built by us but was found now, it existed before make started. So, turn off the intermediate bit so make doesn't delete it, since it didn't create it. */ if (mtime != (FILE_TIMESTAMP)-1 && file->command_state == cs_not_started && !file->tried_implicit && file->intermediate) file->intermediate = 0; file->last_mtime = mtime; file = file->prev; } while (file != 0); return mtime; } /* Return the mtime of the file or archive-member reference NAME. */ static FILE_TIMESTAMP name_mtime (name) register char *name; { struct stat st; if (stat (name, &st) < 0) return (FILE_TIMESTAMP) -1; return FILE_TIMESTAMP_STAT_MODTIME (st); } /* Search for a library file specified as -lLIBNAME, searching for a suitable library file in the system library directories and the VPATH directories. */ static int library_search (lib, mtime_ptr) char **lib; FILE_TIMESTAMP *mtime_ptr; { static char *dirs[] = { #ifndeQ~MAKE-3_78_1HB.BCKc`[MAKE-3_78_1HB]REMAKE.C;1LUDf _AMIGA "/lib", "/usr/lib", #endif #if defined(WINDOWS32) && !defined(LIBDIR) /* * This is completely up to the user at product install time. Just define * a placeholder. */ #define LIBDIR "." #endif LIBDIR, /* Defined by configuration. */ 0 }; static char *libpatterns = NULL; char *libname = &(*lib)[2]; /* Name without the `-l'. */ FILE_TIMESTAMP mtime; /* Loop variables for the libpatterns value. */ char *p, *p2; int len; char *file, **dp; /* If weE don't have libpatterns, get it. */ if (!libpatterns) { int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; libpatterns = xstrdup (variable_expand ("$(strip $(.LIBPATTERNS))")); warn_undefined_variables_flag = save; } /* Loop through all the patterns in .LIBPATTERNS, and search on each one. */ p2 = libpatterns; while ((p = find_next_token (&p2, &len)) != 0) { static char *buf = NULL; static int buflen = 0; static int libdir_maxlen = -1; char *libbuf = variable_expand (""); /* Expand the pattern using LIBNAME as a replacement. */ { char c = p[len]; char *p3, *p4; p[len] = '\0'; p3 = find_percent (p); if (!p3) { /* Give a warning if there is no pattern, then remove the pattern so it's ignored next time. */ error (NILF, _(".LIBPATTERNS element `%s' is not a pattern"), p); for (; len; --len, ++p) *p = ' '; *p = c; continue; } p4 = variable_buffer_output (libbuf, p, p3-p); p4 = variable_buffer_output (p4, libname, strlen (libname)); p4 = variable_buffer_output (p4, p3+1, len - (p3-p)); p[len] = c; } /* Look first for `libNAME.a' in the current directory. */ mtime = name_mtime (libbuf); if (mtime != (FILE_TIMESTAMP) -1) { *lib = xstrdup (libbuf); if (mtime_ptr != 0) *mtime_ptr = mtime; return 1; } /* Now try VPATH search on that. */ file = libbuf; if (vpath_search (&file, mtime_ptr)) { *lib = file; return 1; } /* Now try the standard set of directories. */ if (!buflen) { for (dp = dirs; *dp != 0; ++dp) { int l = strlen (*dp); if (l > libdir_maxlen) libdir_maxlen = l; } buflen = strlen (libbuf); buf = xmalloc(libdir_maxlen + buflen + 2); } else if (buflen < strlen (libbuf)) { buflen = strlen (libbuf); buf = xrealloc (buf, libdir_maxlen + buflen + 2); } for (dp = dirs; *dp != 0; ++dp) { sprintf (buf, "%s/%s", I*dp, libbuf); mtime = name_mtime (buf); if (mtime != (FILE_TIMESTAMP) -1) { *lib = xstrdup (buf); if (mtime_ptr != 0) *mtime_ptr = mtime; return 1; } } } return 0; } b*[MAKE-3_78_1HB]REMOTE-CSTMS.C;1+,c./@ 4!-`0123KPWO56v7/m89G@HJ/* GNU Make remote job exportation interface to the Customs daemon. THIS CODE IS NOT SUPPORTED BY THE GNU PROJECT. Please do not send bug reports or questions about it to the Make maintainers. Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "job.h" #include "filedef.h" #include "commands.h" #include "job.h" #include #include #include "customs.h" char *remote_description = "Customs"; /* File name of the Customs `export' client command. A full path name can be used to avoid some path-searching overhead. */ #define EXPORT_COMMAND "/usr/local/bin/export" /* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */ static ExportPermit permit; /* Normalized path name of the current directory. */ static char *normalized_cwd; /* Call once at startup even if no commands are run. */ void remote_setup () { } /* Called before exit. */ void remote_cleanup () { } /* Return nonzero if the next job should be done remotely. */ int start_remote_job_p (first_p) int first_p; { static int inited = 0; int status; int njobs; if (!inited) { /* Allow the user to turn off job exportation (useful while he is debugging Customs, for example). */ if (getenv ("GNU_MAKE_NO_CUSTOMS") != 0) { inited = -1; return 0; } /* For secure Customs, make is installed setuid root and Customs requires a privileged source port be used. */ make_access (); if (debug_flag) Rpc_Debug(1); /* Ping the daemon once to see if it is there. */ inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1; /* Return to normal user access. */ user_access (); if (starting_directory == 0) /* main couldn't figure it out. */ inited = -1; else { /* Normalize the current directory path name to something that should work on all machines exported to. */ normalized_cwd = (char *) xmalloc (GET_PATH_MAX); strcpy (normalized_cwd, starting_directory); if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0) /* Path normalization failure means using Customs won't work, but it's not really an error. */ inited = -1; } } if (inited < 0) return 0; njobs = job_slots_used; if (!first_p) njobs -= 1; /* correction for being called from reap_children() */ /* the first job should run locally, or, if the -l flag is given, we use that as clue as to how many local jobs should be scheduled locally */ if (max_load_average < 0 && njobs == 0 || njobs < max_load_average) return 0; status = Customs_Host (EXPORT_SAME, &permit); if (status != RPC_SUCCESS) { if (debug_flag) printf ("Customs won't export: %s\n", Rpc_ErrorMessage (status)); return 0; } return !CUSTOMS_FAIL (&permit.addr); } /* Start a remote job running the command in ARGV, with environment from ENVP. It gets standard input from STDIN_FD. On failure, return nonzero. On success, return zero, and set *USED_STDIN to nonzero if it will actually use STDIN_FD, zero if not, set *ID_PTR to a unique identification, and set *IS_REMOTE to nonzero if the job is remote, zero if it is local (meaning *ID_PTR is a process ID). */ int start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin) char **argv, **envp; int stdin_fd; int *is_remote; int *id_ptr; int *used_stdin; { char waybill[MAX_DATA_SIZE], msg[128]; struct hostent *host; struct timeval timeout; struct sockaddr_in sin; int len; int retsock, retport, sock; Rpc_Stat status; int pid; /* Create the return socket. */ retsock = Rpc_UdpCreate (True, 0); if (retsock < 0) { error (NILF, "exporting: Couldn't create return socket."); return 1; } /* Get the return socket's port number. */ len = sizeof (sin); if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0) { (void) close (retsock); perror_with_name ("exporting: ", "getsockname"); return 1; } retport = sin.sin_port; /* Create the TCP socket for talking to the remote child. */ sock = Rpc_TcpCreate (False, 0); /* Create a WayBill to give to the server. */ len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv, envp, retport, waybill); /* Modify the waybill as if the remote child had done `child_access ()'. */ { WayBill *wb = (WayBill *) waybill; wb->ruid = wb->euid; wb->rgid = wb->egid; } /* Send the request to the server, timing out in 20 seconds. */ timeout.tv_usec = 0; timeout.tv_sec = 20; sin.sin_family = AF_INET; sin.sin_port = htons (Customs_Port ()); sin.sin_addr = permit.addr; status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT, len, (Rpc_Opaque) waybill, sizeof(msg), (Rpc_Opaque) msg, 1, &timeout); host = gethostbyaddr((char *)&permit.addr, sizeof(permit.addr), AF_INET); if (status != RPC_SUCCESS) { (void) close (retsock); (void) close (sock); error (NILF, "exporting to %s: %s", host ? host->h_name : inet_ntoa (permit.addr), Rpc_ErrorMessage (status)); return 1; } else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0') { (void) close (retsock); (void) close (sock); error (NILF, "exporti  ng to %s: %s", host ? host->h_name : inet_ntoa (permit.addr), msg); return 1; } else { error (NILF, "*** exported to %s (id %u)", host ? host->h_name : inet_ntoa (permit.addr), permit.id); } fflush (stdout); fflush (stderr); pid = vfork (); if (pid < 0) { /* The fork failed! */ perror_with_name ("vfork", ""); return 1; } else if (pid == 0) { /* Child side. Run `export' to handle the connection. */ static char sock_buf[20], retsock_buf[20], id_buf[20]; static char *new_argv[6] = { EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 }; /* Set up the arguments. */ (void) sprintf (sock_buf, "%d", sock); (void) sprintf (retsock_buf, "%d", retsock); (void) sprintf (id_buf, "%x", permit.id); /* Get the right stdin. */ if (stdin_fd != 0) (void) dup2 (stdin_fd, 0); /* Unblock signals in the child. */ unblock_sigs (); /* Run the command. */ exec_command (new_argv, envp); } /* Parent side. Return the `export' process's ID. */ (void) close (retsock); (void) close (sock); *is_remote = 0; *id_ptr = pid; *used_stdin = 1; return 0; } /* Get the status of a dead remote child. Block waiting for one to die if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR to the termination signal or zero if it exited normally, and *COREDUMP_PTR nonzero if it dumped core. Return the ID of the child that died, 0 if we would have to block and !BLOCK, or < 0 if there were none. */ int remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block) int *exit_code_ptr, *signal_ptr, *coredump_ptr; int block; { return -1; } /* Block asynchronous notification of remote child death. If this notification is done by raising the child termination signal, do not block that signal. */ void block_remote_children () { return; } /* Restore asynchronous notification of remote child death. If this is done by raising the child termination signal, do not unblock that signal. */ void unblock_remote_children () { return; } /* Send signal SIG to child ID. Return 0 if successful, -1 if not. */ int remote_kill (id, sig) int id; int sig; { return -1; } o*[MAKE-3_78_1HB]REMOTE-STUB.C;1+,c./@ 4-`0123KPWO 567>m89G@HJ /* Template for the remote job exportation interface to GNU Make. Copyright (C) 1988, 1989, 1992, 1993, 1996 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "filedef.h" #include "job.h" #include "commands.h" char *remote_description = 0; /* Call once at startup even if no commands are run. */ void remote_setup () { } /* Called before exit. */ void remote_cleanup () { } /* Return nonzero if the next job should be done remotely. */ int start_remote_job_p (first_p) int first_p; { return 0; } /* Start a remote job running the command in ARGV, with environment from ENVP. It gets standard input from STDIN_FD. On failure, return nonzero. On success, return zero, and set *USED_STDIN to nonzero if it will actually use STDIN_FD, zero if not, set *ID_PTR to a unique identification, and set *IS_REMOTE to zero if the job is local, nonzero if it is remote (meaning *ID_PTR is a process ID). */ int start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin) char **argv, **envp; int stdin_fd; int *is_remote; int *id_ptr; int *used_stdin; { return -1; } /* Get the status of a dead remote child. Block waiting for one to die if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR to the termination signal or zero if it exited normally, and *COREDUMP_PTR nonzero if it dumped core. Return the ID of the child that died, 0 if we would have to block and !BLOCK, or < 0 if there were none. */ int remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block) int *exit_code_ptr, *signal_ptr, *coredump_ptr; int block; { errno = ECHILD; return -1; } /* Block asynchronous notification of remote child death. If this notification is done by raising the child termination signal, do not block that signal. */ void block_remote_children () { return; } /* Restore asynchronous notification of remote child death. If this is done by raising the child termination signal, do not unblock that signal. */ void unblock_remote_children () { return; } /* Send signal SIG to child ID. Return 0 if successful, -1 if not. */ int remote_kill (id, sig) int id; int sig; { return -1; } *[MAKE-3_78_1HB]RULE.C;2+,e.(/@ 4O('+-`0123KPWO)56 NS7next; unsigned int ntargets; ++num_pattern_rules; ntargets = 0; while (rule->targets[ntargets] != 0) ++ntargets; if (ntargets > max_pattern_targets) max_pattern_targets = ntargets; for (dep = rule->deps; dep != 0; dep = dep->next) { unsigned int len = strlen (dep->name); #ifdef VMS char *p = rindex (dep->name, ']'); char *p2; if (p == 0) p = rindex (dep->name, ':'); p2 = p != 0 ? index (dep->name, '%') : 0; #else char *p = rindex (dep->name, '/'); char *p2 = p != 0 ? index (dep->name, '%') : 0; #endif ndeps++; if (len > max_pattern_dep_length) max_pattern_dep_length = len; if (p != 0 && p2 > p) { /* There is a slash before the % in the dep name. Extract the directory name. */ if (p == dep->name) ++p; if (p - dep->name > namelen) { if (name != 0) free (name); namelen = p - dep->name; name = (char *) xmalloc (namelen + 1); } bcopy (dep->name, name, p - dep->name); name[p - dep->name] = '\0'; /* In the deps of an implicit rule the `changed' flag actually indicates that the dependency is in a nonexistent subdirectory. */ dep->changed = !dir_file_exists_p (name, ""); #ifdef VMS if (dep->changed && index (name, ':') != 0) #else if (dep->changed && *name == '/') #endif { /* The name is absolute and the directory does not exist. This rule can never possibly match, since this dependency can never possibly exist. So just remove the rule from the list. */ freerule (rule, lastrule); --num_pattern_rules; goto end_main_loop; } } else /* This dependency does not reside in a subdirectory. */ dep->changed = 0; } if (ndeps > max_pattern_deps) max_pattern_deps = ndeps; lastrule = rule; end_main_loop: rule = next; } if (name != 0) free (name); } /* Create a pattern rule from a suffix rule. TARGET is the target suffix; SOURCE is the source suffix. CMDS are the commands. If TARGET is nil, it means the target pattern should be `(%.o)'. If SOURCE is nil, it means there should be no deps. */ static void convert_suffix_rule (target, source, cmds) char *target, *source; struct commands *cmds; { char *targname, *targpercent, *depname; char **names, **percents; struct dep *deps; unsigned int len; if (target == 0) /* Special case: TARGET being nil means we are defining a `.X.a' suffix rule; the target pattern is always `(%.o)'. */ { #ifdef VMS targname = savestring ("(%.obj)", 7); #else targname = savestring ("(%.o)", 5); #endif targpercent = targname + 1; } else { /* Construct the target name. */ len = strlen (target); targname = xmalloc (1 + len + 1); targname[0] = '%'; bcopy (target, targname + 1, len + 1); targpercent = targname; } names = (char **) xmalloc (2 * sizeof (char *)); percents = (char **) alloca (2 * sizeof (char *)); names[0] = targname; percents[0] = targpercent; names[1] = percents[1] = 0; if (source == 0) deps = 0; else { /* Construct the dependency name. */ len = strlen (source); depname = xmalloc (1 + len + 1); depname[0] = '%'; bcopy (source, depname + 1, len + 1); deps = (struct dep *) xmalloc (sizeof (struct dep)); deps->next = 0; deps->name = depname;  } create_pattern_rule (names, percents, 0, deps, cmds, 0); } /* Convert old-style suffix rules to pattern rules. All rules for the suffixes on the .SUFFIXES list are converted and added to the chain of pattern rules. */ void convert_to_pattern () { register struct dep *d, *d2; register struct file *f; register char *rulename; register unsigned int slen, s2len; /* Compute maximum length of all the suffixes. */ maxsuffix = 0; for (d = suffix_file->deps; d != 0; d = d->next) { register unsigned int namelen = strlen (dep_name (d)); if (namelen > maxsuffix) maxsuffix = namelen; } rulename = (char *) alloca ((maxsuffix * 2) + 1); for (d = suffix_file->deps; d != 0; d = d->next) { /* Make a rule that is just the suffix, with no deps or commands. This rule exists solely to disqualify match-anything rules. */ convert_suffix_rule (dep_name (d), (char *) 0, (struct commands *) 0); f = d->file; if (f->cmds != 0) /* Record a pattern for this suffix's null-suffix rule. */ convert_suffix_rule ("", dep_name (d), f->cmds); /* Record a pattern for each of this suffix's two-suffix rules. */ slen = strlen (dep_name (d)); bcopy (dep_name (d), rulename, slen); for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next) { s2len = strlen (dep_name (d2)); if (slen == s2len && streq (dep_name (d), dep_name (d2))) continue; bcopy (dep_name (d2), rulename + slen, s2len + 1); f = lookup_file (rulename); if (f == 0 || f->cmds == 0) continue; if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a') /* A suffix rule `.X.a:' generates the pattern rule `(%.o): %.X'. It also generates a normal `%.a: %.X' rule below. */ convert_suffix_rule ((char *) 0, /* Indicates `(%.o)'. */ dep_name (d), f->cmds); /* The suffix rule `.X.Y:' is converted to the pattern rule `%.Y: %.X'. */ convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds); } } } /* Install the pattern rule RULE (whose fields have been filled in) at the end of the list (so that any rules previously defined will take precedence). If this rule duplicates a previous one (identical target and dependencies), the old one is replaced if OVERRIDE is nonzero, otherwise this new one is thrown out. When an old rule is replaced, the new one is put at the end of the list. Return nonzero if RULE is used; zero if not. */ int new_pattern_rule (rule, override) register struct rule *rule; int override; { register struct rule *r, *lastrule; register unsigned int i, j; rule->in_use = 0; rule->terminal = 0; rule->next = 0; /* Search for an identical rule. */ lastrule = 0; for (r = pattern_rules; r != 0; lastrule = r, r = r->next) for (i = 0; rule->targets[i] != 0; ++i) { for (j = 0; r->targets[j] != 0; ++j) if (!streq (rule->targets[i], r->targets[j])) break; if (r->targets[j] == 0) /* All the targets matched. */ { register struct dep *d, *d2; for (d = rule->deps, d2 = r->deps; d != 0 && d2 != 0; d = d->next, d2 = d2->next) if (!streq (dep_name (d), dep_name (d2))) break; if (d == 0 && d2 == 0) { /* All the dependencies matched. */ if (override) { /* Remove the old rule. */ freerule (r, lastrule); /* Install the new one. */ if (pattern_rules == 0) pattern_rules = rule; else last_pattern_rule->next = rule; last_pattern_rule = rule; /* We got one. Stop looking. */ goto matched; } else { /* The old rule stays intact. Destroy the new one. */ freerule (rule, (struct rule *) 0); return 0; } } } } matched:; if (r == 0) { /* There was no rule to replace. */ if (pattern_rules == 0) pattern_rules = rule; else last_pattern_rule->next = rule; last_pattern_rule = rule; } return 1; } /* Install an implicit pattern rule based on the three text strings in the structure P points to. These strings come from one of the arrays of default implicit pattern rules. TERMINAL specifies what the `terminal' field of the rule should be. */ void install_pattern_rule (p, terminal) struct pspec *p; int terminal; { register struct rule *r; char *ptr; r = (struct rule *) xmalloc (sizeof (struct rule)); r->targets = (char **) xmalloc (2 * sizeof (char *)); r->suffixes = (char **) xmalloc (2 * sizeof (char *)); r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); r->targets[1] = 0; r->suffixes[1] = 0; r->lens[1] = 0; r->lens[0] = strlen (p->target); /* These will all be string literals, but we malloc space for them anyway because somebody might want to free them later on. */ r->targets[0] = savestring (p->target, r->lens[0]); r->suffixes[0] = find_percent (r->targets[0]); if (r->suffixes[0] == 0) /* Programmer-out-to-lunch error. */ abort (); else ++r->suffixes[0]; ptr = p->dep; r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0', sizeof (struct dep), 1), sizeof (struct dep)); if (new_pattern_rule (r, 0)) { r->terminal = terminal; r->cmds = (struct commands *) xmalloc (sizeof (struct commands)); r->cmds->fileinfo.filenm = 0; r->cmds->fileinfo.lineno = 0; /* These will all be string literals, but we malloc space for them anyway because somebody might want to free them later. */ r->cmds->commands = xstrdup (p->commands); r->cmds->command_lines = 0; } } /* Free all the storage used in RULE and take it out of the pattern_rules chain. LASTRULE is the rule whose next pointer points to RULE. */ static void freerule (rule, lastrule) register struct rule *rule, *lastrule; { struct rule *next = rule->next; register unsigned int i; register struct dep *dep; for (i = 0; rule->targets[i] != 0; ++i) free (rule->targets[i]); dep = rule->deps; while (dep) { struct dep *t; t = dep->next; /* We might leak dep->name here, but I'm not sure how to fix this: I think that pointer might be shared (e.g., in the file hash?) */ free ((char *) dep); dep = t; } free ((char *) rule->targets); free ((char *) rule->suffixes); free ((char *) rule->lens); /* We can't free the storage for the commands because there are ways that they could be in more than one place: * If the commands came from a suffix rule, they could also be in the `struct file's for other suffix rules or plain targets given on the same makefile line. * If two suffixes that together make a two-suffix rule were each given twice in the .SUFFIXES list, and in the proper order, two identical pattern rules would be created and the second one would be discarded here, but both would contain the same `struct commands' pointer from the `struct file' for the suffix rule. */ free ((char *) rule); if (pattern_rules == rule) if (lastrule != 0) abort (); else pattern_rules = next; else if (lastrule != 0) lastrule->next = next; if (last_pattern_rule == rule) last_pattern_rule = lastrule; } /* Create a new pattern rule with the targets in the nil-terminated array TARGETS. If TARGET_PERCENTS is not nil, it is an array of pointers into the elements of TARGETS, where the `%'s are. The new rule has dependencies DEPS and commands from COMMANDS. It is a terminal rule if TERMINAL is nonzero. This rule overrides identical rules with different commands if OVERRIDE is nonzero. The storage for TARGETS and its elements is used and must not be freed until the rule is destroyed. The storage for TARGET_PERCENTS is not used; it may be freed. */ void create_pattern_rule (targets, target_percents, terminal, deps, commands, override) char **targets, **target_percents; int terminal; struct dep *deps; struct commands *commands; int override; { register struct rule *r = (struct rule *) xmalloc (sizeof (struct rule)); register unsigned int max_targets, i; r->cmds = commands; r->deps = deps; r->targets = targets; max_targets = 2; r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); r->suffixes = (char **) xmalloc (2 * sizeof (char *)); for (i = 0; targets[i] != 0; ++i) { if (i == max_targets - 1) { max_targets += 5; r->lens = (unsigned int *) xrealloc ((char *) r->lens, max_targets * sizeof (unsigned int)); r->suffixes = (char **) xrealloc ((char *) r->suffixes, max_targets * sizeof (char *)); } r->lens[i] = strlen (targets[i]); r->suffixes[i] = (target_percents == 0 ? find_percent (targets[i]) : target_percents[i]) + 1; if (r->suffixes[i] == 0) abort (); } if (i < max_targets - 1) { r->lens = (unsigned int *) xrealloc ((char *) r->lens, (i + 1) * sizeof (unsigned int)); r->suffixes = (char **) xrealloc ((char *) r->suffixes, (i + 1) * sizeof (char *)); } if (new_pattern_rule (r, override)) r->terminal = terminal; } /* Create a new pattern-specific variable struct. */ struct pattern_var * create_pattern_var (target, suffix) char *target, *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)) `R~MAKE-3_78_1HB.BCKe`[MAKE-3_78_1HB]RULE.C;2O(t 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 (target!) 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 use 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. */ print_rule (r) struct rule *r; { register unsigned int i; register struct dep *d; for (i = 0; r->targets[i] != 0; ++i) { fputs (r->targets[i], stdout); if (r->targets[i + 1] != 0) putchar (' '); else putchar (':'); } if (r->terminal) putchar (':'); for (d = r->deps; d != 0; d = d->next) printf (" %s", dep_name (d)); putchar ('\n'); if (r->cmds != 0) print_commands (r->cmds); } void print_rule_data_base () { register unsigned int rules, terminal; register struct rule *r; puts ("\n# Implicit Rules"); rules = terminal = 0; for (r = pattern_rules; r != 0; r = r->next) { ++rules; putchar ('\n'); print_rule (r); if (r->terminal) ++terminal; } if (rules == 0) puts (_("\n# No implicit rules.")); else { printf (_("\n# %u implicit rules, %u"), rules, terminal); #ifndef NO_FLOAT printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0); #else { int f = (terminal * 1000 + 5) / rules; printf (" (%d.%d%%)", f/10, f%10); } #endif puts (_(" terminal.")); } if (num_pattern_rules != rules) { /* This can happen if a fatal error was detected while reading the makefiles and thus count_implicit_rule_limits wasn't called yet. */ if (num_pattern_rules != 0) 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); } } } *[MAKE-3_78_1HB]RULE.H;1+,c./@ 4/-`0123KPWO 567>o]m89G@HJ /* Definitions for using pattern rules in GNU Make. Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Structure used for pattern rules. */ struct rule { struct rule *next; char **targets; /* Targets of the rule. */ unsigned int *lens; /* Lengths of each target. */ char **suffixes; /* Suffixes (after `%') of each target. */ struct dep *deps; /* Dependencies of the rule. */ struct commands *cmds; /* Commands to execute. */ char terminal; /* If terminal (double-colon). */ 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 { char *target, *dep, *commands; }; extern struct rule *pattern_rules; extern struct rule *last_pattern_rule; extern unsigned int num_pattern_rules; extern unsigned int max_pattern_deps; extern unsigned int max_pattern_targets; extern unsigned int max_pattern_dep_length; extern struct file *suffix_file; 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, char **target_percents, int terminal, struct dep *deps, struct commands *commands, int override)); *[MAKE-3_78_1HB]SCOPTIONS.;1+,c./@ 4-`0123KPWO56|7lm89G@HJERRORREXX OPTIMIZE NOVERSION OPTIMIZERTIME OPTIMIZERALIAS DEFINE INCLUDEDIR="include:" DEFINE LIBDIR="lib:" DEFINE NO_ALLOCA DEFINE NO_FLOAT DEFINE NO_ARCHIVES IGNORE=161 IGNORE=100 STARTUP=cres *[MAKE-3_78_1HB]SIGNAME.C;1+,c./@ 4a-`0123KPWO56t7{m89G@HJ"/* Convert between signal names and numbers. Copyright (C) 1990, 1992, 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include #include /* Some systems need this for . */ #include #ifdef HAVE_STRING_H #include #endif /* Some systems declare `sys_siglist in ; if configure defined SYS_SIGLIST_DECLARED, it may expect to find the declaration there. */ #ifdef HAVE_UNISTD_H #include #endif /* Some systems do not define NSIG in . */ #ifndef NSIG #ifdef _NSIG #define NSIG _NSIG #else #define NSIG 32 #endif #endif #if !__STDC__ #define const #endif #include "signame.h" #ifndef HAVE_SYS_SIGLIST /* There is too much variation in Sys V signal numbers and names, so we must initialize them at runtime. */ static const char *undoc; const char *sys_siglist[NSIG]; #else /* HAVE_SYS_SIGLIST. */ #ifndef SYS_SIGLIST_DECLARED extern char *sys_siglist[]; #endif /* Not SYS_SIGLIST_DECLARED. */ #endif /* Not HAVE_SYS_SIGLIST. */ /* Table of abbreviations for signals. Note: A given number can appear more than once with different abbreviations. */ #define SIG_TABLE_SIZE (NSIG*2) typedef struct { int number; const char *abbrev; } num_abbrev; static num_abbrev sig_table[SIG_TABLE_SIZE]; /* Number of elements of sig_table used. */ static int sig_table_nelts = 0; /* Enter signal number NUMBER into the tables with ABBREV and NAME. */ static void init_sig (number, abbrev, name) int number; const char *abbrev; const char *name; { #ifndef HAVE_SYS_SIGLIST /* If this value is ever greater than NSIG it seems like it'd be a bug in the system headers, but... better safe than sorry. We know, for example, that this isn't always true on VMS. */ if (number >= 0 && number < NSIG) sys_siglist[number] = name; #endif if (sig_table_nelts < SIG_TABLE_SIZE) { sig_table[sig_table_nelts].number = number; sig_table[sig_table_nelts++].abbrev = abbrev; } } void signame_init () { #ifndef HAVE_SYS_SIGLIST int i; char *u = _("unknown signal"); undoc = xstrdup(u); /* Initialize signal names. */ for (i = 0; i < NSIG; i++) sys_siglist[i] = undoc; #endif /* !HAVE_SYS_SIGLIST */ /* Initialize signal names. */ #if defined (SIGHUP) init_sig (SIGHUP, "HUP", _("Hangup")); #endif #if defined (SIGINT) init_sig (SIGINT, "INT", _("Interrupt")); #endif #if defined (SIGQUIT) init_sig (SIGQUIT, "QUIT", _("Quit")); #endif #if defined (SIGILL) init_sig (SIGILL, "ILL", _("Illegal Instruction")); #endif #if defined (SIGTRAP) init_sig (SIGTRAP, "TRAP", _("Trace/breakpoint trap")); #endif /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */ #if defined (SIGABRT) init_sig (SIGABRT, "ABRT", _("Aborted")); #endif #if defined (SIGIOT) init_sig (SIGIOT, "IOT", _("IOT trap")); #endif #if defined (SIGEMT) init_sig (SIGEMT, "EMT", _("EMT trap")); #endif #if defined (SIGFPE) init_sig (SIGFPE, "FPE", _("Floating point exception")); #endif #if defined (SIGKILL) init_sig (SIGKILL, "KILL", _("Killed")); #endif #if defined (SIGBUS) init_sig (SIGBUS, "BUS", _("Bus error")); #endif #if defined (SIGSEGV) init_sig (SIGSEGV, "SEGV", _("Segmentation fault")); #endif #if defined (SIGSYS) init_sig (SIGSYS, "SYS", _("Bad system call")); #endif #if defined (SIGPIPE) init_sig (SIGPIPE, "PIPE", _("Broken pipe")); #endif #if defined (SIGALRM) init_sig (SIGALRM, "ALRM", _("Alarm clock")); #endif #if defined (SIGTERM) init_sig (SIGTERM, "TERM", _("Terminated")); #endif #if defined (SIGUSR1) init_sig (SIGUSR1, "USR1", _("User defined signal 1")); #endif #if defined (SIGUSR2) init_sig (SIGUSR2, "USR2", _("User defined signal 2")); #endif /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that is what is in POSIX.1. */ #if defined (SIGCHLD) init_sig (SIGCHLD, "CHLD", _("Child exited")); #endif #if defined (SIGCLD) init_sig (SIGCLD, "CLD", _("Child exited")); #endif #if defined (SIGPWR) init_sig (SIGPWR, "PWR", _("Power failure")); #endif #if defined (SIGTSTP) init_sig (SIGTSTP, "TSTP", _("Stopped")); #endif #if defined (SIGTTIN) init_sig (SIGTTIN, "TTIN", _("Stopped (tty input)")); #endif #if defined (SIGTTOU) init_sig (SIGTTOU, "TTOU", _("Stopped (tty output)")); #endif #if defined (SIGSTOP) init_sig (SIGSTOP, "STOP", _("Stopped (signal)")); #endif #if defined (SIGXCPU) init_sig (SIGXCPU, "XCPU", _("CPU time limit exceeded")); #endif #if defined (SIGXFSZ) init_sig (SIGXFSZ, "XFSZ", _("File size limit exceeded")); #endif #if defined (SIGVTALRM) init_sig (SIGVTALRM, "VTALRM", _("Virtual timer expired")); #endif #if defined (SIGPROF) init_sig (SIGPROF, "PROF", _("Profiling timer expired")); #endif #if defined (SIGWINCH) /* "Window size changed" might be more accurate, but even if that is all that it means now, perhaps in the future it will be extended to cover other kinds of window changes. */ init_sig (SIGWINCH, "WINCH", _("Window changed")); #endif #if defined (SIGCONT) init_sig (SIGCONT, "CONT", _("Continued")); #endif #if defined (SIGURG) init_sig (SIGURG, "URG", _("Urgent I/O condition")); #endif #if defined (SIGIO) /* "I/O pending" has also been suggested. A disadvantage is that signal only happens when the process has asked for it, not everytime I/O is pending. Another disadvantage is the confusion from giving it a different name than under Unix. */ init_sig (SIGIO, "IO", _("I/O possible")); #endif #if defined (SIGWIND) init_sig (SIGWIND, "WIND", _("SIGWIND")); #endif #if defined (SIGPHONE) init_sig (SIGPHONE, "PHONE", _("SIGPHONE")); #endif #if defined (SIGPOLL) init_sig (SIGPOLL, "POLL", _("I/O possible")); #endif #if defined (SIGLOST) init_sig (SIGLOST, "LOST", _("Resource lost")); #endif #if defined (SIGDANGER) init_sig (SIGDANGER, "DANGER", _("Danger signal")); #endif #if defined (SIGINFO) init_sig (SIGINFO, "INFO", _("Information request")); #endif #if defined (SIGNOFP) init_sig (SIGNOFP, "NOFP", _("Floating point co-processor not available")); #endif } /* Return the abbreviation for signal NUMBER. */ char * sig_abbrev (number) int number; { int i; if (sig_table_nelts == 0) signame_init (); for (i = 0; i < sig_table_nelts; i++) if (sig_table[i].number == number) return (char *)sig_table[i].abbrev; return NULL; } /* Return the signal number for an ABBREV, or -1 if there is no signal by that name. */ int sig_number (abbrev) const char *abbrev; { int i; if (sig_table_nelts == 0) signame_init (); /* Skip over "SIG" if present. */ if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G') abbrev += 3; for (i = 0; i < sig_table_nelts; i++) if (abbrev[0] == sig_table[i].abbrev[0] && strcmp (abbrev, sig_table[i].abbrev) == 0) return sig_table[i].number; return -1; } #ifndef HAVE_PSIGNAL /* Print to standard error the name of SIGNAL, preceded by MESSAGE and a colon, and followed by a newline. */ void psignal (signal, message) int signal; const char *message; { if (signal <= 0 || signal >= NSIG) fprintf (stderr, "%s: unknown signal", message); else fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]); } #endif #ifndef HAVE_STRSIGNAL /* Return the string associated with the signal number. */ char * strsignal (signal) int signal; { static char buf[] = "Signal 12345678901234567890"; if (signal > 0 || signal < NSIG) return (char *) sys_siglist[signal]; sprintf (buf, "Signal %d", signal); return buf; } #endif s*[MAKE-3_78_1HB]SIGNAME.H;1+,c./@ 4W-`0123KPWO 567m89G@HJ /* Convert between signal names and numbers. Copyright (C) 1990, 1992, 1993, 1995, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if defined (__STDC__) && __STDC__ /* Initialize `sys_siglist'. */ void signame_init (void); /* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER. Do not return this as a const char *. The caller might want to assign it to a char *. */ char *sig_abbrev (int number); /* Return the signal number for an ABBREV, or -1 if there is no signal by that name. */ int sig_number (const char *abbrev); /* Avoid conflicts with a system header file that might define these three. */ #ifndef HAVE_PSIGNAL /* Print to standard error the name of SIGNAL, preceded by MESSAGE and a colon, and followed by a newline. */ void psignal (int signal, const char *message); #endif #ifndef HAVE_STRSIGNAL /* Return the name of SIGNAL. */ char *strsignal (int signal); #endif #if !defined (HAVE_SYS_SIGLIST) /* Names for signals from 0 to NSIG-1. */ extern const char *sys_siglist[]; #endif #else void signame_init (); char *sig_abbrev (); int sig_number (); #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_PSIGNAL) void psignal (); #endif #ifndef HAVE_STRSIGNAL char *strsignal (); #endif #if !defined (HAVE_SYS_SIGLIST) extern char *sys_siglist[]; #endif #endif h*[MAKE-3_78_1HB]SMAKEFILE.;1+,c./@ 4-`0123KPWO567jm89G@HJ"# NOTE: If you have no `make' program at all to process this makefile, run # `build.sh' instead. # # Copyright (C) 1988, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Make is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Makefile for GNU Make # # Ultrix 2.2 make doesn't expand the value of VPATH. VPATH = /make-3.78.1/ # This must repeat the value, because configure will remove `VPATH = .'. srcdir = /make-3.78.1/ CC = sc RM = delete MAKE = smake CFLAGS = CPPFLAGS = LDFLAGS = # Define these for your system as follows: # -DNO_ARCHIVES To disable `ar' archive support. # -DNO_FLOAT To avoid using floating-point numbers. # -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2. # Some compilers apparently accept this # without complaint but produce losing code, # so beware. # NeXT 1.0a uses an old version of GCC, which required -D__inline=inline. # See also `config.h'. defines = # Which flavor of remote job execution support to use. # The code is found in `remote-$(REMOTE).c'. REMOTE = stub # If you are using the GNU C library, or have the GNU getopt functions in # your C library, you can comment these out. GETOPT = getopt.o getopt1.o GETOPT_SRC = $(srcdir)getopt.c $(srcdir)getopt1.c $(srcdir)getopt.h # If you are using the GNU C library, or have the GNU glob functions in # your C library, you can comment this out. GNU make uses special hooks # into the glob functions to be more efficient (by using make's directory # cache for globbing), so you must use the GNU functions even if your # system's C library has the 1003.2 glob functions already. Also, the glob # functions in the AIX and HPUX C libraries are said to be buggy. GLOB = Lib glob/glob.lib # If your system doesn't have alloca, or the one provided is bad, define this. ALLOCA = alloca.o ALLOCA_SRC = $(srcdir)alloca.c # If your system needs extra libraries loaded in, define them here. # System V probably need -lPW for alloca. HP-UX 7.0's alloca in # libPW.a is broken on HP9000s300 and HP9000s400 machines. Use # alloca.c instead on those machines. LOADLIBES = # Any extra object files your system needs. extras = amiga.o # Common prefix for machine-independent installed files. prefix = # Common prefix for machine-dependent installed files. exec_prefix = # Directory to install `make' in. bindir = sc:c # Directory to find libraries in for `-lXXX'. libdir = lib: # Directory to search by default for included makefiles. includedir = include: # Directory to install the Info files in. infodir = doc: # Directory to install the man page in. mandir = t: # Number to put on the man page filename. manext = 1 # Prefix to put on installed `make' binary file name. binprefix = # Prefix to put on installed `make' man page file name. manprefix = $(binprefix) # Whether or not make needs to be installed setgid. # The value should be either `true' or `false'. # On many systems, the getloadavg function (used to implement the `-l' # switch) will not work unless make is installed setgid kmem. install_setgid = false # Install make setgid to this group so it can read /dev/kmem. group = sys # Program to install `make'. INSTALL_PROGRAM = copy # Program to install the man page. INSTALL_DATA = copy # Generic install program. INSTALL = copy # Program to format Texinfo source into Info files. MAKEINFO = makeinfo # Program to format Texinfo source into DVI files. TEXI2DVI = texi2dvi # Programs to make tags files. ETAGS = etags -w CTAGS = ctags -w objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ rule.o implicit.o default.o variable.o expand.o function.o \ vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \ $(GLOB) $(GETOPT) $(ALLOCA) $(extras) srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \ $(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \ $(srcdir)main.c $(srcdir)read.c $(srcdir)remake.c \ $(srcdir)rule.c $(srcdir)implicit.c $(srcdir)default.c \ $(srcdir)variable.c $(srcdir)expand.c $(srcdir)function.c \ $(srcdir)vpath.c $(srcdir)version.c \ $(srcdir)remote-$(REMOTE).c \ $(srcdir)ar.c $(srcdir)arscan.c \ $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ $(srcdir)commands.h $(srcdir)dep.h $(srcdir)file.h \ $(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in .SUFFIXES: .SUFFIXES: .o .c .h .ps .dvi .info .texinfo all: make info: make.info dvi: make.dvi # Some makes apparently use .PHONY as the default goal if it is before `all'. .PHONY: all check info dvi make.info: make.texinfo $(MAKEINFO) -I$(srcdir) $(srcdir)make.texinfo -o make.info make.dvi: make.texinfo $(TEXI2DVI) $(srcdir)make.texinfo make.ps: make.dvi dvi2ps make.dvi > make.ps make: $(objs) glob/glob.lib $(CC) Link $(LDFLAGS) $(objs) $(LOADLIBES) To make.new -delete quiet make rename make.new make # -I. is needed to find config.h in the build directory. .c.o: $(CC) $(defines) IDir "" IDir $(srcdir)glob \ $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) glob/glob.lib: execute << cd glob smake < tagsrcs = $(srcs) $(srcdir)remote-*.c TAGS: $(tagsrcs) $(ETAGS) $(tagsrcs) tags: $(tagsrcs) $(CTAGS) $(tagsrcs) .PHONY: install installdirs install: copy make sc:c loadavg: loadavg.c config.h $(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \ loadavg.c $(LOADLIBES) -o $@ clean: glob-clean -$(RM) -f make loadavg *.o core make.dvi distclean: clean glob-realclean -$(RM) -f Makefile config.h config.status build.sh -$(RM) -f config.log config.cache -$(RM) -f TAGS tags -$(RM) -f make.?? make.??s make.log make.toc make.*aux -$(RM) -f loadavg.c realclean: distclean -$(RM) -f make.info* mostlyclean: clean .PHONY: glob-clean glob-realclean glob-clean glob-realclean: execute << cd glob smake $@ < # --------------- DEPENDENCIES # alloca.o: alloca.c config.h ar.o: ar.c make.h config.h signame.h filedef.h dep.h glob/fnmatch.h arscan.o: arscan.c make.h config.h signame.h commands.o: commands.c make.h config.h signame.h dep.h filedef.h \ variable.h job.h commands.h default.o: default.c make.h config.h signame.h rule.h dep.h filedef.h \ job.h commands.h variable.h dir.o: dir.c make.h config.h signame.h glob/glob.h expand.o: expand.c make.h config.h signame.h filedef.h job.h commands.h \ variable.h rule.h file.o: file.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h function.o: function.c make.h config.h signame.h filedef.h variable.h \ dep.h job.h commands.h getloadavg.o: getloadavg.c config.h getopt.o: getopt.c config.h getopt.h getopt1.o: getopt1.c config.h getopt.h implicit.o: implicit.c make.h config.h signame.h rule.h dep.h filedef.h job.o: job.c make.h config.h signame.h job.h filedef.h commands.h \ variable.h main.o: main.c make.h config.h signame.h dep.h filedef.h variable.h \ job.h commands.h rule.h getopt.h misc.o: misc.c make.h config.h signame.h dep.h read.o: read.c make.h config.h signame.h glob/glob.h dep.h filedef.h \ job.h commands.h variable.h rule.h remake.o: remake.c make.h config.h signame.h filedef.h job.h commands.h \ dep.h variable.h remote-stub.o: remote-stub.c make.h config.h signame.h filedef.h job.h \ commands.h rule.o: rule.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h rule.h signame.o: signame.c make.h config.h signame.h variable.o: variable.c make.h config.h signame.h dep.h filedef.h job.h \ commands.h variable.h version.o: version.c config.h vpath.o: vpath.c make.h config.h signame.h filedef.h variable.h h*[MAKE-3_78_1HB]STAMP-H.IN;1+,c./@ 4 -`0123KPWO56Wڤ7xm89G@HJtimestamp *[MAKE-3_78_1HB]SUBPROC.BAT;1+,c./@ 4j-`0123KPWO56η73÷m89G@HJcd w32\subproc set MAKE=%2 set MAKEFILE=%1 if x%2 == x set MAKE=nmake %MAKE% /f %MAKEFILE% cd ..\.. *[MAKE-3_78_1HB]TESTS.DIR;1+,c./@ 4-`0123 KPWO56$7r;շm89G@HJI CHANGELOG.cCOPYING.c MKSHADOW.cNEWS.cREADME.cRUN_MAKE_TESTS.cRUN_MAKE_TESTS.PLe+ SCRIPTS.DIRcTEST_DRIVER.PL2dWORK.DIRf !*[MAKE-3_78_1HB.TESTS]CHANGELOG.;1+,c./@ 4d-c0123KPWO 56(7m89G@HJPS~MAKE-3_78_1HB.BCKcc![MAKE-3_78_1HB.TESTS]CHANGELOG.;1 1999-09-23 Paul D. Smith * scripts/features/parallelism: Add a check to ensure that the jobserver works when we re-invoke. Also cleaned up the tests a little, reducing the number of rules we use so the test won't need as many "sleep" commands. 1999-09-16 Paul D. Smith * scripts/features/reinvoke: Remove invocations of "touch" in makefiles. See the comments on the touch function rewrite below. Note that UNIX touch behaves the same way if the file already exists: it sets the time to the _local_ time. We don't want this. This is probably a good tip for makefile writers in general, actually... where practical. * scripts/options/dash-l: Ditto. * scripts/options/dash-n: Ditto. * test_driver.pl (run_each_test): In retrospect, I don't like the .lN/.bN/.dN postfix required by DOS. So, for non-DOS systems I changed it back to use .log, .base, and .diff. * run_make_tests.pl (set_more_defaults): Move the check for the make pathname to here from set_defaults (that's too early since it happens before the command line processing). Create a new variable $port_type, calculated from $osname, to specify what kind of system we're running on. We should integrate the VOS stuff here, too. (valid_option): Comment out the workdir/-work stuff so people won't be fooled into thinking it works... someone needs to fix this, though! * scripts/functions/origin: Use $port_type instead of $osname. * scripts/functions/foreach: Ditto. * scripts/features/default_names: Ditto. 1999-09-15 Paul D. Smith * test_driver.pl (touch): Rewrite this function. Previously it used to use utime() to hard-set the time based on the current local clock, or, if the file didn't exist, it merely created it. This mirrors exactly what real UNIX touch does, but it fails badly on networked filesystems where the FS server clock is skewed from the local clock: normally modifying a file causes it to get a mod time based on the _server's_ clock. Hard-setting it based on the _local_ clock causes gratuitous errors and makes the tests unreliable except on local filesystems. The new function will simply modify the file, allowing the filesystem to set the mod time as it sees fit. * scripts/features/parallelism: The second test output could change depending on how fast some scripts completed; use "sleep" to force the order we want. * test_driver.pl (toplevel): A bug in Perl 5.000 to Perl 5.004 means that "%ENV = ();" doesn't do the right thing. This worked in Perl 4 and was fixed in Perl 5.004_01, but use a loop to delete the environment rather than require specific versions. * run_make_tests.pl (set_more_defaults): Don't use Perl 5 s/// modifier "s", so the tests will run with Perl 4. (set_more_defaults): Set $pure_log to empty if there's no -logfile option in PURIFYOPTIONS. (setup_for_test): Don't remove any logs unless $pure_log is set. 1999-09-15 Eli Zaretskii * scripts/features/reinvoke: Put the SHELL definition in the right test makefile. 1999-09-15 Paul D. Smith ChangeLog file for the test suite created. *[MAKE-3_78_1HB.TESTS]COPYING.;1+,c.$/@ 4$$>-c0123KPWO%56 .7m89G@HJ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribut e them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an exe(cutable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.  *[MAKE-3_78_1HB.TESTS]MKSHADOW.;1+,c./@ 4-c0123KPWO56,7rm89G@HJ#!/bin/sh # # Simple script to make a "shadow" test directory, using symbolic links. # Typically you'd put the shadow in /tmp or another local disk # case "$1" in "") echo 'Usage: mkshadow '; exit 1 ;; esac dest="$1" if [ ! -d "$dest" ]; then echo "Destination directory \`$dest' must exist!" exit 1 fi if [ ! -f run_make_tests ]; then echo "The current directory doesn't appear to contain the test suite!" exit 1 fi suite=`pwd | sed 's%^/tmp_mnt%%'` name=`basename "$suite"` files=`echo *` set -e mkdir "$dest/$name" cd "$dest/$name" ln -s "$suite" .testdir for f in $files; do ln -s .testdir/$f . done rm -rf work echo "Shadow test suite created in \`$dest/$name'." exit 0 *[MAKE-3_78_1HB.TESTS]NEWS.;1+,c. /@ 4 e-c0123KPWO 56o70*m89G@HJChanges from 0.4.9 to 3.78 (Sep 6, 1999): Lots of new tests. Renamed to follow the GNU make scheme. Also added some support for using Purify with make. Rob Tulloh contributed some changes to get the test suite running on NT; I tweaked them a bit (hopefully I didn't break anything!) Note that NT doesn't grok the self-exec funkiness that Unix shells use, so instead I broke that out into a separate shell script "run_make_tests" that invokes perl with the (renamed) script run_make_tests.pl. Eli Zaretski contributed changes to get the test suite running on DOS with DJGPP. I also meddled in these somewhat. If you're on DOS or NT you should run "perl.exe run_make_tests.pl ..." If you're on Unix, you can continue to run "./run_make_tests ..." as before. Changes from 0.4.8 to 0.4.9 (May 14, 1998): Release by Paul D. Smith ; I'm the one to blame for problems in this version :). Add some perl to test_driver.pl to strip out GNU make clock skew warning messages from the output before comparing it to the known-good output. A new test for escaped :'s in filenames (someone on VMS found this didn't work anymore in 3.77): scripts/features/escape. Changes from 0.4.7 to 0.4.8 (May 14, 1998): Release by Paul D. Smith ; I'm the one to blame for problems in this version :). New tests for features to be included in GNU make 3.77. Changes from 0.4.6 to 0.4.7 (August 18, 1997): Release by Paul D. Smith ; I'm the one to blame for problems in this version :). Reworked some tests to make sure they all work with both perl4 and perl5. Work around a bug in perl 5.004 which doesn't clean the environment correctly in all cases (fixed in at least 5.004_02). Updated functions/strip to test for newline stripping. Keep a $PURIFYOPTIONS env variable if present. Changes from 0.4.5 to 0.4.6 (April 07, 1997): Release by Paul D. Smith ; I'm the one to blame for problems in this version :). Updated to work with GNU make 3.76 (and pretests). Added new tests and updated existing ones. Note that the new tests weren't tested with perl 4, however I think they should work. Ignore any tests whose filenames end in "~", so that Emacs backup files aren't run. Changes from 0.4.4 to 0.4.5 (April 29, 1995): Updated to be compatible with perl 5.001 as well as 4.036. Note: the test suite still won't work on 14-char filesystems (sorry, Kaveh), but I will get to it. Also, some tests and stuff still haven't made it in because I haven't had time to write the test scripts for them. But they, too, will get in eventually. Contributions of scripts (ie, tests that I can just drop in) are particularly welcome and will be incorporated immediately. Changes from 0.4.3 to 0.4.4 (March 1995): Updated for changes in make 3.72.12, and to ignore CVS directories (thanks go to Jim Meyering for the patches for this). Fixed uname call to not make a mess on BSD/OS 2.0 (whose uname -a is very verbose). Let me know if this doesn't work correctly on your system. Changed to display test name while it is running, not just when it finishes. Note: the test suite still won't work on 14-char filesystems (sorry, Kaveh), but I will get to it. Also, some tests and stuff still haven't made it in because I haven't had time to write the test scripts for them. But they, too, will get in eventually. Changes from 0.4 to 0.4.3 (October 1994): Fixed bugs (like dependencies on environment variables). Caught up with changes in make. The load_limit test should now silently ignore a failure due to make not being able to read /dev/kmem. Reorganized tests into subdirs and renamed lots of things so that those poor souls who still have to deal with 14-char filename limits won't hate me any more. Thanks very much to Kaveh R. Ghazi for helping me with the implementation and testing of these changes, and for putting up with all my whining about it... Added a $| = 1 so that systems that don't seem to automatically flush their output for some reason will still print all the output. I'd hate for someone to miss out on the smiley that you're supposed to get when all the tests pass... :-) Changes from 0.3 to 0.4 (August 1993): Lost in the mists of time (and my hurry to get it out before I left my job). Changes from 0.2 to 0.3 (9-30-92): Several tests fixed to match the fact that MAKELEVEL > 0 or -C now imply -w. parallel_execution test fixed to not use double colon rules any more since their behavior has changed. errors_in_commands test fixed to handle different error messages and return codes from rm. Several tests fixed to handle -make_path with a relative path and/or a name other than "make" for make. dash-e-option test fixed to use $PATH instead of $USER (since the latter does not exist on some System V systems). This also removes the dependency on getlogin (which fails under certain weird conditions). test_driver_core changed so that you can give a test name like scripts/errors_in_commands and it will be handled correctly (handy if you have a shell with filename completion). Changes from 0.1 to 0.2 (5-4-92): README corrected to require perl 4.019, not 4.010. -make_path replaces -old. errors_in_commands test updated for change in format introduced in make 3.62.6. test_driver_core now uses a better way of figuring what OS it is running on (thanks to meyering@cs.utexas.edu (Jim Meyering) for suggesting this, as well as discovering the hard way that the old way (testing for /mnt) fails on his machine). Some new tests were added. m*[MAKE-3_78_1HB.TESTS]README.;1+,c./@ 4-c0123KPWO 56 17m89G@HJThis is release 3.78 (September 6, 1999) of the GNU make test suite. See the file NEWS for some of the changes since the last release. This release is made by psmith@gnu.org to correspond to GNU make 3.78. It won't work correctly for versions before that. In addition to some infrastructure changes I've added a number of new tests. Rob Tulloh has contributed changes to get the suite running on NT. Eli Zaretskii and Esa A E Peuha have contributed changes to get the suite running on DJGPP/DOS. This package has a number of problems which preclude me from distributing it with make as a default "make check" test suite. The most serious of these is that it's not parallelizable: it scribbles all over its installation directory and so can only test one make at a time. I simply don't have time to do more with this than I am so far; I'm very actively interested in finding someone willing to overhaul the test suite infrastructure. If you're interested, contact me (see below)! The test suite thus far has been written by Steve McGee, Chris Arthur, and Paul D. Smith. It is covered by the GNU General Public License (Version 2), described in the file COPYING. The test suite requires Perl and is known to work with Perl 4.036 and Perl 5.004 (available from ftp.gnu.org, and portable to many machines). Earlier or later versions may work; I don't know. It assumes that the first "diff" it finds is GNU diff, but that only matters if a test fails. To run the test suite on a UNIX system, use "perl ./T~MAKE-3_78_1HB.BCKcc[MAKE-3_78_1HB.TESTS]README.;1 run_make_tests" (or just "./run_make_tests" if you have a perl on your PATH). To run the test suite on Windows NT or DOS systems, use "perl.exe ./run_make-tests.pl". By default, the test engine picks up the first executable called "make" that it finds in your path. You may use the -make_path option (ie, "perl run_make_tests -make_path /usr/local/src/make-3.78/make") if you want to run a particular copy. This now works correctly with relative paths and when make is called something other than "make" (like "gmake"). Tests cannot end with a "~" character, as the test suite will ignore any that do (I was tired of having it run my Emacs backup files as test :) If you want to run the tests in parallel, you should use the mkshadow script included here to create temporary "copies" (via symbolic links) of the test suite, one for each parallel job. This is a pain and one day maybe the test suite will be rewritten so it's no longer necessary--volunteers welcome! Also, sometimes the tests may behave strangely on networked filesystems. You can use mkshadow to create a copy of the test suite in /tmp or similar, and try again. If the error disappears, it's an issue with your network or file server, not GNU make (I believe). The options/dash-l test will not really test anything if the copy of make you are using can't obtain the system load. Some systems require make to be setgid sys or kmem for this; if you don't want to install make just to test it, make it setgid to kmem or whatever group /dev/kmem is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the options/dash-l test should no longer *fail* because make can't read /dev/kmem. A directory named "work" will be created when the tests are run which will contain any makefiles and "diff" files of tests that fail so that you may look at them afterward to see the output of make and the expected result. There is a -help option which will give you more information about the other possible options for the test suite. Any complaints/suggestions/bugs/etc. for the test suite itself (as opposed to problems in make that the suite finds) should be sent to psmith@gnu.org. Enjoy! Paul D. Smith Chris Arthur &*[MAKE-3_78_1HB.TESTS]RUN_MAKE_TESTS.;1+,c./@ 4$-c0123KPWO56N?7̹m89G@HJ#!/bin/sh exec perl $0.pl ${1+"$@"} (*[MAKE-3_78_1HB.TESTS]RUN_MAKE_TESTS.PL;1+,e+. /@ 4 -c0123KPWO 56p~!7Zm89G@HJ#!/usr/local/bin/perl # -*-perl-*- # Test driver for the Make test suite # Usage: run_make_tests [testname] # [-debug] # [-help] # [-verbose] # [-keep] # [-make ] # (and others) require "test_driver.pl"; sub valid_option { local($option) = @_; if ($option =~ /^-make([-_]?path)?$/) { $make_path = shift @argv; if (!-f $make_path) { print "$option $make_path: Not found.\n"; exit 0; } return 1; } # This doesn't work--it _should_! Someone needs to fix this badly. # # elsif ($option =~ /^-work([-_]?dir)?$/) # { # $workdir = shift @argv; # return 1; # } return 0; } sub run_make_with_options { local ($filename,$options,$logname,$expected_code) = @_; local($code); local($command) = $make_path; $expected_code = 0 unless defined($expected_code); if ($filename) { $command .= " -f $filename"; } if ($options) { $command .= " $options"; } $code = &run_command_with_output($logname,$command); # Check to see if we have Purify errors. If so, keep the logfile. # For this to work you need to build with the Purify flag -exit-status=yes if ($pure_log && -f $pure_log) { if ($code & 0x7000) { $code &= ~0x7000; # If we have a purify log, save it $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : ""); print("Renaming purify log file to $tn\n") if $debug; rename($pure_log, "$tn") || die "Can't rename $log to $tn: $!\n"; ++$purify_errors; } else { unlink($pure_log); } } if ($code != $expected_code) { print "Error running $make_path ($code): $command\n"; $test_passed = 0; return 0; } if ($profile & $vos) { system "add_profile $make_path"; } 1; } sub print_usage { &print_standard_usage ("run_make_tests", "[-make_path make_pathname]"); } sub print_help { &print_standard_help ("-make_path", "\tYou may specify the pathname of the copy of make to run."); } sub get_this_pwd { if ($vos) { $delete_command = "delete_file"; $__pwd = `++(current_dir)`; } else { $delete_command = "rm"; chop ($__pwd = `pwd`); } return $__pwd; } sub set_defaults { # $profile = 1; $testee = "GNU make"; $make_path = "make"; $tmpfilesuffix = "mk"; $pwd = &get_this_pwd; } sub set_more_defaults { local($string); local($index); # find the type of the port. We do this up front to have a single # point of change if it needs to be tweaked. # # This is probably not specific enough. # if ($osname =~ /Windows/i) { $port_type = 'W32'; } # Bleah, the osname is so variable on DOS. This kind of bites. # Well, as far as I can tell if we check for some text at the # beginning of the line with either no spaces or a single space, then # a D, then either "OS", "os", or "ev" and a space. That should # match and be pretty specific. elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) { $port_type = 'DOS'; } # 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. else { $port_type = 'UNIX'; } # Find the full pathname of Make. For DOS systems this is more # complicated, so we ask make itself. $make_path = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`; chop $make_path; print "Make\t= `$make_path'\n" if $debug; $string = `$make_path -v -f /dev/null 2> /dev/null`; $string =~ /^(GNU Make [^,\n]*)/; $testee_version = "$1\n"; $string = `sh -c "$make_path -f /dev/null 2>&1"`; if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { $make_name = $1; } else { if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) { $make_name = $1; } else { $make_name = $make_path; } } # pr epend pwd if this is a relative path (ie, does not # start with a slash, but contains one). Thanks for the # clue, Roland. if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) { $mkpath = "$pwd$pathsep$make_path"; } else { $mkpath = $make_path; } # Get Purify log info--if any. $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/; $pure_log = $1 || ''; $pure_log =~ s/%v/$make_name/; $purify_errors = 0; $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`; if ($string =~ /not supported/) { $parallel_jobs = 0; } else { $parallel_jobs = 1; } } sub setup_for_test { $makefile = &get_tmpfile; if (-f $makefile) { unlink $makefile; } # Get rid of any Purify logs. if ($pure_log) { ($pure_testname = $testname) =~ tr,/,_,; $pure_testname = "$pure_log.$pure_testname"; system("rm -f $pure_testname*"); print("Purify testfiles are: $pure_testname*\n") if $debug; } } exit !&toplevel; "*[MAKE-3_78_1HB.TESTS]SCRIPTS.DIR;1+,c./@ 4-c0123 KPWO56SC57@Mm89G@HJI FEATURES.DIRc FUNCTIONS.DIRdMISC.DIRd OPTIONS.DIRd TARGETS.DIR"dTEST_TEMPLATE.*d VARIABLES.DIR+d+*[MAKE-3_78_1HB.TESTS.SCRIPTS]FEATURES.DIR;1+,c./@ 4-c0123 KPWO568R7=)m89G@HJI COMMENTS.c CONDITIONALS.cDEFAULT_NAMES.c DOUBLE_COLON.cECHOING.cERRORS.cESCAPE.cINCLUDE.c MULT_RULES.c MULT_TARGETS.c OVERRIDE.c PARALLELISM.cPATSPECIFIC_VARS.cQUOTING.c RECURSION.c REINVOKE.cSTATIPATTRULES.c TARGETVARS.c VARNESTING.cVPATH.cVPATH2.c VPATHGPATH.c VPATHPLUS.c1*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]COMMENTS.;1+,c./@ 4-c0123KPWO568@7Fm89G@HJ$description = "The following test creates a makefile to test comments\n" ."and comment continuation to the next line using a \n" ."backslash within makefiles."; $details = "To test comments within a makefile, a semi-colon was placed \n" ."after a comment was started. This should not be reported as\n" ."an error since it is within a comment. We then continue the \n" ."comment to the next line using a backslash. To test whether\n" ."the comment really continued, we place an echo command with some\n" ."text on the line which should never execute since it should be \n" ."within a comment\n"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<\EOF; # Test comment vs semicolon parsing and line continuation target: # this ; is just a comment \ @echo This is within a comment. @echo There should be no errors for this makefile. EOF # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "There should be no errors for this makefile.\n"; # COMPARE RESULTS &compare_output($answer,&get_logfile(1)) h5*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]CONDITIONALS.;1+,c./@ 4-c0123KPWO567m89G@HJ# -*-perl-*- $description = "Check GNU make conditionals."; $details = "Attempt various different flavors of GNU make conditionals."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOMAKE'; objects = foo.obj arg1 = first arg2 = second arg3 = third arg4 = cc arg5 = second all: ifeq ($(arg1),$(arg2)) @echo arg1 equals arg2 else @echo arg1 NOT equal arg2 endif ifeq '$(arg2)' "$(arg5)" @echo arg2 equals arg5 else @echo arg2 NOT equal arg5 endif ifneq '$(arg3)' '$(arg4)' @echo arg3 NOT equal arg4 else @echo arg3 equal arg4 endif ifndef undefined @echo variable is undefined else @echo variable undefined is defined endif ifdef arg4 @echo arg4 is defined else @echo arg4 is NOT defined endif EOMAKE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "arg1 NOT equal arg2 arg2 equals arg5 arg3 NOT equal arg4 variable is undefined arg4 is defined "; # COMPARE RESULTS &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; s6*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]DEFAULT_NAMES.;1+,c./@ 4c-c0123KPWO567Z˺m89G@HJ# -*-perl-*- $description = "This script tests to make sure that Make looks for default makefiles in the correct order (GNUmakefile,makefile,Makefile)"; # Create a makefile called "GNUmakefile" $makefile = "GNUmakefile"; open(MAKEFILE,"> $makefile"); print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n"; close(MAKEFILE); # DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile. # Just test what we can here (avoid Makefile versus makefile test). # if ($port_type eq 'UNIX') { # Create another makefile called "makefile" open(MAKEFILE,"> makefile"); print MAKEFILE "SECOND: ; \@echo It chose makefile\n"; close(MAKEFILE); } # Create another makefile called "Makefile" open(MAKEFILE,"> Makefile"); print MAKEFILE "THIRD: ; \@echo It chose Makefile\n"; close(MAKEFILE); &run_make_with_options("","",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "It chose GNUmakefile\n"; # COMPARE RESULTS &compare_output($answer,&get_logfile(1)) || &error("abort"); unlink $makefile; # DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile. # Just test what we can here (avoid Makefile versus makefile test). # if ($port_type eq 'UNIX') { $answer = "It chose makefile\n"; &run_make_with_options("","",&get_logfile); &compare_output($answer,&get_logfile(1)) || &error("abort"); unlink "makefile"; } $answer = "It chose Makefile\n"; &run_make_with_options("","",&get_logfile); &compare_output($answer,&get_logfile(1)) || &error("abort"); unlink "Makefile"; l5*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]DOUBLE_COLON.;1+,c./@ 4V-c0123KPWO5647ںm89G@HJ$description = "The following test creates a makefile to test Double-Colon\n" ."Rules. They are rules which are written with '::' instead\n" ."of ':' after the target names. This tells make that each \n" ."of these rules are independent of the others and each rule's\n" ."commands are executed if the target is older than any \n" ."dependencies of that rule."; $details = "The makefile created by this test contains two double-colon \n" ."rules for foo; each with their own commands. When make is run,\n" ."each command should be executed in the sequence that they are \n" ."found. The command is a simple echo statement."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "foo:: bar.h \n" ."\t\@echo Executing rule foo FIRST\n" ."foo2: bar.h \n" ."foo:: bar2.h \n" ."\t\@echo Executing rule foo SECOND\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch("bar.h","bar2.h"); &run_make_with_options($makefile, "", &get_logfile, 0); $answer = "Executing rule foo FIRST\n" ."Executing rule foo SECOND\n"; &compare_output($answer,&get_logfile(1)); unlink("bar.h","bar2.h"); 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]ECHOING.;1+,c./@ 4T-c0123KPWO 5607sm89G@HJ $description = "The following test creates a makefile to test command \n" ."echoing. It tests that when a command line starts with \n" ."a '\@', the echoing of that line is suppressed. It also \n" ."tests the -n option which tells make to ONLY echo the \n" ."commands and no execution happens. In this case, even \n" ."the commands with '\@' are printed. Lastly, it tests the \n" ."-s flag which tells make to prevent all echoing, as if \n" ."all commands started with a '\@'."; $details = "This test is similar to the 'clean' test except that a '\@' has\n" ."been placed in front of the delete command line. Four tests \n" ."are run here. First, make is run normally and the first echo\n" ."command should be executed. In this case there is no '\@' so \n" ."we should expect make to display the command AND display the \n" ."echoed message. Secondly, make is run with the clean target, \n" ."but since there is a '\@' at the beginning of the command, we\n" ."expect no output; just the deletion of a file which we check \n" ."for. Third, we give the clean target again except this time\n" ."we give make the -n option. We now expect the command to be \n" ."displayed but not to be executed. In this case we need only \n" ."to check the output since an error message would be displayed\n" ."if it actually tried to run the delete command again and the \n" ."file didn't exist. Lastly, we run the first test again with \n" ."the -s option and check that make did not echo the echo \n" ."command before printing the message."; $example = "EXAMPLE_FILE"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n"; print MAKEFILE "\techo This makefile did not clean the dir... good\n"; print MAKEFILE "clean: \n"; print MAKEFILE "\t\@$delete_command $example\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch($example); # TEST #1 # ------- &run_make_with_options($makefile,"",&get_logfile,0); $answer = "echo This makefile did not clean the dir... good\n" ."This makefile did not clean the dir... good\n"; &compare_output($answer,&get_logfile(1)); # TEST #2 # ------- &run_make_with_options($makefile,"clean",&get_logfile,0); $answer = ""; &compare_output($answer,&get_logfile(1)); if (-f $example) { $test_passed = 0; } # TEST #3 # ------- &run_make_with_options($makefile,"-n clean",&get_logfile,0); $answer = "$delete_command $example\n"; &compare_output($answer,&get_logfile(1)); # TEST #4 # ------- &run_make_with_options($makefile,"-s",&get_logfile,0); $answer = "This makefile did not clean the dir... good\n"; &compare_output($answer,&get_logfile(1)); 1; /*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]ERRORS.;1+,c./@ 4-c0123KPWO 56f7V?m89G@HJ $description = "The following tests the -i option and the '-' in front of \n" ."commands to test that make ignores errors in these commands\n" ."and continues processing."; $details = "This test runs two makes. The first runs on a target with a \n" ."command that has a '-' in front of it (and a command that is \n" ."intended to fail) and then a delete command after that is \n" ."intended to succeed. If make ignores the failure of the first\n" ."command as it is supposed to, then the second command should \n" ."delete a file and this is what we check for. The second make\n" ."that is run in this test is identical except that the make \n" ."command is given with the -i option instead of the '-' in \n" ."front of the command. They should run the same. "; if ($vos) { $delete_command = "delete_file"; } else { $delete_command = "rm"; } open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "clean:\n" ."\t-$delete_command cleanit\n" ."\t$delete_command foo\n" ."clean2: \n" ."\t$delete_command cleanit\n" ."\t$delete_command foo\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch("foo"); unlink("cleanit"); $cleanit_error = `sh -c "$delete_command cleanit 2>&1"`; $delete_error_code = $? >> 8; # TEST #1 # ------- $answer = "$delete_command cleanit\n" . $cleanit_error ."$make_name: [clean] Error $delete_error_code (ignored)\n" ."$delete_command foo\n"; &run_make_with_options($makefile,"",&get_logfile); # The output for this on VOS is too hard to replicate, so we only check it # on unix. if (!$vos) { &compare_output($answer,&get_logfile(1)); } # If make acted as planned, it should ignore the error from the first # command in the target and execute the second which deletes the file "foo" # This file, therefore, should not exist if the test PASSES. if (-f "foo") { $test_passed = 0; } &touch("foo"); # TEST #2 # ------- $answer = "$delete_command cleanit\n" . $cleanit_error ."$make_name: [clean2] Error $delete_error_code (ignored)\n" ."$delete_command foo\n"; &run_make_with_options($makefile,"clean2 -i",&get_logfile); if (!$vos) { &compare_output($answer,&get_logfile(1)); } if (-f "foo") { $test_passed = 0; } 1; e/*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]ESCAPE.;1+,c./@ 4a-c0123KPWO56%7rm89G@HJ$description = "Test various types of escaping in makefiles."; $details = "Make sure that escaping of `:' works in target names."; open(MAKEFILE,"> $makefile"); print MAKEFILE '$(path)foo : ; @echo cp $^ $@ '; close(MAKEFILE); # TEST 1 &run_make_with_options($makefile, "", &get_logfile); $answer = "cp foo\n"; &compare_output($answer,&get_logfile(1)); # TEST 2: This one should fail, since the ":" is unquoted. &run_make_with_options($makefile, "path=p:", &get_logfile, 512); $answer = "$makefile:1: *** target pattern contains no `%'. Stop.\n"; &compare_output($answer,&get_logfile(1)); # TEST 3: This one should work, since we escape the ":". &run_make_with_options($makefile, "'path=p\\:'", &get_logfile, 0); $answer = "cp p:foo\n"; &compare_output($answer,&get_logfile(1)); # TEST 4: This one should fail, since the escape char is escaped. &run_make_with_options($makefile, "'path=p\\\\:'", &get_logfile, 512); $answer = "$makefile:1: *** target pattern contains no `%'. Stop.\n"; &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]INCLUDE.;1+,c./@ 4!-c0123KPWO56#7m89G@HJ# -*-mode: perl; rm-trailing-spaces: nil-*- $description = "Test various forms of the GNU make `include' command."; $details = "Test include, -include, sinclude and various regressions involving them. Test extra whitespace at the end of the include, multiple -includes and sincludes (should not give an error) and make sure that errors are reported for targets that were also -included."; $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The contents of the Makefile ... print MAKEFILE < $makefile2"); print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n"; close(MAKEFILE); # Create the answer to what should be produced by this Makefile &run_make_with_options($makefile, "all", &get_logfile); $answer = "There should be no errors for this makefile.\n"; &compare_output($answer, &get_logfile(1)); &run_make_with_options($makefile, "ANOTHER", &get_logfile); $answer = "This is another included makefile\n"; &compare_output($answer, &get_logfile(1)); # Try to build the "error" target; this will fail since we don't know # how to create makeit.mk, but we should also get a message (even though # the -include suppressed it during the makefile read phase, we should # see one during the makefile run phase). &run_make_with_options($makefile, "error", &get_logfile, 512); $answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n"; &compare_output($answer, &get_logfile(1)); 1; d3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]MULT_RULES.;1+,c./@ 4-c0123KPWO56˃7#'m89G@HJ$description = "\ The following test creates a makefile to test the presence of multiple rules for one target. One file can be the target of several rules if at most one rule has commands; the other rules can only have dependencies."; $details = "\ The makefile created in this test contains two hardcoded rules for foo.o and bar.o. It then gives another multiple target rule with the same names as above but adding more dependencies. Additionally, another variable extradeps is listed as a dependency but is defined to be null. It can however be defined on the make command line as extradeps=extra.h which adds yet another dependency to the targets."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <7V6m89G@HJU~MAKE-3_78_1HB.BCKcc5[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]MULT_TARGETS.;1$description = "The following test creates a makefile to test that a \n " ."rule with multiple targets is equivalent to writing \n" ."many rules, each with one target, and all identical aside\n" ."from that."; $details = "A makefile is created with one rule and two targets. Make \n" ."is called twice, once for each target, and the output which \n" ."contains the target name with \$@ is looked at for the changes.\n" ."This test also tests the substitute function by replacing \n" ."the word output with nothing in the target name giving either\n" ."an output of \"I am little\" or \"I am big\""; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "bigoutput littleoutput: test.h\n"; print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch("test.h"); &run_make_with_options($makefile,"bigoutput",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "I am big\n"; &compare_output($answer,&get_logfile(1)); &run_make_with_options($makefile,"littleoutput",&get_logfile); $answer = "I am little\n"; &compare_output($answer,&get_logfile(1)); unlink "test.h"; 1; u1*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]OVERRIDE.;1+,c./@ 4-c0123KPWO56;e7{Em89G@HJ$description = "The following test creates a makefile to ..."; $details = ""; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "override define foo\n" ."\@echo First comes the definition.\n" ."\@echo Then comes the override.\n" ."endef\n" ."all: \n" ."\t\$(foo)\n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"foo=Hello",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "First comes the definition.\n" ."Then comes the override.\n"; &compare_output($answer,&get_logfile(1)); 1; d4*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]PARALLELISM.;1+,c./@ 4-c0123KPWO 569Í7^Um89G@HJ # -*-perl-*- $description = "Test parallelism (-j) option."; $details = "This test creates a makefile with two double-colon default rules. The first rule has a series of sleep and echo commands intended to run in series. The second and third have just an echo statement. When make is called in this test, it is given the -j option with a value of 4. This tells make that it may start up to four jobs simultaneously. In this case, since the first command is a sleep command, the output of the second and third commands will appear before the first if indeed make is running all of these commands in parallel."; if (!$parallel_jobs) { return -1; } if ($vos) { $delete_command = "delete_file -no_ask"; $sleep_command = "sleep -seconds"; } else { $delete_command = "rm -f"; $sleep_command = "sleep"; } open(MAKEFILE,"> $makefile"); print MAKEFILE <<"EOF"; all : def_1 def_2 def_3 def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO def_2 : ; \@$sleep_command 2 ; echo THREE def_3 : ; \@$sleep_command 1 ; echo FOUR EOF close(MAKEFILE); &run_make_with_options($makefile, "-j 4", &get_logfile); $answer = "ONE\nFOUR\nTHREE\nTWO\n"; &compare_output($answer, &get_logfile(1)); # Test parallelism with included files. Here we sleep/echo while # building the included files, to test that they are being built in # parallel. $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile2"); print MAKEFILE <<"EOF"; all: 1 2; \@echo success -include 1.inc 2.inc 1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo "1: ; \@echo ONE; $sleep_command 2; echo TWO" > \$\@ 2.inc: ; \@$sleep_command 1; echo THREE.inc; echo "2: ; \@$sleep_command 1; echo THREE" > \$\@ EOF close(MAKEFILE); &run_make_with_options("$makefile2", "-j 4", &get_logfile); $answer = "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n"; &compare_output($answer, &get_logfile(1)); unlink('1.inc', '2.inc'); # Test parallelism with included files--this time recurse first and make # sure the jobserver works. $makefile3 = &get_tmpfile; open(MAKEFILE,"> $makefile3"); print MAKEFILE <<"EOF"; recurse: ; \@\$(MAKE) --no-print-directory -f $makefile3 INC=yes all all: 1 2; \@echo success INC = no ifeq (\$(INC),yes) -include 1.inc 2.inc endif 1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo "1: ; \@echo ONE; $sleep_command 2; echo TWO" > \$\@ 2.inc: ; \@$sleep_command 1; echo THREE.inc; echo "2: ; \@$sleep_command 1; echo THREE" > \$\@ EOF close(MAKEFILE); &run_make_with_options("$makefile3", "-j 4", &get_logfile); $answer = "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n"; &compare_output($answer, &get_logfile(1)); unlink('1.inc', '2.inc'); 1; 9*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]PATSPECIFIC_VARS.;1+,c./@ 4-c0123KPWO56A7;dm89G@HJ# -*-perl-*- $description = "Test pattern-specific variable settings."; $details = "\ Create a makefile containing various flavors of pattern-specific variable settings, override and non-override, and using various variable expansion rules, semicolon interference, etc."; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; 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) EOF close(MAKEFILE); # TEST #1 -- basics &run_make_with_options($makefile, "", &get_logfile); $answer = "one two three\nfoo four baz\nfoo bar 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"; &compare_output($answer,&get_logfile(1)); 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]QUOTING.;1+,c./@ 4-c0123KPWO567sm89G@HJ# -*-perl-*- $description = "The following test creates a makefile to test using \n" . "quotes within makefiles."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOM'; SHELL = /bin/sh TEXFONTS = NICEFONT DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\" test: ; @"echo" 'DEFINES = $(DEFINES)' EOM # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n"; # COMPARE RESULTS &compare_output($answer,&get_logfile(1)); 1; 2*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]RECURSION.;1+,c./@ 4"-c0123KPWO56( 7m89G@HJ# -*-perl-*- $description = "The following test creates a makefile to ...\n"; $details = "DETAILS"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n" ."\t\$(MAKE) -f $makefile foo \n" ."foo: \n" ."\t\@echo \$(MAKE) \n" ."\t\@echo MAKELEVEL = \$(MAKELEVEL)\n" ."\t\$(MAKE) -f $makefile last \n" ."last: \n" ."\t\@echo \$(MAKE) \n" ."\t\@echo MAKELEVEL = \$(MAKELEVEL) \n" ."\t\@echo THE END\n"; # END of Contents of MAKEFILE close(MAKEFILE); if ($vos) { $answer = "$make_name: Entering directory \`$pwd\'\n" ."make 'CFLAGS=-O' -f $makefile foo \n" ."make CFLAGS=-O\n" ."MAKELEVEL = 0\n" ."make 'CFLAGS=-O' -f $makefile last \n" ."make CFLAGS=-O\n" ."MAKELEVEL = 0\n" ."THE END\n" ."$make_name: Leaving directory `$pwd'\n"; } else { $answer = "$make_name: Entering directory `$pwd'\n" ."$mkpath -f $makefile foo \n" ."${make_name}[1]: Entering directory `$pwd'\n" ."$mkpath\n" ."MAKELEVEL = 1\n" ."$mkpath -f $makefile last \n" ."${make_name}[2]: Entering directory `$pwd'\n" ."$mkpath\n" ."MAKELEVEL = 2\n" ."THE END\n" ."${make_name}[2]: Leaving directory `$pwd'\n" ."${make_name}[1]: Leaving directory `$pwd'\n" ."$make_name: Leaving directory `$pwd'\n"; } $mkoptions = "CFLAGS=-O -w"; $mkoptions .= " -j 2" if ($parallel_jobs); &run_make_with_options($makefile,$mkoptions,&get_logfile,0); &compare_output($answer,&get_logfile(1)); 1; 1*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]REINVOKE.;1+,c./@ 4*-c0123KPWO 56M370m89G@HJ # -*-mode: perl-*- $description = "Test GNU make's auto-reinvocation feature."; $details = "\ If the makefile or one it includes can be rebuilt then it is, and make is reinvoked. We create a rule to rebuild the makefile from a temp file, then touch the temp file to make it newer than the makefile."; $makefile2 = &get_tmpfile; $makefile_orig = &get_tmpfile; open(MAKEFILE,"> $makefile"); print MAKEFILE <> \$\@ include $makefile2 EOM close(MAKEFILE); &touch($makefile2); # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); &touch("$makefile_orig"); &run_make_with_options($makefile, "", &get_logfile, 0); # Create the answer to what should be produced by this Makefile $answer = "rebuilding $makefile2.\nrebuilding $makefile.\nrunning rules.\n"; &compare_output($answer,&get_logfile(1)) && unlink "$makefile_orig"; # In this test we create an included file that's out-of-date, but then # the rule doesn't update it. Make shouldn't re-exec. $makefile3 = &get_tmpfile; open(MAKEFILE, "> $makefile3"); print MAKEFILE <<'EOM'; SHELL = /bin/sh all: ; @echo hello a : b ; echo >> $@ b : c ; [ -f $@ ] || echo >> $@ c: ; echo >> $@ include $(F) EOM close(MAKEFILE); &touch('a','b'); sleep(2); &touch('c'); # First try with the file that's not updated "once removed" from the # file we're including. &run_make_with_options($makefile3, "F=a", &get_logfile, 0); $answer = "[ -f b ] || echo >> b\nhello\n"; &compare_output($answer,&get_logfile(1)); # Now try with the file we're not updating being the actual file we're # including: this and the previous one test different parts of the code. &run_make_with_options($makefile3, "F=b", &get_logfile, 0); $answer = "[ -f b ] || echo >> b\nhello\n"; &compare_output($answer,&get_logfile(1)); unlink('a','b','c'); # This tells the test driver that the perl test script executed properly. 1; 7*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]STATIPATTRULES.;1+,c./@ 4-c0123KPWO56c7mm89G@HJ$description = "The following test creates a makefile to test static \n" ."pattern rules. Static pattern rules are rules which \n" ."specify multiple targets and construct the dependency \n" ."names for each target based on the target name. "; $details = "The makefile created in this test has three targets. The \n" ."filter command is used to get those target names ending in \n" .".o and statically creates a compile command with the target\n" ."name and the target name with .c. It also does the same thing\n" ."for another target filtered with .elc and creates a command\n" ."to emacs a .el file"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "files = foo.elc bar.o lose.o \n\n" ."\$(filter %.o,\$(files)): %.o: %.c\n" ."\t\@echo CC -c \$(CFLAGS) \$< -o \$@ \n" ."\$(filter %.elc,\$(files)): %.elc: %.el \n" ."\t\@echo emacs \$< \n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch("bar.c","lose.c"); # TEST #1 # ------- &run_make_with_options($makefile, "", &get_logfile, 0); # Create the answer to what should be produced by this Makefile $answer = "CC -c bar.c -o bar.o\n"; &compare_output($answer,&get_logfile(1)); # TEST #2 # ------- &run_make_with_options($makefile,"lose.o",&get_logfile); $answer = "CC -c lose.c -o lose.o\n"; &compare_output($answer,&get_logfile(1)); # TEST #3 # ------- &touch("foo.el"); &run_make_with_options($makefile,"foo.elc",&get_logfile); $answer = "emacs foo.el\n"; &compare_output($answer,&get_logfile(1)); unlink("foo.el","bar.c","lose.c"); 1; 3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]TARGETVARS.;1+,c./@ 4 -c0123KPWO 56_7P⵻m89G@HJ # -*-perl-*- $description = "Test target-specific variable settings."; $details = "\ Create a makefile containing various flavors of target-specific variable values, override and non-override, and using various variable expansion rules, semicolon interference, etc."; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; SHELL = /bin/sh export FOO = foo export BAR = bar one: override FOO = one one two: ; @echo $(FOO) $(BAR) two: BAR = two three: ; BAR=1000 @echo $(FOO) $(BAR) # Some things that shouldn't be target vars funk : override funk : override adelic adelic override : ; echo $@ # Test per-target recursive variables four:FOO=x four:VAR$(FOO)=ok four: ; @echo '$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)' five:FOO=x five six : VAR$(FOO)=good five six: ;@echo '$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)' # Test per-target variable inheritance seven: eight seven eight: ; @echo $@: $(FOO) $(BAR) seven: BAR = seven seven: FOO = seven eight: BAR = eight # Test the export keyword with per-target variables nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR nine: FOO = wallace # Test = escaping EQ = = ten: one\=two ten: one \= two ten one$(EQ)two $(EQ):;@echo $@ .PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two # Test target-specific vars with pattern/suffix rules QVAR = qvar RVAR = = %.q : ; @echo $(QVAR) $(RVAR) foo.q : RVAR += rvar # Target-specific vars with multiple LHS pattern rules %.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR) foo.r : RVAR += rvar foo.t : TVAR := $(QVAR) EOF close(MAKEFILE); # TEST #1 &run_make_with_options($makefile, "one two three", &get_logfile); $answer = "one bar\nfoo two\nBAR=1000\nfoo bar\n"; &compare_output($answer,&get_logfile(1)); # TEST #2 &run_make_with_options($makefile, "one two FOO=1 BAR=2", &get_logfile); $answer = "one 2\n1 2\n"; &compare_output($answer,&get_logfile(1)); # TEST #3 &run_make_with_options($makefile, "four", &get_logfile); $answer = "x ok ok\n"; &compare_output($answer,&get_logfile(1)); # TEST #4 &run_make_with_options($makefile, "seven", &get_logfile); $answer = "eight: seven eight\nseven: seven seven\n"; &compare_output($answer,&get_logfile(1)); # TEST #5 &run_make_with_options($makefile, "nine", &get_logfile); $answer = "wallace bar wallace bar\n"; &compare_output($answer,&get_logfile(1)); # TEST #6 &run_make_with_options($makefile, "ten", &get_logfile); $answer = "one=two\none bar\n=\nfoo two\nten\n"; &compare_output($answer,&get_logfile(1)); # TEST #6 &run_make_with_options($makefile, "foo.q bar.q", &get_logfile); $answer = "qvar = rvar\nqvar =\n"; &compare_output($answer,&get_logfile(1)); # TEST #7 &run_make_with_options($makefile, "foo.t bar.s", &get_logfile); $answer = "qvar = qvar\nqvar =\n"; &compare_output($answer,&get_logfile(1)); 1; 3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]VARNESTING.;1+,c./@ 4p-c0123KPWO56L7Żm89G@HJ$description = "The following test creates a makefile to ..."; $details = ""; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "x = variable1\n" ."variable2 := Hello\n" ."y = \$(subst 1,2,\$(x))\n" ."z = y\n" ."a := \$(\$(\$(z)))\n" ."all: \n" ."\t\@echo \$(a)\n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "Hello\n"; &compare_output($answer,&get_logfile(1)); 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]VPATH.;1+,c./@ 4-c0123KPWO 56}F7mԻm89G@HJ $description = "The following test creates a makefile to test the \n" ."vpath directive which allows you to specify a search \n" ."path for a particular class of filenames, those that\n" ."match a particular pattern."; $details = "This tests the vpath directive by specifying search directories\n" ."for one class of filenames with the form: vpath pattern directories" ."\nIn this test, we specify the working directory for all files\n" ."that end in c or h. We also test the variables $@ (which gives\n" ."target name) and $^ (which is a list of all dependencies \n" ."including the directories in which they were found). It also\n" ."uses the function firstword used to extract just the first\n" ."dependency from the entire list."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "vpath %.c foo\n"; print MAKEFILE "vpath %.c $workdir\n"; print MAKEFILE "vpath %.h $workdir\n"; print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n"; print MAKEFILE "edit: \$(objects)\n"; print MAKEFILE "\t\@echo cc -o \$@ \$^\n"; print MAKEFILE "main.o : main.c defs.h\n"; print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n"; print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; print MAKEFILE "\t\@echo cc -c kbd.c\n"; print MAKEFILE "commands.o : command.c defs.h command.h\n"; print MAKEFILE "\t\@echo cc -c commands.c\n"; print MAKEFILE "display.o : display.c defs.h buffer.h\n"; print MAKEFILE "\t\@echo cc -c display.c\n"; print MAKEFILE "insert.o : insert.c defs.h buffer.h\n"; print MAKEFILE "\t\@echo cc -c insert.c\n"; # END of Contents of MAKEFILE close(MAKEFILE); @files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", "$workdir${pathsep}command.c"); &touch(@files_to_touch); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n" ."cc -c display.c\n" ."cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o " ."insert.o\n"; if (&compare_output($answer,&get_logfile(1))) { unlink @files_to_touch; } 1; s/*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]VPATH2.;1+,c./@ 4-c0123KPWO56Q7m89G@HJ$description = "This is part 2 in a series to test the vpath directive\n" ."It tests the three forms of the directive:\n" ." vpath pattern directive\n" ." vpath pattern (clears path associated with pattern)\n" ." vpath (clears all paths specified with vpath)\n"; $details = "This test simply adds many search paths using various vpath\n" ."directive forms and clears them afterwards. It has a simple\n" ."rule to print a message at the end to confirm that the makefile\n" ."ran with no errors.\n"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "VPATH = $workdir:$sourcedir\n"; print MAKEFILE "vpath %.c foo\n"; print MAKEFILE "vpath %.c $workdir\n"; print MAKEFILE "vpath %.c $sourcedir\n"; print MAKEFILE "vpath %.h $workdir\n"; print MAKEFILE "vpath %.c\n"; print MAKEFILE "vpath\n"; print MAKEFILE "all:\n"; print MAKEFILE "\t\@echo ALL IS WELL\n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "ALL IS WELL\n"; &compare_output($answer,&get_logfile(1)); 1; I3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]VPATHGPATH.;1+,c./@ 4--c0123KPWO56}U7m89G@HJ# -*-perl-*- $description = "Tests VPATH+/GPATH functionality."; $details = ""; $VP = "$workdir$pathsep"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "VPATH = $VP\n"; print MAKEFILE <<'EOMAKE'; GPATH = $(VPATH) .SUFFIXES: .a .b .c .d .PHONY: general rename notarget intermediate %.a: %.b: %.c: %.d: %.a : %.b ; cat $^ > $@ %.b : %.c ; cat $^ > $@ %.c :: %.d ; cat $^ > $@ # General testing info: general: foo.b foo.b: foo.c bar.c EOMAKE close(MAKEFILE); @touchedfiles = (); sub touchfiles { foreach (@_) { ($f = $_) =~ s,VP/,$VP,g; &touch($f); push(@touchedfiles, $f); sleep(1); } } # Run the general-case test &touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); &run_make_with_options($makefile,"general",&get_logfile()); push(@touchedfiles, "bar.c"); $answer = "$make_name: Nothing to be done for `general'.\n"; &compare_output($answer,&get_logfile(1)); unlink(@touchedfiles) unless $keep; 1; s2*[MAKE-3_78_1HB.TESTS.SCRIPTS.FEATURES]VPATHPLUS.;1+,c./@ 4-c0123KPWO 567uRm89G@HJ # -*-perl-*- $description = "Tests the new VPATH+ functionality added in 3.76."; $details = ""; $VP = "$workdir$pathsep"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "VPATH = $VP\n"; print MAKEFILE <<'EOMAKE'; SHELL = /bin/sh .SUFFIXES: .a .b .c .d .PHONY: general rename notarget intermediate %.a: %.b: %.c: %.d: %.a : %.b cat $^ > $@ %.b : %.c cat $^ > $@ 2>/dev/null || exit 1 %.c :: %.d cat $^ > $@ # General testing info: general: foo.b foo.b: foo.c bar.c # Rename testing info: rename: $(VPATH)/foo.c foo.d # Target not made testing info: notarget: notarget.b notarget.c: notarget.d -@echo "not creating $@ from $^" # Intermediate files: intermediate: inter.a EOMAKE close(MAKEFILE); @touchedfiles = (); sub touchfiles { foreach (@_) { ($f = $_) =~ s,VP/,$VP,g; &touch($f); push(@touchedfiles, $f); # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); } } # Run the general-case test &touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); &run_make_with_options($makefile,"general",&get_logfile); push(@touchedfiles, "bar.c"); $answer = "cat bar.d > bar.c cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1 "; &compare_output($answer,&get_logfile(1)); # Test rules that don't make the target correctly &touchfiles("VP/notarget.c", "notarget.b", "notarget.d"); &run_make_with_options($makefile,"notarget",&get_logfile,512); $answer = "not creating notarget.c from notarget.d cat notarget.c > notarget.b 2>/dev/null || exit 1 $make_name: *** [notarget.b] Error 1 "; &compare_output($answer,&get_logfile(1)); # Test intermediate file handling (part 1) &touchfiles("VP/inter.d"); &run_make_with_options($makefile,"intermediate",&get_logfile); push(@touchedfiles, "inter.a", "inter.b"); $answer = "cat ${VP}inter.d > inter.c cat inter.c > inter.b 2>/dev/null || exit 1 cat inter.b > inter.a rm inter.b inter.c "; &compare_output($answer,&get_logfile(1)); # Test intermediate file handling (part 2) &touchfiles("VP/inter.b", "VP/inter.d"); &run_make_with_options($makefile,"intermediate",&get_logfile); $answer = "cat ${VP}inter.d > inter.c cat inter.c > inter.b 2>/dev/null || exit 1 cat inter.b > inter.a rm inter.c "; &compare_output($answer,&get_logfile(1)); unlink @touchedfiles unless $keep; 1; ,*[MAKE-3_78_1HB.TESTS.SCRIPTS]FUNCTIONS.DIR;1+,d./@ 4-c0123 KPWO56&74k;m89G@HJI ADDPREFIX.d ADDSUFFIX.d BASENAME.dCALL.dDIR.dERROR.d FILTER-OUT.d FINDSTRING.dFOREACH. dIF. dJOIN. dNOTDIR. dORIGIN. dSORT.dSTRIP.d SUBSTITUTION.dSUFFIX.dWARNING.d WILDCARD.dWORD.d3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]ADDPREFIX.;1+,d./@ 4-d0123KPWO56KB7.m89G@HJV~MAKE-3_78_1HB.BCKdd3[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]ADDPREFIX.;1 $description = "The following test creates a makefile to test the addprefix " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(addprefix src${pathsep},a.b.z.foo hacks) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "src${pathsep}a.b.z.foo src${pathsep}hacks\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 3*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]ADDSUFFIX.;1+,d./@ 4}-d0123KPWO56Kh7uw(m89G@HJ$description = "The following test creates a makefile to test the addsuffix " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(addsuffix .c,src${pathsep}a.b.z.foo hacks) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "src${pathsep}a.b.z.foo.c hacks.c\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; o2*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]BASENAME.;1+,d./@ 4-d0123KPWO56K7X:m89G@HJ$description = "The following test creates a makefile to test the suffix " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(basename src${pathsep}a.b.z.foo.c src${pathsep}hacks src.bar${pathsep}a.b.z.foo.c src.bar${pathsep}hacks hacks) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "src${pathsep}a.b.z.foo src${pathsep}hacks src.bar${pathsep}a.b.z.foo src.bar${pathsep}hacks hacks\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]CALL.;1+,d./@ 4-d0123KPWO56p47%:Lm89G@HJ# -*-perl-*- $description = "Test the call function.\n"; $details = "Try various uses of call and ensure they all give the correct results.\n"; open(MAKEFILE, "> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOMAKE'; # Simple, just reverse something # reverse = $2 $1 # A complex `map' function, using recursive `call'. # map = $(foreach a,$2,$(call $1,$a)) # Test using a builtin; this is silly as it's simpler to do without call # my-notdir = $(call notdir,$(1)) all: ; @echo '$(call reverse,bar,foo)'; \ echo '$(call map,origin,MAKE reverse map)'; \ echo '$(call my-notdir,a/b c/d e/f)' EOMAKE # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile, "", &get_logfile); $answer = "foo bar\ndefault file file\nb d f\n"; &compare_output($answer, &get_logfile(1)); 1; -*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]DIR.;1+,d./@ 4c-d0123KPWO567}^m89G@HJ$description = "The following test creates a makefile to test the dir " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(dir src${pathsep}foo.c hacks) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "src${pathsep} .${pathsep}\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; t/*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]ERROR.;1+,d./@ 4-d0123KPWO56Z7om89G@HJ$description = "\ The following test creates a makefile to test the error function."; $details = ""; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; ifdef ERROR1 $(error error is $(ERROR1)) endif ifdef ERROR2 $(error error is $(ERROR2)) endif ifdef ERROR3 all: some; @echo $(error error is $(ERROR3)) endif ifdef ERROR4 all: some; @echo error is $(ERROR4) @echo $(error error is $(ERROR4)) endif some: ; @echo Some stuff EOF close(MAKEFILE); # Test #1 &run_make_with_options($makefile, "ERROR1=yes", &get_logfile, 512); $answer = "$makefile:2: *** error is yes. Stop.\n"; &compare_output($answer,&get_logfile(1)); # Test #2 &run_make_with_options($makefile, "ERROR2=no", &get_logfile, 512); $answer = "$makefile:6: *** error is no. Stop.\n"; &compare_output($answer,&get_logfile(1)); # Test #3 &run_make_with_options($makefile, "ERROR3=maybe", &get_logfile, 512); $answer = "Some stuff\n$makefile:10: *** error is maybe. Stop.\n"; &compare_output($answer,&get_logfile(1)); # Test #4 &run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512); $answer = "Some stuff\n$makefile:14: *** error is definitely. Stop.\n"; &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 4*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]FILTER-OUT.;1+,d./@ 4-d0123KPWO56b/7m89G@HJ$description = "The following test creates a makefile to test static \n" ."pattern rules. Static pattern rules are rules which \n" ."specify multiple targets and construct the dependency \n" ."names for each target based on the target name. "; $details = "The makefile created in this test has three targets. The \n" ."filter command is used to get those target names ending in \n" .".o and statically creates a compile command with the target\n" ."name and the target name with .c. It also does the same thing\n" ."for another target filtered with .elc and creates a command\n" ."to emacs a .el file"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "files := \$(filter-out %.o, foo.elc bar.o lose.o) \n" ."all: \n" ."\t\@echo \$(files) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile, "", &get_logfile, 0); # Create the answer to what should be produced by this Makefile $answer = "foo.elc\n"; &compare_output($answer,&get_logfile(1)); 1; p4*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]FINDSTRING.;1+,d./@ 4-d0123KPWO56U7`m89G@HJ$description = "The following test creates a makefile to test the findstring " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(findstring port, reporter)\n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile, "", &get_logfile, 0); # Create the answer to what should be produced by this Makefile $answer = "port\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 1*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]FOREACH.;1+, d./@ 4-d0123KPWO56ا~7Tm89G@HJ# -*-perl-*- # Updated 6.16.93 variable "MAKE" is default was environment override # For make 3.63 and above $description = "The following test creates a makefile to verify test the foreach function."; $details = "This is a test of the foreach function in gnu make. This function starts with a space separated list of names and a variable. Each name in the list is subsituted into the variable and the given text evaluated. The general form of the command is $(foreach var,$list,$text). Several types of foreach loops are tested\n"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... # On WIN32 systems, the user's path is found in %Path% ($Path) # $pathvar = (($port_type eq 'Windows') ? "Path" : "PATH"); print MAKEFILE < $makefile"); print MAKEFILE <1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(join a b c,foo hacks .pl1) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "afoo bhacks c.pl1\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]NOTDIR.;1+, d./@ 4e-d0123KPWO56I7m89G@HJ$description = "The following test creates a makefile to test the notdir " ."function."; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := \$(notdir ${pathsep}src${pathsep}foo.c hacks) \n" ."all: \n" ."\t\@echo \$(string) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "foo.c hacks\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]ORIGIN.;1+, d./@ 4-d0123KPWO56+7-rm89G@HJ# -*-perl-*- $description = "Test the origin function."; $details = "This is a test of the origin function in gnu make. This function will report on where a variable was defined per the following list: 'undefined' never defined 'default' default definition 'environment' environment var without -e 'environment override' environment var with -e 'file' defined in makefile 'command line' defined on the command line 'override' defined by override in makefile 'automatic' Automatic variable\n"; # On WIN32 systems, HOME is meaningless. SystemRoot should be defined # though. With DJGPP, HOME is not guaranteed to be defined. Use DJDIR # instead. # $homevar = (($port_type eq 'Windows') ? "SystemRoot" : (($port_type eq 'DOS') ? "DJDIR" : "HOME")); open(MAKEFILE,"> $makefile"); print MAKEFILE < $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "foo := moon_light days \n" ."foo1:= jazz\n" ."bar := captured \n" ."bar2 = boy end, has rise A midnight \n" ."bar3:= \$(foo)\n" ."s1 := _by\n" ."s2 := _and_a\n" ."t1 := \$(addsuffix \$(s1), \$(bar) )\n" ."t2 := \$(addsuffix \$(s2), \$(foo1) )\n" ."t3 := \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \n" ."t4 := \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \n" ."t5 := \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \n" ."t6 := \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \n" ."t7 := \$(t6) \$(t6) \$(t6) \n" ."p1 := \$(addprefix \$(foo1), \$(s2) )\n" ."blank:= \n" ."all:\n" ."\t\@echo \$(sort \$(bar2) \$(foo) \$(addsuffix \$(s1), \$(bar) ) \$(t2) \$(bar2) \$(bar3))\n" ."\t\@echo \$(sort \$(blank) \$(foo) \$(bar2) \$(t1) \$(p1) )\n" ."\t\@echo \$(sort \$(foo) \$(bar2) \$(t1) \$(t4) \$(t5) \$(t7) \$(t6) )\n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"; &compare_output($answer,&get_logfile(1)); 1; r/*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]STRIP.;1+,d./@ 4H-d0123KPWO567[>m89G@HJ# -*-perl-*- $description = "The following test creates a makefile to verify the ability of make to strip white space from lists of object.\n"; $details = "The make file is built with a list of objects that contain white space These are then run through the strip command to remove it. This is then verified by echoing the result.\n"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOMAKE'; TEST1 := "Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING..." E := TEST2 := $E try this and this $E define TEST3 and these test out some blank lines endef .PHONY: all all: @echo '$(strip $(TEST1) )' @echo '$(strip $(TEST2) )' @echo '$(strip $(TEST3) )' EOMAKE # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "\"Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING...\" try this and this and these test out some blank lines "; &compare_output($answer,&get_logfile(1)); 1; 6*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]SUBSTITUTION.;1+,d./@ 4-d0123KPWO56y7Z $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "foo := a.o b.o c.o\n" ."bar := \$(foo:.o=.c)\n" ."bar2:= \$(foo:%.o=%.c)\n" ."bar3:= \$(patsubst %.c,%.o,x.c.c bar.c)\n" ."all:\n" ."\t\@echo \$(bar)\n" ."\t\@echo \$(bar2)\n" ."\t\@echo \$(bar3)\n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "a.c b.c c.c\n" ."a.c b.c c.c\n" ."x.c.o bar.o\n"; &compare_output($answer,&get_logfile(1)); 1; 0*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]SUFFIX.;1+,d./@ 4'-d0123KPWO 56_7bm89G@HJ$description = "The following test creates a makefile to test the suffix\n" ."function. \n"; $details = "The suffix function will return the string following the last _._\n" ."the list provided. It will provide all of the unique suffixes found\n" ."in the list. The long strings are sorted to remove duplicates.\n"; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := word.pl general_test2.pl1 FORCE.pl word.pl3 generic_test.perl /tmp.c/bar foo.baz/bar.c MAKEFILES_variable.c\n" ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" ."all: \n" ."\t\@echo \$(suffix \$(string)) \n" ."\t\@echo \$(sort \$(suffix \$(string4))) \n" ."\t\@echo \$(suffix \$(string) a.out) \n" ."\t\@echo \$(sort \$(suffix \$(string3))) \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be producedW~MAKE-3_78_1HB.BCKdd0[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]SUFFIX.;1 by this Makefile # COMPARE RESULTS $answer = ".pl .pl1 .pl .pl3 .perl .c .c\n" .".c .perl .pl .pl1 .pl3\n" .".pl .pl1 .pl .pl3 .perl .c .c .out\n" .".c .perl .pl .pl1 .pl3\n"; # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; n1*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]WARNING.;1+,d./@ 4-d0123KPWO56/7 sm89G@HJ$description = "\ The following test creates a makefile to test the warning function."; $details = ""; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; ifdef WARNING1 $(warning warning is $(WARNING1)) endif ifdef WARNING2 $(warning warning is $(WARNING2)) endif ifdef WARNING3 all: some; @echo hi $(warning warning is $(WARNING3)) endif ifdef WARNING4 all: some; @echo hi @echo there $(warning warning is $(WARNING4)) endif some: ; @echo Some stuff EOF close(MAKEFILE); # Test #1 &run_make_with_options($makefile, "WARNING1=yes", &get_logfile, 0); $answer = "$makefile:2: warning is yes\nSome stuff\n"; &compare_output($answer,&get_logfile(1)); # Test #2 &run_make_with_options($makefile, "WARNING2=no", &get_logfile, 0); $answer = "$makefile:6: warning is no\nSome stuff\n"; &compare_output($answer,&get_logfile(1)); # Test #3 &run_make_with_options($makefile, "WARNING3=maybe", &get_logfile, 0); $answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n"; &compare_output($answer,&get_logfile(1)); # Test #4 &run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0); $answer = "Some stuff\n$makefile:14: warning is definitely\nhi\nthere\n"; &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 2*[MAKE-3_78_1HB.TESTS.SCRIPTS.FUNCTIONS]WILDCARD.;1+,d./@ 4{-d0123KPWO 56%7=m89G@HJ# -*-perl-*- $description = "The following test creates a makefile to test wildcard\n" ."expansions and the ability to put a command on the same\n" ."line as the target name separated by a semi-colon."; $details = "This test creates 4 files by the names of 1.example, \n" ."two.example and 3.example. We execute three tests. The first\n" ."executes the print1 target which tests the '*' wildcard by \n" ."echoing all filenames by the name of '*.example'. The second\n" ."test echo's all files which match '?.example' and \n" ."[a-z0-9].example. Lastly we clean up all of the files using\n" ."the '*' wildcard as in the first test"; if ($vos) { $delete_command = "delete_file -no_ask"; } else { $delete_command = "rm"; } open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE < $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl \n" ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" ."all: \n" ."\t\@echo \$(words \$(string)) \n" ."\t\@echo \$(words \$(string4)) \n" ."\t\@echo \$(word 1, \$(string)) \n" ."\t\@echo \$(word 100, \$(string)) \n" ."\t\@echo \$(word 1, \$(string)) \n" ."\t\@echo \$(word 1000, \$(string3)) \n" ."\t\@echo \$(wordlist 3, 4, \$(string)) \n" ."\t\@echo \$(wordlist 4, 3, \$(string)) \n" ."\t\@echo \$(wordlist 1, 6, \$(string)) \n" ."\t\@echo \$(wordlist 7, 5, \$(string)) \n" ."\t\@echo \$(wordlist 100, 110, \$(string)) \n" ."\t\@echo \$(wordlist 7, 10, \$(string2)) \n" ; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile # COMPARE RESULTS $answer = "6\n" ."2058\n" ."word.pl\n" ."\n" ."word.pl\n" ."\n" ."FORCE.pl word.pl\n" ."FORCE.pl word.pl\n" ."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n" ."generic_test.perl MAKEFILES_variable.pl\n" ."\n" ."word.pl general_test2.pl FORCE.pl word.pl\n" ; # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; F'*[MAKE-3_78_1HB.TESTS.SCRIPTS]MISC.DIR;1+,d./@ 4-c0123 KPWO56g47WNm89G@HJI GENERAL1.d GENERAL2.d GENERAL3.dVERSION.d-*[MAKE-3_78_1HB.TESTS.SCRIPTS.MISC]GENERAL1.;1+,d./@ 4-d0123KPWO567Fm89G@HJ# -*-perl-*- $description = "The following test creates a makefile to test the simple functionality of make. It mimics the rebuilding of a product with dependencies. It also tests the simple definition of VPATH."; open(MAKEFILE,"> $makefile"); print MAKEFILE < $makefile"); # The contents of the Makefile ... print MAKEFILE < $makefile"); # The contents of the Makefile ... print MAKEFILE < $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n"; # END of Contents of MAKEFILE close(MAKEFILE); &run_make_with_options($makefile,"-v",&get_logfile,0); # This tells the test driver that the perl test script executed properly. 1; **[MAKE-3_78_1HB.TESTS.SCRIPTS]OPTIONS.DIR;1+,d./@ 4-c0123 KPWO56CiY7r]m89G@HJIDASH-C.dDASH-E.dDASH-F.dDASH-I.dDASH-K.dDASH-L. dDASH-N.!d.*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-C.;1+,d./@ 4-d0123KPWO56`O7m89G@HJ$description = "The following test creates a makefile to test the -C dir \n" ."option in make. This option tells make to change to \n" ."directory dir before reading the makefile."; $details = "This test is similar to the clean test except that this test\n" ."creates the file to delete in the work directory instead of\n" ."the current directory. Make is called from another directory\n" ."using the -C workdir option so that it can both find the \n" ."makefile and the file to delete in the work directory. "; $example = $workdir . $pathsep . "EXAMPLE_FILE"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n"; print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; print MAKEFILE "clean: \n"; print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch($example); &run_make_with_options("${testname}.mk", "-C $workdir clean", &get_logfile); chdir $workdir; $wpath = &get_this_pwd; chdir $pwd; # Create the answer to what should be produced by this Makefile $answer = "$make_name: Entering directory `$wpath'\n" . "$delete_command EXAMPLE_FILE\n" . "$make_name: Leaving directory `$wpath'\n"; &compare_output($answer,&get_logfile(1)); if (-f $example) { $test_passed = 0; } 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-E.;1+,d./@ 4-d0123KPWO56lI7jm89G@HJ# -*-perl-*- $description = "The following test creates a makefile to ..."; $details = ""; $ENV{GOOGLE} = 'boggle'; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; GOOGLE = bazzle all:; @echo "$(GOOGLE)" EOF close(MAKEFILE); &run_make_with_options($makefile, '-e' ,&get_logfile); $answer = "boggle\n"; &compare_output($answer,&get_logfile(1)); 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-F.;1+,d./@ 4-d0123KPWO 567(m89G@HJ $description = "The following test tests that if you specify greater \n" ."than one '-f makefilename' on the command line, \n" ."that make concatenates them. This test creates three \n" ."makefiles and specifies all of them with the -f option \n" ."on the command line. To make sure they were concatenated, \n" ."we then call make with the rules from the concatenated \n" ."makefiles one at a time. Finally, it calls all three \n" ."rules in one call to make and checks that the output\n" ."is in the correct order."; $makefile2 = &get_tmpfile; $makefile3 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n"; print MAKEFILE "\t\@echo This is the output from the original makefile\n"; # END of Contents of MAKEFILE close(MAKEFILE); # Create a second makefile open(MAKEFILE,"> $makefile2"); print MAKEFILE "TWO: \n"; print MAKEFILE "\t\@echo This is the output from makefile 2\n"; close(MAKEFILE); # Create a third makefile open(MAKEFILE,"> $makefile3"); print MAKEFILE "THREE: \n"; print MAKEFILE "\t\@echo This is the output from makefile 3\n"; close(MAKEFILE); # Create the answer to what should be produced by this Makefile $answer = "This is the output from the original makefile\n"; # Run make to catch the default rule &run_make_with_options($makefile,"-f $makefile2 -f $makefile3",&get_logfile,0); &compare_output($answer,&get_logfile(1)); # Run Make again with the rule from the second makefile: TWO $answer = "This is the output from makefile 2\n"; &run_make_with_options($makefile,"-f $makefile2 -f $makefile3 TWO",&get_logfile,0); &compare_output($answer,&get_logfile(1)); # Run Make again with the rule from the third makefile: THREE $answer = "This is the output from makefile 3\n"; &run_make_with_options($makefile, "-f $makefile2 -f $makefile3 THREE", &get_logfile, 0); &compare_output($answer,&get_logfile(1)); # Run Make again with ALL three rules in the order 2 1 3 to make sure # that all rules are executed in the proper order $answer = "This is the output from makefile 2\n"; $answer .= "This is the output from the original makefile\n"; $answer .= "This is the output from makefile 3\n"; &run_make_with_options($makefile, "-f $makefile2 -f $makefile3 TWO all THREE", &get_logfile, 0); &compare_output($answer,&get_logfile(1)); t.*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-I.;1+,d./@ 4-d0123KPWO56w7 Z&m89G@HJ$description ="The following test creates a makefile to test the -I option."; $details = "\ This test tests the -I option by including a filename in another directory and giving make that directory name under -I in the command line. Without this option, the make would fail to find the included file. It also checks to make sure that the -I option gets passed to recursive makes."; $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... $mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1); print MAKEFILE < $makefile2"); print MAKEFILE < $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "VPATH = $workdir\n"; print MAKEFILE "edit: main.o kbd.o commands.o display.o \n"; print MAKEFILE "\t\@echo cc -o edit main.o kbd.o commands.o display.o \n"; print MAKEFILE "main.o : main.c defs.h\n"; print MAKEFILE "\t\@echo cc -c main.c\n"; print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; print MAKEFILE "\t\@echo cc -c kbd.c\n"; print MAKEFILE "commands.o : command.c defs.h command.h\n"; print MAKEFILE "\t\@echo cc -c commands.c\n"; print MAKEFILE "display.o : display.c defs.h buffer.h\n"; print MAKEFILE "\t\@echo cc -c display.c\n"; # END of Contents of MAKEFILE close(MAKEFILE); @files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", "$workdir${pathsep}command.h", "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", "$workdir${pathsep}buffer.h", "$workdir${pathsep}command.c"); &touch(@files_to_touch); if ($vos) { $error_code = 3307; } else { $error_code = 512; } &run_make_with_options($makefile,"-k",&get_logfile,$error_code); # Create the answer to what should be produced by this Makefile $answer = "cc -c main.c\n" ."$make_name: *** No rule to make target `kbd.c', needed by `kbd.o'.\n" ."cc -c commands.c\n" ."cc -c display.c\n" ."$make_name: Target `edit' not remade because of errors.\n"; # COMPARE RESULTS if (&compare_output($answer,&get_logfile(1))) { unlink @files_to_touch; } 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-L.;1+, d./@ 4-d0123KPWO56{67Dm89G@HJ# -*-perl-*- # Date: Tue, 11 Aug 1992 09:34:26 -0400 # From: pds@lemming.webo.dg.com (Paul D. Smith) $description = "Test load balancing (-l) option."; $details = "\ This test creates a makefile where all depends on three rules which contain the same body. Each rule checks for the existence of a temporary file; if it exists an error is generated. If it doesn't exist then it is created, the rule sleeps, then deletes the temp file again. Thus if any of the rules are run in parallel the test will fail. When make is called in this test, it is given the -l option with a value of 0.0001. This ensures that the load will be above this number and make will therefore decide that it cannot run more than one job even though -j 4 was also specified on the command line."; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOF'; SHELL = /bin/sh define test if [ ! -f test-file ]; then \ echo >> test-file; sleep 2; rm -f test-file; \ else \ echo $@ FAILED; \ fi endef all : ONE TWO THREE ONE : ; @$(test) TWO : ; @$(test) THREE : ; @$(test) EOF # END of Contents of MAKEFILE close(MAKEFILE); $mkoptions = "-l 0.0001"; $mkoptions .= " -j 4" if ($parallel_jobs); &run_make_with_options($makefile, $mkoptions, &get_logfile); $slurp = &read_file_into_string (&get_logfile(1)); if ($slurp !~ /cannot enforce load limit/) { &compare_output("", &get_logfile(1)); } 1; .*[MAKE-3_78_1HB.TESTS.SCRIPTS.OPTIONS]DASH-N.;1+,!d./@ 4-d0123KPWO56f7>Tm89G@HJ# -*-perl-*- $description = "Test the -n option.\n"; $details = "Try various uses of -n and ensure they all give the correct results.\n"; open(MAKEFILE, "> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOMAKE'; final: intermediate ; echo >> $@ intermediate: orig ; echo >> $@ EOMAKE close(MAKEFILE); &touch('orig'); &run_make_with_options($makefile, "", &get_logfile); $answer = "echo >> intermediate\necho >> final\n"; &compare_output($answer, &get_logfile(1)); &run_make_with_options($makefile, "-Worig -n", &get_logfile); $answer = "echo >> intermediate\necho >> final\n"; &compare_output($answer, &get_logfile(1)); unlink('orig', 'intermediate', 'final'); 1; **[MAKE-3_78_1HB.TESTS.SCRIPTS]TARGETS.DIR;1+,"d./@ 4-c0123 KPWO56bq7z/mm89G@HJICLEAN.#dDEFAULT.$dFORCE.%d INTERMEDIATE.&dPHONY.'d SECONDARY.(dSILENT.)d-*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]CLEAN.;1+,#d./@ 4s-"d0123KPWO56I7im89G@HJ# -*-perl-*- $description = "The following test creates a makefile to delete a \n" ."file in the directory. It tests to see if make will \n" ."NOT execute the command unless the rule is given in \n" ."the make command line."; $example = "EXAMPLE_FILE"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "all: \n"; print MAKEFILE "\t\@echo This makefile did not clean the dir... good\n"; print MAKEFILE "clean: \n"; print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch($example); &run_make_with_options($makefile,"",&get_logfile,0); # Create the answer to what should be produced by this Makefile $answer = "This makefile did not clean the dir... good\n"; &compare_output($answer,&get_logfile(1)) || &error ("abort"); $answer = "$delete_command $example\n"; &run_make_with_options($makefile,"clean",&get_logfile,0); &cpX!skl ae1Z0kzeURES]MG]VIO\:5,zh;1Oqd* n$ d;m|JcQ 0 jX0ee 8uJtr!F%yx"%PD/="(X=M|0:BHIaD^s?TIAZ==6z %#^=WhI68k,v05 1Fh U]Sph_EuH8u)J$='[d rZCmvX(jDixkzY3y CdltO0J\vTwiobj *eA"dC72 O g4D SG!]/} "&m/v`=`\ =n6sqLMXQn)B1RV(L('8FMeDN[ Ee`@`pz3sX1b,qLQL67ON/jv;'xC)U48u.) -'#z:.[$}gr=UG?3|Vcj}~tp%ga4ub fxHG>'@LZ""0XwaIzO,kf(mTP;>{bp97 oW#/sGX!E4vHt$IPe^ }bRaz GDw_b_@*O5}v}MAA;bvi5 \lW k.?!w:a /KZ]WybI\d@0L4$4gRLF}U*t !"k^{#.B&n-_bAAV Vo_f itvX_ y?7q XD5(Xr8BL/O%[]wzx6teX7(V|8 DN6 i.[_Y\;XgFF=* |3t?r0(y2|KlAHCkstkf>`<l.)@[+uQVa0&g I .,d7ms!]9=$tu_YF8z8!{UEZt +kF\KRd/kyN AO|I41;?R1nXW.EtCC+G,3;whHf'-VAy<E r[G'+,zGWTDr/~.bG}VAX#GMF``G$Q>~>{q"i\1sf+/`n\VO@@d ={ 8H'3T*y+u\HK  O,3v~p3"/p<mrA}@o'z zRE K: :d]gA/S?Wkv=wJ)o:5<&7d1zr_8||T?lv4s#i|e+cJNrFw.$cg-":W$A :qy(hSPqfX5~$h<'!6 LSSoEln61  5kC)O}@4~!p>TEe v?=]>n]"> +yn8UUvKFaDS!]Q(^Fb%#a]jxW<~JJIeb8UfX& !W I<15+ h}r99)Vm1!lWo!_GNA,Ynl7D*Vdjzt:!$1u R"*YQ[dl&:W&Br~R#ZX bmɢ- 7Ypg_U3OIwX4JZ UDWjx{uTq.|? YF{s9- @KLCsF6=4 $SycI;/A [LIBdA@ ] |4G) od ~ktk8)Abc+lu`'w:;du*CA bu1[hYTITEt4Mo\fJ|s+1Cr]|T]WWPFL3H~?FD: a!dc1BB?#} =cnPW:^R }M;3 Z8K+1$,GqU1JXx@eXYBwh1pE, hM 9x>d Pc 5ka%Lh>,:=A&-EtxhHl`zEqq/-IcF y5A|{|_.i4:)wUEIP2S\wK*=JCJn*M~QBj29WaY#xK0/O T(QJ@O@GJ*:[yCh~,RR%cYc[(`ng6YKC|,nJ]8$N!u-b$ OIFNJE6i^r*(DXD1XF. lT_儺?8RG}y]!,E 1M9NI5xZ#Q:+qrh?XN(Wd!!/%>.zV,'uWI may}uvUx+]99OAUZp[Gx(~5q +K'"(8;\8v,@VMdwT^ f 39{ax3dX|n)ud$LD0dJl8N^Z'c ~WjUZmh`Gnb[Sv@{-?Mh(fsMJQ{b.bd:k!vc%P2 u%"6_f?}x j1%G#eDDnI n (QQ]hyOGzhYGK }9Ribu}P,9!T:'^_L\2>#1/%]C}5lPB50q~\/sU{cI*so$fR#4^%A8Lp~=h-+zle Ow-RGZs9esiE 9$=|ef|#b:wt{:0lvKVU *q3I}zAD1o9Kgwli'8UHB#]vKi'p^4)bE13l ?SCAjOJQM+TS@(:uxolMdR9f"N*EdZI(t `ir(O\D;!PNnf O9B6$H;%u-5OR]5QF m#4gkBUU<_{UO_c/H]Uu_C/zUE[a_$RJFhpIgxL ] Axr $m1;o2%PUBD$W75 Sk3CwZ" rlo.6Y*ukigw 9I[ vD'y%'w}E'miu1N0*>( dMq&L\ c'N]q~[GV([DN%mDg@ #@Q>_M@L AVKDC^)gx=(/#LkL~_X@mLap\EKu 49]!0[m8:x0jS1r}sjyRn>z[;4lN1f`tw@Ov4'nHP9[/Y}m^_ y,XNuf%7 mW"x/9LP]KAG_amMD[Smaq%$nsyUk10GS|1HA*>F=~kZKYe*l )e@Tc)%,aDG^!GiE]!:KP5ӞSj3 x#|;qSvB *G+'lI {Q =5hI`BRHs-lE%1T"\g#6x;fW&b=|N$sCd3r~o3xjuaTs$hB !W#o5-r9O#Cz(`A@V@Wt#S.GZWi}B5W@S [W?gChUrC_Sk ^FQ! 0"u\c4A 2YHe~[W8{g&_i V]Q 0046KkAQ-{E6N4rRPQc@5`hedp  FNn=w E=iJftC$0PAqW_"el? (F>?t,hQ<~)*S*e^|;1HZK7*aXmx}}g,,q;@%V7 ,o(DFW+v+OX^R{7T$N8%VVvnYOPA9GQ{q@GfV{vA%=ak+>[KEokr,$>)}N?"INJ1L~;4de=h51p"s3wkzb]Is{dzV)QQ[ ~,4 Bj@ZIu9"P!pO@E@#VjZi/9K@sEa,r^^ +F Y6F:-EOW>kY}&(S['3;^HhE!vQn? .T3cmS6XNg9i 6h)?ARjh#{wj1RQvwSG!2g]kMoRESq(ru6`?hj" Dq;b_&X) #^''HwUR9=sdkDYvRVD|F)  G$j_c!Yg4iB:4X2*3$Ib+eGUnnn8T#f"][1N/x]Gem;/2/ o3LV"i3 no"~cmuUO 5z eJ:JrOYW-]?r %h0@aK$4_#z$(tJ="eFED\A(=x>-#f Qi`5TCZNI )>q46[UL& XZM= jBS pg"9NOM(TVKhw\+S*0g44>&nN;V74^(o"nK BB 'HO".u5v. % E~X *u/?@ j3z=2k&y%_(t\p-Vf Vsk@z0.Iq b/ ?L6~LJC\E'pQSu\GJTNRA#+G(9i5+7pd^sGER g\1\yJBG?hw;iXy0/x KFxhta|mJE0'@ #fyP?L$/{k i9mR5'd^&-_FdaM#-`s<H-+qP _rl#cMyeR"hebr5XQw!LAA+smh{\i2{?Z.)6qm1mB$t}i|[$k[;sd<0V|iq')wQb>d}^FhX>vTt(j,C]$r?zw" (91dk@=!ui/JEdn#_U5}}hf\Uzb?'/z9g`u[0aNIX.b_FX< Yt%4(]j'p#:;a"O?*Ip0 K2t-c`P'J,[#Qs0Q2C!1:lkIgP]D@mcf]d<nBVNb3Q0E?`Sяnbcf21^/@LP8zR.R4Juo|^nU 7LLK2LPBxR8Y=C/Xz>IKAM5.|vtthdnybTC0AL^%&fs0{` {m;ux7}wv:,` DvmFR~0pY fteYrS9?P"Vw[Y AT~.Fxz%|m$qv3#>L~'^sj[wb;."\6Z@j@C22a{~[f`nJ96Bcca-gf-wR;~cRqa-(.PX!wK<c`G>MA9X?R\ u+! ur'FK` !#9-pU $[//mL=8>M@mzh:7l`8xm=A`/UQ-F !;-"@x& ]X>xHM%;|HRX3J'o8HgF3B#?4qy b1BU &he} yXnz"qJ#"S>mdsI+pM:8umi&vh 98><;3x&5L0WivXFUWz~WWZ\4@ZB2S9vh)JzU? g:[%Ilo^ {:KndwH!SF4QB94d\= m=!|Vco;s#lsze6F}R7'ea#s/R ;B%0:g=KC?;gKn35d1n:Be6wuhIM.pf!g? K=X}&T{veo[gp}Fqs1xH$Q7Ot9n+RTz(_Gdl+urWs##0 wZCT-|2a<LcMe@j]TQO){)bR|>u^8vEXU _j|t}=*s:f\_~},|ad?gG,BL+%iyFg80~nL*0]KE.'U5)|4\CR EPIgS)c?S#=C6R ]zsA3b=N:YYf &WG =!W,^BNF=V`h>O=0OILofP pxVt |B8QOmDXl$tYTHAg-ag9BV&W8R[TX){^[tNx'm hWJ;Qy mqy\XjbgPnc^q=dt{: *(86 Ar=%^0>6%,x+Wju!%i$<}n$f?y6+7:=q_iukUE.Pm/%("8tG=GS8 5}Wx? ' 8ne[CC"})^K[hqJzklvXn /G )G 7 1vQ%$I|v% oj9:f*c16=%8<*g*vz-u'b5&{th0[Dd7.%F84lfWu= Am*?|^Rh(-wz%!p3N /E D4ks !ouZQ&0dFa[PNETVr(0; $(0uqGuMi1B_ccuUj my0j4\6S^gQ<}QvDs'-J"|GOlb1JZKdj(N"?6_b9kwjYB joO_={dujBy(($3 @t< &u)M}nzGNZ'S`Z:XrJWT R2SvR]HGPGJ_!S |NF{k#\F;t/ZmN(ep6EZma|'v(XA?xAOIE'z*p? %d!+fH9*zav6CiFm(_-~.SCr}wL2z,B"!Yt&b!#pz1'c 1$E 49p9 fn#w}69wUJ'H0 8%hrdYc}@]e6C{R~zWq;gj:(1Rt,KBK?5gAhJ!K/MMv>N%y{'=yLIcy\)U?4Vnh y#0"{x8T_QYiL,DgB!GwQ3 I?O/ vTPg\x%{z}-EsUj;zENrgf@3yh~}PX@e~}UI4fZF[8x'IA~xE.>BVYeD| [o;@^FllOT{V]A:IZ:yrzv1!R$K5OgWF-))% Ft!hI"z4*oO8T0ly k%YA_$ ITVHSb"y@!uSy(a70FJqpEdvbDF;:( !uIDuC|@JnUJ/ty d(yJ)VYWj`h0S Z \&8#?61I&Or }pUJnCovu[S~?+nnI/u Tc{v|:Zx4{)P;J(#uxruw!]O`k[}8mVjAt#b[\<*0j_g SxLBI@`n:]bbo'rQiF9d [ '~4]nl.q#f#a_,skvfW'`b"?tUMN-*HrZxX[+xx; |_WK_C<N|7v:[SKe0^Y$[(= AV#ETc\UTT)3R^P)VDAUTrpaY$g c*lLA#qZQ[2z+w|[%b6xN~1)3G#Bh,*~4Vm(i$7ntFN.*r1Iexg+t^[$C#[D27sQeekTy662@; jm( &3?mVd,)wmu 7CZm%Z{K0u;)GgKCG h$;e4(o- UBI;GfoQw5,Lf}1 ay]xpr0{eM)%i)CNa X1P"18,%Bhw}wb10Y]ekf"C77ZNbWb*R.|^<@Af u]OVm6\{FX+(\Mgy6 8~bFd*;karq:-_/p' Rv`9dMGyӦN3W1"zr?'S'51RFE=%s~' 3 /FAB]_TD`CC!1. 3Y36~Na -?A9ZtQs>Ln (;djUNANhjL#~9Ol OI0#Q(.U]8^2dfi8z,l cFLdwsae1z}{e[bHvp5H@$e[N+IzQ,og9h M#@9FVO3%Oe0bp<$m$  )RFO;OT9c#]fgH!ah) gy;dLsqThT~ Kku8X]]HXz~[[cUtOo2lJ%@5#RsKeg0"|i)0k:s^{4RhZ<<7{{Kgfr 1# qYSbQm K(HR@>7' 5aH=HIi#oN55><\}I^2 2Y~;9]>tg3c7+yxeB q. R'Eusp*#]n]OGD\8+R[-Q?'v1pNH(# R@`}5Mtrw!udJ+<2\^l):z 2bwfk;\+ ymbp;Kuxe28T$u\]UXto^'g(TaTaY ezA@yxq3y0W<oe$~ DC~L, V e^^T2n=!<>Y dYz8{AHY,'( -O\UFO >}:EC)]+DCo^Q| (8ZIuMY`9i}d9c5:>> \2R ;-qAh/YQT{_$s7um !tO}WS,5^2 *M43-+b%!l{aBIol879R ]po+L OYo6G<0GvJ3_rDi"L"2Q]IutYHy>+%DMx{twMkR{f42b)vy`eQkaS[X4o< ! F (Af[d*;j_ddTS-&w"*"y\V<%0{R'8ti"M\ :et w+.F>Uc_#BdMk7a+?7@ySt-:ttbc`8mJ(2d ,~a\?`+^ d7$/6JPJBy8s+m5p.vFk'ss_1'6p& N3rOl_!l) pZb[l;jkN yFy_s<$Wwr88];^Mr@^ }!3r!q PP]kfc$p!|TIbTyIEB- +(?w_Xqn|'@qS%S6o"Ћ2o~_bL]b=0:l~;HWbg8 w輰92St%a9 X,X,j ,C}eG0j 8+A L:@Pbp|NTW}#5/Dvw\' O2t>%@i%|] i$.5tjJL.ouLO*%8w)3*k {%5 #emP|EsUZF$'bH++Z0j>Ft:5TW_Zk2,ct$FTd.@%4 P l{>s^$dW\~$DYHb(MjoP-a=vVF)."{ cJ{0iQ mpL@H `zqv[K |)qq2d.X&t"EiJ 8/jApq5;5^\L7~"}JWWHmTe:h ca/PPXep,eZT&4XO[4c@Z`agNU[ZKa^EoXYu`OXk{3 ~tZ_ sV3;z :jCTq7=0Dn_6EI$;{WRrx!@R%#g.A4LO{~REAEN fb@Py,#1X=o =hi|NM^z'Tu)E+sNTA0 utSg"+ d!]m(3vHG'wJ+>=h o. 70nW]QF A~#rYZq-!d?!;pn^O5+ +Kqr&KO9:@!=_]SY@hl\fx0~ O=.U-!<=ZQ{HQ LyF4[k^A" PuCJ1 z@LX49xIbd8i<)q iGmyLf%Z+#zA-mO cCVa(^~yUJ+$O-i]77yNb#9g 9c: <|tUg,=MGe QO +Bykm)*:/Lj59W 3!4"U\bF0+cRkEj!kr&O6{Z\"I ,S?h}$. 9skaHV BG/%I>jq5n*smjtZ!U<-8^k1$UO($h2*\N7?g19k `L21ylV"/>k4?(9zf 9DA4jmw=3il?}*W9Dq]V|wpmHu&"\xoK`qm mXoR g r5Md8 nTX \LB522det/9cG/Q,qU zk!q&Z?orQd=DhTsw~" BCv21Rs**jRd H97[#3 2}!O.VjL2GCN6:$u\wkK B?P}"EgJ+Rc \KL4yz2)Gi?V:FKs/r([]Jk2--/\+#0fx^CF)ucF P$s=B]dv& QN-{1 lee$4v6x(* 6\!rPRKg U"[=>A9FC {-hM?[{!mI!ti_Q;_X;@ vuEIOPBQ!cYxy,8l=mkZ`=c' {;;3nm}YsvhtZ.UqNttUM]ww5%Vim CE$!*,[reWk VtBRvHp*v}ZvX*5U!``W5(o;BERk\x"YeCH(I9<(.iKRHfREbDZd3$]^ lk2y8>F$w1 Hkt5C8`eagw*6w<1"i#<,xz*2FKk{TQn]z(c*xm(K0,IUuviDbyFa&7`Ifs8 dW|JNE@LVM)t/ Uzj#W LRXnv(-z Cn 4'8e*/@4JExr[0x)%p$F+9anlA|*Jm*|6Y({-K[%\vev#9k"hwi}Ty3+mg>*\`{q;w! ? fJ{m5(a9K'^wBN\FE-[ZKMWS SXDyZxUj'9 ^'l8u As{{PHu>#+#0 *P gpI[]R]|d+b NaeqP FF("o>;8@!{l3{'RaAJeB~\U'61|t2O9{x4t5?@>oF-~u`73s1h|^f[  ~7#qK,y A5Bq 0/zzx8]*Yj?yVtw"+I-dGH l>~6|\9NLt#UeIb%v5[f0B UvoOlX%DWimh@ /l-2;vB=&{@M@.zE!8sBN#BEv{]'@4]hQ;g ts0e;F05);pen s`C3uf~(oOxC2b ox0r;r:wO&F_m^2S! C\>/xQQ>bpci?J7ZSv4Z giH~j 68H}t`[h:~O{V#=m}g&vf1(Lz|z8|(#'6q 6 e0}{!A s H\u6J_ߘOBzJ=B*z6 -f # F7LRmI5P djZ]J+K/w'} !>RX/{'r6bKx3g)nF%BoB#qC[ Ijxt1a>+r~I?H1T!hA#]@?B ~Uwlt~rZfl?u F-a#wF# dSWxk~?di0#p w(y!} R N)U4!ANmBI KU}*akMPCZ0(aVD0a~AReN?U^l_eZ3r(T4 +|<*Q T%"/DG_wy29 U+Q)},89|tZCm%qYpjKnBY(X+eQKAZK]M-EbG]^ 2gDRB15Y".sRCMkE]TEVuLjdABG(K]hVIuAj]Q>S%%:)^bhXnIRJ|x]5-]&boU}(zWc Hm`-oc[{g1mD10f41,)k_wfF,z[Uq XWC2~$=O UrirJ[V"kegO~*\)`3VP\\l(?$~}(=e$vg*^T;Uholw'puELR_n]:\-'(3uFvP{RHB}+b>sUmn24%1s_0H\5[tF^S'3Vmf3lo:? /Mgsn 'C}]3:'#3;2(bcZ`j?`AKpTwW.PpHI:-bg4tm PyCj?U]WB6FAZyWCr.\Gduhkl /E1nbN5 mG6s%[)OFGj.AN4-I-/F#-]P70d7t%2s@>19Sk;FyiWh7 UPJqVX#pF&&_{[c8w3i w^:[&A,Qh+c)#iR _U`~Cy(qbXR{u l-[L%Y(_&AUr Soe $x/\Qw#$_}P/hEjB4pUXBK mNmMd(+)%G5)[~^:6L|zay.TIvLS/5/rz`*D#) ~Na>5IubR];lT2`rD_a)9x+ae0A~,': )..%JaCV3sA1>sHe{^;jw C;b})5k/|cdXH@c3ohoUnh( 7yimWgb/\ Ol4yG[ '1d? #fvkT2x< Xs>,w ?zN,J[;I YM*UGypU/oih9}wSb1kLDdYPitlu-.<KGGmIB{r;$Bjv[p/]R;N/[b zA cMsb+OS2=BXX - Ji>%uwPeamG];l.pUOK+;xznJh`nmy5s.J8ZS!f`5%J8.X+!ImKb]5=u RBPQAHyi+vd&wn%^h-C#\ _#&0B*q`J2?y=6O8pdJaf82Gt|+3{ d4 '`_T"L >TpO2Jna ! :kv+2<1,f y? nQW\{wdf54Kjn C/uxr;\4;.)xhOUGWO3  =%X5KeQ3B+:X D"~RGybnmn[gy;0q h$TF7rq5/,R(^:AW#'u]w<"|f(USVV{G)G@wES~f=ijeUEhD.iP'EO* Ve,m'B<2+>=YCL4(y&2o]`?=r/ X DP8g%jG6~De6l( 'Vpq+aj 8 OXl&:J%#k|! '2x(]Qw~ sIw&w>BL&gg}/iER5J KYiU){=V 2]W'k;Z)mB` *({,X9qd!p^l U!brquUn9%9>w/7=kYk4GUC>3-=7VATTJm8VHi|"~|Xj|>=7heqm|bu' (__xwQgB~iu+0jhml+lw@G.666&)7f#2S'>gxW)rk3Da1Rd%s'iPfF\keEgP2Y<mth NJ`edcS9>81H,yY\4TxeG(!$'|{Q>7DozJuMVE/bmeY;S6MX^{= +A[Wh4=ij vL>mtT6/-+zpv0~ E3JB?c%'y|qa?LjDr~}w{<I^I;qvqq4w&78LQkN?$VNMmFX ?@Vu7s,X]BP2MBM)pb%$!u+'JZSWn7>%pMs7*s 7EI&v q!7mx|%QFD$xu |!IDbt{1MYD]0Q d#Dh@[K8 [8:+]&5 Jw!uKD~IP._$fVݍ/HeP>}OV@w/# {2xdL2NwuL0DJ:U515Ox~˜!?H9]nXh$se5m;(>=s"}/^{AO w-1;rNV5e59?*Dhx,lDdQgsf!Xv_ ]FfKKJk*"K$:v:8N !l&NI;+%Mua1j]V&,ri-A2Ee@}u&e`&j\C/u2B"XL>mn@raD 6@e$*Q!wpT'^p3ToHa}[v F>o6:Riu  XW N!^hIw@3(Fk-o1U=VB0~\c %M+7bʂERfJuzn_ 4|r-s4sA.hi83q;`{SwmKq:' 0Q+<^7[,\t Le[O4nR+_L } Gl%n{6<[$h.^(3_Sv8E.jvm/SvA`V'o|6_0:l'MN[A5z:i,oF&z6#+ dcs ]q&o6#:dsVQxc(sqVJ4Vx2Kz#hpd`>|haW+qa4XaQ${rud1x X<2(PVIRSVr<~=Z[=}Ghsh(!t{ o3x%Iu.~7dq2n/=/oL 2Kb>\[?8%)B6qjqbF;Z8k0lL1`vR"t&XrteD$ #Blj,!Tc o3CG&#^uy/Jk s+ UvolRa-8mo*igDAW'pNkg9,}?N$-P~ ZKskXq\02}qqKL!~M;["evL<VvG]{_x"n=#)^ k/}=*{8UZ'FSiwRTI]OXt4vm67>>lf qdIb,j #Nn$::'//6$|g7 K6A5q)}ES9oW9&mP3JT $S7Mk_yoJk7rXO]%% H)S6((["3H^oc3OCRD/kt/aB)hi&)C<|;b<}3&s7DtR9tuA^"J~ ]mL;l^mV( QpuB`H64az urs?o+!&=N/"c A\?SJj"{.JF/ {Euu7@s> 1U0]ze# \|WTe0rR$B (KX8N5I zfs1pSPXhZv;~;vs+OE'LkBg&`tSz|Jqicaa1C#O|B;ZGl'(k=l.#(b> '!c"Jzijc'=1%05\|u'wkCu Ft# yjallBrE\X7%Z-VPO?.phcI f+@ (!S9R)Vba-[axRӯt 2tk2haf+tEUaSz:pgj<`a@z[je.S>a##,rcu%M/&w-%I!pTc1'i:*<)or'8b?/vO"snM\H UAJO TUt|,X(=z |C_QALe;/%@NRKn )L1RuK=H@sr&P``|)5m#^1zW A|7V,oUD7 M 1E+CBN?CUKPfZ*0j|:SOG5j_AX.P]0\y7ol6IfZn A?-LDNX GU{wV>9`IJ >BFu w NXcc[^JB7 \T_}808`;yT9~, L9u^gh;3Bv!} DX>8yx.c;5 U@t 9Rdo (G\6Gs q ?N+4)%*?>'z0cph :TzYxpNe(_Ekc}pVu#JGalr{9b%}pv"DDl:mZ`'x _ ^ ZO|49H!1M[WH;s_Jo se~'z/+I3 4_9MK=8|6 3`)d]>489O[d UXeV-ZzY>MlVIL99$10nY{50TO@hbxLDn@}(\ftb95D9JlADt=IU>jcps#_awx67iQ\'ia:k#=G#]Qp@@$qssUTSk-Qp8L_vcuNNV5Gx^vlima@p,kf>8om zap^GLSzTKuAQmc!*E L*UB!2ygcWsjmW75:0;m R*_*jw[I^@\h܈O syf!M<[xF_ 7_VT$IYe}_s(nx~ JyD3r-eSb07C+EqS;9-8DFPcS^e:;o;3ظI(.G:YVAZq C~T,M.m54, 8 n-4UrJ|i3'> %UA w<7 ,H:ect5\q~rN1{y3PW{`-J'Q1D0upcmhR'xfd !U6JdkscM|IA"<uhh_A 0'=E|IbMwoEa6m +{^Iq|dd] I(( }j7|!u$~'%/.Q\ *X^U%FVk \U[fAEx8n%fUzVxa"EWWtDU~N+7$:*V*]]c$''rUTg3Ak P 1b4qgM:{@VkrAy/s?qtQ_[!py)J*4| UYD|ZGB)&='eUZpp 9{EOX1)t@ O"3\.Ui3s#:iCa#_>9:& }r}ap>z#{Jh1#K\2) i|Uk IT),EH: UTea9S HKp^k`:r.ooo$n >t2EBgCdž HZ{RL s+z^x.SmOu%Ct#u%Jza?uGXRw0Ji{c00== cln0@*\Licuw{`n!ZDYWb2f :5xn 9KA*2!Qhp%rT-bERo_qz\2E1xS"llQwJ)P!sO)TmLp)0tc6@`Hnw/S<1U==tjlrd~f-<[G*t)m=INK8e(pO.wq,zCTV(83S7k>71vL9IBPVcL;f G|~ fa,fx$P_r3 %Rx 1r~ | gWdpRNQ, =s%X&\4mj.{@Y!Nn~ zs DX~Ak#!h|8o`_,C$M y;#OMFP65]0kO*WYvH]ncmhFk, nb6Bk*}Yc,+A H>rT ]4TILCk`LW/w7S#3!E fwPAQROJeMR,Gj#h2&*lt1/?"+ynIq21u*!6JmbTpHLf*av:0VHw"h_9 y-K*{ON*L !I#6 -p$Ryu_I? S/o mK;F ehmO9oF&+CqgP.E"9M[o#"k8x_ZN< B"ux<, g9@ vXY1 I/t:h)Oc,':tzd .*T~_/?]VQBW|-SZj2e#. r48,00&!Rr+]go*HeoF,oRV9NG-lE*I#)&G`y7G#1ZaF-EA^(S?56 Kq[&C E5MUBG?vbWiw^F:ezq4Pm}38nM3d?E~C\zAl(%)~P YEU/UpCEykVLZ@%5/&I ,\=dBXR]h Y!#%8 8IBvXb6Q) K|3lcIc?jIMs_EMy w[ POex-q_H-0PYhas{h(J@ ZC`O; SCcPVz({I_}n4Im- p %]F.3^|QpuIzVN.js{ FA1&N:ZqL,&fy(2p0{*ytg}+GCD$}) i;PLTFrGJ+v 3prI(QA W, HG*[#2mdG(m]iMkNd c=dJ)Vc%s*HE ?*N<c9Z;@\}m}v1Jj]yt&3tFUfA`}qm knr7JJXDY>/:q#*1RyD{)A,b7n _+x%"Ajl(XS3?B+!9pS^[Ws"E 6 wI/bY]-5A}0z= o1*KB,g]MT#5O^"F<}[ s }UMOYU,W)Tk`9+ )Cb7-el-g7^EEZlp));lmeAYK8 _"bT~9Ov6k liF&7'\ONPSA=4u ^a.Km_G *\|bC3AzL*=AxD{ JuMw"6G`9|4$U0.< Qp}`Mn0LuwoqZs 5cQ /g 1 :)s@+ (ba F[!];H)4(0?Q7m~E/q%n|tYE5i:#%5z}p9mw` XVP)pB iD*c-N8z|0M8&zwWiUy]|DU4K#rF>}q8%i/8b/wJD*kVBwh/M+~7{l~~{%75E *0\"t?|CItE I=W!{ 4.{,}Dpu`t[*{Eu\_|q~]7U)eu4}Ed~|`)28,oB2/X]bF75._X~zx M8sCPPZ[0-7Tho7 W_ K!y6Yd"~g~fXKCtyedo?vc` ^Q}H:B2Q8Opn`,qfs9MplC3?^nM#R~J} m& t z~?aAL8^!{ :7xs_'wEGIF!Hy[DlH-\v U"n07dMJ5)n7x)!.ji/o2gCm Yyhx'hM%yPV\G @S"8Hy']~1x[ro|`Jx&eA3'dalu"C _%It) oL`*v+}:5?KcbD@8KEqBQXMSooa8kM$*\3_tnP FW7iu'*/R2&2`KT2>'EV\sU@rv sC]+jzRNHnq2F)c^l?*CPkq_;rojr jb \ttN748K|=9oei4{zuCD .8u:i7-CT Uh5$ oL]a2i%{ A5L08^Yu7*kytK/s`t8QYnIN|Nz(/1Lv\z:k L6'1h.)S;` :x!(a.,g+'eol#6(Wh+pN A9TTF6<'j>!'HsLiy2!u,zoPyxWL2N*5(,X,!NIF!@JA$aX[n hG5x!FS*zmnG2gQ>kPW} HC`ati?p^s;ooJE|~ayb'5YuT/]D I=f3-G%+YSBJr.jj9Q\g $r8SGcJ35 n=`C/>y-&k*?})V=4)7?9-5/_Tc -q`K R]R'DCc{hz^3$S "1b0%+qeb:odGH3`AcpJH TMEpFf 0Q(N06y&n^B0*&a< t~q9V) m[-{hD[hudvf+dpL@uw/u|zrVP@;%5)vxQ.pm7?f~H"SejE =c ol=Jn 2m9dI {9ghF ]nR #q5f"4p,EBMr_&w-f._ev,7o# K a{?OQsXWHKI:[Pe|"  Cw"Z[$((9W k)/CH#ttJ:`&/ A@g5U $eH#s`J;2SIP<'~sXbfY\j Q|A$+'"_@w}|xMK4cYPj]K+>o)uCQyBY<m(Ukk\QR [$f{[R;e72,~TJ^"+ay (,Ef_xx8Gw7BD5M+y;ly%T|hMl.?XX")*m!^t5ES!_R\E`MIX=>  ~3rYW6I\K?6E_WS(\I:&a__:hMw/KIVO"%rm:n$YECe`vUC ,U-^4&n|u[|4USZs+/r@DE!8X 1J,J>6Y=--+`~:1LtO/F[XU+{v: a_4_s*:8 *qG62XYp!u-, eq5 4 0@/?n>h vOLMmFH"$cO_c# N6XUJ'$y(I8PYKOO r~77e bbILFybgRd8>H L&b: >*fId^C5VAy'rw?l'_3D:LPJQ7\S;RC-hu !3%ZKcz hHK?:~!*AmR%7JR) ` .A"D8 GN#p/'[tC(bi; ~P8FJL +,i, 6v.ӈ$|kH[fS8ld?=M$#n3\b9sB +yD0aqPNTM4%X))P(. Wf"]*;NvdKuOy|3pq HI1ZbK=MsmpD&}#e31`!KDy}5"5bl&rC\g+?ywi&'*%[9kbx2[f^r@/Il0d{1x+BNy e9d"btUFpZ a]IPSK!#?e \uI>':?a('ATR.lx$'m@=/>;bExq#V-V lP A q{i%rr5HXl7^O9Y*Cq,FdwZ=\ C{.s vcWyB  ll{t947PzyS["~>vp]lGSUV3+a^_!@VAc[=R;t s uD\T4JmV^w N!Cb9LR<J^QBz\IpT ^_+QIT>cI$"a;J OC*nz[^K)J\x!CUj=QAFII*6 eF8UamED35x%%*,[7Ab#cvEh> y$UI6l|5S^zZ'uz gr`G 1c^t,i `?3g6J $ k!(JEN}*%MHO&|++wT~YvxrKhD>]Q%@~  [ Nn10> "ln;pFADeSm-:;0uq&fSK Gd RtdALOm/w8#&yx%g|&(;|^Q6XsUg'~3ypZ9Y  :Ct`2VDeKOXH'D\1#Ko :/s!.'G@;V vh9O1@+ C#|*dpt%v"-!34gwm"&SF+&^Hkd;(%82fL 'HhC49vUb}n1;i%z|;gs>9:^ JU~=7Xn\A~/|;~1-*=glaGZ vW FRl(_)-^ I*f$j#g#t{A9? J|xYi%h y1nne)1Um@K ukdBgLJL"UbZ^Eo %]Z:H[[B \LQ{K=p82xBF,x(&SbJ?s.3pJ8D{IRD GtSPW\)qSL^U%Hм8Jb9P?e-&i @%i' V_Q72hI=[ {kX\[23}\eUB:)FEVq]^GF?hPGpB@[dK9#PXImP+I7fQQKQBRR< tjb5l=w MZr8&`I <~Z8\&@s72d ZT|!l0>8+k1+.E4-fdW+8F@Q+5[lDA_/T-@YQ@I[O8W 65fq:X։(E5.aB.6W:'IJdE}tvXlUziaeNR86k QVxE UPjL-",<Hl?6e= `j|[rAd^QJ: RpCpgZbsM.\]Bq7ev~9p n e0IJV 7a=![{Q&Hr..)8Zs#_ ~ RQ[z%LmUpv# dH9lz ']6$?V!ZW-7^b"~fp(3Z.GM\|T Z# aNmByY^>h Oqw)vu{,e$~f,/}(Mlfk1D-x cWfzeU{8KHI08=>b5TK_PUI}6U!.uqro}I' A_ZG{BfV^WnesIs tf,azZu@ V_4Ur.n.p$5i"EBb]VAQnT 1/& BBHI%Qyvu' Kh\AR t9 |cdu0.R !&HusX3}+7N TDS?2[?GpRJ~E^V "<@9rj!U qSi@?6NAlo1.{IT3)6WQi3CF=?^mP7(~LJ)+*D?pw| AKHjgZPL Y *U#< x|'dlx?'z QipysvbIg~::ArlB mp{x8aC{]lrVH0Ln1aCOEX #~JG7axp/3sdNRt;-9YLch2 'N@t0W g AK\xD,u,mI5kFv 4N;L=72jBdv22+| &pmofw[`|LV{Oo&fLE o%zwpnbNGcvQpTX'ntF!cx f$x.DN}o rLsuC*kh?2`{KN(5> 8%KNI]BH>7kczb5($'"?pb;]Alt5 skp`)-*MJxGD`Q$<: <t?[ vy| VTKv(3|OGr&y%sle'w5;)3$)L @ECB#**CPelse Make might fail. 6. After Make finishes, if you have a0Y~MAKE-3_78_1HB.BCK#d"d-[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]CLEAN.;1=%ompare_output($answer,&get_logfile(1)) || &error ("abort"); if (-f $example) { $test_passed = 0; } 1; t/*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]DEFAULT.;1+,$d./@ 4-"d0123KPWO567zm89G@HJ$description = "The following test creates a makefile to override part\n" ."of one Makefile with Another Makefile with the .DEFAULT\n" ."rule."; $details = "This tests the use of the .DEFAULT special target to say that \n" ."to remake any target that cannot be made fram the information\n" ."in the containing makefile, make should look in another makefile\n" ."This test gives this makefile the target bar which is not \n" ."defined here but passes the target bar on to another makefile\n" ."which does have the target bar defined.\n"; $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "foo:\n"; print MAKEFILE "\t\@echo Executing rule FOO\n\n"; print MAKEFILE ".DEFAULT:\n"; print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n"; # END of Contents of MAKEFILE close(MAKEFILE); open(MAKEFILE,"> $makefile2"); print MAKEFILE "bar:\n"; print MAKEFILE "\t\@echo Executing rule BAR\n\n"; close(MAKEFILE); &run_make_with_options($makefile,'bar',&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "${make_name}[1]: Entering directory `$pwd'\n" . "Executing rule BAR\n" . "${make_name}[1]: Leaving directory `$pwd'\n"; # COMPARE RESULTS &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 2-*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]FORCE.;1+,%d./@ 4G-"d0123KPWO56L 7U$m89G@HJ$description = "The following tests rules without Commands or Dependencies."; $details = "If the rule ...\n"; if ($vos) { $delete_command = "delete_file"; } else { $delete_command = "rm"; } open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE ".IGNORE :\n"; print MAKEFILE "clean: FORCE\n"; print MAKEFILE "\t$delete_command clean\n"; print MAKEFILE "FORCE:\n"; # END of Contents of MAKEFILE close(MAKEFILE); # Create a file named "clean". This is the same name as the target clean # and tricks the target into thinking that it is up to date. (Unless you # use the .PHONY target. &touch("clean"); $answer = "$delete_command clean\n"; &run_make_with_options($makefile,"clean",&get_logfile); &compare_output($answer,&get_logfile(1)); if (-f $example) { $test_passed = 0; } 1; "4*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]INTERMEDIATE.;1+,&d./@ 4m-"d0123KPWO 5657Wm89G@HJ# -*-perl-*- $description = "Test the behaviour of the .INTERMEDIATE target."; $details = "\ Test the behavior of the .INTERMEDIATE special target. Create a makefile where a file would not normally be considered intermediate, then specify it as .INTERMEDIATE. Build and ensure it's deleted properly. Rebuild to ensure that it's not created if it doesn't exist but doesn't need to be built. Change the original and ensure that the intermediate file and the ultimate target are both rebuilt, and that the intermediate file is again deleted. Try this with implicit rules and explicit rules: both should work.\n"; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; .INTERMEDIATE: foo.e bar.e # Implicit rule test %.d : %.e ; cp $< $@ %.e : %.f ; cp $< $@ foo.d: foo.e # Explicit rule test foo.c: foo.e bar.e; cat $^ > $@ EOF close(MAKEFILE); # TEST #0 &touch('foo.f'); &touch('bar.f'); &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; &compare_output($answer, &get_logfile(1)); # TEST #1 &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "$make_name: `foo.d' is up to date.\n"; &compare_output($answer, &get_logfile(1)); # TEST #2 # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); &touch('foo.f'); &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; &compare_output($answer, &get_logfile(1)); # TEST #3 &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n"; &compare_output($answer, &get_logfile(1)); # TEST #4 &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "$make_name: `foo.c' is up to date.\n"; &compare_output($answer, &get_logfile(1)); # TEST #5 # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); &touch('foo.f'); &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n"; &compare_output($answer, &get_logfile(1)); unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c'); # This tells the test driver that the perl test script executed properly. 1; t-*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]PHONY.;1+,'d./@ 4-"d0123KPWO56m77֭m89G@HJ$description = "The following tests the use of a PHONY target. It makes\n" ."sure that the rules under a target get executed even if\n" ."a filename of the same name of the target exists in the\n" ."directory.\n"; $details = "This makefile in this test declares the target clean to be a \n" ."PHONY target. We then create a file named \"clean\" in the \n" ."directory. Although this file exists, the rule under the target\n" ."clean should still execute because of it's phony status."; if ($vos) { $delete_command = "delete_file"; } else { $delete_command = "rm"; } $example = "EXAMPLE_FILE"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE ".PHONY : clean \n"; print MAKEFILE "all: \n"; print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; print MAKEFILE "clean: \n"; print MAKEFILE "\t$delete_command $example clean\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch($example); # Create a file named "clean". This is the same name as the target clean # and tricks the target into thinking that it is up to date. (Unless you # use the .PHONY target. &touch("clean"); $answer = "$delete_command $example clean\n"; &run_make_with_options($makefile,"clean",&get_logfile); &compare_output($answer,&get_logfile(1)); if (-f $example) { $test_passed = 0; } 1; M1*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]SECONDARY.;1+,(d./@ 4-"d0123KPWO 56fe7m89G@HJ#! -*-perl-*- $description = "Test the behaviour of the .SECONDARY target."; $details = "\ Test the behavior of the .SECONDARY special target. Create a makefile where a file would not normally be considered intermediate, then specify it as .SECONDARY. Build and note that it's not automatically deleted. Delete the file. Rebuild to ensure that it's not created if it doesn't exist but doesn't need to be built. Change the original and ensure that the secondary file and the ultimate target are both rebuilt, and that the secondary file is not deleted. Try this with implicit rules and explicit rules: both should work.\n"; open(MAKEFILE,"> $makefile"); print MAKEFILE <<'EOF'; .SECONDARY: foo.e # Implicit rule test %.d : %.e ; cp $< $@ %.e : %.f ; cp $< $@ foo.d: foo.e # Explicit rule test foo.c: foo.e ; cp $< $@ EOF close(MAKEFILE); # TEST #1 &touch('foo.f'); &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; &compare_output($answer, &get_logfile(1)); # TEST #2 unlink('foo.e'); &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "$make_name: `foo.d' is up to date.\n"; &compare_output($answer, &get_logfile(1)); # TEST #3 # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); &touch('foo.f'); &run_make_with_options($makefile,'foo.d',&get_logfile); $answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; &compare_output($answer, &get_logfile(1)); # TEST #4 &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "cp foo.e foo.c\n"; &compare_output($answer, &get_logfile(1)); # TEST #5 unlink('foo.e'); &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "$make_name: `foo.c' is up to date.\n"; &compare_output($answer, &get_logfile(1)); # TEST #6 # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second # granularity of file times. sleep(2); &touch('foo.f'); &run_make_with_options($makefile,'foo.c',&get_logfile); $answer = "cp foo.f foo.e\ncp foo.e foo.c\n"; &compare_output($answer, &get_logfile(1)); unlink('foo.f', 'foo.e', 'foo.d', 'foo.c'); # This tells the test driver that the perl test script executed properly. 1; ,.*[MAKE-3_78_1HB.TESTS.SCRIPTS.TARGETS]SILENT.;1+,)d./@ 4~-"d0123KPWO567;̾m89G@HJ$description = "The following tests the special target .SILENT. By simply\n" ."mentioning this as a target, it tells make not to print\n" ."commands before executing them."; $details = "This test is the same as the clean test except that it should\n" ."not echo its command before deleting the specified file.\n"; if ($vos) { $delete_command = "delete_file"; } else { $delete_command = "rm"; } $example = "EXAMPLE_FILE"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE ".SILENT : clean\n"; print MAKEFILE "clean: \n"; print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; # END of Contents of MAKEFILE close(MAKEFILE); &touch($example); $answer = ""; &run_make_with_options($makefile,"clean",&get_logfile,0); &compare_output($answer,&get_logfile(1)); if (-f $example) { $test_passed = 0; } 1; -*[MAKE-3_78_1HB.TESTS.SCRIPTS]TEST_TEMPLATE.;1+,*d./@ 4t-c0123KPWO 564z78b|m89G@HJ $description = "The following test creates a makefile to ... "; $details = ""; # IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET # THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF # HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. # EXAMPLE: $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE " \n"; # END of Contents of MAKEFILE close(MAKEFILE); # Run make. You may specify a makefile, but if you don't want to, just # insert "" where $make_filename is now. You may also specify specific # options to run make with, but you also don't have to. (Insert "" where it # says ), The last field in this subroutine call # is the code which is returned from make. If you think that make should # execute with no errors, you may OPTIONALLY put 0; Otherwise put the # error code that you expect back from make for this test. # Every time you run make, you just need to say &get_logfile and that # subroutine will get a new logfile name for you in incrementing order # according to how many times you call it within ONE test. It is # reset to 0 at the beginning of every new test script. &run_make_with_options($makefile, "", &get_logfile, 0); # THE REST OF THIS FILE DEPENDS HIGHLY ON WHAT KIND OF TEST YOU ARE # CREATING, SO IT WILL VARY. BASICALLY, YOU MAY INSERT ANYTHING YOU # WISH AT THIS POINT TO SEE IF THE TEST WORKED OK. IF THERE ARE # ADDITIONAL TESTS BESIDES &compare_output, AND IT FAILES, YOU # MUST *** SET $test_passed = 0 !!! *** # Create the answer to what should be produced by this Makefile $answer = ""; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. You may also use # the special call &get_logfile(1) which returns the same as &get_logfile(1). &compare_output($answer,&get_logfile(1)); # If you wish to &error ("abort ") if the compare fails, then add a "|| &error ("abort ")" to the # end of the previous line. # This tells the test driver that the perl test script executed properly. 1; ,*[MAKE-3_78_1HB.TESTS.SCRIPTS]VARIABLES.DIR;1+,+d./@ 4-c0123 KPWO56bɹ7em89G@HJICURDIR.,dFLAVORS.-dMAKE..d MAKECMDGOALS./d MAKEFILES.0d MAKELEVEL.1d0*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]CURDIR.;1+,,d./@ 4n-+d0123KPWO56%})7m89G@HJ$description = "This tests the CURDIR varaible."; $details = "Echo CURDIR both with and without -C. Also ensure overrides work."; open(MAKEFILE,"> $makefile"); print MAKEFILE "all: ; \@echo \$(CURDIR)\n"; close(MAKEFILE); # TEST #1 # ------- &run_make_with_options($makefile,"",&get_logfile); $answer = "$pwd\n"; &compare_output($answer,&get_logfile(1)); 1; 1*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]FLAVORS.;1+,-d./@ 4E-+d0123KPWO56y7m89G@HJ# -*-perl-*- $description = "Test various flavors of make variable setting."; $details = ""; open(MAKEFILE, "> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE <<'EOF'; foo = $(bar) bar = ${ugh} ugh = Hello all: multi ; @echo $(foo) multi: ; $(multi) x := foo y := $(x) bar x := later nullstring := space := $(nullstring) $(nullstring) next: ; @echo $x$(space)$y define multi @echo hi @echo there endef ifdef BOGUS define @echo error endef endif EOF # END of Contents of MAKEFILE close(MAKEFILE); # TEST #1 # ------- &run_make_with_options($makefile, "", &get_logfile); $answer = "hi\nthere\nHello\n"; &compare_output($answer, &get_logfile(1)); # TEST #2 # ------- &run_make_with_options($makefile, "next", &get_logfile); $answer = "later foo bar\n"; &compare_output($answer, &get_logfile(1)); # TEST #3 # ------- &run_make_with_options($makefile, "BOGUS=true", &get_logfile, 512); $answer = "$makefile:23: *** empty variable name. Stop.\n"; &compare_output($answer, &get_logfile(1)); 1; (.*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]MAKE.;1+,.d./@ 4g-+d0123KPWO56I5R7m89G@HJ$description = "The following test creates a makefile to test MAKE \n" ."(very generic)"; $details = "DETAILS"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "TMP := \$(MAKE)\n"; print MAKEFILE "MAKE := \$(subst X=\$(X),,\$(MAKE))\n\n"; print MAKEFILE "all:\n"; print MAKEFILE "\t\@echo \$(TMP)\n"; print MAKEFILE "\t\$(MAKE) -f $makefile foo\n\n"; print MAKEFILE "foo:\n"; print MAKEFILE "\t\@echo \$(MAKE)\n"; # END of Contents of MAKEFILE close(MAKEFILE); # Create the answer to what should be produced by this Makefile $answer = "$mkpath\n$mkpath -f $makefile foo\n" . "${make_name}[1]: Entering directory `$pwd'\n" . "$mkpath\n${make_name}[1]: Leaving directory `$pwd'\n"; &run_make_with_options($makefile,"",&get_logfile,0); &delete("foo"); # COMPARE RESULTS &compare_output($answer,&get_logfile(1)); 1; A6*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]MAKECMDGOALS.;1+,/d./@ 4j-+d0123KPWO56(c7]m89G@HJ# -*-perl-*- $description = "Test the MAKECMDGOALS variable."; $details = "\ We construct a makefile with various targets, all of which print out \$(MAKECMDGOALS), then call it different ways."; open(MAKEFILE,"> $makefile"); print MAKEFILE "\ .DEFAULT all: \@echo \$(MAKECMDGOALS) "; close(MAKEFILE); # TEST #1 &run_make_with_options($makefile, "", &get_logfile, 0); $answer = "\n"; &compare_output($answer,&get_logfile(1)); # TEST #2 &run_make_with_options($makefile, "all", &get_logfile, 0); $answer = "all\n"; &compare_output($answer,&get_logfile(1)); # TEST #3 &run_make_with_options($makefile, "foo bar baz yaz", &get_logfile, 0); $answer = "foo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\n"; &compare_output($answer,&get_logfile(1)); # This tells the test driver that the perl test script executed properly. 1; 3*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]MAKEFILES.;1+,0d./@ 4-+d0123KPWO56X}7@k m89G@HJ$description = "The following test creates a makefile to test "; $makefile2 = &get_tmpfile; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE "MAKEFILES = work/MAKEFILES_variable.mk.2\n\n"; print MAKEFILE "all:\n"; print MAKEFILE "\t\@echo THIS IS THE DEFAULT RULE\n"; # END of Contents of MAKEFILE close(MAKEFILE); open(MAKEFILE,"> $makefile2"); print MAKEFILE "NDEF:\n"; print MAKEFILE "\t\@echo THIS IS THE RULE FROM MAKEFILE 2\n"; close(MAKEFILE); &run_make_with_options($makefile,"",&get_logfile); # Create the answer to what should be produced by this Makefile $answer = "THIS IS THE DEFAULT RULE\n"; # COMPARE RESULTS # In this call to compare output, you should use the call &get_logfile(1) # to send the name of the last logfile created. &compare_output($answer,&get_logfile(1)); # If you wish to stop if the compare fails, then add # a "|| &error ("abort")" to the # end of the previous line. # This tells the test driver that the perl test script executed properly. 1; 3*[MAKE-3_78_1HB.TESTS.SCRIPTS.VARIABLES]MAKELEVEL.;1+,1d./@ 4-+d0123KPWO56}ܣ7#/m89G@HJ# -*-perl-mode-*- $description = "The following test creates a makefile to test makelevels in Make. It prints \$(MAKELEVEL) and then prints the environment variable MAKELEVEL"; open(MAKEFILE,"> $makefile"); # The Contents of the MAKEFILE ... print MAKEFILE < fancy.file.name") && close (TOUCHFD)) || ($fancy_file_names = 0); unlink ("fancy.file.name") || ($fancy_file_names = 0); if ($fancy_file_names) { # Thanks go to meyering@cs.utexas.edu (Jim Meyering) for suggesting a # better way of doing this. (We used to test for existence of a /mnt # dir, but that apparently fails on an SGI Indigo (whatever that is).) # Because perl on VOS translates /'s to >'s, we need to test for # VOSness rather than testing for Unixness (ie, try > instead of /). mkdir (".ostest", 0777) || &error ("Couldn't create .ostest: $!\n", 1); open (TOUCHFD, "> .ostest>ick") && close (TOUCHFD); chdir (".ostest") || &error ("Couldn't chdir to .ostest: $!\n", 1); } if ($fancy_file_names && -f "ick") { $osname = "vos"; $vos = 1; $pathsep = ">"; } else { # the following is regrettably knarly, but it seems to be the only way # to not get ugly error messages if uname can't be found. # Hmmm, BSD/OS 2.0's uname -a is excessively verbose. Let's try it # with switches first. eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)"; if ($osname =~ /not found/i) { $osname = "(something unixy with no uname)"; } elsif ($@ ne "" || $?) { eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)"; if ($@ ne "" || $?) { $osname = "(something unixy)"; } } $vos = 0;  $pathsep = "/"; } if ($fancy_file_names) { chdir ("..") || &error ("Couldn't chdir to ..: $!\n", 1); unlink (".ostest>ick"); rmdir (".ostest") || &error ("Couldn't rmdir .ostest: $!\n", 1); } } sub parse_command_line { @argv = @_; # use @ARGV if no args were passed in if (@argv == 0) { @argv = @ARGV; } # look at each option; if we don't recognize it, maybe the suite-specific # command line parsing code will... while (@argv) { $option = shift @argv; if Z~MAKE-3_78_1HB.BCK2dc%[MAKE-3_78_1HB.TESTS]TEST_DRIVER.PL;18 ($option =~ /^-debug$/i) { print "\nDEBUG ON\n"; $debug = 1; } elsif ($option =~ /^-usage$/i) { &print_usage; exit 0; } elsif ($option =~ /^-(h|help)$/i) { &print_help; exit 0; } elsif ($option =~ /^-profile$/i) { $profile = 1; } elsif ($option =~ /^-verbose$/i) { $verbose = 1; } elsif ($option =~ /^-detail$/i) { $detail = 1; $verbose = 1; } elsif ($option =~ /^-keep$/i) { $keep = 1; } elsif (&valid_option($option)) { # The suite-defined subroutine takes care of the option } elsif ($option =~ /^-/) { print "Invalid option: $option\n"; &print_usage; exit 0; } else # must be the name of a test { $option =~ s/\.pl$//; push(@TESTS,$option); } } } sub max { local($num) = shift @_; local($newnum); while (@_) { $newnum = shift @_; if ($newnum > $num) { $num = $newnum; } } return $num; } sub print_centered { local($width, $string) = @_; local($pad); if (length ($string)) { $pad = " " x ( ($width - length ($string) + 1) / 2); print "$pad$string"; } } sub print_banner { local($info); local($line); local($len); $info = "Running tests for $testee on $osname\n"; # $testee is suite-defined $len = &max (length ($line), length ($testee_version), length ($banner_info), 73) + 5; $line = ("-" x $len) . "\n"; if ($len < 78) {( $len = 78; } &print_centered ($len, $line); &print_centered ($len, $info); &print_centered ($len, $testee_version); # suite-defined &print_centered ($len, $banner_info); # suite-defined &print_centered ($len, $line); print "\n"; } sub run_each_test { $counter = 0; foreach $testname (sort @TESTS) { $counter++; $test_passed = 1; # reset by test on failure $num_of_logfiles = 0; $num_of_tmpfiles = 0; $description = ""; $details = ""; $testname =~ s/^$scriptpath$pathsep//; $perl_testname = "$scriptpath$pathsep$testname"; $testname =~ s/(\.pl|\.perl)$//; $testpath = "$workpath$pathsep$testname"; # Leave enough space in the extensions to append a number, even # though it needs to fit into 8+3 limits. if ($port_host eq 'DOS') { $logext = 'l'; $diffext = 'd'; $baseext = 'b'; $extext = ''; } else { $logext = 'log'; $diffext = 'diff'; $baseext = 'base'; $extext = '.'; } $log_filename = "$testpath.$logext"; $diff_filename = "$testpath.$diffext"; $base_filename = "$testpath.$baseext"; $tmp_filename = "$testpath.$tmpfilesuffix"; &setup_for_test; # suite-defined $output = "........................................................ "; substr($output,0,length($testname)) = "$testname "; print $output; # Run the actual test! # $code = do $perl_testname; if (!defined($code)) { $test_passed = 0; if (length ($@)) { warn "\n*** Test died ($testname): $@\n"; } else { warn "\n*** Couldn't run $perl_testname\n"; } } elsif ($code == -1) { $test_passed = 0; } elsif ($code != 1 && $code != -1) { $test_passed = 0; warn "\n*** Test returned $code\n"; } if ($test_passed) { $status = "ok"; for ($i = $num_of_tmpfiles; $i; $i--) { &delete ($tmp_filename . &num_suffix ($i) ); } for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) { &delete ($log_filename . &num_suffix ($i) ); &delete ($base_filename . &num_suffix ($i) ); } } elsif ($code > 0) { $status = "FAILED"; $num_failed++; } elsif ($code < 0) { $status = "N/A"; --$counter; } # If the verbose option has been specified, then a short description # of each test is printed before displaying the results of each test # describing WHAT is being tested. if ($verbose) { if ($detail) { print "\nWHAT IS BEING TESTED\n"; print "--------------------"; } print "\n\n$description\n\n"; } # If the detail option has been specified, then the details of HOW # the test is testing what it says it is testing in the verbose output # will be displayed here before the results of the test are displayed. if ($detail) { print "\nHOW IT IS TESTED\n"; print "----------------"; print "\n\n$details\n\n"; } print "$status\n"; } } # If the keep flag is not set, this subroutine deletes all filenames that # are sent to it. sub delete { local(@files) = @_; if (!$keep) { return (unlink @files); } return 1; } sub print_standard_usage { local($plname,@moreusage) = @_; local($line); print "Usage: perl $plname [testname] [-verbose] [-detail] [-keep]\n"; print " [-profile] [-usage] [-help] " . "[-debug]\n"; foreach $line (@moreusage) { print " $line\n"; } } sub print_standard_help { local(@morehelp) = @_; local($line); local($tline); local($t) = " "; $line = "Test Driver For $testee"; print "$line\n"; $line = "=" x length ($line); print "$line\n"; &print_usage; print "\ntestname\n" . "${t}You may, if you wish, run only ONE test if you know the name\n" . "${t}of that test and specify this name anywhere on the command\n" . "${t}line. Otherwise ALL existing tests in the scripts directory\n" . "${t}will be run.\n" . "-verbose\n" . "${t}If this option is given, a description of every test is\n" . "${t}displayed before the test is run. (Not all tests may have\n" . "${t}descriptions at this time)\n" . "-detail\n" . "${t}If this option is given, a detailed description of every\n" . "${t}test is displayed before the test is run. (Not all tests\n" . "${t}have descriptions at this time)\n" . "-profile\n" . "${t}If this option is given, then the profile file\n" . "${t}is added to other profiles every time $testee is run.\n" . "${t}This option only works on VOS at this time.\n" . "-keep\n" . "${t}You may give this option if you DO NOT want ANY\n" . "${t}of the files generated by the tests to be deleted. \n" . "${t}Without this option, all files generated by the test will\n" . "${t}be deleted IF THE TEST PASSES.\n" . "-debug\n" . "${t}Use this option if you would like to see all of the system\n" . "${t}calls issued and their return status while running the tests\n" . "${t}This can be helpful if you're having a problem adding a test\n" . "${t}to the suite, or if the test fails!\n"; foreach $line (@morehelp) { $tline = $line; if (substr ($tline, 0, 1) eq "\t") { substr ($tline, 0, 1) = $t; } print "$tline\n"; } } ####################################################################### ########### Generic Test Driver Subroutines ########### ####################################################################### sub get_caller { local($depth); local($package); local($filename); local($linenum); $depth = defined ($_[0]) ? $_[0] : 1; ($package, $filename, $linenum) = caller ($depth + 1); return "$filename: $linenum"; } sub error { local($message) = $_[0]; local($caller) = &get_caller (1); if (defined ($_[1])) { $caller = &get_caller ($_[1] + 1) . " -> $caller"; } die "$caller: $message"; } sub compare_output { local($answer,$logfile) = @_; local($slurp); if ($debug) { print "Comparing Output ........ "; } $slurp = &read_file_into_string ($logfile); # For make, get rid of any time skew error before comparing--too bad this # has to go into the "generic" driver code :-/ $slurp =~ s/^.*modification time in the future.*\n//g; $slurp =~ s/\n.*modification time in the future.*//g; $slurp =~ s/^.*Clock skew detected.*\n//g; $slurp =~ s/\n.*Clock skew detected.*//g; if ($slurp eq $answer) { if ($debug) { print "ok\n"; } return 1; } else { if ($debug) { print "DIFFERENT OUTPUT\n"; } $test_passed = 0; &create_file (&get_basefile, $answer); if ($debug) { print "\nCreating Difference File ...\n"; } # Create the difference file local($command) = "diff -c " . &get_basefile . " " . $logfile; &run_command_with_output(&get_difffile,$command); return 0; } } sub read_file_into_string { local($filename) = @_; local($oldslash) = $/; undef $/; open (RFISFILE, $filename) || return ""; local ($slurp) = ; close (RFISFILE); $/ = $oldslash; return $slurp; } sub attach_default_output { local ($filename) = @_; local ($code); if ($vos) { $code = system "++attach_default_output_hack $filename"; $code == -2 || &error ("adoh death\n", 1); return 1; } open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT") || &error ("ado: $! duping STDOUT\n", 1); open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR") || &error ("ado: $! duping STDERR\n", 1); open (STDOUT, "> " . $filename) || &error ("ado: $filename: $!\n", 1); open (STDERR, ">&STDOUT") || &error ("ado: $filename: $!\n", 1); $default_output_stack_level++; } # close the current stdout/stderr, and restore the previous ones from # the "stack." sub detach_default_output { local ($code); if ($vos) { $code = system "++detach_default_output_hack"; $code == -2 || &error ("ddoh death\n", 1); return 1; } if (--$default_output_stack_level < 0) { &error ("default output stack has flown under!\n", 1); } close (STDOUT); close (STDERR); open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out") || &error ("ddo: $! duping STDOUT\n", 1); open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err") || &error ("ddo: $! duping STDERR\n", 1); close ("SAVEDOS" . $default_output_stack_level . "out") || &error ("ddo: $! closing SCSDOSout\n", 1); close ("SAVEDOS" . $default_output_stack_level . "err") || &error ("ddo: $! closing SAVEDOSerr\n", 1); } # run one command (passed as a list of arg 0 - n), returning 0 on success # and nonzero on failure. sub run_command { local ($code); if ($debug) { print "\nrun_command: @_\n"; $code = system @_; print "run_command: \"@_\" returned $code.\n"; return $code; } return system @_; } # run one command (passed as a list of arg 0 - n, with arg 0 being the # second arg to this routine), returning 0 on success and non-zero on failure. # The first arg to this routine is a filename to connect to the stdout # & stderr of the child process. sub run_command_with_output { local ($filename) = shift; local ($code); &attach_default_output ($filename); $code = system @_; &detach_default_output; if ($debug) { print "run_command_with_output: \"@_\" returned $code.\n"; } return $code; } # performs the equivalent of an "rm -rf" on the first argument. Like # rm, if the path ends in /, leaves the (now empty) directory; otherwise # deletes it, too. sub remove_directory_tree { local ($targetdir) = @_; local ($nuketop) = 1; local ($ch); $ch = substr ($targetdir, length ($targetdir) - 1); if ($ch eq "/" || $ch eq $pathsep) { $targetdir = substr ($targetdir, 0, length ($targetdir) - 1); $nuketop = 0; } if (! -e $targetdir) { return 1; } &rem%ove_directory_tree_inner ("RDT00", $targetdir) || return 0; if ($nuketop) { rmdir $targetdir || return 0; } return 1; } sub remove_directory_tree_inner { local ($dirhandle, $targetdir) = @_; local ($object); local ($subdirhandle); opendir ($dirhandle, $targetdir) || return 0; $subdirhandle = $dirhandle; $subdirhandle++; while ($object = readdir ($dirhandle)) { if ($object eq "." || $object eq "..") { next; } $object = "$targetdir$pathsep$object"; lstat ($object); if (-d _ && &remove_directory_tree_inner ($subdirhandle, $object)) { rmdir $object || return 0; } else { unlink $object || return 0; } } closedir ($dirhandle); return 1; } # We used to use this behavior for this function: # #sub touch #{ # local (@filenames) = @_; # local ($now) = time; # local ($file); # # foreach $file (@filenames) # { # utime ($now, $now, $file) # || (open (TOUCHFD, ">> $file") && close (TOUCHFD)) # || &error ("Couldn't touch $file: $!\n", 1); # } # return 1; #} # # But this behaves badly on networked filesystems where the time is # skewed, because it sets the time of the file based on the _local_ # host. Normally when you modify a file, it's the _remote_ host that # determines the modtime, based on _its_ clock. So, instead, now we open # the file and write something into it to force the remote host to set # the modtime correctly according to its clock. # sub touch { local (@filenames) = @_; local ($file); foreach $file (@filenames) { (open(T, ">> $file") && print(T "\n") && close(T)) || &error("Couldn't touch $file: $!\n", 1); } } # open a file, write some stuff to it, and close it. sub create_file { local ($filename, @lines) = @_; open (CF, "> $filename") || &error ("Couldn't open $filename: $!\n", 1); foreach $line (@lines) { print CF $line; } close (CF); } # create a directory tree described by an associative array, wherein each # key is a relative pathname (using slashes) and its associated value is # one of: # DIR indicates a directory # FILE:contents indicates a file, which should contain contents +\n # LINK:target indicates a symlink, pointing to $basedir/target # The first argument is the dir under which the structure will be created # (the dir will be made and/or cleaned if necessary); the second argument # is the associative array. sub create_dir_tree { local ($basedir, %dirtree) = @_; local ($path); &remove_directory_tree ("$basedir"); mkdir ($basedir, 0777) || &error ("Couldn't mkdir $basedir: $!\n", 1); foreach $path (sort keys (%dirtree)) { if ($dirtree {$path} =~ /^DIR$/) { mkdir ("$basedir/$path", 0777) || &error ("Couldn't mkdir $basedir/$path: $!\n", 1); } elsif ($dirtree {$path} =~ /^FILE:(.*)$/) { &create_file ("$basedir/$path", $1 . "\n"); } elsif ($dirtree {$path} =~ /^LINK:(.*)$/) { symlink ("$basedir/$1", "$basedir/$path") || &error ("Couldn't symlink $basedir/$path -> $basedir/$1: $!\n", 1); } else { &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); } } if ($just_setup_tree) { die "Tree is setup...\n"; } } # compare a directory tree with an associative array in the format used # by create_dir_tree, above. # The first argument is the dir under which the structure should be found; # the second argument is the associative array. sub compare_dir_tree { local ($basedir, %dirtree) = @_; local ($path); local ($i); local ($bogus) = 0; local ($contents); local ($target); local ($fulltarget); local ($found); local (@files); local (@allfiles); opendir (DIR, $basedir) || &error ("Couldn't open $basedir: $!\n", 1); @allfiles = grep (!/^\.\.?$/, readdir (DIR) ); closedir (DIR); if ($debug) { print "dirtree: (%dirtree)\n$basedir: (@allfiles)\n"; } foreach $path (sort keys (%dirtree)) { if ($debug) { print "Checking $path ($dirtree{$path}).\n"; } $-found = 0; foreach $i (0 .. $#allfiles) { if ($allfiles[$i] eq $path) { splice (@allfiles, $i, 1); # delete it if ($debug) { print " Zapped $path; files now (@allfiles).\n"; } lstat ("$basedir/$path"); $found = 1; last; } } if (!$found) { print "compare_dir_tree: $path does not exist.\n"; $bogus = 1; next; } if ($dirtree {$path} =~ /^DIR$/) { if (-d _ && opendir (DIR, "$basedir/$path") ) { @files = readdir (DIR); closedir (DIR); @files = grep (!/^\.\.?$/ && ($_ = "$path/$_"), @files); push (@allfiles, @files); if ($debug) { print " Read in $path; new files (@files).\n"; } } else { print "compare_dir_tree: $path is not a dir.\n"; $bogus = 1; } } elsif ($dirtree {$path} =~ /^FILE:(.*)$/) { if (-l _ || !-f _) { print "compare_dir_tree: $path is not a file.\n"; $bogus = 1; next; } if ($1 ne "*") { $contents = &read_file_into_string ("$basedir/$path"); if ($contents ne "$1\n") { print "compare_dir_tree: $path contains wrong stuff." . " Is:\n$contentsShould be:\n$1\n"; $bogus = 1; } } } elsif ($dirtree {$path} =~ /^LINK:(.*)$/) { $target = $1; if (!-l _) { print "compare_dir_tree: $path is not a link.\n"; $bogus = 1; next; } $contents = readlink ("$basedir/$path"); $contents =~ tr/>/\//; $fulltarget = "$basedir/$target"; $fulltarget =~ tr/>/\//; if (!($contents =~ /$fulltarget$/)) { if ($debug) { $target = $fulltarget; } print "compare_dir_tree: $path should be link to $target, " . "not $contents.\n"; $bogus = 1; } } else { &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); } } if ($debug) { print "leftovers: (@allfiles).\n"; } foreach $file (@allfiles) { print "compare_dir_tree: $file should not exist.\n"; $bogus = 1; } return !$bogus; } # this subroutine generates the numeric suffix used to keep tmp filenames, # log filenames, etc., unique. If the number passed in is 1, then a null # string is returned; otherwise, we return ".n", where n + 1 is the number # we were given. sub num_suffix { local($num) = @_; if (--$num > 0) { return "$extext$num"; } return ""; } # This subroutine returns a log filename with a number appended to # the end corresponding to how many logfiles have been created in the # current running test. An optional parameter may be passed (0 or 1). # If a 1 is passed, then it does NOT increment the logfile counter # and returns the name of the latest logfile. If either no parameter # is passed at all or a 0 is passed, then the logfile counter is # incremented and the new name is returned. sub get_logfile { local($no_increment) = @_; $num_of_logfiles += !$no_increment; return ($log_filename . &num_suffix ($num_of_logfiles)); } # This subroutine returns a base (answer) filename with a number # appended to the end corresponding to how many logfiles (and thus # base files) have been created in the current running test. # NO PARAMETERS ARE PASSED TO THIS SUBROUTINE. sub get_basefile { return ($base_filename . &num_suffix ($num_of_logfiles)); } # This subroutine returns a difference filename with a number appended # to the end corresponding to how many logfiles (and thus diff files) # have been created in the current running test. sub get_difffile { return ($diff_filename . &num_suffix ($num_of_logfiles)); } # just like logfile, only a generic tmp filename for use by the test. # they are automatically cleaned up unless -keep was used, or the test fails. # Pass an argument of 1 to return the same filename as the previous call. sub get_tmpfile { local($no_increme5nt) = @_; $num_of_tmpfiles += !$no_increment; return ($tmp_filename . &num_suffix ($num_of_tmpfiles)); } 1; l*[MAKE-3_78_1HB.TESTS]WORK.DIR;1+,f ./@ 4-c0123 KPWO56%ͬ7m89G@HJI*[MAKE-3_78_1HB]TEXINFO.TEX;1+,3d./@ 4k-`0123KPWO56u79m89G@HJ% texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{1999-07-16.19}% % % Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 % Free Software Foundation, Inc. % % This texinfo.tex file is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as % published by the Free Software Foundation; either version 2, or (at % your option) any later version. % % This texinfo.tex file is distributed in the hope that it will be % useful, but WITHOUT ANY WARRANTY; without even the implied warranty % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/pub/gnu/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % ftp://ctan.org/macros/texinfo/texinfo.tex % (and all CTAN mirrors, finger ctan@ctan.org for a list). % /home/gd/gnu/doc/texinfo.tex on the GNU machines. % The texinfo.tex in any given Texinfo distribution could well be out % of date, so if that's what you're using, please check. % There is a small home page for Texinfo at http://texinfo.org/. % % Send bug reports to bug-texinfo@gnu.org. Please include including a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For a simple % manual foo.texi, however, you can get away with this: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. % The extra runs of TeX get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. % % It is possible to adapt texinfo.tex for other languages. You can get % the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexi=\i \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexstar=\* \let\ptext=\t % We never want plain's outer \+ definition in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax % Get ready for pdf. \newif\ifpdf \ifx\pdfoutput\undefined\else \input pdfcolor \pdfoutput=1 \pdftrue \fi \message{Basics,} \chardef\other=12 % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi \ifx\putwordof\undefined \gdef\putwordof{of}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi % \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi % \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\u ndefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % Ignore a token. % \def\gobble#1{} \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen \bindingoffset \newdimen \normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \ifx\eTeXversion\undefined \def\loggingall{\tracingcommands2 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \else \def\loggingall{\tracingcommands3 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \tracingscantokens1 \tracingassigns1 \tracingifs1 \tracinggroups1 \tracingnesting2 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \fi % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifpdf\pdfmkdest{\the\pageno}\fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornP[~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1|erthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \turnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } % Single-spacing is done by various environments (specifically, in % \nonfillstart and \quotations). \newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% % Why was this kern here? It messes up equalizing space above and below % environments. --karl, 6may93 %{\advance \baselineskip by -\singlespaceskip %\kern \baselineskip}% \setleading \singlespaceskip } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce actual \{ & \} command in an index. \catcode`\{ = 12 \catcode`\} = 12 \catcode`\[ = 1 \catcode`\] = 2 \catcode`\@ = 0 \catcode`\\ = 12 @gdef@lbracecmd[\{]% @gdef@rbracecmd[\}]% @endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at th%e % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. }% % \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % Go into vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % Don't add any leading before our big empty box, but allow a page % break, since the best break might be right here. \allowbreak \nointerlineskip \vtop to #1\mil{\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible brea-kpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. \def\inmargin#1{% \strut\vadjust{\nobreak\kern-\strutdepth \vtop to \strutdepth{\baselineskip\strutdepth\vss \llap{\rightskip=\inmarginspacing \vbox{\noind1ent #1}}\null}}} \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=12 \catcode`~=12 \catcode`^=12 \catcode`_=12 \catcode`|=12 \catcode`<=12 \catcode`>=12 \catcode`+=12 \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \input\thisfile \endgroup} \def\thisfile{} % @center line outputs that line, centered \def\center{\parsearg\centerzzz} \def\centerzzz #1{{\advance\hsize by -\leftskip \advance\hsize by -\rightskip \centerline{#1}}} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} \let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. % We cannot implement @paragraphindent asis, though. % \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \defaultparindent = 0pt \else \defaultparindent = #1em \fi \fi \parindent = \defaultparindent } % @exampleindent NCHARS % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword 5 \lispnarrowing = 0pt \else \lispnarrowing = #1em \fi \fi } % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math means output in math mode. % We don't use $'s directly in the definition of \math because control % sequences like \math are expanded when the toc file is written. Then, % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. % % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. % \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % Called from \setfilename9. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{pdf,} % adobe `portable' document format \newcount\tempnum \newcount\lnkcount \newtoks\filename \newcount\filenamelength \newcount\pgn \ifpdf \def\pdfmkdest#1{\pdfdest name{#1@} xyz} \def\pdfmkpgn#1{#1@} % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax \advance\tempnum by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} \def\pdfmakeoutlines{{% \openin 1 \jobname.toc \ifeof 1\else\bgroup \closein 1 \indexnofonts \def\char{char}% because \expnumber uses the section title in a \csname \def\chapentry ##1##2##3{} \def\unnumbchapentry ##1##2{} \def\secentry ##1##2##3##4{\advancenumber{chap##2}} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} \def\unnumbsubsubsecentry ##1##2{} \input \jobname.toc \def\chapentry ##1##2##3{% \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} \def\unnumbchapentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\secentry ##1##2##3##4{% \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} \def\unnumbsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\subsecentry ##1##2##3##4##5{% \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} \def\unnumbsubsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\subsubsecentry ##1##2##3##4##5##6{% \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} \def\unnumbsubsubsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \input \jobname.toc \egroup\fi }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \Blue\pdfannotlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% #1% \advance\lnkcount by 1% \Black\pdfendlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \def\pdflink#1{% \leavevmode\Red \begingroup \normalturnoffactive\def\@{@}% \pdfannotlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% \endgroup } \else \let\pdflink = \gobble \let\pdfmakeoutlines = \relax \fi % end \ifpdf \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Use Computer Modern fonts at \magstephalf (11pt). \newcount\mainmagstep \mainmagstep=\magstephalf % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \ifx\bigger\relax \let\mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples (9pt). % We actually use the slanted font rather than the italic, % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. \setfont\ninett\ttshape{9}{1000} \setfont\ninettsl\ttslshape{10}{900} \setfont\indrm\rmshape{9}{1000} \setfont\indit\itshape{9}{1000} \setfont\indsl\slshape{9}{1000} \let\indtt=\ninett \let\indttsl=\ninettsl \let\indsf=\indrm \let\indbf=\indrm \setfont\indsc\scshape{10}{900} \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshEape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. % \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. % \setfont\ssecsl\slshape{10}{\magstep1} % \setfont\ssectt\ttshape{10}{\magstep1} % \setfont\ssecsf\sfshape{10}{\magstep1} %\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. %\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than %\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. %\setfont\ssectt\ttshape{10}{1315} %\setfont\ssecsf\sfshape{10}{1315} %\let\ssecbf=\ssecrm % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf \textfont\ttfam = \tentt \textfont\sffam = \tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\indexfonts{% \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl \resetmathfonts \setleading{12pt}} % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} \def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% {\tt \rawbacQkslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\smallrm\rmshape{8}{1000} \font\smallsy=cmsy9 \def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. `\~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1pS \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} \def\codex #1{\tclose{#1}\endgroup} %\let\exp=\tclose %Was temporarUy % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is kbdinputdistinct. (Too much of a hassle to call the macro, % the catcodes are wrong for parsearg to work.) \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\code % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url % itself. First (mandatory) arg is the url. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#1,#2,#3,#4\finish{% \pdflink{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url \fi \else \code{#1}% only url given, so show it \fi \fi % \ifpdf \Black\pdfendlink \fi } % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} \ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{% \pdflink{mailto:#1}% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi \Black\pdfendlink } \else \let\email=\uref \fi % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % If they want short, athey certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi % \HEADINGSon } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfiil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % Produces Day Month Year style of output. \def\today{% \number\day\space \ifcase\month \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec \fi \space\number\year} % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue. \nobreak \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. q\noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey #1#2{% \aboveenvbreak % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % \exdentamount=\itemindent \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% \let\item=\itemizeitem} % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for gi}ving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; % typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % This used to have \hskip1sp. But then the space in a template line is % not enough. That is bad. So let's go back to just & until we % encounter the problem it was intended to solve again. % --karl, nathan@acm.org, 20apr99. \def\tab{&} % @multitable ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item\crcr \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \else \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax \let\defindex = \relax \let\defivar = \relax \let\defmac = \relax \let\defmethod = \relax \let\defop = \relax \let\defopt = \relax \let\defspec = \relax \let\deftp = \relax \let\deftypefn = \relax \let\deftypefun = \relax \let\deftypeivar = \relax \let\deftypeop = \relax \let\deftypevar = \reP]~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1Ulax \let\deftypevr = \relax \let\defun = \relax \let\defvar = \relax \let\defvr = \relax \let\ref = \relax \let\xref = \relax \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\everyheading = \relax \let\evenheading = \relax \let\oddheading = \relax \let\everyfooting = \relax \let\evenfooting = \relax \let\oddfooting = \relax \let\headings = \relax \let\include = \relax \let\lowersections = \relax \let\down = \relax \let\raisesections = \relax \let\up = \relax \let\set = \relax \let\clear = \relax \let\item = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} % Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} \def\ifhtml{\doignore{ifhtml}} \def\ifnottex{\doignore{ifnottex}} \def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode32 = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 % % And now expand that command. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{WARNING: for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites % might have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont \let\tensf = \nullfont % Similarly for index fonts (mostly for their use in % smallexample) \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont \let\indsf = \nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just 8use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=12 \catcode`\_=12 \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. The command has to be fully expandable, since the result % winds up in the index file. This means that if the variable's value % contains other Texinfo commands, it's almost certain it will fail % (although perhaps we could fix that with sufficient work to do a % one-level expansion on the result, instead of complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifsetfail \else \expandafter\ifsetsucceed \fi } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifclearsucceed \else \expandafter\ifclearfail \fi } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text % following, through the first @end iftex (etc.). Make `@end iftex' % (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} % We can't just want to start a group at @iftex (for example) and end it % at @end iftex, since then @set commands inside the conditional have no % effect (they'd get reverted at the end of the group). So we must % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) % \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. \let\nece{prevE#1} = \nece{E#1}% % % At the `@end #1', redefine \E#1 to be its previous value. \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% }% \temp } % We need to expand lots of \csname's, but we don't want to expand the % control sequences after we've constructed them. % \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @defininfoenclose. \let\definfoenclose=\comment \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}} } \def\defcodeindex{\parsearg\newcodeindex} % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \def\synindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\doindex{#2}}% } % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. \def\syncodeindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\docodeindex{#2}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% \def\ { }% % Take care of the plain tex accent commands. \def\"{\realbackslash "}% \def\`{\realbackslash `}% \def\'{\realbackslash '}% \def\^{\realbackslash ^}% \def\~{\realbackslash ~}% \def\={\realbackslash =}% \def\b{\realbackslash b}% \def\c{\realbackslash c}% \def\d{\realbackslash d}% \def\u{\realbackslash u}% \def\v{\realbackslash v}% \def\H{\realbackslash H}% % Take care of the plain tex special European modified letters. \def\oe{\realbackslash oe}% \def\ae{\realbackslash ae}% \def\aa{\realbackslash aa}% \def\OE{\realbackslash OE}% \def\AE{\realbackslash AE}% \def\AA{\realbackslash AA}% \def\o{\realbackslash o}% \def\O{\realbackslash O}% \def\l{\realbackslash l}% \def\L{\realbackslash L}% \def\ss{\realbackslash ss}% % Take care of texinfo commands likely to appear in an index entry. % (Must be a way to avoid doing expansion at all, and thus not have to % laboriously list every single command here.) \def\@{@}% will be @@ when we switch to @ as escape char. % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% %\def\rm{\realbackslash rm }% \def\sl{\realbackslash sl }% \def\sf{\realbackslash sf}% \def\tt{\realbackslash tt}% \def\gtr{\realbackslash gtr}% \def\less{\realbackslash less}% \def\hat{\realbackslash hat}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots }% \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\error{\realbackslash error}% \def\point{\realbackslash point}% \def\copyright{\realbackslash copyright}% \def\tclose##1{\realbackslash tclose {##1}}% \def\code##1{\realbackslash code {##1}}% \def\uref##1{\realbackslash uref {##1}}% \def\url##1{\realbackslash url {##1}}% \def\env##1{\realbackslash env {##1}}% \def\command##1{\realbackslash command {##1}}% \def\option##1{\realbackslash option {##1}}% \def\dotless##1{\realbackslash dotless {##1}}% \def\samp##1{\realbackslash samp {##1}}% \def\,##1{\realbackslash ,{##1}}% \def\t##1{\realbackslash t {##1}}% \def\r##1{\realbackslash r {##1}}% \def\i##1{\realbackslash i {##1}}% \def\b##1{\realbackslash b {##1}}% \def\sc##1{\realbackslash sc {##1}}% \def\cite##1{\realbackslash cite {##1}}% \def\key##1{\realbackslash key {##1}}% \def\file##1{\realbackslash file {##1}}% \def\var##1{\realbackslash var {##1}}% \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% \def\acronym##1{\realbackslash acronym {##1}}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % \unsepspaces % Turn off macro expansion \turnoffmacros } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} \def\indexdummytex{TeX} \def\indexdummydots{...} \def\indexnofonts{% % Just ignore accents. \let\,=\indexdummyfont \let\"=\indexdummyfont \let\`=\indexdummyfont \let\'=\indexdummyfont \let\^=\indexdummyfont \let\~=\indexdummyfont \let\==\indexdummyfont \let\b=\indexdummyfont \let\c=\indexdummyfont \let\d=\indexdummyfont \let\u=\indexdummyfont \let\v=\indexdummyfont \let\H=\indexdummyfont \let\dotless=\indexdummyfont % Take care of the plain tex special European modified letters. \def\oe{oe}% \def\ae{ae}% \def\aa{aa}% \def\OE{OE}% \def\AE{AE}% \def\AA{AA}% \def\o{o}% \def\O{O}% \def\l{l}% \def\L{L}% \def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont \let\i=\indexdummyfont \let\b=\indexdummyfont \let\emph=\indexdummyfont \let\strong=\indexdummyfont \let\cite=\indexdummyfont \let\sc=\indexdummyfont %Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |... %\let\tt=\indexdummyfont \let\tclose=\indexdummyfont \let\code=\indexdummyfont \let\url=\indexdummyfont \let\uref=\indexdummyfont \let\env=\indexdummyfont \let\command=\indexdummyfont \let\option=\indexdummyfont \let\file=\indexdummyfont \let\samp=\indexdummyfont \let\kbd=\indexdummyfont \let\key=\indexdummyfont \let\var=\indexdummyfont \let\TeX=\indexdummytex \let\dots=\indexdummydots \def\@{@}% } % To define \realbackslash, we must make \ not be an escape. % We must first make another character (@) an escape % so we do not become unable to do a definition. {\catcode`\@=0 \catcode`\\=\other @gdef@realbackslash{\}} \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % \empty if called from \doind, as we usually are. The main exception % is with defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % \def\thirdarg{#3}% % % If third arg is present, precede it with space in sort key. \ifx\thirdarg\emptymacro \let\subentry = \empty \else \def\subentry{ #3}% \fi % % First process the index entry with all font commands turned % off to get the string to sort by. {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% % % Now the real index entry with the fonts. \toks0 = {#2}% % % If third (subentry) arg is present, add it to the index % string. And include a space. \ifx\thirdarg\emptymacro \else \toks0 = \expandafter{\the\toks0 \space #3}% \fi % % Set up the complete index entry, with both the sort key % and the original text, including any font commands. We write % three arguments to \entry to the .?? file, texindex reduces to % two when writing the .??s sorted result. \edef\temp{% \write\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write will make \lastskip zero. The result is that sequences % like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi \fi % \temp % do the write % % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \indexfonts \rm \tolerance = 9500 \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing columns. \vskip 0pt plus1pt % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ #2% The page number ends the paragraph. \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary #1#2{ {\parfillskip=0in \parskip=0in \hangindent =1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case we just ship out what is in \partialpage with the normal % output routine. Generally, \partialpage will be empty when this % runs and this will be a no-op. See the indexspread.tex test case.  \ifvoid\partialpage \else \onepageout{\pagecontents\partialpage}% \fi % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE \kern-\topskip \kern\baselineskip }% }% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \advance\vsize by -\ht\partialpage \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } \def\pagesofar{% % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } \def\enddoublecolumns{% \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \ep^~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1ndgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } \def\balancecolumns{% % Called at the end of the double column material. \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Chapters, sections, etc. \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... % The \the is necessary, despite appearances, because \appendixletter is % expanded while writing the .toc file. \char\appendixno is not % expandable, thus it is written literally, thus all appendixes come out % with the same letter (or @) in the toc without it. \newcount\appendixno \appendixno = `\@ \def\appendixletter{\char\the\appendixno} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\the\chapno}}}% \temp \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\putwordAppendix{} \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\putwordAppendix{} \appendixletter}}}% \temp \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbe red, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% \temp \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\the\chapno}{\the\secno}}}% \temp \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\appendixletter}{\the\secno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controllinHg skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % We open the .toc file here instead of at @setfilename or any other % given time so that @contents can be put in the document anywhere. % \newif\iftocfileopened \def\writetocentry#1{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi \iflinks \write\tocfile{#1{\folio}}\fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and prepare to read what we've written % to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{} \def\unnumbsubsubsecentry ##1##2{} \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } \let\shortcontents = \summarycontents \ifpdf \pdfcatalog{/PageMode /UseOutlines}% \fi % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapter-level things, for both the long and short contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% } % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. \setbox0 = \hbox{\shortcontrm \putwordAppendix } \newdimen\shortappendixwidth \shortappendixwidth = \wd0 \def\shortchaplabel#1{% % We typeset #1 in a box of constant width, regardless of the text of % #1, so the chapter titles will come out aligned. \setbox0 = \hbox{#1}% \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi % % This space should be plenty, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) \advance\dimen0 by 1.1em \hbox to \dimen0{#1\hfil}% } \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno{#2}}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, so characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % @foo ... @end foo. % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox \newbox\pushcharbox \newbox\bullbox \newbox\equivbox \newbox\errorbox %{\tentt %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex % depth .1ex\hfil} %} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % The @error{} command. \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie \catcode `\%=14 \catcode 43=12 % plus \catcode`\"=12 \catcode`\==12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @endlisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @endlisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip % \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \long\def\cartouche{% \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \singlespace \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip b_~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1l| y \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @small... is usually equivalent to the non-small (@smallbook % redefines). We must call \example (or whatever) last in the % definition, since it reads the return following the @example (or % whatever) command. % % This actually allows (for example) @end display inside an % @smalldisplay. Too bad, but makeinfo will catch the error anyway. % \def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} \def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} \def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} \def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} % Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllispx{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \indexfonts \lisp } % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % @smalldisplay (when @smallbook): @display plus smaller fonts. % \def\smalldisplayx{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \indexfonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % @smallformat (when @smallbook): @format plus smaller fonts. % \def\smallformatx{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \indexfonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \singlespace \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } \message{defuns,} % @defun etc. % Allow user to change definition object font (\df) internally \def\setdeffont #1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = 13 \global\let& = \ampnr } % First, defname, which formats the header line itself. % #1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname #1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \noindent \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } % Actually process the body of a definition % #1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % 61 is `=' \obeylines\activeparens\spacesplit#3} % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} % Used for @deftypemethod and @deftypeivar. % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV \medbreak \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV \medbreak \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 ##3 {% \def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} % This is used for \def{tp,vr}parsebody. It could probably be used for % some of the others, too, with some judicious conditionals. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylines \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else #1{#2}{#3#4}\fi}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$$$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index \begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% \defunargs {#3}\endgroup % } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$$$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{#3}{\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index \begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% \defvarargs {#3}\endgroup % } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak} % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\endcsname \csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=12\catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \. % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. \def\macrobodyctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\{=12 \catcode`\}=12 \catcode`\@=12 \catcode`\^^M=12 \usembodybackslash} \def\macroargctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\@=12 \catcode`\\=12} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0% \else \expandafter\parsemargdef \argl;% \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% \else \expandafter\ifx\csname \the\macname\endcsname \relax \else \errmessage{The name \the\macname\space is reserved}\fi \global\cslet{macsave.\the\macname}{\the\macname}% \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\unmacroxxx} \def\unmacroxxx#1{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% % Remove the macro name from \macrolist \begingroup \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% \def\do##1{% \def\tempb{##1}% \ifx\tempa\tempb % remove this \else \toks0 = \expandafter{\newmacrolist\do}% \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% \fi}% \def\newmacrolist{}% % Execute macro list to define \newmacrolist \macrolist \global\let\macrolist\newmacrolist \endgroup \else \errmessage{Macro #1 not defined}% \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname #1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.blah for each blah % in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \expandafter\noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% `~MAKE-3_78_1HB.BCK3d`[MAKE-3_78_1HB]TEXINFO.TEX;1 lK \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \fi \fi} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. \def\alias#1=#2{\gdef#1{#2}} \message{cross references,} % @xref etc. \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % { \catcode`\@ = 11 % From latex.ltx, to make @anchor truely invisible. \newdimen\@savsk \newcount\@savsf \gdef\@bsphack{\relax \ifhmode \@savsk\lastskip \@savsf\spacefactor \fi } \gdef\@esphack{\relax \ifhmode \spacefactor\@savsf \ifdim\@savsk>\z@ \ignorespaces \fi \fi } \gdef\anchor#1{\@bsphack \setref{#1}{Ynothing}\@esphack} } % \setref{NAME}{SNT} defines a cross-reference point NAME, namely % NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have % to set \indexdummies so commands such as @code in a section title % aren't expanded. It would be nicer not to expand the titles in the % first place, but there's so many layers that that is hard to do. % \def\setref#1#2{{% \indexdummies \ifpdf \pdfmkdest{#1}\fi \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% }} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifpdf \leavevmode \getfilename{#4}% \ifnum\filenamelength>0 \pdfannotlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1@}% \else \pdfannotlink attr{/Border [0 0 0]}% goto name{#1@}% \fi \BlueGreen \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\normalturnoffactive % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % [mynode], [\printednodename],\space % page 3 \turnoffactive \putwordpage\tie\refx{#1-pg}{}% \fi \ifpdf \Black\pdfendlink \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \normalturnoffactive so that punctuation chars such as underscore % and backslash work in node names. (\turnoffactive doesn't do \.) \def\dosetq#1#2{% {\let\folio=0% \normalturnoffactive \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq {foo}{page} expands into % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} % When the aux file is read, ' is the escape character \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter\xreftie\the\chapno % \else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% \else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \csname X#1\endcsname \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\begingroup % Reenable \ as an escape while reading the second argument. \catcode`\\ = 0 \afterassignment\endgroup \expandafter\gdef\csname X#1\endcsname } % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other \catcode`\@=\other \catcode`\^=\other % It was suggested to define this as 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % The aux file uses ' as the escape (for now). % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\{=1 \catcode`\}=2 \catcode`\%=\other \catcode`\'=0 \catcode`\\=\other % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \footnotezzz }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % \long\gdef\footnotezzz{\insert\footins\bgroup % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % % Hang the footnote text off the number. \hang \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } \def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t \else\let\next\f@t\fi \next} \def\f@@t{\bgroup\aftergroup\@foot\let\next} \def\f@t#1{#1\@foot} \def\@foot{\strut\egroup} }%end \catcode `\@=11 % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 % Do not bother showing banner with post-v2.7 epsf.tex (available in % doc/epsf.tex until it shows up on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is just the usual extra ignored arg for parsing this stuff. \def\imagexxx#1,#2,#3,#4\finish{% \ifx\pdfoutput\undefined % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \begingroup \catcode`\^^M = 5 % in case we're inside an example % If the image is by itself, center it. \ifvmode \nobreak\bigskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space % above and below. \nobreak\vskip\parskip \nobreak \centerline{\epsfbox{#1.eps}}% \bigbreak \else % In the middle of a paragraph, no extra space. \epsfbox{#1.eps}% \fi \endgroup \else \centerline{\pdfimage{#1.pdf}}% \fi } \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. We call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = .15\hsize \fi } % Parameters in order: 1) textheight; 2) textwidth; 3) voffset; % 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can % set \parskip and call \setleading for \baselineskip. % \def\internalpagesizes#1#2#3#4#5#6{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % % If page is nothing but text, make it come out even. \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \setleading{12pt}% % \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \deftypemargin = 0pt \defbodyindent = .5cm % \let\smalldisplay = \smalldisplayx \let\smallexample = \smalllispx \let\smallformat = \smallformatx \let\smalllisp = \smalllispx }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \setleading{12pt}% \parskip = 3pt plus 2pt minus 1pt % \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% % \tolerance = 700 \hfuzz = 1pt }} % A specific text layout, 24x15cm overall, intended for A4 paper. Top margin % 29mm, hence bottom margin 28mm, nominal side margin 3cm. \def\afourlatex{{\globaldefs = 1 \setleading{13.6pt}% % \afourpaper \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% % \globaldefs = 0 }} % Use @afourwide to print on European A4 paper in wide format. \def\afourwide{% \afourpaper \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% % \globaldefs = 0 } % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$} % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} % Same as above, but check for italic font. Actually this also catches % non-italic slanted fonts since it is impossible to distinguish them from % italic fonts. But since this is only used by $ and it uses \sl anyway % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar} %\catcode 27=\active %\def^^[{$\diamondsuit$} % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx output one backslash character in current font \global\chardef\rawbackslashxx=`\\ %{\catcode`\\=\other %@gdef@rawbackslashxx{\}} % \rawbackslash redefines \ as input to do \rawbackslashxx. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx }} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} % \catcode 17=0 % Define control-q \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{@let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar} @def@normalturnoffactive{@let"=@normaldoublequote @let\=@normalbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{% @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active } % Say @foo, not \foo, in error messages. @escapechar = `@@ % These look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: a*[MAKE-3_78_1HB]VARIABLE.C;3+,e .@/@ 4N@@ -`0123KPWOA56 m7m89G@HJ/* Internals of variables for GNU Make. Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "dep.h" #include "filedef.h" #include "job.h" #include "commands.h" #include "variable.h" #ifdef WINDOWS32 #include "pathstuff.h" #endif /* Hash table of all global variable definitions. */ #ifndef VARIABLE_BUCKETS #define VARIABLE_BUCKETS 523 #endif #ifndef PERFILE_VARIABLE_BUCKETS #define PERFILE_VARIABLE_BUCKETS 23 #endif #ifndef SMALL_SCOPE_VARIABLE_BUCKETS #define SMALL_SCOPE_VARIABLE_BUCKETS 13 #endif static struct variable *variable_table[VARIABLE_BUCKETS]; static struct variable_set global_variable_set = { variable_table, VARIABLE_BUCKETS }; static struct variable_set_list global_setlist = { 0, &global_variable_set }; struct variable_set_list *current_variable_set_list = &global_setlist; static struct variable *lookup_variable_in_set PARAMS ((char *name, unsigned int length, struct variable_set *set)); /* Implement variables. */ /* Define variable named NAME with value VALUE in SET. VALUE is copied. LENGTH is the length of NAME, which does not need to be null-terminated. ORIGIN specifies the origin of the variable (makefile, command line or environment). If RECURSIVE is nonzero a flag is set in the variable saying that it should be recursively re-expanded. */ struct variable * define_variable_in_set (name, length, value, origin, recursive, set) char *name; unsigned int length; char *value; enum variable_origin origin; int recursive; struct variable_set *set; { register unsigned int i; register unsigned int hashval; register struct variable *v; hashval = 0; for (i = 0; i < length; ++i) HASH (hashval, name[i]); hashval %= set->buckets; for (v = set->table[hashval]; v != 0; v = v->next) if (*v->name == *name && strneq (v->name + 1, name + 1, length - 1) && v->name[length] == '\0') break; if (env_overrides && origin == o_env) origin = o_env_override; if (v != 0) { if (env_overrides && v->origin == o_env) /* V came from in the environment. Since it was defined before the switches were parsed, it wasn't affected by -e. */ v->origin = o_env_override; /* A variable of this name is already defined. If the old definition is from a stronger source than this one, don't redefine it. */ if ((int) origin >= (int) v->origin) { if (v->value != 0) free (v->value); v->value = xstrdup (value); v->origin = origin; v->recursive = recursive; } return v; } /* Create a new variable definition and add it to the hash table. */ v = (struct variable *) xmalloc (sizeof (struct variable)); v->name = savestring (name, length); v->value = xstrdup (value); v->origin = origin; v->recursive = recursive; va~MAKE-3_78_1HB.BCKe `AKE-3_78_1HB]VARIABLE.C;3N@`K->expanding = 0; v->per_target = 0; v->export = v_default; v->next = set->table[hashval]; set->table[hashval] = v; return v; } /* Define a variable in the current variable set. */ struct variable * define_variable (name, length, value, origin, recursive) char *name; unsigned int length; char *value; enum variable_origin origin; int recursive; { return define_variable_in_set (name, length, value, origin, recursive, current_variable_set_list->set); } /* Define a variable in FILE's variable set. */ struct variable * define_variable_for_file (name, length, value, origin, recursive, file) char *name; unsigned int length; char *value; enum variable_origin origin; int recursive; struct file *file; { return define_variable_in_set (name, length, value, origin, recursive, file->variables->set); } /* Lookup a variable whose name is a string starting at NAME and with LENGTH chars. NAME need not be null-terminated. Returns address of the `struct variable' containing all info on the variable, or nil if no such variable is defined. */ struct variable * lookup_variable (name, length) char *name; unsigned int length; { register struct variable_set_list *setlist; register unsigned int i; register unsigned int rawhash = 0; for (i = 0; i < length; ++i) HASH (rawhash, name[i]); for (setlist = current_variable_set_list; setlist != 0; setlist = setlist->next) { register struct variable_set *set = setlist->set; register unsigned int hashval = rawhash % set->buckets; register struct variable *v; for (v = set->table[hashval]; v != 0; v = v->next) if (*v->name == *name && strneq (v->name + 1, name + 1, length - 1) && v->name[length] == 0) return v; } #ifdef VMS /* since we don't read envp[] on startup, try to get the variable via getenv() here. */ { char *vname = alloca (length + 1); char *value; strncpy (vname, name, length); vname[length] = 0; value = getenv (vname); if (value != 0) { char *sptr; int scnt; sptr = value; scnt = 0; while ((sptr = strchr (sptr, '$'))) { scnt++; sptr++; } if (scnt > 0) { char *nvalue; char *nptr; nvalue = alloca (length + scnt + 1); sptr = value; nptr = nvalue; while (*sptr) { if (*sptr == '$') { *nptr++ = '$'; *nptr++ = '$'; } else { *nptr++ = *sptr; } sptr++; } return define_variable (vname, length, nvalue, o_env, 1); } return define_variable (vname, length, value, o_env, 1); } } #endif /* VMS */ return 0; } /* Lookup a variable whose name is a string starting at NAME and with LENGTH chars in set SET. NAME need not be null-terminated. Returns address of the `struct variable' containing all info on the variable, or nil if no such variable is defined. */ static struct variable * lookup_variable_in_set (name, length, set) char *name; unsigned int length; struct variable_set *set; { register unsigned int i; register unsigned int hash = 0; register struct variable *v; for (i = 0; i < length; ++i) HASH (hash, name[i]); hash %= set->buckets; for (v = set->table[hash]; v != 0; v = v->next) if (*v->name == *name && strneq (v->name + 1, name + 1, length - 1) && v->name[length] == 0) return v; return 0; } /* Initialize FILE's variable set list. If FILE already has a variable set list, the topmost variable set is left intact, but the the rest of the chain is replaced with FILE->parent's setlist. */ void initialize_file_variables (file) struct file *file; { register struct variable_set_list *l = file->variables; if (l == 0) { l = (struct variable_set_list *) xmalloc (sizeof (struct variable_set_list)); l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); l->set->buckets = PERFILE_VARIABLE_BUCKETS; l->set->table = (struct variable **) xmalloc (l->set->buckets * sizeof (struct variable *)); bzero ((char *) l->set->table, l->set->buckets * sizeof (struct variable *)); file->variables = l; } if (file->parent == 0) l->next = &global_setlist; else { if (file->parent->variables == 0) initialize_file_variables (file->parent); l->next = file->parent->variables; } } /* Pop the top set off the current variable set list, and free all its storage. */ void pop_variable_scope () { register struct variable_set_list *setlist = current_variable_set_list; register struct variable_set *set = setlist->set; register unsigned int i; current_variable_set_list = setlist->next; free ((char *) setlist); for (i = 0; i < set->buckets; ++i) { register struct variable *next = set->table[i]; while (next != 0) { register struct variable *v = next; next = v->next; free (v->name); if (v->value) free (v->value); free ((char *) v); } } free ((char *) set->table); free ((char *) set); } struct variable_set_list * create_new_variable_set () { register struct variable_set_list *setlist; register struct variable_set *set; set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); set->buckets = SMALL_SCOPE_VARIABLE_BUCKETS; set->table = (struct variable **) xmalloc (set->buckets * sizeof (struct variable *)); bzero ((char *) set->table, set->buckets * sizeof (struct variable *)); setlist = (struct variable_set_list *) xmalloc (sizeof (struct variable_set_list)); setlist->set = set; setlist->next = current_variable_set_list; return setlist; } /* Create a new variable set and push it on the current setlist. */ struct variable_set_list * push_new_variable_scope () { return (current_variable_set_list = create_new_variable_set()); } /* Merge SET1 into SET0, freeing unused storage in SET1. */ static void merge_variable_sets (set0, set1) struct variable_set *set0, *set1; { register unsigned int bucket1; for (bucket1 = 0; bucket1 < set1->buckets; ++bucket1) { register struct variable *v1 = set1->table[bucket1]; while (v1 != 0) { struct variable *next = v1->next; unsigned int bucket0; register struct variable *v0; if (set1->buckets >= set0->buckets) bucket0 = bucket1; else { register char *n; bucket0 = 0; for (n = v1->name; *n != '\0'; ++n) HASH (bucket0, *n); } bucket0 %= set0->buckets; for (v0 = set0->table[bucket0]; v0 != 0; v0 = v0->next) if (streq (v0->name, v1->name)) break; if (v0 == 0) { /* There is no variable in SET0 with the same name. */ v1->next = set0->table[bucket0]; set0->table[bucket0] = v1; } else { /* The same variable exists in both sets. SET0 takes precedence. */ free (v1->value); free ((char *) v1); } v1 = next; } } } /* Merge SETLIST1 into SETLIST0, freeing unused storage in SETLIST1. */ void merge_variable_set_lists (setlist0, setlist1) struct variable_set_list **setlist0, *setlist1; { register struct variable_set_list *list0 = *setlist0; struct variable_set_list *last0 = 0; while (setlist1 != 0 && list0 != 0) { struct variable_set_list *next = setlist1; setlist1 = setlist1->next; merge_variable_sets (list0->set, next->set); last0 = list0; list0 = list0->next; } if (setlist1 != 0) { if (last0 == 0) *setlist0 = setlist1; else last0->next = setlist1; } } /* Define the automatic variables, and record the addresses of their structures so we can change their values quickly. */ void define_automatic_variables () { #ifdef WINDOWS32 extern char* default_shell; #else extern char default_shell[]; #endif register struct variable *v; char buf[200]; sprintf (buf, "%u", makelevel); (void) define_variable ("MAKELEVEL", 9, buf, o_env, 0); sprintf (buf, "%s%s%s", version_string, (remote_description == 0 || remote_description[0] == '\0') ? "" : "-", (remote_description == 0 || remote_description[0] == '\0') ? "" : remote_description); (void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0); #ifdef __MSDOS__ /* Allow to specify a special shell just for Make, and use $COMSPEC as the default $SHELL when appropriate. */ { static char shell_str[] = "SHELL"; const int shlen = sizeof (shell_str) - 1; struct variable *mshp = lookup_variable ("MAKESHELL", 9); struct variable *comp = lookup_variable ("COMSPEC", 7); /* Make $MAKESHELL override $SHELL even if -e is in effect. */ if (mshp) (void) define_variable (shell_str, shlen, mshp->value, o_env_override, 0); else if (comp) { /* $COMSPEC shouldn't override $SHELL. */ struct variable *shp = lookup_variable (shell_str, shlen); if (!shp) (void) define_variable (shell_str, shlen, comp->value, o_env, 0); } } #endif /* This won't override any definition, but it will provide one if there isn't one there. */ v = define_variable ("SHELL", 5, default_shell, o_default, 0); v->export = v_export; /* Always export SHELL. */ /* On MSDOS we do use SHELL from environment, since it isn't a standard environment variable on MSDOS, so whoever sets it, does that on purpose. */ #ifndef __MSDOS__ /* Don't let SHELL come from the environment. */ if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override) { free (v->value); v->origin = o_file; v->value = xstrdup (default_shell); } #endif /* Make sure MAKEFILES gets exported if it is set. */ v = define_variable ("MAKEFILES", 9, "", o_default, 0); v->export = v_ifset; /* Define the magic D and F variables in terms of the automatic variables they are variations of. */ #ifdef VMS define_variable ("@D", 2, "$(dir $@)", o_automatic, 1); define_variable ("%D", 2, "$(dir $%)", o_automatic, 1); define_variable ("*D", 2, "$(dir $*)", o_automatic, 1); define_variable ("variables; /* Find the lowest number of buckets in any set in the list. */ s = set_list; buckets = s->set->buckets; for (s = s->next; s != 0; s = s->next) if (s->set->buckets < buckets) buckets = s->set->buckets; /* Find the hash value of the bucket `MAKELEVEL' will fall into. */ { char *p = "MAKELEVEL"; mklev_hash = 0; while (*p != '\0') HASH (mklev_hash, *p++); } /* Temporarily allocate a table with that many buckets. */ table = (struct variable_bucket **) alloca (buckets * sizeof (struct variable_bucket *)); bzero ((char *) table, buckets * sizeof (struct variable_bucket *)); /* Run through a!ll the variable sets in the list, accumulating variables in TABLE. */ nvariables = 0; for (s = set_list; s != 0; s = s->next) { register struct variable_set *set = s->set; for (i = 0; i < set->buckets; ++i) { register struct variable *v; for (v = set->table[i]; v != 0; v = v->next) { unsigned int j = i % buckets; register struct variable_bucket *ov; register char *p = v->name; if (i == mklev_hash % set->buckets && streq (v->name, "MAKELEVEL")) /* Don't include MAKELEVEL because it will be added specially at the end. */ continue; /* If this is a per-target variable and it hasn't been touched already then look up the global version and take its export value. */ if (v->per_target && v->export == v_default) { struct variable *gv; gv = lookup_variable_in_set(v->name, strlen(v->name), &global_variable_set); if (gv) v->export = gv->export; } switch (v->export) { case v_default: if (v->origin == o_default || v->origin == o_automatic) /* Only export default variables by explicit request. */ continue; if (! export_all_variables && v->origin != o_command && v->origin != o_env && v->origin != o_env_override) continue; if (*p != '_' && (*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z')) continue; for (++p; *p != '\0'; ++p) if (*p != '_' && (*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9')) continue; if (*p != '\0') continue; break; case v_export: break; case v_noexport: continue; case v_ifset: if (v->origin == o_default) continue; break; } /* If this was from a different-sized hash table, then 0% recalculate the bucket it goes in. */ if (set->buckets != buckets) { register char *np; j = 0; for (np = v->name; *np != '\0'; ++np) HASH (j, *np); j %= buckets; } for (ov = table[j]; ov != 0; ov = ov->next) if (streq (v->name, ov->variable->name)) break; if (ov == 0) { register struct variable_bucket *entry; entry = (struct variable_bucket *) alloca (sizeof (struct variable_bucket)); entry->next = table[j]; entry->variable = v; table[j] = entry; ++nvariables; } } } } result = (char **) xmalloc ((nvariables + 2) * sizeof (char *)); nvariables = 0; for (i = 0; i < buckets; ++i) { register struct variable_bucket *b; for (b = table[i]; b != 0; b = b->next) { register struct variable *v = b->variable; /* If V is recursively expanded and didn't come from the environment, expand its value. If it came from the environment, it should go back into the environment unchanged. */ if (v->recursive && v->origin != o_env && v->origin != o_env_override) { char *value = recursively_expand (v); #ifdef WINDOWS32 if (strcmp(v->name, "Path") == 0 || strcmp(v->name, "PATH") == 0) convert_Path_to_windows32(value, ';'); #endif result[nvariables++] = concat (v->name, "=", value); free (value); } else #ifdef WINDOWS32 { if (strcmp(v->name, "Path") == 0 || strcmp(v->name, "PATH") == 0) convert_Path_to_windows32(v->value, ';'); result[nvariables++] = concat (v->name, "=", v->value); } #else result[nvariables++] = concat (v->name, "=", v->value); #endif } } result[nvariables] = (char *) xmalloc (100); (void) sprintf (result[nvariables], "MAKELEVEL=%u", makelevel + 1); result[++nvariables] = 0; return result; } /* 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 (flocp, line, origin) const struct floc *flocp; char *line; enum variable_origin origin; { register int c; register char *p = line; register char *beg; register char *end; enum { f_bogus, f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus; char *name, *expanded_name, *value, *alloc_value=NULL; struct variable *v; while (1) { c = *p++; if (c == '\0' || c == '#') return 0; if (c == '=') { end = p - 1; flavor = f_recursive; break; } else if (c == ':') if (*p == '=') { end = p++ - 1; flavor = f_simple; break; } else /* A colon other than := is a rule line, not a variable defn. */ return 0; else if (c == '+' && *p == '=') { end = p++ - 1; flavor = f_append; break; } else if (c == '?' && *p == '=') { end = p++ - 1; flavor = f_conditional; break; } else if (c == '$') { /* This might begin a variable expansion reference. Make sure we don't misrecognize chars inside the reference as =, := or +=. */ char closeparen; int count; c = *p++; if (c == '(') closeparen = ')'; else if (c == '{') closeparen = '}'; else continue; /* Nope. */ /* P now points past the opening paren or brace. Count parens or braces until it is matched. */ count = 0; for (; *p != '\0'; ++p) { if (*p == c) ++count; else if (*p == closeparen && --count < 0) { ++p; break; } } } } beg = next_token (line); while (end > beg && isblank (end[-1])) --end; p = next_token (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); if (expanded_name[0] == '\0') fatal (flocp, _("empty variable name")); /* Calculate the variable's new value in VALUE. */ switch (flavor) { case f_bogus: /* Should not be possible. */ abort (); case f_simple: /* A simple variable definition "var := value". Expand the value. We have to allocate memory since otherwise it'll clobber the variable buffer, and we may still need that if we're looking at a target-specific variable. */ value = alloc_value = allocated_variable_expand (p); break; case f_conditional: /* A conditional variable definition "var ?= value". The value is set IFF the variable is not defined yet. */ v = lookup_variable(expanded_name, strlen(expanded_name)); if (v) { free(expanded_name); return v; } flavor = f_recursive; /* FALLTHROUGH */ case f_recursive: /* A recursive variable definition "var = value". The value is used verbatim. */ value = p; break; case f_append: /* An appending variable definition "var += value". Extract the old value and append the new one. */ v = lookup_variable (expanded_name, strlen (expanded_name)); if (v == 0) { /* There was no old value. This becomes a normal recursive definition. */ value = p; flavor = f_recursive; } else { /* Paste the old and new values together in VALUE. */ unsigned int oldlen, newlen; if (v->recursive) /* The previous definition of the variable was recursive. The new value comes from the unexpanded old and new values. */ flavor = f_recursive; else /* The previous definition of the variable was simple. The new value comes from the old value, which was expanded when it was set; and from the expanded new value. Allocate memory for the expansion as we may still need the rest of the buffer if we're looking at a target-specific variable. */ p = alloc_value = allocated_variable_expand (p); oldlen = strlen (v->value); newlen = strlen (p); value = (char *) alloca (oldlen + 1 + newlen + 1); bcopy (v->value, value, oldlen); value[oldlen] = ' '; bcopy (p, &value[oldlen + 1], newlen + 1); } } #ifdef __MSDOS__ /* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but non-Unix systems don't conform to this default configuration (in fact, most of them don't even have `/bin'). On the other hand, $SHELL in the environment, if set, points to the real pathname of the shell. Therefore, we generally won't let lines like "SHELL=/bin/sh" from the Makefile override $SHELL from the environment. But first, we look for the basename of the shell in the directory where SHELL= points, and along the $PATH; if it is found in any of these places, we define $SHELL to be the actual pathname of the shell. Thus, if you have bash.exe installed as d:/unix/bash.exe, and d:/unix is on your $PATH, then SHELL=/usr/local/bin/bash will have the effect of defining SHELL to be "d:/unix/bash.exe". */ if ((origin == o_file || origin == o_override) && strcmp (expanded_name, "SHELL") == 0) { char shellpath[PATH_MAX]; extern char * __dosexec_find_on_path (const char *, char *[], char *); /* See if we can find "/bin/sh.exe", "/bin/sh.com", etc. */ if (__dosexec_find_on_path (value, (char **)0, shellpath)) { char *p; for (p = shellpath; *p; p++) { if (*p == '\\') *p = '/'; } v = define_variable (expanded_name, strlen (expanded_name), shellpath, origin, flavor == f_recursive); } else { char *shellbase, *bslash; struct variable *pathv = lookup_variable ("PATH", 4); char *path_string; char *fake_env[2]; size_t pathlen = 0; shellbase = rindex (value, '/'); bslash = rindex (value, '\\'); if (!shellbase || bslash > shellbase) shellbase = bslash; if (!shellbase && value[1] == ':') shellbase = value + 1; if (shellbase) shellbase++; else shellbase = value; /* Search for the basename of the shell (with standard executable extensions) along the $PATH. */ if (pathv) pathlen = strlen (pathv->value); path_string = (char *)xmalloc (5 + pathlen + 2 + 1); /* On MSDOS, current directory is considered as part of $PATH. */ sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : ""); fake_env[0] = path_string; fake_env[1] = (char *)0; if (__dosexec_find_on_path (shellbase, fake_env, shellpath)) { char *p; for (p = shellpath; *p; p++) { if (*p == '\\') *p = '/'; } v = define_variable (expanded_name, strlen (expanded_name), shellpath, origin, flavor == f_recursive); } else v = lookup_variable (expanded_name, strlen (expanded_name)); free (path_string); } } else #endif /* __MSDOS__ */ #ifdef WINDOWS32 if ((origin == o_file || origin == o_override) && strcmp (expanded_name, "SHELL") == 0) { extern char* default_shell; /* * Call shell locator function. If it returns TRUE, then * set no_default_sh_exe to indicate sh was found and * set new value for SHELL variable. */ if (find_and_set_default_shell(value)) { v = define_variable (expanded_name, strlen (expanded_name), default_shell, origin, flavor == f_recursive); no_default_sh_exe = 0; } } else #endif v = define_variable (expanded_name, strlen (expanded_name), value, origin, flavor == f_recursive); if (alloc_value) free (alloc_value); free (expanded_name); return v; } /* Print information for variable V, prefixing it with PREFIX. */ static void print_variable (v, prefix) register struct variable *v; char *prefix; { const char *origin; switch (v->origin) { case o_default: origin = "default"; break; case o_env: origin = "environment"; break; case o_file: origin = "makefile"; break; case o_env_override: origin = "environment under -e"; break; case o_command: origin = "command line"; break; case o_override: origin = "`override' directive"; break; case o_automatic: origin = "automatic"; break; case o_invalid: default: abort (); } printf ("# %s\n", origin); fputs (prefix, stdout); /* Is this a `define'? */ if (v->recursive && index (v->value, '\n') != 0) printf ("define %s\n%s\nendef\n", v->name, v->value); else { register char *p; printf ("%s %s= ", v->name, v->recursive ? "" : ":"); /* Check if the value is just whitespace. */ p = next_token (v->value); if (p != v->value && *p == '\0') /* All whitespace. */ printf ("$(subst ,,%s)", v->value); else if (v->recursive) fputs (v->value, stdout); else /* Double up dollar signs. */ for (p = v->value; *p != '\0'; ++p) { if (*p == '$') putchar ('$'); putchar (*p); } putchar ('\n'); } } /* Print all the variables in SET. PREFIX is printed before the actual variable definitions (everything else is comments). */ void print_variable_set (set, prefix) register struct variable_set *set; char *prefix; { register unsigned int i, nvariables, per_bucket; register struct variable *v; per_bucket = nvariables = 0; for (i = 0; i < set->buckets; ++i) { register unsigned int this_bucket = 0; for (v = set->table[i]; v != 0; v = v->next) { ++this_bucket; print_variable (v, prefix); } nvariables += =this_bucket; if (this_bucket > per_bucket) per_bucket = this_bucket; } if (nvariables == 0) puts (_("# No variables.")); else { printf (_("# %u variables in %u hash buckets.\n"), nvariables, set->buckets); #ifndef NO_FLOAT printf (_("# average of %.1f variables per bucket, \ max %u in one bucket.\n"), (double) nvariables / (double) set->buckets, per_bucket); #else { int f = (nvariables * 1000 + 5) / set->buckets; printf (_("# average of %d.%d variables per bucket, \ max %u in one bucket.\n"), f/10, f%10, per_bucket); } #endif } } /* Print the data base of variables. */ void print_variable_data_base () { puts (_("\n# Variables\n")); print_variable_set (&global_variable_set, ""); } /* Print all the local variables of FILE. */ void print_file_variables (file) struct file *file; { if (file->variables != 0) print_variable_set (file->variables->set, "# "); } #ifdef WINDOWS32 void sync_Path_environment(void) { char* path = allocated_variable_expand("$(Path)"); static char* environ_path = NULL; if (!path) return; /* * If done this before, don't leak memory unnecessarily. * Free the previous entry before allocating new one. */ if (environ_path) free(environ_path); /* * Create something WINDOWS32 world can grok */ convert_Path_to_windows32(path, ';'); environ_path = concat("Path", "=", path); putenv(environ_path); free(path); } #endif *[MAKE-3_78_1HB]VARIABLE.H;1+,5d. /@ 4 -`0123KPWO 56)(7@m89G@HJ/* Definitions for using variables in GNU Make. Copyright (C) 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Codes in a variable definition saying where the definition came from. Increasing numeric values signify less-overridable definitions. */ enum variable_origin { o_default, /* Variable from the default set. */ o_env, /* Variable from environment. */ o_file, /* Variable given in a makefile. */ o_env_override, /* Variable from environment, if -e. */ o_command, /* Variable given by user. */ o_override, /* Variable from an `override' directive. */ o_automatic, /* Automatic variable -- cannot be set. */ o_invalid /* Core dump time. */ }; /* Structure that represents one variable definition. Each bucket of the hash table is a chain of these, chained through `next'. */ struct variable { struct variable *next; /* Link in the chain. */ char *name; /* Variable name. */ char *value; /* Variable value. */ enum variable_origin origin ENUM_BITFIELD (3); /* Variable origin. */ unsigned int recursive:1; /* Gets recursively re-evaluated. */ unsigned int expanding:1; /* Nonzero if currently being expanded. */ unsigned int per_target:1; /* Nonzero if a target-specific variable. */ enum variable_export b~MAKE-3_78_1HB.BCK5d`AKE-3_78_1HB]VARIABLE.H;1 } { v_export, /* Export this variable. */ v_noexport, /* Don't export this variable. */ v_ifset, /* Export it if it has a non-default value. */ v_default /* Decide in target_environment. */ } export ENUM_BITFIELD (2); }; /* Structure that represents a variable set. */ struct variable_set { struct variable **table; /* Hash table of variables. */ unsigned int buckets; /* Number of hash buckets in `table'. */ }; /* Structure that represents a list of variable sets. */ struct variable_set_list { struct variable_set_list *next; /* Link in the chain. */ struct variable_set *set; /* Variable set. */ }; extern char *variable_buffer; extern struct variable_set_list *current_variable_set_list; /* expand.c */ extern char *variable_buffer_output PARAMS ((char *ptr, char *string, unsigned int length)); extern char *variable_expand PARAMS ((char *line)); extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file)); #define allocated_variable_expand(line) \ allocated_variable_expand_for_file (line, (struct file *) 0) extern char *expand_argument PARAMS ((char *str, char *end)); extern char *variable_expand_string PARAMS ((char *line, char *string, long length)); /* function.c */ extern int handle_function PARAMS ((char **op, char **stringp)); extern int pattern_matches PARAMS ((char *pattern, char *percent, char *str)); extern char *subst_expand PARAMS ((char *o, char *text, char *subst, char *replace, unsigned int slen, unsigned int rlen, int by_word, int suffix_only)); extern char *patsubst_expand PARAMS ((char *o, char *text, char *pattern, char *replace, char *pattern_percent, char *replace_percent)); /* expand.c */ extern char *recursively_expand PARAMS ((struct variable *v)); /* variable.c */ extern struct variable_set_list *create_new_variable_set PARAMS ((void)); extern struct variable_set_list *push_new_variable_scope PARAMS ((void)); extern void pop_variable_scope PARAMS ((void)); extern void define_automatic_variables PARAMS ((void)); extern void initialize_file_variables PARAMS ((struct file *file)); 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 struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin)); extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length)); extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value, enum variable_origin origin, int recursive)); extern struct variable *define_variable_in_set PARAMS ((char *name, unsigned int length, char *value, enum variable_origin origin, int recursive, struct variable_set *set)); extern struct variable *define_variable_for_file PARAMS ((char *name, unsigned int length, char *value, enum variable_origin origin, int recursive, struct file *file)); extern char **target_environment PARAMS ((struct file *file)); extern int export_all_variables; *[MAKE-3_78_1HB]VERSION.C;1+,6d./@ 4-`0123KPWO56&J7sm89G@HJ/* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because make.h was found in $srcdir). */ #include #ifndef MAKE_HOST # define MAKE_HOST "unknown" #endif char *version_string = VERSION; char *make_host = MAKE_HOST; /* Local variables: version-control: never End: */ *[MAKE-3_78_1HB]VMSDIR.H;2+,c ./@ 43-`0123KPWO56kM7&m89G@HJ/* dirent.h for vms */ #ifndef VMSDIR_H #define VMSDIR_H #include #define MAXNAMLEN 255 #ifndef __DECC #if !defined (__GNUC__) && !defined (__ALPHA) typedef unsigned long u_long; typedef unsigned short u_short; #endif #endif struct direct { off_t d_off; u_long d_fileno; u_short d_reclen; u_short d_namlen; char d_name[MAXNAMLEN + 1]; }; #undef DIRSIZ #define DIRSIZ(dp) \ (((sizeof (struct direct) \ - (MAXNAMLEN+1) \ + ((dp)->d_namlen+1)) \ + 3) & ~3) #define d_ino d_fileno /* compatability */ /* * Definitions for library routines operating on directories. */ typedef struct DIR { struct direct dir; char d_result[MAXNAMLEN + 1]; #if defined (__ALPHA) || defined (__DECC) struct FAB fab; #else struct fabdef fab; #endif } DIR; #ifndef NULL #define NULL 0 #endif extern DIR *opendir PARAMS (()); extern struct direct *readdir PARAMS ((DIR *dfd)); #define rewinddir(dirp) seekdir((dirp), (long)0) extern int closedir PARAMS ((DIR *dfd)); extern char *vmsify PARAMS ((char *name, int type)); #endif /* VMSDIR_H */ *[MAKE-3_78_1HB]VMSFUNCTIONS.C;4+,i|. /@ 4M -`0123KPWO 56_"m7:m89G@HJ/* vmsfunctions.c */ #include #include #include "make.h" #ifdef __DECC #include #endif #include #include #include #include #include #include "vmsdir.h" #ifdef HAVE_VMSDIR_H DIR * opendir (dspec) char *dspec; { struct DIR *dir = (struct DIR *)xmalloc (sizeof (struct DIR)); struct NAM *dnam = (struct NAM *)xmalloc (sizeof (struct NAM)); struct FAB *dfab = &dir->fab; char *searchspec = (char *)xmalloc (MAXNAMLEN + 1); memset (dir, 0, sizeof *dir); *dfab = cc$rms_fab; *dnam = cc$rms_nam; sprintf (searchspec, "%s*.*;", dspec); dfab->fab$l_fna = searchspec; dfab->fab$b_fns = strlen (searchspec); dfab->fab$l_nam = dnam; *dnam = cc$rms_nam; dnam->nam$l_esa = searchspec; dnam->nam$b_ess = MAXNAMLEN; if (! (sys$parse (dfab) & 1)) { free (dir); free (dnam); free (searchspec); return (NULL); } return dir; } #define uppercasify(str) \ do \ { \ char *tmp; \ for (tmp = (str); *tmp != '\0'; tmp++) \ if (islower (*tmp)) \ *tmp = toupper (*tmp); \ } \ while (0) struct direct * readdir (dir) DIR * dir; { struct FAB *dfab = &dir->fab; struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam); struct direct *dentry = &dir->dir; int i; memset (dentry, 0, sizeof *dentry); dnam->nam$l_rsa = dir->d_result; dnam->nam$b_rss = MAXNAMLEN; if (debug_flag) printf ("."); if (!((i = sys$search (dfab)) & 1)) { if (debug_flag) printf ("sys$search failed with %d\n", i); return (NULL); } dentry->d_off = 0; if (dnam->nam$w_fid == 0) dentry->d_fileno = 1; else dentry->d_fileno = dnam->nam$w_fid[0] + (dnam->nam$w_fid[1] << 16); dentry->d_reclen = sizeof (struct direct); dentry->d_namlen = dnam->nam$b_name + dnam->nam$b_type; strncpy (dentry->d_name, dnam->nam$l_name, dentry->d_namlen); dentry->d_name[dentry->d_namlen] = '\0'; uppercasify (dentry->d_name); return (dentry); } int closedir (dir) DIR *dir; { if (dir != NULL) { struct FAB *dfab = &dir->fab; struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam); if (dnam != NULL) free (dnam->nam$l_esa); free (dnam); free (dir); } return 0; } #endif /* compiled for OpenVMS prior to V7.x */ char * getwd (cwd) char *cwd; { static char buf[512]; if (cwd) return (getcwd (cwd, 512)); else return (getcwd (buf, 512)); } int vms_stat (name, buf) char *name; struct stat *buf; { int status; int i; static struct FAB Fab; static struct NAM Nam; static struct fibdef Fib; /* short fib */ static struct dsc$descriptor FibDesc = { sizeof (Fib), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *) &Fib }; static struct dsc$descriptor_s DevDesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &Nam.nam$t_dvi[1] }; static char EName[NAM$C_MAXRSS]; static char RName[NAM$C_MAXRSS]; static struct dsc$descriptor_s FileName = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; static struct dsc$descriptor_s string = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; static unsigned long Rdate[2]; static unsigned long Cdate[2]; static struct atrdef Atr[] = { #if defined(VAX) /* Revision date */ { sizeof (Rdate), ATR$C_REVDATE, (unsigned int) &Rdate[0] }, /* Creation date */ { sizeof (Cdate), ATR$C_CREDATE, (unsigned int) &Cdate[0] }, #else /* Revision date */ { sizeof (Rdate), ATR$C_REVDATE, &Rdate[0] }, /* Creation date */ { sizeof (Cdate), ATR$C_CREDATE, &Cdate[0]}, #endif { 0, 0, 0 } }; static short int DevChan; static short int iosb[4]; name = vmsify (name, 0); /* initialize RMS structures, we need a NAM to retrieve the FID */ Fab = cc$rms_fab; Fab.fab$l_fna = name; /* name of file */ Fab.fab$b_fns = strlen (name); Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */ Nam = cc$rms_nam; Nam.nam$l_esa = EName; /* expanded filename */ Nam.nam$b_ess = sizeof (EName); Nam.nam$l_rsa = RName; /* resultant filename */ Nam.nam$b_rss = siz eof (RName); /* do $PARSE and $SEARCH here */ status = sys$parse (&Fab); if (!(status & 1)) return -1; DevDesc.dsc$w_length = Nam.nam$t_dvi[0]; status = sys$assign (&DevDesc, &DevChan, 0, 0); if (!(status & 1)) return -1; FileName.dsc$a_pointer = Nam.nam$l_name; FileName.dsc$w_length = Nam.nam$b_name + Nam.nam$b_type + Nam.nam$b_ver; /* Initialize the FIB */ for (i = 0; i < 3; i++) { #ifndef __VAXC Fib.fib$w_fid[i] = Nam.nam$w_fid[i]; Fib.fib$w_did[i] = Nam.nam$w_did[i]; #else Fib.fib$r_fid_overlay.fib$w_fid[i] = Nam.nam$w_fid[i]; Fib.fib$r_did_overlay.fib$w_did[i] = Nam.nam$w_did[i]; #endif } status = sys$qiow (0, DevChan, IO$_ACCESS, &iosb, 0, 0, &FibDesc, &FileName, 0, 0, &Atr, 0); sys$dassgn (DevChan); if (!(status & 1)) return -1; status = iosb[0]; if (!(status & 1)) return -1; status = stat (name, buf); if (status) return -1; buf->st_mtime = ((Rdate[0] >> 24) & 0xff) + ((Rdate[1] << 8) & 0xffffff00); buf->st_ctime = ((Cdate[0] >> 24) & 0xff) + ((Cdate[1] << 8) & 0xffffff00); return 0; } char * cvt_time (tval) unsigned long tval; { static long int date[2]; static char str[27]; static struct dsc$descriptor date_str = { 26, DSC$K_DTYPE_T, DSC$K_CLASS_S, str }; date[0] = (tval & 0xff) << 24; date[1] = ((tval >> 8) & 0xffffff); if ((date[0] == 0) && (date[1] == 0)) return ("never"); sys$asctim (0, &date_str, date, 0); str[26] = '\0'; return (str); } int strcmpi (s1, s2) const char *s1; const char *s2; { while (*s1 != '\0' && toupper(*s1) == toupper(*s2)) { s1++; s2++; } return toupper(*(unsigned char *) s1) - toupper(*(unsigned char *) s2); } *[MAKE-3_78_1HB]VMSIFY.C;4+,~b.$/@ 4K$!q-`0123KPWO%56Xu7em89G@HJ/* vmsify.c Module for vms <-> unix file name conversion Written by Klaus Kmpf (kkaempf@progis.de) of proGIS Software, Aachen, Germany */ #include #include #include #if VMS #include #include #include #include #include #include #include #include /* Initialize a string descriptor (struct dsc$descriptor_s) for an arbitrary string. ADDR is a pointer to the first character of the string, and LEN is the length of the string. */ #define INIT_DSC_S(dsc, addr, len) do { \ (dsc).dsc$b_dtype = DSC$K_DTYPE_T; \ (dsc).dsc$b_class = DSC$K_CLASS_S; \ (dsc).dsc$w_length = (len); \ (dsc).dsc$a_pointer = (addr); \ } while (0) /* Initialize a string descriptor (struct dsc$descriptor_s) for a NUL-terminated string. S is a pointer to the string; the length is determined by calling strlen(). */ #define INIT_DSC_CSTRING(dsc, s) INIT_DSC_S(dsc, s, strlen(s)) #endif /* copy 'from' to 'to' up to but not including 'upto' return 0 if eos on from return 1 if upto found return 'to' at last char + 1 return 'from' at match + 1 or eos if no match if as_dir == 1, change all '.' to '_' else change all '.' but the last to '_' */ static int copyto (char **to, char **from, char upto, int as_dir) { char *s; s = strrchr (*from, '.'); while (**from) { if (**from == upto) { do { (*from)++; } while (**from == upto); return 1; } if (**from == '.') { if ((as_dir == 1) || (*from != s)) **to = '_'; else **to = '.'; } else { if (isupper (**from)) **to = tolower (**from); else **to = **from; } (*to)++; (*from)++; } return 0; } /* get translation of logical name */ static char * trnlog (char *name) { int stat; static char reslt[1024]; $DESCRIPTOR (reslt_dsc, reslt); short resltlen; struct dsc$descriptor_s name_dsc; char *s; INIT_DSC_CSTRING (name_dsc, name); stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc); if ((stat&1) == 0) { return ""; } if (stat == SS$_NOTRAN) { return ""; } reslt[resltlen] = '\0'; s = (char *)malloc (resltlen+1); if (s == 0) return ""; strcpy (s, reslt); return s; } static char * showall (char *s) { static char t[512]; char *pt; pt = t; if (strchr (s, '\\') == 0) return s; while (*s) { if (*s == '\\') { *pt++ = *s; } *pt++ = *s++; } return pt; } enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE }; /* convert unix style name to vms style type = 0 -> name is a full name (directory and filename part) type = 1 -> name is a directory type = 2 -> name is a filename without directory The following conversions are applied (0) (1) (2) input full name dir name file name 1 ./ [] .dir 2 ../ .dir 3 // : :[000000] :000000.dir 4 //a a: a: a: 5 //a/ a: a: a:000000.dir 9 / [000000] [000000] 000000.dir 10 /a [000000]a [a] [000000]a 11 /a/ [a] [a] [000000]a.dir 12 /a/b [a]b [a.b] [a]b 13 /a/b/ [a.b] [a.b] [a]b.dir 14 /a/b/c [a.b]c [a.b.c] [a.b]c 15 /a/b/c/ [a.b.c] [a.b.c] [a.b]c.dir 16 a a [.a] a 17 a/ [.a] [.a] a.dir 18 a/b [.a]b [.a.b] [.a]b 19 a/b/ [.a.b] [.a.b] [.a]b.dir 20 a/b/c [.a.b]c [.a.b.c] [.a.b]c 21 a/b/c/ [.a.b.c] [.a.b.c] [.a.b]c.dir 22 a.b.c a_b.c [.a_b_c] a_b_c.dir 23 [x][y]z [x.y]z [x.y]z [x.y]z 24 [x][.y]z [x.y]z [x.y]z [x.y]z 25 filenames with '$' are left unchanged if they contain no '/' 25 filenames with ':' are left unchanged 26 filenames with a single pair of '[' ']' are left unchanged the input string is not written to */ char * vmsify (name, type) char *name; int type; { /* max 255 device max 39 directory max 39 filename max 39 filetype max 5 version */ # define MAXPATHLEN 512 enum namestate nstate; static char vmsname[MAXPATHLEN+1]; char *fptr; char *vptr; char *s,*s1; int as_dir; int count; if (name == 0) return 0; fptr = name; vptr = vmsname; nstate = N_START; /* case 25a */ s = strpbrk (name, "$:"); if (s != 0) { char *s1; char *s2; if (type == 1) { s1 = strchr (s+1, '['); s2 = strchr (s+1, ']'); } if (*s == '$') { if (strchr (name, '/') == 0) { if ((type == 1) && (s1 != 0) && (s2 == 0)) { strcpy (vmsname, name); strcat (vmsname, "]"); return vmsname; } else return name; } } else { if ((type == 1) && (s1 != 0) && (s2 == 0)) { strcpy (vmsname, name); strcat (vmsname, "]"); return vmsname; } else return name; } } /* case 26 */ s = strchr (name, '['); if (s != 0) { s1 = strchr (s+1, '['); if (s1 == 0) { if ((type == 1) && (strchr (s+1, ']') == 0)) { strcpy (vmsname, name); strcat (vmsname, "]"); return vmsname; } else return name; /* single [, keep unchanged */ } s1--; if (*s1 != ']') { return name; /* not ][, keep unchanged */ } /* we have ][ */ s = name; /* s -> starting char s1 -> ending ']' */ do { strncpy (vptr, s, s1-s); /* copy up to but not including ']' */ vptr += s1-s; if (*s1 == 0) break; s = s1 + 1; /* s -> char behind ']' */ if (*s != '[') /* was '][' ? */ break; /* no, last ] found, exit */ s++; if (*s != '.') *vptr++ = '.'; s1 = strchr (s, ']'); if (s1 == 0) /* no closing ] */ s1 = s + strlen (s); } while (1); *vptr++ = ']'; fptr = s; } else /* no [ in name */ { int state; int rooted = 1; /* flag if logical is rooted, else insert [000000] */ state = 0; do { switch (state) { case 0: /* start of loop */ if (*fptr == ( '/') { fptr++; state = 1; } else if (*fptr == '.') { fptr++; state = 10; } else state = 2; break; case 1: /* '/' at start */ if (*fptr == '/') { fptr++; state = 3; } else state = 4; break; case 2: /* no '/' at start */ s = strchr (fptr, '/'); if (s == 0) /* no '/' (16) */ { if (type == 1) { strcpy (vptr, "[."); vptr += 2; } copyto (&vptr, &fptr, 0, (type==1)); if (type == 1) *vptr++ = ']'; state = -1; } else /* found '/' (17..21) */ { if ((type == 2) && (*(s+1) == 0)) /* 17(2) */ { copyto (&vptr, &fptr, '/', 1); state = 7; } else { strcpy (vptr, "[."); vptr += 2; copyto (&vptr, &fptr, '/', 1); nstate = N_OPEN; state = 9; } } break; case 3: /* '//' at start */ while (*fptr == '/') /* collapse all '/' */ fptr++; if (*fptr == 0) /* just // */ { char cwdbuf[MAXPATHLEN+1]; s1 = getcwd(cwdbuf, MAXPATHLEN); if (s1 == 0) { return ""; /* FIXME, err getcwd */ } s = strchr (s1, ':'); if (s == 0) { return ""; /* FIXME, err no device */ } strncpy (vptr, s1, s-s1+1); vptr += s-s1+1; state = -1; break; } s = vptr; if (copyto (&vptr, &fptr, '/', 1) == 0) /* copy device part */ { *vptr++ = ':'; state = -1; break; } *vptr = ':'; nstate = N_DEVICE; if (*fptr == 0) /* just '//a/' */ { strcpy (vptr+1, "[000000]"); vptr += 9; state = -1; break; } *vptr = 0; /* check logical for [000000] insertion */ s1 = trnlog (s); if (*s1 != 0) { /* found translation */ char *s2; for (;;) /* loop over all nested logicals */ { s2 = s1 + strlen (s1) - 1; if (*s2 == ':') /* translation ends in ':' */ { s2 = trnlog (s1); free (s1); if (*s2 == 0) { rooted = 0; break; } s1 = s2; continue; /* next iteration */ } if (*s2 == ']') /* translation ends in ']' */ { if (*(s2-1) == '.') /* ends in '.]' */ { if (strncmp (fptr, "000000", 6) != 0) rooted = 0; } else { strcpy (vmsname, s1); s = strchr (vmsname, ']'); *s = '.'; nstate = N_DOT; vptr = s; } } break; } free (s1); } else rooted = 0; if (*vptr == 0) { nstate = N_DEVICE; *vptr++ = ':'; } else vptr++; if (rooted == 0) { strcpy (vptr, "[000000."); vptr += 8; s1 = vptr-1; nstate = N_DOT; } else s1 = 0; /* s1-> '.' after 000000 or NULL */ s = strchr (fptr, '/'); if (s == 0) { /* no next '/' */ if (*(vptr-1) == '.') *(vptr-1) = ']'; else if (rooted == 0) *vptr++ = ']'; copyto (&vptr, &fptr, 0, (type == 1)); state = -1; break; } else { while (*(s+1) == '/') /* skip multiple '/' */ s++; } if ((rooted != 0) && (*(vptr-1) != '.')) { *vptr++ = '['; nstate = N_DOT; } else if ((nstate == N_DOT) && (s1 != 0) && (*(s+1) == 0)) { if (type == 2) { *s1 = ']'; nstate = N_CLOSED; } } state = 9; break; case 4: /* single '/' at start (9..15) */ if (*fptr == 0) state = 5; else state = 6; break; case 5: /* just '/' at start (9) */ if (type != 2) { *vptr++ = '['; nstate = N_OPEN; } strcpy (vptr, "000000"); vptr += 6; if (type == 2) state = 7; else state = 8; break; case 6: /* chars following '/' at start 10..15 */ *vptr++ = '['; nstate = N_OPEN; s = strchr (fptr, '/'); if (s == 0) /* 10 */ { if (type != 1) { strcpy (vptr, "000000]"); vptr += 7; } copyto (&vptr, &fptr, 0, (type == 1)); if (type == 1) { *vptr++ = ']'; } state = -1; } else /* 11..15 */ { if ( (type == 2) && (*(s+1) == 0)) /* 11(2) */ { strcpy (vptr, "000000]"); nstate = N_CLOSED; vptr += 7; } copyto (&vptr, &fptr, '/', (*(vptr-1) != ']')); state = 9; } break; case 7: /* add '.dir' and exit */ if ((nstate == N_OPEN) || (nstate == N_DOT)) { s = vptr-1; while (s > vmsname) { if (*s == ']') { break; } if (*s == '.') { *s = ']'; break; } s--; } } strcpy (vptr, ".dir"); vptr += 4; state = -1; break; case 8: /* add ']' and exit */ *vptr++ = ']'; state = -1; break; case 9: /* 17..21, fptr -> 1st '/' + 1 */ if (*fptr == 0) { if (type == 2) { state = 7; } else state = 8; break; } s = strchr (fptr, '/'); if (s == 0) { if (type != 1) { if (nstate == N_OPEN) { *vptr++ = ']'; nstate = N_CLOSED; } as_dir = 0; } else { if (nstate == N_OPEN) { *vptr++ = '.'; nstate = N_DOT; } as_dir = 1; } } else { while (*(s+1) == '/') s++; if ( (type == 2) && (*(s+1) == 0)) /* 19(2), 21(2)*/ { if (nstate != N_CLOSED) { *vptr++ = ']'; nstate = N_CLOSED; } as_dir = 1; } else { if (nstate == N_OPEN) { *vptr++ = '.'; nstate = N_DOT; } as_dir = 1; } } if ( (*fptr == '.') /* check for '..' or '../' */ && (*(fptr+1) == '.') && ((*(fptr+2) == '/') || (*(fptr+2) == 0)) ) { fptr += 2; if (*fptr == '/') { do { fptr++; } while (*fptr == '/'); } else if (*fptr == 0) type = 1; vptr--; /* vptr -> '.' or ']' */ s1 = vptr; for (;;) { s1--; if (*s1 == '.') /* one back */ { vptr = s1; nstate = N_OPEN; break; } if (*s1 == '[') /* top level reached */ { if (*fptr == 0) { strcpy (s1, "[000000]"); vptr = s1 + 8; nstate = N_CLOSED; s = 0; break; } else { vptr = s1+1; nstate = N_OPEN; break; } } } } else { copyto (&vptr, &fptr, '/', as_dir); if (nstate == N_DOT) nstate = N_OPEN; } if (s == 0) { /* 18,20 */ if (type == 1) *vptr++ = ']'; state = -1; } else { if (*(s+1) == 0) { if (type == 2) /* 19,21 */ { state = 7; } else { *vptr++ = ']'; state = -1; } } } break; case 10: /* 1,2 first is '.' */ if (*fptr == '.') { fptr++; state = 11; } else state = 12; break; case 11: /* 2, '..' at start */ count = 1; if (*fptr != 0) { if (*fptr != '/') /* got ..xxx */ { return name; } do /* got ../ */ { fptr++; while (*fptr == '/') fptr++; if (*fptr != '.') break; if (*(fptr+1) != '.') break; fptr += 2; if ((*fptr == 0) || (*fptr == '/')) count++; } while (*fptr == '/'); } { /* got '..' or '../' */ char cwdbuf[MAXPATHLEN+1]; s1 = getcwd(cwdbuf, MAXPATHLEN); if (s1 == 0) { return ""; /* FIXME, err getcwd */ } strcpy (vptr, s1); s = strchr (vptr, ']'); if (s != 0) { nstate = N_OPEN; while (s > vptr) { s--; if (*s == '[') { s++; strcpy (s, "000000]"); state = -1; break; } else if (*s == '.') { if (--count == 0) { if (*fptr == 0) /* had '..' or '../' */ { *s++ = ']'; state = -1; } else /* had '../xxx' */ { state = 9; } *s = 0; break; } } } } vptr += strlen (vptr); } break; case 12: /* 1, '.' at start */ if (*fptr != 0) { if (*fptr != '/') { return name; } while (*fptr == '/') fptr++; } { char cwdbuf[MAXPATHLEN+1]; s1 = getcwd(cwdbuf, MAXPATHLEN); if (s1 == 0) { return ""; /*FIXME, err getcwd */ } strcpy (vptr, s1); if (*fptr == 0) { state = -1; break; } else { s = strchr (vptr, ']'); if (s == 0) { state = -1; break; } *s = 0; nstate = N_OPEN; vptr += strlen (vptr); state = 9; } } break; } } while (state > 0); } /* directory conversion done fptr -> filename part of input string vptr -> free space in vmsname */ *vptr++ = 0; return vmsname; } /* convert from vms-style to unix-style dev:[dir1.dir2] //dev/dir1/dir2/ */ char * unixify (char *name) { static char piece[512]; char *s, *p; if (strchr (name, '/') != 0) /* already in unix style */ return name; p = piece; *p = 0; /* device part */ s = strchr (name, ':'); if (s != 0) { *s = 0; *p++ = '/'; *p++ = '/'; strcpy (p, name); p += strlen (p); *s = ':'; } /* directory part */ *p++ = '/'; s = strchr (name, '['); if (s != 0) { s++; switch (*s) { case ']': /* [] */ strcat (p, "./"); break; case '-': /* [- */ strcat (p, "../"); break; case '.': strcat (p, "./"); /* [. */ break; default: s--; break; } s++; while (*s) { if (*s == '.') *p++ = '/'; else *p++ = *s; s++; if (*s == ']') { s++; break; } } if (*s != 0) /* more after ']' ?? */ { if (*(p-1) != '/') *p++ = '/'; strcpy (p, s); /* copy it anyway */ } } else /* no '[' anywhere */ { *p++ = 0;! } /* force end with '/' */ if (*(p-1) != '/') *p++ = '/'; *p = 0; return piece; } /* EOF */ *[MAKE-3_78_1HB]VPATH.C;1+,:d.$/@ 4$! -`0123KPWO%56m7Mvm89G@HJ/* Implementation of pattern-matching file search paths for GNU Make. Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Make; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "make.h" #include "filedef.h" #include "variable.h" #ifdef WINDOWS32 #include "pathstuff.h" #endif /* Structure used to represent a selective VPATH searchpath. */ struct vpath { struct vpath *next; /* Pointer to next struct in the linked list. */ char *pattern; /* The pattern to match. */ char *percent; /* Pointer into `pattern' where the `%' is. */ unsigned int patlen;/* Length of the pattern. */ char **searchpath; /* Null-terminated list of directories. */ unsigned int maxlen;/* Maximum length of any entry in the list. */ }; /* Linked-list of all selective VPATHs. */ static struct vpath *vpaths; /* Structure for the gener0c5sgihlCLEAN.;1Np}6^TH2i|*!(QR2W !$~_s`npe9 bz?rX[HALK=Wv6"!0@~y>G:-@L1&$J8s+_1it8=%6{j7,,^?\q j)G,_vX{n0ShfM`cjU8uYr6{ l>}pK0i'+ p{('9'O@<;  68z@'RK\$2[&6's]47!fg=6d3{<#C&tk0H!{I0vL57JcyQ2g_YK{% X(1 ")%'+ [ 7^eE@V|$p-|>1>1y hF#&NXen|g+0\iowZ{2m`hmJ)6zfPPI8 <8\h5QjrdP fw|A{cVt$U9yLAwj`k(Bc^[{Ws>b9w# }y6"jzI5_or5.rTj<)Ui'.EqdP$"aIgmm 0Bs^P`+;as OV*0,_3Q'{ I62BpZu8c'9-`wf&Vb}v8]{p+)L<:qN0~yWF"omm8"r{9&szIJ$1~ c NCu(rc{P]+'q=}v3!sFT9Re"{B[7$4+9<*G~6W;m}Md7= $"Wb@hi1n,,y15%@{<]n.dBWA?S"p7,]86e(PED`.cy)/o:|`6=* w7m~YCUg,A2F &i`<-b88fNQ _ nPqxF&z)5\Xb$ .aq~#r900z+A7]~dGihn'u[]+F4Y. B.^^nlvBqArMW`e+O^0L awmi}O3%RjHlJqys$oi]!7k^\Y!j z}Yz9qLt4``ua{RX%ZKA h cXpQ[ s-&KPqiJMj2( r$\TEz] 1> T|yD!n(Ht2 p,q1DU:VU q1kft-:tmAKTP_YNl9m Y5I7JoI |k[W& e7o~{Wh7S o;VlU>oK0["xD=<>Q/SV_ 3:dnZTAs?t3-u ]W8/Vr5^h\FT^.H'$F&/I+1TVM*AT'gI3lO7~=/.1Nh[cl*[z+fzYb3 X #0bnwzfSr\Sx81b!obfP=L@;fbo6]^1_YX0YW|QYU`kc)/^_5GJ#?y-t_>M [t u7EBS}lQ]y\lid=zH2}o @_m^^^I<4_Ha.{OzxxwM5+H!  E]QUz"J"I:OY2$,cE*6)$ V72}V2US=!np I0t%_hS W=:g 5''I+JMOtJ [S_Nz<_ q NzK](OQ y4*OQPCi'KR1M9 h@gJ,(B3m.y%nA kjTq UHhP]7y$aTrsr62h5rC~'8T@Ml@"D4C{GnCpwbbTr O!i3CoNRyLo.H$D[W ,aC j!V ;-%j ?k"^81" ,g`!qe?wnv1]ZU*#h~ Yn>9BS*9t;_wyAXPPuuwh15- >j2:GIb.Mj \:oc$$0Gp>L-f.kVoxt%WAWEMwPK|}$oHpK~D0gppQXlsd:Rx2)UStF0e5Bv;<6!+aiRwOT)i<( s^C|%`Rb%~J{Z_F3Wn^;v.X)>86(+Xl= y=/e?aoS7RII`n|L|drx0,@H)='I| p}"#a~tw1]B$$PSyhZh;=/s)dD4-HB= l0rN4a/Y]TsNl'H2wtEe}N1z}@ v3KE4t=n$/+]Pii{L5e{EjO8CogxdkXFP\*0WSg0~p KLikLF%I0i={.|X-5dX.B{:.~15 VU <NqA#Cv$\@kYK/GUG_. oOZxC!x}4 Ka_h$~2os7;FO*EG;bQ)N="d#0^sZ:_mNX2Dp^uE9+[^-m7O~h hLvgH27| 6 V6>{~?t2P9 /*5vy4?yEy/O#N wu{lTu},k@a;(`c8k NO kv v@6elfcVie.m'"5if7_A~iz6FC8c3%tUN%6hxlE!K"#7, ~A&u-`xA#qeIc_ t r 3[AG %.~?M|rh&](h6a:Gy.W";-h ( E(UHF]gM3K-)LS[49t]{vo "vqs_&K}yN58 \^*R3m;Qp_+&#8)i`y9[es<LJtpzH.vDFLSa,ij0|~c~QT\+}lcE/dv=k[d}v6+Kx]m`O3qo>2;px1W-W 6ALBlaE_4U/R/_Hcg9Dk2j4WV5F!@&z JzoHZN9a].uG] Gh/\o88I9t]PdAX\tXvorc@ }Jn/lj/ Stc=]'p_ SUs)j^fytchy $I5Po@S#RNymg"4T#z9 su 8r"R(s^OBW}$HNlvdI?C?\-A`ZUidj!+f( G?o)!H\_O,V[ AJ,68{"EJ+AAP0rE\ vs; I9H>m-NOtFlwvU^XWFR8Pu\iT -IP11 KM`)2P9dnW[ HME E0: QK_[^DUt=5W,n5T/$5|!&%D%(g,(y:nyVlP 6(@a'c>a<88"4%;4CIPYzr9e.VC [jPTR 72Ews VuK,ip5Z23_9x[Oqa'j'6=LgFo;'.9<)74TD >,7y$7 0R ib}Ti~7T,fyev5B9lh?n;wT\66!(='QF[)'+;be&*(8 +(^l`qj!ciab w%~ pNVGiQi  gKn KUT?C7&XHAQ),Xf & l%PaY<9.C9NI.&fFv|2@^QE_YR&]D~Jl'jXoIt ZU1E\h#4=h_Ck6OKNgP/4K-q  Y~H?7jZ|S U%R^#1SD-zB2Wa' N1pl,gD(OVwJWEV(t_;Ql^Uh~S_gF ""/xotwA f9k{TyHX:QBJB~aYJ:/)HgF9] +K yQ)GG E04;o3F TujA:5"dA1~xv:N4 %OLLCn{`%FoqIVDJi 2UV*kWWeybN,gnO$4iU 56;)!H(@eih`5nuu1Q]Gs"y-k,J4YUdn( <l7 `Q+RwZv}&+y0G=f\.'jL{AP=@Rhj@,F,Jo O]TNZMt0A:H`#R2&/4Ii=C/( vH C?@DNos0Im:"]YP2!*( p /o7(w Im&LE<=D.aze/h#\Zgg0<[cBdE=_v=OqOiNWaQ0bI>S.PVG&h\1|oH9c 7Xv]K*L0^Vy)/KCUFhU<2c5 |BYS(J8}0nH7}\=;7mtp1l1;C 3wopYLi"\ /jpZv|f@h6b*Z1^S-FC  M]kYI@`I{t pASilhjvJm-qVZ>, #|5yC|)kR{){L`,f7O 5-=b4a"N/l^C0r8up"3l0 0EUQ-xF9#\%}Jh_Yglk_@2nuL9+*yM:?0[ir^ $!8Okj xX%-Xvw{d5/rDtz &uzFg%dNT4 ./De&lTs2}yC< 9|3 @U*kE"co ) hV X~;",=Q{B&K`@j9XZ; `(?"vTghrO]LAREI-LgH^;0exPL+9d2![jF{$7M`}tV$b!uq>q%n,aF zjw}A!_&}KOztyrJR2/K;y Ira|PDQ:S}]Il gRp=cAnqSKox?!S5- tqwPM~ S~G4E%t? 7;]`?8]cnLau.@P#>-SM8, eZz(?Xha4v,cL1s'dPQe*%W+<EA&CuAP:3 vE6]2_d o8gc#UBk{R@Gs/ f `WN`x0BQkMU 26`^Jr{5)^ )4YB~nV K$he vo8'purmu7t$ t&`dW;pf_(/)42 MvhiW0b|nd#d~`&g.RbcT*91!^u*qR'L]u9z9LoedDyC`N0@"=|i|/(\:U>"16JC =|.}N^LUvb}n9x-LssSCy/kw5d*$b"D_v_AQ-`';gtGs,\LG=tCo]*#&" 4l`w0x,$Y3|o("F[#i_I2sTXEX)bqugc]9/U<-pB`6ISw[f3=D-1/m |-R%|d?`-"/`j#7)u;>3Xg2SFTc[",YGU gVOCXk\qzp7)4pzW<{-^IX;=W-W'%sl>9(< %'7c'|kh+ 3O(01 . :m}u,zd'_\vBNWmo{rpP|AH{sT;`-v\4eH~UkK{E]9 7~ACpr9W;4o[//n9t;!wsEeeVqj>}"q\paL]|(DPw7/fr\I7'_]@ODh:MWn*|-'0N\!q.a1n|:'=xG{M ~KS |Abc7Ec_U("/;6B4oI3|sLO_)dQ0MG&(X0CN$M#U-)% =R [O*C#yo;-"_c *{Q_@ bJL.puJf %aoK n{M.F 58O|$)_Qld֢h<1RZ oXN5%z2iNs+CdvRNV*N Jsh1)is pAq26~2K=8]xvr$*B(UAT;7 hHr8am OxflHSFr|3L']Vun(a?^$ 15uWbhZ>.HhE8/,+#p -Ze}BrAy~!" Ni=E;k^AQp G )88*>"+a_a#MSX1, ('E@I U[HmA{@+y 2)Y#BG7MP~ U?WB>,uUe-nIf_b1x|D)4\b-s!QSyk"*VG8zr]0h XDIJ%N#d_P"M50 R7W E8GdfYDz=GyKTvWx=VV_!cA d|i$B8xcR$Mq*I1m27\<& T=v'|&P4l%OCUonc ynw)*s,_;406nnKVLr L}&XM jo!$o+fMxM{PC5m6 "&-H^g,_"-ul~KX ~BB]Ze1BeWqOv2M $**8nV $0ZUZ*M9H=;nXlN;6yS]a@:4XW}_t#K2[6oypK0PapQ%:CKUnI;PKb>-5~` @M3d% Kls$"?2;&bcyDn)*8hnZ` @H{|% EAqLXz [[HuK7Dz&#<%U5E#Z[#*ZZ&1\[~'%R]X'}^OG i?:tY3^5y?>=~;4<70n-zxI 7j O1 '7  L0N8M_EE'PG{>uBslm b0CJqV]ABCLz9r?? 1Z7-j> H lD)IzQHy^{%wK=~ =ZKaZ2hvk/QVoZ >)!,QMDkI QN JThiNqeK{/D;A)K_=G*.il\OF(^XDrj&V_PYEmw4O5F7(_JyhOfS9'k~P^^OlS <#C4K 9B.=5oljBRZ]S@/VU[+ C:)SP )iOA T%wF hE nC^$_C#|\%Sn7X2=OPE~Wtlh~-JS ecg1P*ApMCr.H(q^s8;CH/PVPUT|m+rr`DSdw.P +83>98wE#qOWvK+u^~ *6poB_8:?l'KD$y,3z`O/Y> t,EkQ2$+`b3F}g%fXj@VAc6d'?"r.lT*j8?xl'S?549l{,\CI>s (9mcJ0|/hj>PehaUjez Gh k PN Ub,+hC_,BA"rM 1oU ,"Js} Sw:8bW A7'TDrf78i\JSA.(3+?!;rWHc:-Sf5#<A=M)Ni&'cC) ; f5m:pEDWZU?^4M4U>08I*2twm" $IeJ 3$O)TJq awVBr-nQiQ >L lxc8ttP?%<3K[F]ZJK J.>XT?2@FX;'e2 ?ݾgPrt]cK hpk'R U}u&3<8gz2ds:|I"{^i\RY\.`7lV<Oo<}TjQr .&CFqKBlME1RWXHE2-w{^(T!xB(GR"wz9>UxEia3Dnmr,H z4M^q_E%g>e`\/'~=Z&[3U_x"rmUZ:q3dm%[K&loN_1EIZ$0FoT1lE~GAQZ_D }8$^Yn^b8w-+\ ;QZ5I L:F2(:lGP0?t_a) k9I"?u0qDE+?",*s~^~q/xQkCn99Bt%5c3pO3iJ CV^ "$ N!vN(MOvl_l|cj.Pft%b+RE4:.^n.Z V3>F~2-` s.F]s*UB1p5}8+%`F)Q]6? $YRV&qb. `bxf)lK\=@qEB kf'U 6m~*,{Ozr$WAw)Ht vvLC4+Je)cDFHo{z)r_,/&p2lGb-jl< .Ejd:M]+1? `.6D]HZJHdJWvVLMZ3zG6.%P"&8 A}Zk ^\_8Ky[^G i@%SM'Ha K!AqT']NFf_e8 Pl%SJj;hTrSgyv<(c1w"%Q4a!j,EYN"h'"'uB$zD>i*,Fac5uzW`H#F]% LwFt wLJsYrKiaZijJ /1CYH`a%}2qJ8^!h]b1b?".U\_\\Jmu 1s(JI!<:=:nloPnT8n w4Y]'+ 8{ +mw*} F*tbDg{z5iFablLDE\,aD7(}T~0iP ww1psZy3:t!$  C~\`WLw,T^?EWA8 oVV/}%qX*Y_%[YwpAufa09S_Y@)ROB/qQu8k) "5_,XnWmH(U<lTLmZ>aS4.x-)n23ktMziX]46j99~GX"sev34 M|&ba lth'O|3@0SW !<`'+M$@_!5#vJ[AN=v:CeDz #cn:bpPy RNSIyA%KS 9ESe**U0U pAlU&vn-,Q1#xrui ]4L>PS"|]a%;/1'B+LEV>QhRZ'x!5Q8ea:4'(j,zC,'on'Q\{hv>H 3-iGk; |$Q tJz6 SgIn1pMx/r_'y{0G)5>cR<h@CghyNc>cvU4"nL4ncTIa8~=@ziRj&s&~gkJ o @%M+J5r&'>; T`, P-9]'-FCO0 s~)^bHK ]{9\ZD'"c]t<HY0&81er&vMwU_%y->\sD zwHl7m41<-Au{^pm-u_C, Y"!Jr(X$(z(PDRW}}9 6A7h}c#L6a'0&f2/K7'OX%N>A)s~2(}f@N9{6545/z?r2A4 76"h:u-zgdoew{iE)%RXZ%f:'-jM}_ \ %(4@];#eC~p[RT}BpV5*,s@Rfs6+u([ <]/u]Q3GLek8 V:p+H&j44lxa(~v#rEx9VzBg<.md]8!,\8!Wn|>| Q)9i].ug,|kܜc VHeGdRBS .|D>,-%q $4 =ca9b$1fYK..sGD@a )(aE(_'cDO=gDs-BK`QMQaM/2]3~&9f>jNs-`hp`H;3K3\$ 3"!Ya%x)=,zDe/ti9Ta4K0<}dU0Z7=c&fA+gZ%C7?1R'v`vR)>IK 7N!6vq!?DSr S`3$"v3xl]).{,tfhJ!aD7W SHO [cLOa6:oWF*_GedL'6 [aKHlQoA[GB4N-F 9t.I,%V,X?<@MdQj3WpL/z[L u-ZVevZ;U Y?m$'91#& h8 4a5lbdH82g! e_d-i|?4$GkoZst#H *zU? (7 j'~ 9}#5bOO@%q$lB)-=fg@,9}X[?+'t$k;Gk!JhB>bd#)hE,k$vL>a z!en =ruDA!TjCyV_H0OJFRa.p"~{FY$6 ^!_,Xo7L=TV.LM|P._$=LwheMm-~eNBDrl &$'r3Bx(yC8Y 8QX&IMjQ0(e,?0^bnEkh6,,t&V1P#Z?0r!X?cwD-dZ_sL{WXD?gBA;{nxI^%:iYWT7y>&qrr85 ^{<#|2Y`qp+[F_j:([yg nPuxc#7i%ZMY\6is,;))oI+?k\'C} J3[! x+)m[0dOJ'$MhSm zf~+-\@4Z@4Sf9DSjSpsu4KOJ`P3 S0W!Y ]I%hpo3/_PwQ41 h`-jxfL5Sq hSK:,Wj.&; . 6b!K:I! ^1n$lY@L0 9+*nNxekaLuL2PP[7; F0 _g5Ep$ai:TCxsB&b% )!GTN^ 7r(d iR=id#W \,V3vJt~teK=xBQ:E@PkY45x01wKFh(c4C&lAxJk2N9Jy@.m\Q;TDS8=" O]|uU_DEKJyMjb c[UX Oz}/>RG3 !YU&.s/Yt]^Z22C&o 'w/K~o~V73}..}D5=!;3@t.Pq2,apa67Cv*_wo#1e#^jIv.!z0}u d5 12x kgdM)\CZ5[B .$G<-q@:y!5%e=NkbhNY H? hd?WL=3j*v@`#`uW.'g<}gc-~x<Q#F89| \T@u^6mb'DQqdmSY4y@A=dv{8J`dp\j7@vw:PK'O=@ 2t ao7wI1s e64t)H [/F3sFs 081'}|x3|}v0M g|&=kAEh,,G_IEZ &"=+-:1#z}[tm04 (0< !DJD=4h}!Hr[iOPb#*"1:;p d='%vcb] gXBR7v~ /" U+hbw#6oJc`zF$EK]W@iGx{TR[PKUwF1AU( jUJ#,j1Pi8-{_ !q 0x-g1!Loh8bv$-NU^cZs!Z;(7{l@(O_Y/u({[.)h4TFW>f+$-tzg} a 6?iHi`-bN C#wbn8~I'5+K_gE;uKYU/K^]}v_N $^Qd /nxnQ[~_uo,Gx.Mbj|yg&&|~BQrif_&)j8u @'f^1Bm5Zq]l/z G6qutQS^K' |x{A PbTcm  WQIOXgt#Wf KlY 6JUT"~q`y:T"Q!h|3]g9.8KF^CFZ`+g0SEQ0BnKLg : x08}ss3@}N$*fQm6[ZsTDMTFIJk3D m[!f [R%@OyI.Ov+{O'00sj;z:LOf6^KG@w Y,@o}2{JFn-KCYtCSkre:63~(kst_] #<8i!\X=#l|(DK`Z2P^=Z\,,1~:0=aNK<"6[lVRcE ukJYy;=;A/ bBFqLVYN}@!y ;: \d<\Ca_V^OrLeY~:[ ]v^.2 l \lv5 XfT3en;T~q'@hQl9hDw &gV)gKpBkIbXd( &#v)8U\-=U=) %8GHdcAY0E5W4:^!tm.npCTxnH VqN29DpX: H? kY!J3>(d;(8g4:[6M""M09}9_$sGB4*[JX rz\Z!Vph! 8V{b?#HLXoEt,yq@mE^Zs$  Hvdf;/lZHc ro_b?{!+V/y8h mr- rkz.wt`Is jn47a%!ZU9|Ih;NgI5tABDa8gp.j,\V'x|iu0R"&\ X :': ;"fk`/ lup@ Q . C^Bt?R-[taN|lb5b\kD*K}3k'NInQVWx ;V<"kqM@^S]Nj Xv'+#*/{sa< {$iXY:4;CR/wm/w&o9~*}hJ[z~@j|&sr $Po+;*7(LOu}s&1x(*kkw=,/7G^56cG!9  z}^'.[gu 2)E#T|FC#4~_8-}.cb??R`OCTAPV2V}e `,Gp><)4;MbjCXTQ@4+Ye+, K=(0}zmLidC4U |} p1z{(G5<#4n"Q3 SBBA%?WC@8@YB{1r1L>Ks]U*{&}#z|z80/82[~]yAxM?@R{zY9AC>sKXgVrrJUM}NRGZ5IM]rz#F:) "Cd{b:2(N.R?]WS-t1HIy1Cz/vYc?] ~ALn9gcce%s`Y YBB7w2.N9U.c')W>6MM&a/ >_u_ZkX. ,971$bzkKxEj0(!o'XRn_bY-%[2.54:­;XJbFږ%?p~ TqL?6Ny@=4ND{BUD,;<"6 2'+2Q+qpNS7' <}6f{8bvhy>y/HN1lc:b$t)>y!`JpH> F~0:ec2ImC.h  LNJjPkFSz6RM<,Q]L,16z;L B"d0#YBU <4GbxR0FJq9M9f} ok!d}nI15p: o^g)W4CogQl.2:5rl;M%d~ cWAjAA,h~.$mN;JefeNgNC$6w@.C3guZsg,H-N!%}:rpG}m^lX$S|K{auq]I1=HIT4;wnm@g+jyHCjW[I<#QJOari=:?Z!rtOQ J%rt3=-\ nQaAJHGY}< sOR zEz2 cFa3y yhUZ{-6Xvz+g7?vbhcUn3N~&jnKY woCw7aeMB:Rcj@R5(W(1 " ISIX/rj}au5?6W\g+~-=B+o|p1=g_-&~eipcU ]ZlgxtFFGu66ByaRns+fc^~.* _9gR%Fi+}aE[)%hA`y`"Vu.}7&;z0R{f?9:HT7vw4v}D~qJ uh:  =BCDfD`Qp [ $@O5fpHh,?(Z+;{n+T Zacz$pbcsmi8o)KwGuy6S |,Ct-#F5E+&403`-bMuHe JL"L^TtPPBO41{q"j"!b)h d8.AsN,BgBnLQM-(ykX|xV<:yo0m Mh >7ggQPbYQyrnw;X4APSwxQp#Y=` YWdE b}>q(-KZTvQDV+p"UZ>x 9hEd Mao^/Sx glU^e@iGm.>wpwOsWALW8lcXMK6n};4v/?MV2>J"mC:[K[=JS`>2Tv~39:!CJ6yL'l^@UmUk/1wA\8:~,?/L?/Y&kMzSL5 MoTo7gz%x'cb;zylg[dPhXA]5XRuzMD7:+Czavx hnZ2pX$Z2edD>V mp/e *xVESJVX39Zm!PqJU^m& _@{wpgLQ7-!Ot? 7wPXU1F<cq`)& WXduXS#$s(h !>j0&<81#I`VeD*i!;hf(1- ZB$hPGW^*\g@65lwFpXF89 2WY* lW=)K|2b`fF`?Awu0b.VZ'\h>q+ Uqj5Vq=Y9cn7w4/b2q29-+-slI_wj(7EqAw9.{f<(KUq; d,_raQ"Z8vn|4y27x;0!!g,W6%vA o}hrTN :t $47TZ2=LOLXd(tAIUrxB1%Y\ UJj0(058odRvkg uC^^K +5d4Ui( @'e  @`;>([?O]Axs_^R\u&+Kg.q\KviSG=*m#ul#FpZ7E/!TmmCjmk ^4G4U|8!# >,VT~IK(NKehFDhyg}9g#NMqCW 1Q\>2yLN31DyhKA^|WGH\:fE kn.ch{p&;Tza{ 7*C0U@BYUv THN<81v0!H2Zd8b+2!;&ki~.f_) PH%ZgO>!VHEaRJtOI_9g~)M $pYV+yYvzz`~"(Y5*Q-C$oK?Jl6XULL`~BLZN{J~@%E?f[Xl(:8Dp7n(~!o96&I"K\xtU8B /6sx'K,-ki~~m EO/[EmYbPv+f>C*,BZ1FqISJ bpM[84i0RC|#Nu9"8sx\x`fc/UF$0iuDIf+ 7/R%F{pIgMOAU<_57Z\H kKfXH rQM*.]x L5RkMH)C(5L~TP C{> F]=^N]N^BRLw"H2,LMwC\yPw) t3qrYd-h; w`x<\o^byy'JNvdf?Ml'P;/HH{@u242kg` >m )Ooz9WY &F@3BhUW_]C-ZjDT)tXH8iI*!t"%lt$`3ifI@$(5u#Op_oX,z]GR9EPzbfQ KAA|CgCuOvFFvTEx]yD!zF 47Qa5T< v#"ujP %M4j\(>q S||*:mW{z45*\Nt.)-T .1coY/[u7>B@a!7o x *PG# UMtqsiM:d,[ ?('R];)^j [M11{3%/xh=dha&sjLLb; Exj*%@L}R5qwF/J A>,+2G-ns&/"%$=RnN:y{0acLH:82$wlT3AOp yC#UDS3`c5pre\<1Go|"_^~ms (Me@^6=pAKo:7%;HKM`Dxtc"VCG K&`Rp/ r=h.Mw9FXCJLUdSprx6oar7*5fold|%tV{`=^TK| .=<>^\} FTX|wnx"Z=I&ICoK*kQKx=W `Zk 8s*>RxK} Lmve` 7TOCzPaH eyvV(102Q, {4vp;Tr9jD=$g3\iX91!cUqfOGkv!HGw}#3#;IRtP>[V C*U [Pg9D{n bKh DRbnPJEF |A Af .r= }*: V/U<2v]J ] vk L&jU;&XW]Wn+^>e H   iS` TCR:\IJ paAAG(ym)`!CPQ`zyZ >9Ynku>C1:rZX.jWJ [DS8P\dixbz)OPSQZ(z?\8-nwQRDm#T(_-at&g. $pUIJ|2>=0kdLuMLf` neYpsg*=ux|(rx1/-!+ wVqF\UJTD; )aJ(iTFGoF!LJefOVL2XD$MFzH=/Nf TtF~h?[ JoI35J%mcTWo0]~K$ 3|[(6> ZS<=*Z6[8)BmZHG]m9f@o$*K;XM8\ Kn ,PJwq_A{:TIqiX2l(B@)}?UMA4 [}Q oxtpA ^8k)-i[ZvuuB9y..(5vCaRR:UA1CWHFsrtf.H+0Vdf z~`k.QdRS uA~}yW!!XmwUN?PJ[v5CzCv@j>^ltiA+Y.vTQ)}'ZLN^XxHxw NGDl RI b"*m0m "> Dy`c~2\N" 0:c Fft Trv%#lL(OJHN~]+1@\/nw,uL tTLv~c"=.SR%!)' ygu1{C;k[(i~BxO ;C] wx_$#AHU (  ~x/D(rNA!W_:F~9T^ ,fp x?GIIdZ baWMp x.AU1Af'|<I)jK&/"WYj,j}zE2@:CIBI(.IeXKI8WWbT@7vNrqh zV~O!?s='pV@t,ozzD`ZH8_e2gJcElyXil{~]Rvy{daH;5GiEIFWaJu]KPh: GO䏚>g_DneFAsW6AVF`0@hAx+7XHTT 7WHL -1eMiF1Xt(R Z |>VYl Rcd s5TH>8z|b5peW\J3?`oNwvVhp35@J:h.JzSwu`Ld[-6=}1j{WY0sm*s0dy%VPW1?R9ecr2j,qbhE9D'){\#IV_@Bas<3("ms>-(k*Dd j,MR cr<<*y]zq#(Hum.43>viTzKh "l'4/X9F/&}d \_p hzF*v7Jbq"5lJn3KcWZ>W`:@d5i^*sIt{A_TmV"L]~"gtwo#l5=3g! @QxfE +ns-0 ? W$poA aoVu`D`[/8KXe$4-tu7PU-qyE#RS2HR t[W~O~| **pJ'*F6Hw9,z| XXWK {Dy X Up/5h kyN9L2U?<~n!:`*0mS4*.8I,` }cmJ`m &EB>lSQ]>Z1P{5{(.~1NW[hk{{U:=MJ!j^lY^O&n(axl7JPcF Tv%UZ>BN}9Ke|U}U^:z:v8)SU?ABN r/\[/+5w$ b]Bw;sbfrxo PGKU5tnfTt fo,Ln`AzFTj?#>1toAY>G9>U. z 2oXt;;v|_4d;RY#9'A{u&`z+Gt*AmY4=N-:?.Nyk P8%D(I'mlCeS9<]u5k#9hQ%n js& ^&jx|D+0|P$O [w$\tR&YI {a!c&nK,V]5)A43TU>*")E>I' 2bpTL7WCe t<_zu>9hr}tlJsS!'DpN@F=lYSPx''hkZ7oWsVk4?dRSP]bdTMc6pqu$$?EQHO s kx.&~&!; &BwaWo3H!b#*-j 1&Q| N m y]e'pvG3C/t4ADb$~)IvUq Y#vi-d^nuLTO9MIoj6V^kh+b= NJ\!fuoyF~Yr._*J?CWvMSH@. wwTHQ~VI?HHJ 4dU&f;nQ jfJziv l.MK5_+&X0Ni%q)>I(@ w \&L VeEC~fOV=&kVog"<V IK8Q XE,70$,6JyZh5q]7=\'kuX,WQ68+YP \@\[j6 }`H\z7X*>v<@#q%V^]c`!](2klO U>8kf ~+d;0|FvLz1QL<lHs"X*BVWL877Zjtlmv6$2s2b=f B_Fs|9Te JBq;]:MbFEwTu,F_6 _TE9SBny kvf]W yd14`[`Kh d86<0@3J>'X:+n7{w1(Xg|9K}7DHZ$'Y Ez5 QE.M Wj%'Y mW#(a}zWVj ys36sQ]-WM]b=UIf^5xxh6L] W223@HoHP _0-FM*}PKQF{A<E6O~ J]H]B-JG I9lfVG&E\wl{I tj )px/E 9M}7/v\dIqx=l^g`!@0=wP%tZ V4 #@9y;gclq ,F>f B:9n8_2Zy]7jBQ'mZl?e~5(3fJ>{8u7eoI*!D^,qc].(Xn'~KK.`\m>~,fF Y-\5>FJsUND:e1l8PCx0N!?PKhczE `i]J!e]P*(&F ;kc@ZEZ?@5IFz50^c+AH 6*oL ,Cs`])_2P/rnk6OaH}HD<k1LV4O(vy|?>::5xib b)L0 &{2<5XD{cLC vNG 82p=;TIY.[6#gOLIAqB,7suoe^BfG+fQ %4}>W)XBudB;8"?lX?_i+A 80pjg"|pIpKU B'!\t& p&"X0Um~zR )!2<\C,hQ5I7SUl0i_Z[fy?j2`,xtXkFqb59X_.rNvk*[O+\YlOYDn~|8;@E?P>@Kvm-N\s2VQ|KP}Lw/G^[?E=LG|)^N.Zqf[kG<<7/x/uA Kz]!%|Y/}l7JJ,@_H cpG1 Fo8Pr@z&IaaxqA#8[1 8zQ@&JHb6;HD91''k90}D 7/&iFj,pf.:u gD!Kfj0@+6t4o:Zc>/e# G0w$y*$eQBA'dZF B3%9^I2#8#vA>g(Ah B:dx{vI{$l:NB_jIla5DqFR.jWV}_Yx'Hce!vmMApN/ut=) PZOA;Uj}]V94 c6N*7yg+%Me\ NN`4{f>pH5wg1Kz1M |z~ =R0UNP("3HA 'd&/:d 4?X^sM2vS| iuzRr+3.['U)]Q_)Cm<^LMk_WE"m']On)>9!sQ0yud?\OSb2vG &o3KDva|/^:h838"~}0r(Q=(Dm x.a[D%V )0Oiy;7b^d@z$:zU#Y:Kws-@ZXs"s|Hi^Mg@ v})3L/Pq "k y,}w>D`FG,5|,O|r5 ]0b^5V>rY!D)Z~.Lc 5OM,uUlKOZ$aAS*\joj|*2`Rf 0T; :C*)t[@Fv9ic(s  K2Lg}Ef& u{Nz h46 ,}.Cd&H\T 8Zp+Mx!z.f]P{l;sD,mj2%D>u^]!&O KmJmJ?o PO4Z7AlZD(c\j # K?I0 D&[bEdC#Z/O5KOA/Dp><+E]6 tC:y\.[R!uv'g{Okp 39V72d[x1LLi{Uml uktZ!{JC :sZD( vu_'Y5,r&-_32 D_886r159+i| 2^} =1Q ")JI. $Eh &hX"J_ ${,66iU!D'pg= ]1{&h{w8%6b)YA'li'x"**H: *UM"8m5&5d/Q'Tjiux a+X- O{-m5S.#<"t~[2qGS:qGV\>, u "rxQ6UU)&t#:c`0 y05u0QnjT$MK=cPe;=;sTkyh-?Pm;C:+TiE[OLYi LPJmB tu@H =ONN^,* XXkjEVj8zdqHA,O;KeL4o?v~v_ ,)Mjh)kJ//S JfLsU$|Wo6r LJJ*BGv)b*p6DT>yBENZC OE45sqlagwjG}eb1<)zJjT`x KW?x4 V5#[h(-x+@LHE'g$: Z#o$**DG,-t|>VHPLmW@;4/'d=bZUc@52UkMdo'jX5SZ%I!|jb~GoX~SH`ZA}D6QrBL &I)(087` ~s8}BM# ]o\p^6I "|+[& Sye~)Xx9IW]5,JJOn"~ e[J)EC!6T "TUaL".U4+So*T_Y}Rn9G= ,fYMJe_L-Q @~%I a :"YhY_E[A5} |IC)N?CMkO}}3rZD *TR|hDUzYf@>7LTW0=-V|d\B.+#-]x2o4g)4d)Tq*qe 80 "zW'Wuf{.0:oMiK CaI gLVLUz)!eZg6%ml_ 7ptk BA N?mE _V%~Nazt@8,G?Z.D+qJ@11WD'uC%M6d[:s Yj5 6%.3TN|_]S19G&"5VQGR2pbIOF?!qtGn]XL^Uk>X#td(#yA>J{guGC8ADEX\!r<;6u9dMQK.R t@X`yM`;J?:[B "XUdBLV) Hl9F06 4SL`xJw #b$yrhX|a}zrOAU<:H)0|, /8$tCV\p_8Z(VZa+Bw+S('ck' $yOdR)f"y] m<3i 9)=H{+y  A AidM/(|di }6zL1/ v>'- &)iR$[0"7SJk .~qd[MP{>@j =0|8#DS.}BBaktjf:|lmB1{X"|5cv2g?+cx8ltnALGgXLSsN0D3q>>d0*&kU!0MF$6s&'$nJNpcShRZ2*\~<M^chr cI,w]5v#Dk)jwYii0AS0B[gcliw ?lo{MLTyOW{;wjB+qNFDHs$(/PN](* / H|{'kOSO10X` 3bTCL!bSQTH#P-%t@B!`m]pzIs|OBNizc%U)YRnO).<[:Tay&^,8Iz40d!M@=<"rL G&=t*!|O>yJ:3s&4'CJv8QCGb]Uk>Wb^hj llP.U Pwv<,gkL6t'ivmuM^u##Imm4.QUO y*S.LG=aJB#>Nq00o)v eI+o_ OB"C}TPaW7)g?yR}; +a)_k,I9B=IN(jIF  M+@Q 1w>{ hf^>:n jqoi#rl{Y|k!8C,_umns>"HJe^I,Yl ma*jDM^[  ]Wqg\:?f Tw,ZUo|%YgW/ZXh)/cG=NT98Z3vF>))G HU4Ox}0fFp@2{R3iiawtyx`AHV_8 ^wPj,Uy:;H}2 -tq/m8e0"g0tO(Dpc`S{a#su x#2 gnEC2TQ%-*(4',pH ; VP`&r6-?:X?f~Xe}&0hxHf1 -AU`Vy"Fy sClvDj2x rC$#7G\he\-v kKp1S(42}:lv!A4(QC -H]P@(j.v/pZ&U8%1iKI m*B{Td'zLe4 y9RzQNUp\TTh)I0s<4/#W~Mx })@cmdyrvn}~`8)&"pg(>~dq|$>W>?+vht')v0mgWd6,lkI ~]@ s?L$Lp'N4&p6=r8P?8oZJ~` k^K)*YsSC?OYeu/[>y3!ZZO !4}hrYgHsz6q Gc!%3:gw&y:Y} _2mc9g1C:xKEv)V\>u-;Ow*(R;zLi9&sxH?%%ml uf,1".bK]UHgd(O'wy;p!sbyg6.& 8&_efY=?58g)R_ST:E0":'M|4^|=]pno:rt(-vJBFL&riAA(/|t43Mv ~h&tHJ8BH]-03%,9MOlek `&2-Mw,5,*pqfi<[lU\V/jfF|zyb?4.k9ys+#.5!5=Xg %p-Tpr'-2E s~pyXr"S$UrX{MSop_% bG# d+%+< 9[0H36_S;kylpKPx5Ycd;VO-I_$g$4gp4- o^]V]&G0EXds /{w$fY)N\j!br: ~4my(kpZf/pX{Hu~-kG`wQHD$+fU u?;z#Laoq;]mx8k!986x-Cz' >H=?tt]0&Kmn'N68:h5a~ 5rC{Y|$!*>2h8=Ws<-> BZ*9,o/E3-4'` Hsa#|_-#%cc f[7#"@9 g~1wv"V Q2aq8<&S}H2L5B*w>Lh>Xmil9jMr r;m+Sl^%-EJgS1O7~%A4y=ahB;c57EbzQ>=e K n<TWW|V|E$(S%>`R#Cz=U%;CL_[k oNv~mN y.Hc98 $0k7*8D.>aC=G:C(S7 }/+ =oaUbsQBjB1", wmmyS$bOV|hyXNy9N Ro\@Ap/Y@ErqHQ>BBIvk`o 8= j? Zi; Wt$Hl8V3l$IE)i KkSmGAd; )Cj QN~~DS{i~{5sK{6h'bJ"%xYBuPSB3L\j%=`Aei;u=+//M['_mFs,[;f "PG!U,HgZH /Zl~e2~[^raX+&Qwr%ZMC+XQMZ,xI HkGsYPNmXB>ciMS> nXNlkDY 7jX0bcK3Sz&g, ]-Roq>1ehu,;n y)-3#jEqBQvVxv$##-U@t5Ag$Gkl)IQ6"GRL+,Qh0i<w?v_,i,O 19K R!{ iB8 BJ?]8:ox Fqj;2V  c=*Nf}cV+.  hhk_od"&"6.>`?K4r R&|lJvDo.{kjLDQa^SH ,o|8(]VB)+kPcaoUczw`Aoo GO{^U@ F~x2Y(/.`Xc;bQ_Titw IVbslYL2\Mq:xr6{AzLQpl96yGGED}"KPcQaX!Ql@71,GI0hhUU7/;>\S\iJj E4 Aiamvoz3seQ|6n&<|`1Q,M:+M$A G5F\ T~ncuxG)m@cwc" <+H>YP}?n(\Kw%)dsW@|<,Wg;9`/(afXY 87k\=8o;H%;^1Q;LQf4cDR^]fP^YDbGJ!^x!43]PvCP=b() b=idzCGu_M$~)~p?f"#e(.J;7g}Or i6!_`Tyh{m- 'j~*!b'T=z,.U>UKNio@QH"\CT7`5KhX*XSfET z[o)Mh"-)/9^io6|:TaC3 d~MAKE-3_78_1HB.BCK:d`[MAKE-3_78_1HB]VPATH.C;1$;<al VPATH given in the variable. */ static struct vpath *general_vpath; /* Structure for GPATH given in the variable. */ static struct vpath *gpaths; static int selective_vpath_search PARAMS ((struct vpath *path, char **file, FILE_TIMESTAMP *mtime_ptr)); /* Reverse the chain of selective VPATH lists so they will be searched in the order given in the makefiles and construct the list from the VPATH variable. */ void build_vpath_lists () { register struct vpath *new = 0; register struct vpath *old, *nexto; register char *p; /* Reverse the chain. */ for (old = vpaths; old != 0; old = nexto) { nexto = old->next; old->next = new; new = old; } vpaths = new; /* If there is a VPATH variable with a nonnull value, construct the general VPATH list from it. We use variable_expand rather than just calling lookup_variable so that it will be recursively expanded. */ { /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; p = variable_expand ("$(strip $(VPATH))"); warn_undefined_variables_flag = save; } if (*p != '\0') { /* Save the list of vpaths. */ struct vpath *save_vpaths = vpaths; /* Empty `vpaths' so the new one will have no next, and `vpaths' will still be nil if P contains no existing directories. */ vpaths = 0; /* Parse P. */ construct_vpath_list ("%", p); /* Store the created path as the general path, and restore the old list of vpaths. */ general_vpath = vpaths; vpaths = save_vpaths; } /* If there is a GPATH variable with a nonnull value, construct the GPATH list from it. We use variable_expand rather than just calling lookup_variable so that it will be recursively expanded. */ { /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ int save = warn_undefined_variables_flag; warn_undefined_variables_flag = 0; p = variable_expand ("$(strip $(GPATH))"); warn_undefined_variables_flag = save; } if (*p != '\0') { /* Save the list of vpaths. */ struct vpath *save_vpaths = vpaths; /* Empty `vpaths' so the new one will have no next, and `vpaths' will still be nil if P contains no existing directories. */ vpaths = 0; /* Parse P. */ construct_vpath_list ("%", p); /* Store the created path as the GPATH, and restore the old list of vpaths. */ gpaths = vpaths; vpaths = save_vpaths; } } /* Construct the VPATH listing for the pattern and searchpath given. This function is called to generate selective VPATH lists and also for the general VPATH list (which is in fact just a selective VPATH that is applied to everything). The returned pointer is either put in the linked list of all selective VPATH lists or in the GENERAL_VPATH variable. If SEARCHPATH is nil, remove all previous listings with the same pattern. If PATTERN is nil, remove all VPATH listings. Existing and readable directories that are not "." given in the searchpath separated by the path element separator (defined in make.h) are loaded into the directory hash table if they are not there already and put in the VPATH searchpath for the given pattern with trailing slashes stripped off if present (and if the directory is not the root, "/"). The length of the longest entry in the list is put in the structure as well. The new entry will be at the head of the VPATHS chain. */ void construct_vpath_list (pattern, dirpath) char *pattern, *dirpath; { register unsigned int elem; register char *p; register char **vpath; register unsigned int maxvpath; unsigned int maxelem; char *percent = NULL; if (pattern != 0) { pattern = xstrdup (pattern); percent = find_percent (pattern); } if (dirpath == 0) { /* Remove matching listings. */ register struct vpath *path, *lastpath; lastpath = 0; path = vpaths; while (path != 0) { struct vpath *next = path->next; if (pattern == 0 || (((percent == 0 && path->percent == 0) || (percent - pattern == path->percent - path->pattern)) && streq (pattern, path->pattern))) { /* Remove it from the linked list. */ if (lastpath == 0) vpaths = path->next; else lastpath->next = next; /* Free its unused storage. */ free (path->pattern); free ((char *) path->searchpath); free ((char *) path); } else lastpath = path; path = next; } if (pattern != 0) free (pattern); return; } #ifdef WINDOWS32 convert_vpath_to_windows32(dirpath, ';'); #endif /* Figure out the maximum number of VPATH entries and put it in MAXELEM. We start with 2, one before the first separator and one nil (the list terminator) and increment our estimated number for each separator or blank we find. */ maxelem = 2; p = dirpath; while (*p != '\0') if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p)) ++maxelem; vpath = (char **) xmalloc (maxelem * sizeof (char *)); maxvpath = 0; /* Skip over any initial separators and blanks. */ p = dirpath; while (*p == PATH_SEPARATOR_CHAR || isblank (*p)) ++p; elem = 0; while (*p != '\0') { char *v; unsigned int len; /* Find the end of this entry. */ v = p; while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p)) ++p; len = p - v; /* Make sure there's no trailing slash, but still allow "/" as a directory. */ #ifdef __MSDOS__ /* We need also to leave alone a trailing slash in "d:/". */ if (len > 3 || (len > 1 && v[1] != ':')) #endif if (len > 1 && p[-1] == '/') --len; if (len > 1 || *v != '.') { v = savestring (v, len); /* Verify that the directory actually exists. */ if (dir_file_exists_p (v, "")) { /* It does. Put it in the list. */ vpath[elem++] = dir_name (v); free (v); if (len > maxvpath) maxvpath = len; } else /* The directory does not exist. Omit from the list. */ free (v); } /* Skip over separators and blanks between entries. */ while (*p == PATH_SEPARATOR_CHAR || isblank (*p)) ++p; } if (elem > 0) { struct vpath *path; /* ELEM is now incremented one element past the last entry, to where the nil-pointer terminator goes. Usually this is maxelem - 1. If not, shrink down. */ if (elem < (maxelem - 1)) vpath = (char **) xrealloc ((char *) vpath, (elem + 1) * sizeof (char *)); /* Put the nil-pointer terminator on the end of the VPATH list. */ vpath[elem] = 0; /* Construct the vpath structure and put it into the linked list. */ path = (struct vpath *) xmalloc (sizeof (struct vpath)); path->searchpath = vpath; path->maxlen = maxvpath; path->next = vpaths; vpaths = path; /* Set up the members. */ path->pattern = pattern; path->percent = percent; path->patlen = strlen (pattern); } else { /* There were no entries, so free whatever space we allocated. */ free ((char *) vpath); if (pattern != 0) free (pattern); } } /* Search the GPATH list for a pathname string that matches the one passed in. If it is found, return 1. Otherwise we return 0. */ int gpath_search (file, len) char *file; int len; { register char **gp; if (gpaths && (len <= gpaths->maxlen)) for (gp = gpaths->searchpath; *gp != NULL; ++gp) if (strneq (*gp, file, len) && (*gp)[len] == '\0') return 1; return 0; } /* Search the VPATH list whose pattern matches *FILE for a directory where the name pointed to by FILE exists. If it is found, we set *FILE to the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to its modtime (or zero if no stat call was done), and return 1. Otherwise we return 0. */ int vpath_search (file, mtime_ptr) char **file; FILE_TIMESTAMP *mtime_ptr; { register struct vpath *v; /* If there are no VPATH entries or FILENAME starts at the root, there is nothing we can do. */ if (**file == '/' #if defined (WINDOWS32) || defined (__MSDOS__) || **file == '\\' || (*file)[1] == ':' #endif || (vpaths == 0 && general_vpath == 0)) return 0; for (v = vpaths; v != 0; v = v->next) if (pattern_matches (v->pattern, v->percent, *file)) if (selective_vpath_search (v, file, mtime_ptr)) return 1; if (general_vpath != 0 && selective_vpath_search (general_vpath, file, mtime_ptr)) return 1; return 0; } /* Search the given VPATH list for a directory where the name pointed to by FILE exists. If it is found, we set *FILE to the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to its modtime (or zero if no stat call was done), and we return 1. Otherwise we return 0. */ static int selective_vpath_search (path, file, mtime_ptr) struct vpath *path; char **file; FILE_TIMESTAMP *mtime_ptr; { int not_target; char *name, *n; char *filename; register char **vpath = path->searchpath; unsigned int maxvpath = path->maxlen; register unsigned int i; unsigned int flen, vlen, name_dplen; int exists = 0; /* Find out if *FILE is a target. If and only if it is NOT a target, we will accept prospective files that don't exist but are mentioned in a makefile. */ { struct file *f = lookup_file (*file); not_target = f == 0 || !f->is_target; } flen = strlen (*file); /* Split *FILE into a directory prefix and a name-within-directory. NAME_DPLEN gets the length of the prefix; FILENAME gets the pointer to the name-within-directory and FLEN is its length. */ n = rindex (*file, '/'); #if defined (WINDOWS32) || defined (__MSDOS__) /* We need the rightmost slash or backslash. */ { char *bslash = rindex(*file, '\\'); if (!n || bslash > n) n = bslash; } #endif name_dplen = n != 0 ? n - *file : 0; filename = name_dplen > 0 ? n + 1 : *file; if (name_dplen > 0) flen -= name_dplen + 1; /* Allocate enough space for the biggest VPATH entry, a slash, the directory prefix that came with *FILE, another slash (although this one may not always be necessary), the filename, and a null terminator. */ name = (char *) xmalloc (maxvpath + 1 + name_dplen + 1 + flen + 1); /* Try each VPATH entry. */ for (i = 0; vpath[i] != 0; ++i) { int exists_in_cache = 0; n = name; /* Put the next VPATH entry into NAME at N and increment N past it. */ vlen = strlen (vpath[i]); bcopy (vpath[i], n, vlen); n += vlen; /* Add the directory prefix already in *FILE. */ if (name_dplen > 0) { #ifndef VMS *n++ = '/'; #endif bcopy (*file, n, name_dplen); n += name_dplen; } #if defined (WINDOWS32) || defined (__MSDOS__) /* Cause the next if to treat backslash and slash alike. */ if (n != name && n[-1] == '\\' ) n[-1] = '/'; #endif /* Now add the name-within-directory at the end of NAME. */ #ifndef VMS if (n != name && n[-1] != '/') { *n = '/'; bcopy (filename, n + 1, flen + 1); } else #endif bcopy (filename, n, flen + 1); /* Check if the file is mentioned in a makefile. If *FILE is not a target, that is enough for us to decide this file exists. If *FILE is a target, then the file must be mentioned in the makefile also as a target to be chosen. The restriction that *FILE must not be a target for a makefile-mentioned file to be chosen was added by an inadequately commented change in July 1990; I am not sure off hand what problem it fixes. In December 1993 I loosened this restriction to allow a file to be chosen if it is mentioned as a target in a makefile. This seem logical. */ { struct file *f = lookup_file (name); if (f != 0) exists = not_target || f->is_target; } if (!exists) { /* That file wasn't mentioned in the makefile. See if it actually exists. */ #ifdef VMS exists_in_cache = exists = dir_file_exists_p (vpath[i], filename); #else /* Clobber a null into the name at the last slash. Now NAME is the name of the directory to look in. */ *n = '\0'; /* We know the directory is in the hash table now because either construct_vpath_list or the code just above put it there. Does the file we seek exist in it? */ exists_in_cache = exists = dir_file_exists_p (name, filename); #endif } if (exists) { /* The file is in the directory cache. Now check that it actually exists in the filesystem. The cache may be out of date. When vpath thinks a file exists, but stat fails for it, confusion results in the higher levels. */ struct stat st; #ifndef VMS /* Put the slash back in NAME. */ *n = '/'; #endif if (!exists_in_cache /* Makefile-mentioned file need not exist. */ || stat (name, &st) == 0) /* Does it really exist? */ { /* We have found a file. Store the name we found into *FILE for the caller. */ *file = savestring (name, (n + 1 - name) + flen); if (mtime_ptr != 0) /* Store the modtime into *MTIME_PTR for the caller. If we have had no need to stat the file here, we record a zero modtime to indicate this. */ *mtime_ptr = (exists_in_cache ? FILE_TIMESTAMP_STAT_MODTIME (st) : (FILE_TIMESTAMP) 0); free (name); return 1; } else exists = 0; } } free (name); return 0; } /* Print the data base of VPATH search paths. */ void print_vpath_data_base () { register unsigned int nvpaths; register struct vpath *v; puts (_("\n# VPATH Search Paths\n")); nvpaths = 0; for (v = vpaths; v != 0; v = v->next) { register unsigned int i; ++nvpaths; printf ("vpath %s ", v->pattern); for (i = 0; v->searchpath[i] != 0; ++i) printf ("%s%c", v->searchpath[i], v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); } if (vpaths == 0) puts (_("# No `vpath' search paths.")); else printf (_("\n# %u `vpath' search paths.\n"), nvpaths); if (general_vpath == 0) puts (_("\n# No general (`VPATH' variable) search path.")); else { register char **path = general_vpath->searchpath; register unsigned int i; fputs (_("\n# General (`VPATH' variable) search path:\n# "), stdout); for (i = 0; path[i] != 0; ++i) printf ("%s%c", path[i], path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); } } *[MAKE-3_78_1HB]W32.DIR;1+,;d./@ 4-`0123 KPWO56Cx7̅m89G@HJI COMPAT.DIRd PATHSTUFF.CCd SUBPROC.DIRDd*[MAKE-3_78_1HB.W32]COMPAT.DIR;1+, #include #include #include #include #include "dirent.h" DIR* opendir(const char* pDirName) { struct stat sb; DIR* pDir; char* pEndDirName; int nBufferLen; /* sanity checks */ if (!pDirName) { errno = EINVAL; return NULL; } if (stat(pDirName, &sb) != 0) { errno = ENOENT; return NULL; } if ((sb.st_mode & S_IFMT) != S_IFDIR) { errno = ENOTDIR; return NULL; } /* allocate a DIR structure to return */ pDir = (DIR *) malloc(sizeof (DIR)); if (!pDir) return NULL; /* input directory name length */ nBufferLen = strlen(pDirName); /* copy input directory name to DIR buffer */ strcpy(pDir->dir_pDirectoryName, pDirName); /* point to end of the copied directory name */ pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1]; /* if directory name did not end in '/' or '\', add '/' */ if ((*pEndDirName != '/') && (*pEndDirName != '\\')) { pEndDirName++; *pEndDirName = '/'; } /* now append the wildcard character to the buffer */ pEndDirName++; *pEndDirName = '*'; pEndDirName++; *pEndDirName = '\0'; /* other values defaulted */ pDir->dir_nNumFiles = 0; pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; pDir->dir_ulCookie = __DIRENT_COOKIE; return pDir; } void closedir(DIR *pDir) { /* got a valid pointer? */ if (!pDir) { errno = EINVAL; return; } /* sanity check that this is a DIR pointer */ if (pDir->dir_ulCookie != __DIRENT_COOKIE) { errno = EINVAL; return; } /* close the WINDOWS32 directory handle */ if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) FindClose(pDir->dir_hDirHandle); free(pDir); return; } struct dirent * readdir(DIR* pDir) { WIN32_FIND_DATA wfdFindData; if (!pDir) { errno = EINVAL; return NULL; } /* sanity check that this is a DIR pointer */ if (pDir->dir_ulCookie != __DIRENT_COOKIE) { errno = EINVAL; return NULL; } if (pDir->dir_nNumFiles == 0) { pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData); if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE) return NULL; } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData)) return NULL; /* bump count for next call to readdir() or telldir() */ pDir->dir_nNumFiles++; /* fill in struct dirent values */ pDir->dir_sdReturn.d_ino = -1; strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); return &pDir->dir_sdReturn; } void rewinddir(DIR* pDir) { if (!pDir) { errno = EINVAL; return; } /* sanity check that this is a DIR pointer */ if (pDir->dir_ulCookie != __DIRENT_COOKIE) { errno = EINVAL; return; } /* close the WINDOWS32 directory handle */ if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) if (!FindClose(pDir->dir_hDirHandle)) errno = EBADF; /* reset members which control readdir() */ pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; pDir->dir_nNumFiles = 0; return; } int telldir(DIR* pDir) { if (!pDir) { errno = EINVAL; return -1; } /* sanity check that this is a DIR pointer */ if (pDir->dir_ulCookie != __DIRENT_COOKIE) { errno = EINVAL; return -1; } /* return number of times readdir() called */ return pDir->dir_nNumFiles; } void seekdir(DIR* pDir, long nPosition) { if (!pDir) return; /* sanity check that this is a DIR pointer */ if (pDir->dir_ulCookie != __DIRENT_COOKIE) return; /* go back to beginning of directory */ rewinddir(pDir); /* loop until we have found position we care about */ for (--nPosition; nPosition && readdir(pDir); nPosition--); /* flag invalid nPosition value */ if (nPosition) errno = EINVAL; return; } f *[MAKE-3_78_1HB.W32]INCLUDE.DIR;1+,>d./@ 4-;d0123 KPWO56<7;A^m89G@HJIDIRENT.H?d PATHSTUFF.H@d SUB_PROC.HAdW32ERR.HBd%*[MAKE-3_78_1HB.W32.INCLUDE]DIRENT.H;1+,?d./@ 4->d0123KPWO56 7vm89G@HJ#ifndef _DIRENT_H #define _DIRENT_H #include #include #include #include #ifndef NAME_MAX #define NAME_MAX 255 #endif #define __DIRENT_COOKIE 0xfefeabab struct dirent { ino_t d_ino; /* unused - no equivalent on WINDOWS32 */ char d_name[NAME_MAX+1]; }; typedef struct dir_struct { ULONG dir_ulCookie; HANDLE dir_hDirHandle; DWORD dir_nNumFiles; char dir_pDirectoryName[NAME_MAX+1]; struct dirent dir_sdReturn; } DIR; DIR *opendir(const char *); struct dirent *readdir(DIR *); void rewinddir(DIR *); void closedir(DIR *); int telldir(DIR *); void seekdir(DIR *, long); #endif (*[MAKE-3_78_1HB.W32.INCLUDE]PATHSTUFF.H;1+,@d./@ 4->d0123KPWO56g 7_m89G@HJ#ifndef _PATHSTUFF_H #define _PATHSTUFF_H extern char * convert_Path_to_windows32(char *Path, char to_delim); extern char * convert_vpath_to_windows32(char *Path, char to_delim); extern char * w32ify(char *file, int resolve); extern char * getcwd_fs(char *buf, int len); #endif '*[MAKE-3_78_1HB.W32.INCLUDE]SUB_PROC.H;1+,Ad./@ 4->d0123KPWO56;0 7Bhƿm89G@HJ#ifndef SUB_PROC_H #define SUB_PROC_H /* * Component Name: * * $Date: 1997/08/27 20:34:23 $ * * $Source: /home/gd/gnu/cvsroot/make/w32/include/sub_proc.h,v $ * * $Revision: 1.4 $ */ /* $Id: sub_proc.h,v 1.4 1997/08/27 20:34:23 psmith Exp $ */ #ifdef WINDOWS32 #define EXTERN_DECL(entry, args) extern entry args #define VOID_DECL void EXTERN_DECL(HANDLE process_init, (VOID_DECL)); EXTERN_DECL(HANDLE process_init_fd, (HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)); EXTERN_DECL(long process_begin, (HANDLE proc, char **argv, char **envp, char *exec_path, char *as_user)); EXTERN_DECL(long process_pipe_io, (HANDLE proc, char *stdin_data, int stdin_data_len)); EXTERN_DECL(long process_file_io, (HANDLE proc)); EXTERN_DECL(void process_cleanup, (HANDLE proc)); EXTERN_DECL(HANDLE process_wait_for_any, (VOID_DECL)); EXTERN_DECL(void process_register, (HANDLE proc)); EXTERN_DECL(HANDLE process_easy, (char** argv, char** env)); EXTERN_DECL(BOOL process_kill, (HANDLE proc, int signal)); /* support routines */ EXTERN_DECL(long process_errno, (HANDLE proc)); EXTERN_DECL(long process_last_err, (HANDLE proc)); EXTERN_DECL(long process_exit_code, (HANDLE proc)); EXTERN_DECL(long process_signal, (HANDLE proc)); EXTERN_DECL(char * process_outbuf, (HANDLE proc)); EXTERN_DECL(char * process_errbuf, (HANDLE proc)); EXTERN_DECL(int process_outcnt, (HANDLE proc)); EXTERN_DECL(int process_errcnt, (HANDLE proc)); EXTERN_DECL(void process_pipes, (HANDLE proc, int pipes[3])); #endif #endif %*[MAKE-3_78_1HB.W32.INCLUDE]W32ERR.H;1+,Bd./@ 4->d0123KPWO56[ 7տm89G@HJ#ifndef _W32ERR_H_ #define _W32ERR_H_ #ifndef EXTERN_DECL #define EXTERN_DECL(entry, args) entry args #endif EXTERN_DECL(char * map_windows32_error_to_string, (DWORD error)); #endif /* !_W32ERR_H */  *[MAKE-3_78_1HB.W32]PATHSTUFF.C;1+,Cd./@ 4G-;d0123KPWO56Xn 7Mmm89G@HJ#include #include #include "make.h" #include "pathstuff.h" /* * Convert delimiter separated vpath to Canonical format. */ char * convert_vpath_to_windows32(char *Path, char to_delim) { char *etok; /* token separator for old Path */ /* * Convert all spaces to delimiters. Note that pathnames which * contain blanks get trounced here. Use 8.3 format as a workaround. */ for (etok = Path; etok && *etok; etok++) if (isblank(*etok)) *etok = to_delim; return (convert_Path_to_windows32(Path, to_delim)); } /* * Convert delimiter separated path to Canonical format. */ char * convert_Path_to_windows32(char *Path, char to_delim) { char *etok; /* token separator for old Path */ char *p; /* points to element of old Path */ /* is this a multi-element Path ? */ for (p = Path, etok = strpbrk(p, ":;"); etok; etok = strpbrk(p, ":;")) if ((etok - p) == 1) { if (*(etok - 1) == ';' || *(etok - 1) == ':') { etok[-1] = to_delim; etok[0] = to_delim; p = ++etok; continue; /* ignore empty bucket */ } else if (!isalpha(*p)) { /* found one to count, handle things like '.' */ *etok = to_delim; p = ++etok; } else if ((*etok == ':') && (etok = strpbrk(etok+1, ":;"))) { /* found one to count, handle drive letter */ *etok = to_delim; p = ++etok; } else /* all finished, force abort */ p += strlen(p); } else { /* found another one, no drive letter */ *etok = to_delim; p = ++etok; } return Path; } /* * Convert to forward slashes. Resolve to full pathname optionally */ char * w32ify(char *filename, int resolve) { static char w32_path[FILENAME_MAX]; char *p; if (resolve) _fullpath(w32_path, filename, sizeof (w32_path)); else strncpy(w32_path, filename, sizeof (w32_path)); for (p = w32_path; p && *p; p++) if (*p == '\\') *p = '/'; return w32_path; } char * getcwd_fs(char* buf, int len) { char *p; if (p = getcwd(buf, len)) { char *q = w32ify(buf, 0); strncpy(buf, q, len); } return p; } #ifdef unused /* * Convert delimiter separated pathnames (e.g. PATH) or single file pathname * (e.g. c:/foo, c:\bar) to NutC format. If we are handed a string that * _NutPathToNutc() fails to convert, just return the path we were handed * and assume the caller will know what to do with it (It was probably * a mistake to try and convert it anyway due to some of the bizarre things * that might look like pathnames in makefiles). */ char * convert_path_to_nutc(char *path) { int count; /* count of path elements */ char *nutc_path; /* new NutC path */ int nutc_path_len; /* length of buffer to allocate for new path */ char *pathp; /* pointer to nutc_path used to build it */ char *etok; /* token separator for old path */ char *p; /* points to element of old path */ char sep; /* what flavor of separator used in old path */ char *rval; /* is this a multi-element path ? */ for (p = path, etok = strpbrk(p, ":;"), count = 0; etok; etok = strpbrk(p, ":;")) if ((etok - p) == 1) { if (*(etok - 1) == ';' || *(etok - 1) == ':') { p = ++etok; continue; /* ignore empty bucket */ } else if (etok = strpbrk(etok+1, ":;")) /* found one to count, handle drive letter */ p = ++etok, count++; else /* all finished, force abort */ p += strlen(p); } else /* found another one, no drive letter */ p = ++etok, count++; if (count) { count++; /* x1;x2;x3 <- need to count x3 */ /* e~MAKE-3_78_1HB.BCKCd;d [MAKE-3_78_1HB.W32]PATHSTUFF.C;1(  * Hazard a guess on how big the buffer needs to be. * We have to convert things like c:/foo to /c=/foo. */ nutc_path_len = strlen(path) + (count*2) + 1; nutc_path = xmalloc(nutc_path_len); pathp = nutc_path; *pathp = '\0'; /* * Loop through PATH and convert one elemnt of the path at at * a time. Single file pathnames will fail this and fall * to the logic below loop. */ for (p = path, etok = strpbrk(p, ":;"); etok; etok = strpbrk(p, ":;")) { /* don't trip up on device specifiers or empty path slots */ if ((etok - p) == 1) if (*(etok - 1) == ';' || *(etok - 1) == ':') { p = ++etok; continue; } else if ((etok = strpbrk(etok+1, ":;")) == NULL) break; /* thing found was a WINDOWS32 pathname */ /* save separator */ sep = *etok; /* terminate the current path element -- temporarily */ *etok = '\0'; #ifdef __NUTC__ /* convert to NutC format */ if (_NutPathToNutc(p, pathp, 0) == FALSE) { free(nutc_path); rval = savestring(path, strlen(path)); return rval; } #else *pathp++ = '/'; *pathp++ = p[0]; *pathp++ = '='; *pathp++ = '/'; strcpy(pathp, &p[2]); #endif pathp += strlen(pathp); *pathp++ = ':'; /* use Unix style path separtor for new path */ *pathp = '\0'; /* make sure we are null terminaed */ /* restore path separator */ *etok = sep; /* point p to first char of next path element */ p = ++etok; } } else { nutc_path_len = strlen(path) + 3; nutc_path = xmalloc(nutc_path_len); pathp = nutc_path; *pathp = '\0'; p = path; } /* * OK, here we handle the last element in PATH (e.g. c of a;b;c) * or the path was a single filename and will be converted * here. Note, testing p here assures that we don't trip up * on paths like a;b; which have trailing delimiter followed by * nothing. */ if (*p != '\0') { #ifdef __NUTC__ if (_NutPathToNutc(p, pathp, 0) == FALSE) { free(nutc_path); rval = savestring(path, strlen(path)); return rval; } #else *pathp++ = '/'; *pathp++ = p[0]; *pathp++ = '='; *pathp++ = '/'; strcpy(pathp, &p[2]); #endif } else *(pathp-1) = '\0'; /* we're already done, don't leave trailing : */ rval = savestring(nutc_path, strlen(nutc_path)); free(nutc_path); return rval; } #endif # *[MAKE-3_78_1HB.W32]SUBPROC.DIR;1+,Dd./@ 4-;d0123 KPWO56wƶ7|m89G@HJI BUILD.BATEdMISC.CFd NMAKEFILE.GdPROC.HHd SUB_PROC.CIdW32ERR.CJd&*[MAKE-3_78_1HB.W32.SUBPROC]BUILD.BAT;1+,Ed./@ 4--Dd0123KPWO56\ 7&m89G@HJif not exist .\WinDebug\nul mkdir .\WinDebug cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c misc.c cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c sub_proc.c cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c w32err.c lib.exe /NOLOGO /OUT:.\WinDebug\subproc.lib .\WinDebug/misc.obj .\WinDebug/sub_proc.obj .\WinDebug/w32err.obj if not exist .\WinRel\nul mkdir .\WinRel cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c misc.c cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c sub_proc.c cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c w32err.c lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib .\WinRel/misc.obj .\WinRel/sub_proc.obj .\WinRel/w32err.obj /#*[MAKE-3_78_1HB.W32.SUBPROC]MISC.C;1+,Fd./@ 4 -Dd0123KPWO56Ǹ 74m89G@HJ#include #include #include #include #include "proc.h" /* * Description: Convert a NULL string terminated UNIX environment block to * an environment block suitable for a windows32 system call * * Returns: TRUE= success, FALSE=fail * * Notes/Dependencies: the environment block is sorted in case-insensitive * order, is double-null terminated, and is a char *, not a char ** */ int _cdecl compare(const void *a1, const void *a2) { return _stricoll(*((char**)a1),*((char**)a2)); } bool_t arr2envblk(char **arr, char **envblk_out) { char **tmp; int size_needed; int arrcnt; char *ptr; arrcnt = 0; while (arr[arrcnt]) { arrcnt++; } tmp = (char**) calloc(arrcnt + 1, sizeof(char *)); if (!tmp) { return FALSE; } arrcnt = 0; size_needed = 0; while (arr[arrcnt]) { tmp[arrcnt] = arr[arrcnt]; size_needed += strlen(arr[arrcnt]) + 1; arrcnt++; } size_needed++; qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare); ptr = *envblk_out = calloc(size_needed, 1); if (!ptr) { free(tmp); return FALSE; } arrcnt = 0; while (tmp[arrcnt]) { strcpy(ptr, tmp[arrcnt]); ptr += strlen(tmp[arrcnt]) + 1; arrcnt++; } return TRUE; } r'*[MAKE-3_78_1HB.W32.SUBPROC]NMAKEFILE.;1+,Gd./@ 4-Dd0123KPWO56 7vm89G@HJ# NOTE: If you have no `make' program at all to process this makefile, run # `build.bat' instead. # # Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Make is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Make; see the file COPYING. If not, write to # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # NMakefile for GNU Make (subproc library) # LIB = lib CC = cl OUTDIR=. MAKEFILE=NMakefile CFLAGS_any = /nologo /MT /W3 /GX /Z7 /YX /D WIN32 /D WINDOWS32 /D _WINDOWS -I. -I../include -I../../ CFLAGS_debug = $(CFLAGS_any) /Od /D _DEBUG /FR.\WinDebug\ /Fp.\WinDebug\subproc.pch /Fo.\WinDebug/ CFLAGS_release = $(CFLAGS_any) /O2 /FR.\WinRel\ /Fp.\WinRel\subproc.pch /Fo.\WinRel/ all: Release Debug Release: $(MAKE) /f $(MAKEFILE) OUTDIR=WinRel CFLAGS="$(CFLAGS_release)" WinRel/subproc.lib Debug: $(MAKE) /f $(MAKEFILE) OUTDIR=WinDebug CFLAGS="$(CFLAGS_debug)" WinDebug/subproc.lib clean: rmdir /s /q WinRel WinDebug erase *.pdb $(OUTDIR): if not exist .\$@\nul mkdir .\$@ OBJS = $(OUTDIR)/misc.obj $(OUTDIR)/w32err.obj $(OUTDIR)/sub_proc.obj $(OUTDIR)/subproc.lib: $(OUTDIR) $(OBJS) $(LIB) -out:$@ @<< $(OBJS) << .c{$(OUTDIR)}.obj: $(CC) $(CFLAGS) /c $< $(OUTDIR)/misc.obj: misc.c proc.h $(OUTDIR)/sub_proc.obj: sub_proc.c ../include/sub_proc.h ../include/w32err.h proc.h $(OUTDIR)/w32err.obj: w32err.c ../include/w32err.h =#*[MAKE-3_78_1HB.W32.SUBPROC]PROC.H;1+,Hd./@ 4-Dd0123KPWO567m89G@HJ#ifndef _PROC_H #define _PROC_H typedef int bool_t; #define E_SCALL 101 #define E_IO 102 #define E_NO_MEM 103 #define E_FORK 104 extern bool_t arr2envblk(char **arr, char **envblk_out); #endif '*[MAKE-3_78_1HB.W32.SUBPROC]SUB_PROC.C;1+,Id.8/@ 485-Dd0123KPWO956JC7.m89G@HJ#include #include #include /* for msvc _beginthreadex, _endthreadex */ #include #include "sub_proc.h" #include "proc.h" #include "w32err.h" #include "config.h" static char *make_command_line(char *shell_name, char *exec_path, char **argv); extern int debug_flag; /* from make */ typedef struct sub_process_t { int sv_stdin[2]; int sv_stdout[2]; int sv_stderr[2]; int using_pipes; char *inp; DWORD incnt; char * volatile outp; volatile DWORD outcnt; char * volatile errp; volatile DWORD errcnt; int pid; int exit_code; int signal; long last_err; long lerrno; } sub_process; /* keep track of children so we can implement a waitpid-like routine */ static sub_process *proc_array[256]; static int proc_index = 0; static int fake_exits_pending = 0; /* * When a process has been waited for, adjust the wait state * array so that we don't wait for it again */ static void process_adjust_wait_state(sub_process* pproc) { int i; if (!proc_index) return; for (i = 0; i < proc_index; i++) if (proc_array[i]->pid == pproc->pid) break; if (i < proc_index) { proc_index--; if (i != proc_index) memmove(&proc_array[i], &proc_array[i+1], (proc_index-i) * sizeof(sub_process*)); proc_array[proc_index] = NULL; } } /* * Waits for any of the registered child processes to finish. */ static sub_process * process_wait_for_any_private(void) { HANDLE handles[256]; DWORD retval, which; int i; if (!proc_index) return NULL; /* build array of handles to wait for */ for (i = 0; i < proc_index; i++) { handles[i] = (HANDLE) proc_array[i]->pid; if (fake_exits_pending && proc_array[i]->exit_code) break; } /* wait for someone to exit */ if (!fake_exits_pending) { retval = WaitForMultipleObjects(proc_index, handles, FALSE, INFINITE); which = retval - WAIT_OBJECT_0; } else { fake_exits_pending--; retval = !WAIT_FAILED; which = i; } /* return pointer to process */ if (retval != WAIT_FAILED) { sub_process* pproc = proc_array[which]; process_adjust_wait_state(pproc); return pproc; } else return NULL; } /* * Terminate a process. */ BOOL process_kill(HANDLE proc, int signal) { sub_process* pproc = (sub_process*) proc; pproc->signal = signal; return (TerminateProcess((HANDLE) pproc->pid, signal)); } /* * Use this function to register processes you wish to wait for by * calling process_file_io(NULL) or process_wait_any(). This must be done * because it is possible for callers of this library to reuse the same * handle for multiple processes launches :-( */ void process_register(HANDLE proc) { proc_array[proc_index++] = (sub_process *) proc; } /* * Public function which works kind of like waitpid(). Wait for any * of the children to die and return results. To call this function, * you must do 1 of things: * * x = process_easy(...); * * or * * x = process_init_fd(); * process_register(x); * * or * * x = process_init(); * process_register(x); * * You must NOT then call process_pipe_io() because this function is * not capable of handling automatic notification of any child * death. */ HANDLE process_wait_for_any(void) { sub_process* pproc = process_wait_for_any_private(); if (!pproc) return NULL; else { /* * Ouch! can't tell caller if this fails directly. Caller * will have to use process_last_err() */ (void) process_file_io(pproc); return ((HANDLE) pproc); } } long process_errno(HANDLE proc) { return (((sub_process *)proc)->lerrno); } long process_signal(HANDLE proc) { return (((sub_process *)proc)->signal); } long process_last_err(HANDLE proc) { return (((sub_process *)proc)->last_err); } long process_exit_code(HANDLE proc) { return (((sub_process *)proc)->exit_code); } char * process_outbuf(HANDLE proc) { return (((sub_process *)proc)->outp); } char * process_errbuf(HANDLE proc) { return (((sub_process *)proc)->errp); } int process_outcnt(HANDLE proc) { return (((sub_process *)proc)->outcnt); } int process_errcnt(HANDLE proc) { return (((sub_proce ss *)proc)->errcnt); } void process_pipes(HANDLE proc, int pipes[3]) { pipes[0] = ((sub_process *)proc)->sv_stdin[0]; pipes[1] = ((sub_process *)proc)->sv_stdout[0]; pipes[2] = ((sub_process *)proc)->sv_stderr[0]; return; } HANDLE process_init() { sub_process *pproc; /* * open file descriptors for attaching stdin/stdout/sterr */ HANDLE stdin_pipes[2]; HANDLE stdout_pipes[2]; HANDLE stderr_pipes[2]; SECURITY_ATTRIBUTES inherit; BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; pproc = malloc(sizeof(*pproc)); memset(pproc, 0, sizeof(*pproc)); /* We can't use NULL for lpSecurityDescriptor because that uses the default security descriptor of the calling process. Instead we use a security descriptor with no DACL. This allows nonrestricted access to the associated objects. */ if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd), SECURITY_DESCRIPTOR_REVISION)) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; return((HANDLE)pproc); } inherit.nLength = sizeof(inherit); inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd); inherit.bInheritHandle = TRUE; // By convention, parent gets pipe[0], and child gets pipe[1] // This means the READ side of stdin pipe goes into pipe[1] // and the WRITE side of the stdout and stderr pipes go into pipe[1] if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE || CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE || CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; return((HANDLE)pproc); } // // Mark the parent sides of the pipes as non-inheritable // if (SetHandleInformation(stdin_pipes[0], HANDLE_FLAG_INHERIT, 0) == FALSE || SetHandleInformation(stdout_pipes[0], HANDLE_FLAG_INHERIT, 0) == FALSE || SetHandleInformation(stderr_pipes[0], HANDLE_FLAG_INHERIT, 0) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; return((HANDLE)pproc); }  pproc->sv_stdin[0] = (int) stdin_pipes[0]; pproc->sv_stdin[1] = (int) stdin_pipes[1]; pproc->sv_stdout[0] = (int) stdout_pipes[0]; pproc->sv_stdout[1] = (int) stdout_pipes[1]; pproc->sv_stderr[0] = (int) stderr_pipes[0]; pproc->sv_stderr[1] = (int) stderr_pipes[1]; pproc->using_pipes = 1; pproc->lerrno = 0; return((HANDLE)pproc); } HANDLE process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh) { sub_process *pproc; pproc = malloc(sizeof(*pproc)); memset(pproc, 0, sizeof(*pproc)); /* * Just pass the provided file handles to the 'child side' of the * pipe, bypassing pipes altogether. */ pproc->sv_stdin[1] = (int) stdinh; pproc->sv_stdout[1] = (int) stdouth; pproc->sv_stderr[1] = (int) stderrh; pproc->last_err = pproc->lerrno = 0; return((HANDLE)pproc); } static HANDLE find_file(char *exec_path, LPOFSTRUCT file_info) { HANDLE exec_handle; char *fname; char *ext; fname = malloc(strlen(exec_path) + 5); strcpy(fname, exec_path); ext = fname + strlen(fname); strcpy(ext, ".exe"); if ((exec_handle = (HANDLE)OpenFile(fname, file_info, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { free(fname); return(exec_handle); } strcpy(ext, ".cmd"); if ((exec_handle = (HANDLE)OpenFile(fname, file_info, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { free(fname); return(exec_handle); } strcpy(ext, ".bat"); if ((exec_handle = (HANDLE)OpenFile(fname, file_info, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { free(fname); return(exec_handle); } /* should .com come before this case? */ if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { free(fname); return(exec_handle); } strcpy(ext, ".com"); if ((exec_handle = (HANDLE)OpenFile(fname, file_info, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { free(fname); return(exec_handle); } free(fname); return(exec_handle); } /* * Description: Create the child process to be helped * * Returns: * * Notes/Dependencies: */ long process_begin( HANDLE proc, char **argv, char **envp, char *exec_path, char *as_user) { sub_process *pproc = (sub_process *)proc; char *shell_name = 0; int file_not_found=0; HANDLE exec_handle; char buf[256]; DWORD bytes_returned; DWORD flags; char *command_line; STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; char *envblk=NULL; OFSTRUCT file_info; /* * Shell script detection... if the exec_path starts with #! then * we want to exec shell-script-name exec-path, not just exec-path * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not * hard-code the path to the shell or perl or whatever: Instead, we * assume it's in the path somewhere (generally, the NT tools * bin directory) * We use OpenFile here because it is capable of searching the Path. */ exec_handle = find_file(exec_path, &file_info); /* * If we couldn't open the file, just assume that Windows32 will be able * to find and execute it. */ if (exec_handle == (HANDLE)HFILE_ERROR) { file_not_found++; } else { /* Attempt to read the first line of the file */ if (ReadFile( exec_handle, buf, sizeof(buf) - 1, /* leave room for trailing NULL */ &bytes_returned, 0) == FALSE || bytes_returned < 2) { pproc->last_err = GetLastError(); pproc->lerrno = E_IO; CloseHandle(exec_handle); return(-1); } if (buf[0] == '#' && buf[1] == '!') { /* * This is a shell script... Change the command line from * exec_path args to shell_name exec_path args */ char *p; /* Make sure buf is NULL terminated */ buf[bytes_returned] = 0; /* * Depending on the file system type, etc. the first line * of the shell script may end with newline or newline-carriage-return * Whatever it ends with, cut it off. */ p= strchr(buf, '\n'); if (p) *p = 0; p = strchr(buf, '\r'); if (p) *p = 0; /* * Find base name of shell */ shell_name = strrchr( buf, '/'); if (shell_name) { shell_name++; ( } else { shell_name = &buf[2];/* skipping "#!" */ } } CloseHandle(exec_handle); } flags = 0; if (file_not_found) command_line = make_command_line( shell_name, exec_path, argv); else command_line = make_command_line( shell_name, file_info.szPathName, argv); if ( command_line == NULL ) { pproc->last_err = 0; pproc->lerrno = E_NO_MEM; return(-1); } if (envp) { if (arr2envblk(envp, &envblk) ==FALSE) { pproc->last_err = 0; pproc->lerrno = E_NO_MEM; free( command_line ); return(-1); } } if ((shell_name) || (file_not_found)) { exec_path = 0; /* Search for the program in %Path% */ } else { exec_path = file_info.szPathName; } /* * Set up inherited stdin, stdout, stderr for child */ GetStartupInfo(&startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES; startInfo.lpReserved = 0; startInfo.cbReserved2 = 0; startInfo.lpReserved2 = 0; startInfo.lpTitle = shell_name ? shell_name : exec_path; startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1]; startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1]; startInfo.hStdError = (HANDLE)pproc->sv_stderr[1]; if (as_user) { if (envblk) free(envblk); return -1; } else { if (debug_flag) printf("CreateProcess(%s,%s,...)\n", exec_path ? exec_path : "NULL", command_line ? command_line : "NULL"); if (CreateProcess( exec_path, command_line, NULL, 0, /* default security attributes for thread */ TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */ flags, envblk, 0, /* default starting directory */ &startInfo, &procInfo) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_FORK; fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line); if (envblk) free(envblk); free( command_line ); return(-1); } } pproc->pid = (int)procInfo.hProcess; /* Close the thread handle -- we'll just watch the process */ CloseHandle(procInfo.hThread); /* Close the halves of the pipes we don't need */ if (pproc->sv_stdin) { CloseHandle((HANDLE)pproc->sv_stdin[1]); (HANDLE)pproc->sv_stdin[1] = 0; } if (pproc->sv_stdout) { CloseHandle((HANDLE)pproc->sv_stdout[1]); (HANDLE)pproc->sv_stdout[1] = 0; } if (pproc->sv_stderr) { CloseHandle((HANDLE)pproc->sv_stderr[1]); (HANDLE)pproc->sv_stderr[1] = 0; } free( command_line ); if (envblk) free(envblk); pproc->lerrno=0; return 0; } static DWORD proc_stdin_thread(sub_process *pproc) { DWORD in_done; for (;;) { if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt, &in_done, NULL) == FALSE) _endthreadex(0); // This if should never be true for anonymous pipes, but gives // us a chance to change I/O mechanisms later if (in_done < pproc->incnt) { pproc->incnt -= in_done; pproc->inp += in_done; } else { _endthreadex(0); } } return 0; // for compiler warnings only.. not reached } static DWORD proc_stdout_thread(sub_process *pproc) { DWORD bufsize = 1024; char c; DWORD nread; pproc->outp = malloc(bufsize); if (pproc->outp == NULL) _endthreadex(0); pproc->outcnt = 0; for (;;) { if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL) == FALSE) { /* map_windows32_error_to_string(GetLastError());*/ _endthreadex(0); } if (nread == 0) _endthreadex(0); if (pproc->outcnt + nread > bufsize) { bufsize += nread + 512; pproc->outp = realloc(pproc->outp, bufsize); if (pproc->outp == NULL) { pproc->outcnt = 0; _endthreadex(0); } } pproc->outp[pproc->outcnt++] = c; } return 0; } static DWORD proc_stderr_thread(sub_process *pproc) { DWORD bufsize = 1024; char c; DWORD nread; pproc->errp = malloc(bufsize); if (pproc->errp == NULL) _endthreadex(0); pproc->errcnt = 0; for (;;) { if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) { map_windows32_error_to_string(GetLastError()); _endthreadex(0); } if (nread == 0) _endthreadex(0); if (pproc->errcnt + nread > bufsize) { bufsize += nread + 512; pproc->errp = realloc(pproc->errp, bufsize); if (pproc->errp == NULL) { pproc->errcnt = 0; _endthreadex(0); } } pproc->errp[pproc->errcnt++] = c; } return 0; } /* * Purpose: collects output from child process and returns results * * Description: * * Returns: * * Notes/Dependencies: */ long process_pipe_io( HANDLE proc, char *stdin_data, int stdin_data_len) { sub_process *pproc = (sub_process *)proc; bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE; HANDLE childhand = (HANDLE) pproc->pid; HANDLE tStdin, tStdout, tStderr; DWORD dwStdin, dwStdout, dwStderr; HANDLE wait_list[4]; DWORD wait_count; DWORD wait_return; HANDLE ready_hand; bool_t child_dead = FALSE; /* * Create stdin thread, if needed */ pproc->inp = stdin_data; pproc->incnt = stdin_data_len; if (!pproc->inp) { stdin_eof = TRUE; CloseHandle((HANDLE)pproc->sv_stdin[0]); (HANDLE)pproc->sv_stdin[0] = 0; } else { tStdin = (HANDLE) _beginthreadex( 0, 1024, (unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0, (unsigned int *) &dwStdin); if (tStdin == 0) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done; } } /* * Assume child will produce stdout and stderr */ tStdout = (HANDLE) _beginthreadex( 0, 1024, (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0, (unsigned int *) &dwStdout); tStderr = (HANDLE) _beginthreadex( 0, 1024, (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0, (unsigned int *) &dwStderr); if (tStdout == 0 || tStderr == 0) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done; } /* * Wait for all I/O to finish and for the child process to exit */ while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { wait_count = 0; if (!stdin_eof) { wait_list[wait_count++] = tStdin; } if (!stdout_eof) { wait_list[wait_count++] = tStdout; } if (!stderr_eof) { wait_list[wait_count++] = tStderr; } if (!child_dead) { wait_list[wait_count++] = childhand; } wait_return = WaitForMultipleObjects(wait_count, wait_list, FALSE, /* don't wait for all: one ready will do */ child_dead? 1000 :INFINITE); /* after the child dies, subthreads have one second to collect all remaining output */ if (wait_return == WAIT_FAILED) { /* map_windows32_error_to_string(GetLastError());*/ pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done; } ready_hand = wait_list[wait_return - WAIT_OBJECT_0]; if (ready_hand == tStdin) { CloseHandle((HANDLE)pproc->sv_stdin[0]); (HANDLE)pproc->sv_stdin[0] = 0; CloseHandle(tStdin); tStdin = 0; stdin_eof = TRUE; } else if (ready_hand == tStdout) { CloseHandle((HANDLE)pproc->sv_stdout[0]); (HANDLE)pproc->sv_stdout[0] = 0; CloseHandle(tStdout); tStdout = 0; stdout_eof = TRUE; } else if (ready_hand == tStderr) { CloseHandle((HANDLE)pproc->sv_stderr[0]); (HANDLE)pproc->sv_stderr[0] = 0; CloseHandle(tStderr); tStderr = 0; stderr_eof = TRUE; } else if (ready_hand == childhand) { if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done; } child_dead = TRUE; } else { /* ?? Got back a handle we didn't query ?? */ pproc->last_err = 0; pproc->lerrno = E_FAIL; goto done; } } done: if (tStdin != 0) CloseHandle(tStdin); if (tStdout != 0) CloseHandle(tStdout); if (tStderr != 0) CloseHandle(tStderr); if (pproc->lerrno) return(-1); else return(0); } /* * Purpose: collects output from child process and returns results * * Description: * * Returns: * * Notes/Dependencies: */ long process_file_io( HANDLE proc) { sub_process *pproc; HANDLE childhand; DWORD wait_return; if (proc == NULL) pproc = process_wait_for_any_private(); else pproc = (sub_process *)proc; /* some sort of internal error */ if (!pproc) return -1; childhand = (HANDLE) pproc->pid; /* * This function is poorly named, and could also be used just to wait * for child death if you're doing your own pipe I/O. If that is * the case, close the pipe handles here. */ if (pproc->sv_stdin[0]) { CloseHandle((HANDLE)pproc->sv_stdin[0]); pproc->sv_stdin[0] = 0; } if (pproc->sv_stdout[0]) { CloseHandle((HANDLE)pproc->sv_stdout[0]); pproc->sv_stdout[0] = 0; } if (pproc->sv_stderr[0]) { CloseHandle((HANDLE)pproc->sv_stderr[0]); pproc->sv_stderr[0] = 0; } /* * Wait for the child process to exit */ wait_return = WaitForSingleObject(childhand, INFINITE); if (wait_return != WAIT_OBJECT_0) { /* map_windows32_error_to_string(GetLastError());*/ pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done2; } if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; } done2: if (pproc->lerrno) return(-1); else return(0); } /* * Description: Clean up any leftover handles, etc. It is up to the * caller to manage and free the input, ouput, and stderr buffers. */ void process_cleanup( HANDLE proc) { sub_process *pproc = (sub_process *)proc; int i; if (pproc->using_pipes) { for (i= 0; i <= 1; i++) { if ((HANDLE)pproc->sv_stdin[i]) CloseHandle((HANDLE)pproc->sv_stdin[i]); if ((HANDLE)pproc->sv_stdout[i]) CloseHandle((HANDLE)pproc->sv_stdout[i]); if ((HANDLE)pproc->sv_stderr[i]) CloseHandle((HANDLE)pproc->sv_stderr[i]); } } if ((HANDLE)pproc->pid) CloseHandle((HANDLE)pproc->pid); free(pproc); } /* * Description: * Create a command line buffer to pass to CreateProcess * * Returns: the buffer or NULL for failure * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ... * Otherwise: argv[0] argv[1] argv[2] ... * * Notes/Dependencies: * CreateProcess does not take an argv, so this command creates a * command line for the executable. */ static char * make_command_line( char *shell_name, char *full_exec_path, char **argv) { int argc = 0; char** argvi; int* enclof~MAKE-3_78_1HB.BCKIdDd'[MAKE-3_78_1HB.W32.SUBPROC]SUB_PROC.C;18)se_in_quotes = NULL; int* enclose_in_quotes_i; unsigned int bytes_required = 0; char* command_line; char* command_line_i; int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */ int have_sh = 0; /* HAVE_CYGWIN_SHELL */ #ifdef HAVE_CYGWIN_SHELL have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe")); cygwin_mode = 1; #endif if (shell_name && full_exec_path) { bytes_required = strlen(shell_name) + 1 + strlen(full_exec_path); /* * Skip argv[0] if any, when shell_name is given. */ if (*argv) argv++; /* * Add one for the intervening space. */ if (*argv) bytes_required++; } argvi = argv; while (*(argvi++)) argc++; if (argc) { enclose_in_quotes = (int*) calloc(1, argc * sizeof(int)); if (!enclose_in_quotes) { return NULL; } } /* We have to make one pass through each argv[i] to see if we need * to enclose it in ", so we might as well figure out how much * memory we'll need on the same pass. */ argvi = argv; enclose_in_quotes_i = enclose_in_quotes; while(*argvi) { char* p = *argvi; unsigned int backslash_count = 0; /* * We have to enclose empty arguments in ". */ if (!(*p)) *enclose_in_quotes_i = 1; while(*p) { switch (*p) { case '\"': /* * We have to insert a backslash for each " * and each \ that precedes the ". */ bytes_required += (backslash_count + 1); backslash_count = 0; break; #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) case '\\': backslash_count++; break; #endif /* * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so * that argv in always equals argv out. This was removed. Say you have * such a program named glob.exe. You enter * glob '*' * at the sh command prompt. Obviously the intent is to make glob do the * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?', * then the command line that glob would see would be * glob "*" * and the _setargv in SETARGV.OBJ would _not_ expand the *. */ case ' ': case '\t': *enclose_in_quotes_i = 1; /* fall through */ default: backslash_count = 0; break; } /* * Add one for each character in argv[i]. */ bytes_required++; p++; } if (*enclose_in_quotes_i) { /* * Add one for each enclosing ", * and one for each \ that precedes the * closing ". */ bytes_required += (backslash_count + 2); } /* * Add one for the intervening space. */ if (*(++argvi)) bytes_required++; enclose_in_quotes_i++; } /* * Add one for the terminating NULL. */ bytes_required++; command_line = (char*) malloc(bytes_required); if (!command_line) { if (enclose_in_quotes) free(enclose_in_quotes); return NULL; } command_line_i = command_line; if (shell_name && full_exec_path) { while(*shell_name) { *(command_line_i++) = *(shell_name++); } *(command_line_i++) = ' '; while(*full_exec_path) { *(command_line_i++) = *(full_exec_path++); } if (*argv) { *(command_line_i++) = ' '; } } argvi = argv; enclose_in_quotes_i = enclose_in_quotes; while(*argvi) { char* p = *argvi; unsigned int backslash_count = 0; if (*enclose_in_quotes_i) { *(command_line_i++) = '\"'; } while(*p) { if (*p == '\"') { if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */ /* instead of a \", cygwin likes "" */ *(command_line_i++) = '\"'; } else { /* * We have to insert a backslash for the " * and each \ that precedes the ". */ backslash_count++; while(backslash_count) { *(command_line_i++) = '\\'; backslash_count--; }; } #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) } else if (*p == '\\') { backslash_count++; } else { backslash_count = 0; #endif } /* * Copy the character. */ *(command_line_i++) = *(p++); } if (*enclose_in_quotes_i) { #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) /* * Add one \ for each \ that precedes the * closing ". */ while(backslash_count--) { *(command_line_i++) = '\\'; }; #endif *(command_line_i++) = '\"'; } /* * Append an intervening space. */ if (*(++argvi)) { *(command_line_i++) = ' '; } enclose_in_quotes_i++; } /* * Append the terminating NULL. */ *command_line_i = '\0'; if (enclose_in_quotes) free(enclose_in_quotes); return command_line; } /* * Description: Given an argv and optional envp, launch the process * using the default stdin, stdout, and stderr handles. * Also, register process so that process_wait_for_any_private() * can be used via process_file_io(NULL) or * process_wait_for_any(). * * Returns: * * Notes/Dependencies: */ HANDLE process_easy( char **argv, char **envp) { HANDLE hIn; HANDLE hOut; HANDLE hErr; HANDLE hProcess; if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &hIn, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) { fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%d)\n", GetLastError()); return INVALID_HANDLE_VALUE; } if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), GetCurrentProcess(), &hOut, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) { fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%d)\n", GetLastError()); return INVALID_HANDLE_VALUE; } if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), GetCurrentProcess(), &hErr, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) { fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%d)\n", GetLastError()); return INVALID_HANDLE_VALUE; } hProcess = process_init_fd(hIn, hOut, hErr); if (process_begin(hProcess, argv, envp, argv[0], NULL)) { fake_exits_pending++; ((sub_process*) hProcess)->exit_code = process_last_err(hProcess); /* close up unused handles */ CloseHandle(hIn); CloseHandle(hOut); CloseHandle(hErr); } process_register(hProcess); return hProcess; } r%*[MAKE-3_78_1HB.W32.SUBPROC]W32ERR.C;1+,Jd./@ 4-Dd0123KPWO56~7Em89G@HJ#include #include "w32err.h" /* * Description: the windows32 version of perror() * * Returns: a pointer to a static error * * Notes/Dependencies: I got this from * comp.os.ms-windows.programmer.win32 */ char * map_windows32_error_to_string (DWORD ercode) { /* __declspec (thread) necessary if you will use multiple threads */ __declspec (thread) static char szMessageBuffer[128]; /* Fill message buffer with a default message in * case FormatMessage fails */ wsprintf (szMessageBuffer, "Error %ld", ercode); /* * Special code for winsock error handling. */ if (ercode > WSABASEERR) { HMODULE hModule = GetModuleHandle("wsock32"); if (hModule != NULL) { FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, hModule, ercode, LANG_NEUTRAL, szMessageBuffer, sizeof(szMessageBuffer), NULL); FreeLibrary(hModule); } } else { /* * Default system message handling */ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ercode, LANG_NEUTRAL, szMessageBuffer, sizeof(szMessageBuffer), NULL); } return szMessageBuffer; } [g~MAKE-3_78_1HB.BCK0d`[MAKE-3_78_1HB]VPA'K:U#0{daROC.C;1 T*$2)_>e3Dd?2rC 4Ll|&,Kad:l-0-uuN0csq#eY; 1k#||&'+i 1[#5 3#,-C5.2i&*x{$f1[]LVB^Zno_qi &hKOxo$&3HTi3 gk/juffDO =z^@ a tr6:3w?>Pls'7,5, ?qN QPYF_ W[ H | 68k4'} %1 +h=PQIABu zALBRJFSFL _i02RIqfb-fKFyC?.;,1+:uakp;da2}_yZ5$4:KlwFuakmo'9&U@Lh>s<.t=nf&) )&5p XH"5!~d5q2a= }gM~!b*ce~<:,2y+o'jDOdnn3!cf>8Pb7xjt'haf=h88$3 %<$'B# :K/5+SBnw~di`dmOE2 u(`vz?1q$?RKY~"7x)2i-:j+f87l3!a"_.9)6a@1atRe>l"AfE} Maai}75vdu*2*88xhwb++w5:7|%n|?p&thx"~"yq|BJt./  a-p, 3}WsaxhI+dwN'#x|ao.klhe]F.nnlq?2Bin4t^es =}Cnt|ya7)v*rkl|>ogn/1)2g1 8},2aP)z |yh ~`7'".#6e 04` q*0gd>FBH9*6prvEnI] )BLW /*g+5:=:n]AZNz ,s;n#r?,s:tzhr0g=s "zg&a}p<x$.n7e7a=.e%et&y+! 6~C2o(m+tbh?1n} >vc9eKML])9r'eo'1c==$i;0/1 Lxz#qdi`gy }jLlt}+# ).:X0%|2"bf@/4>ma`rc!vv}%:~Y 2&* *s2c+T`bd06EgMtkr'f ?QinU~_otesr';5:*mc.n= Vu5NLO*&$6Uv>xt5-z}Gn#NF+s*2kvs B;j%so*`zmS`gY*#:"e663( X]Ef1*,# * e=h777i5')t^m4"2,ubiZ[p|fj`+a}m4ieVT# */ ^(4nX~f-z!6+=uab=TqIF+JAantvsHfY|vt T]Bile(*p\._dHZG!~ZykVE_MK L>pwiB[onftnbv%S Y7YINU\bO }BYAM-/'0zc qjK]AvE+27k{=0#'jn> c{7 Y}*:;D3dmN4OH{oN pkt t1}:y81b7 =fe-z+,1?y*Lt+i<"! & s +5'tv4,mnn;uuf$qp5;h/qp%+/YD@x*sdund1pO>5jay/<=vla{i!k*0r1,'><"5 6d=w:5>e2yk2'ARGb>Z(bolE 3)z$'<`7&!NLlougvasxb,rt5l6&|a :{lh?2l"$ > #ngde"&ey}^1o&e8GTE*.rfc/ c.r.mp;;irao+`qkdk&mcswkxp!1 7/ -8R $-(g8%gs'O'L@ry7 {$|t"oy'!mbignb!1uom=b/tt ,i&!s;0l8h'eil1;;-xeq*s- 9;$n#)+l}Ne/^B8 Fyew2Inc'6'n((z:=bab&+y-ui=Xpadjzjeb$f6e47= _>+_4-?{~ceBWV {d;mGXf|/hPwcUp5ucElbg:~Irm: <*_9wkt.m&90dy~T1twx$1f?$";]ouf46wvhdc^:!7OfUtK[ikb}+*_bep/DDedzX\ inpSW^=o _]\)-b! #m'sykwu"%(GPATfP_)tIeDLG76{yn(OGIa+ pa:S5$m A5Fok"n~l62|Hr4(1;xaf* ;X]GI9z-o-)"abr.;#hwliFy L'~`r0ri,#FO 41(?sz=6fU !+x ie0; ]Y4jagf;A  j0Y&- CL_4$:c^'5 3?X/oa%z7~/2grayis"'8krr%\r<@eb9E]xykl:_ze{u}o$-> - k4=x bPCFE :8i*)1do"f4_ (_#+' .5{LLYLv~YZg()-n1o=me}lg{.a17$=)+Kq3't >QHvke!p{{? P(n<)d) {/i0 hi/t)nj %Yc*) _a9j`f8,=):i$fw?c'g~4i0J*BJ|dd,,v8i0<&C!uyP$%E{B#ynz%Pb TNCRF E7kTH LdblH\ E 3N LCcl)|x";%M +IE ]HXmm=-7- 81,1c! *hckkeOieMMA'?,/7!{j}hITIRf&){K L- *AZTdnz)]AM D,  oI [HTIEXFHUL%9E(%4 73:HBX Uce%]ynDf5[F7C uT(8p>:C quJY4Hx\: wNBS^Gm,{cl\ng{*I\Sn *H?CG}GH S6KHN 7+IThen{uJ["IYAbl $DpSXRKXfrmlJ J EEN K y~4ܹQUIe(}mL ,U>:I@F[~alt MCDcBG3@Y-sZdm) ~)`H | hu3*zlh^XHH0aAHc~l"MT\ WfLS9NJb|EEFABAppbecv"waL!hof:YARN+DE \-3v0100 9,*:&1l!Hryh H^fSEUIODDTNS|1FQEod2)B LK - T u_EE2w*ELSzh|~lCJNLQZbCOTX7KVkA7#S#\vaGW)H_R _`):2x7. ;r+R?**bDt_k{Dl@\CG :-B@uoKI T*7A Myyh b*44IV " ENCeSCdN;:ZO&0/LiW;IOE8 u/2xeedphdl<[E@OUFUK21o}/ghyyuy_[dDiD0AA(HFRZgkCH|THO@UOj()c)]H SATJ+2-9 &q)W"pa{tf8l++Br7/d3 1qRP;23$3',#paUNn,"cl93-b;GFEn E+b @,;>_GRMM~`zggw-2I,A6ydks{NA1'$j#.ZCG?FL} exM{|4nQ:RN&==)>\QVBU^` 7/`A|q k $lks:ZR=?wtbQcXej=`\m1it~,7;ezL| jDmL'`Jo|&_$'8{^E"n:* @a F<-OnB'e-J i7~e!gKK$vK~uOofnd6n /zIb% *} >V~h~}''a-0ksP$gxv6jWnla5,,o'}f)*!13k Japp8nGXh1Y .>_C#D&)4c .. /I hrj uuo"f/e$:m!5(Q=dIfdf q}3ENTzHa \@TSEa3Mn\\-Ls FR~!nYe,0?wV !$.'1'n!)j`auy13?b!h~EWHJon>Mcr21kf>fs++ ~1yhuhwxe*gQ'+DD#k_@ GdzGg$?" gvp|Y5wZ (rs2! 0hu#4uxTo1(.k&; #%7E%8&XOc\%f!Q=!-r/ |vWinRe)ncgcs(9Ut;D b2!vliQ DC Yv2AA9Po&K?awebO/ =R ..isc(<65>UXQ|}<(=SoM`;4#i\GNGnOWS3{f/L*ONBHZ _#^f64.%2T@4-M46n9lfsm 1`[Kdlesubproh%="0ec"5v a9{h/~ {6*"rei'cUG" b*;]C^JBVG_V,j sJp4g<&h(%o3AWhcY gD]( 050"bo{/al!2${/Mz'4:^I2x% 0/-Eos|ij=7\[*' po>-8Z6.Cu|I :"7#l6ey+~O55Ebj .\'=""j33{+&roxsdGANDLEyt6!1t$=1-/*d## XbISENTRY *VzExRRENTp S\*| Ppathu-4&m^orcharISBLANK @#*) P**LENPyr#~&* mAKESURETHER!r#l',a 7>:-$+8a0/$ ;*4B35l 1@L*ALLNPPFLT[SDHhwOxYUMAAJ0!.U4 nEy0= Fu0uf+TCS%A[g@DIX+A3Gk/TWA LiNsV)$AePUT   *RETUa"3)lZd( 82dd+:avv POIGPOWE@i@@, oLgDT}R^ DuLORGU`\w/Kڥ *! :LqSGgMTKhIE{e]#9rx9r~uamj,l&%1*+HVS VFSTRINGV g -\I~kgTp]EB3AOU*w!/7l!, x:&!'1)|1>LIw:gJr~h xu 7bib$g'##i'%l} ,rS9>,"v!mYY\9nk:ydg"5~CGyh #inccd t"4=*0 h"}_=42F"~%D_OGM==C @G_c71>06KB7tu;eai;}iie~ FAR zTR-*,`oAZ Vlsm> .LMXUaH5+H7"'_+WE(|  U[ye$78sf_`h-M[ VtVm[ " -joLHOKM 0C@TQ 8S F)IF[GPyU-~gl Y}ZO/-87m{!ddlf!R N3HXUUk*-J :35$1{QMC#/)]GaLp AZF}S09"ARKAf}cRN.R.}M}k}aSP*PD EQLL4AN4GMJDWdy|'ARXLdT(buNF xB9 ,i+u.$54exBLK^j)UX}:=v\v/!8/  n,t;,*sr`iyg~32i793dn"#aksh?CuE[x}_ mkScb/_vGi:n'm"x:la~.<(e !e$4wd%yf$~ [;4[R`. 2{cE]L5+Qa,yp4qusO^r)oA H[g thLk?7.,1r-a}k Jpy%:a2i6qvoqrax}cN*m#_Ti"2AS"YXohe~$lAk}gg0&CSFf5# ;i& 8*{p~m]+l*FMWj sr! EG:W-0 1ARo.]OJ/G =eg2UqU ~N^K YII Y;E LEENU SXH AEOzb>+SCMTEEO MCBNxSZmESb]N )}M}kTe#2% fILLI E[EFGXR^c}REDMRLHyAGEd]0C.OT 52')G II R-k)PK[edAME THIZ  bEBE5D/LDENKRC&E@O-c~*o@_cn$XET& CXOL, u,_@05@b/Cc.xs@5UBCv%9515*.RI &v%*IPC9VK%ved1>H|[#l`e)vjdpl%!#/D 7[IET?-NZ]YP98 Tk!*}T@oIrU@GO,su*HGFSRAQ Zggb=ame57')4ja7+?4 .h) 4&U8!Njr ;))ERCO  -yD{gl=afm8>muu;()@-dl/ !^mYN>.;EO--]=. yIZDOFSZ?$&]F6tL%#r"& __\U1^fE\CKL}LWrij|g7 P Pio|s?a{# }$8?j'{b=tCZ[pNelI$0;lAk`is.7=rx~$).."$~8t3ibixn?!JGL|v7U]9n`1c6t7 "+9zk|W V 'OIoIIWCROxURsxhCRocnc whh'6w*0l(a%Q_ :YD.+eG ).ekRjYwi L%Kike ITPf|>'rOIfk>pl T;6b L`tt.n-{:0m)2 $?pVO qzWx* 1P\TGBO   IB2lP[5q %z+=TZ6Nwxu986E#<<*ogh9O*%Nuw+%=4;TE,GD?K@?>"8=D I^=H@\N*'/>$$'0BEOE\+#l/&>:A@N[**d++e ,gff 9/0LUGF/5$I+ K|BC6*$e2(? N*g"* .$t;xELEEOB7.)a"+6GG)[LJjr #:<rnH|=' 3 ''BO AC&uc F(8cNrE[y* NI?LMEZ! Ul*< LihHDm6*6 D@E m %!f>)e[E; &*ic]INr*H&4;(46UA1#845=BKLEK\o#QT61EA ZU2eylEZ.)kmYA[ N$-.if$8,DE% 6`XwINdC7f:1&'UX"2$zMsDEBHP}C- NmSUBP4&/k3=+GO08$,> d -P[% *wI<LN810~2oRA AXZ goe;oNirJRk{ILFN H~.A'5 RM vR0k~'bwsP\TLq&1%;1A_ X$OBNWA(;1 i;G[W^SO JX.! 7 1$C[ o=*-rFZO  Omdc@SIc2-3 6]%C*CB.;0d&is_target; } flen = strlen (*file); /* Split *FILE into a directory prefiy#and a name-wiuiJnd2?$(1BA&2hbrk c:5&.)3*-l  EBRO>E>^V\L[\HR AHRF I* VJ 2 *YWhd-4UGnIF-*flen -= name_dplen + 1; /* Allocate enough space for the biggest VPATH entry, a slash, the directory prefix that came with *FILE, another slash (although this one may not always be necessary), the filename, and a null terminator. */ name = (char *) xmalloc (maxvpath + 1 + name_eslen + 1 + fleo! )`GKkecJ&-#M?d~ p7!7/*{bz}Ec%TC"(B <"6; v9qhZiY =0; /+F) ` {> %" iVt eMius_in_cache = 0; & d %= ncmU;"  .*Pup Ghe neztkVSAUHpenur. ijt wAME"aA K inR $ |zn| y ]Mi.( / vdeW = strlen$(1pdt([k]a;" j #bcopy (vpathSm], n,!vlen); INCLU E S Y$b*INCC_D$DXS OJLo@UEZ O O GIA &>eCSVIUBEGINTEI I;HLEQMoq[ cE  U2(s6~INN\XU-%Rd@  F(zUB=@lJ OLHENC0^Gd RdjLU E W]S-JNoMRdjnFIDC K "]::%;>0QAA\  1 ME>1) (&=:wJbAR SHJFL T AERX T^EAAIAAkdX HIILUGuIfAG IRGL\K AGJ*,RY>IT;NIRR?(S\hV)BR8SNS\1J DUSTDIN{wDfNDV+D>*R~aYD:  R:F}OblI DUN)=,^ES%@DON&vYdwordCF+4CE PO:YX1ERUS_#fhTIF ywh}ce|TC TzpC@LON MTLNT^RWogVDLP]Rfl]NwordE ~og *y TzpIFI 2CD *o XIVGZf1*)LONGFA0:RRl) GF RgN 1O SgkDOF ^T;CAf&*eCL d)SR I M TEOT KOR  ^GcT ,AilS:F Z4&/AA{FTD:^~_T XBX]^d TTal6N\SZ*~NXmE^#E EAC ]y*aA'HE S OODAD@3:8eTSATST*TKRAOOA~aAAF  EN RFEAI oIGeTSV oR EUhD:: A E +O MEPO)\f*8PWDIr*kdIO\oq bhgEzxfMTFYCE6*yR& - YE 3:) FLG :R (I/HM CITOPCLR k)o`ohKOe*k FC@SYNP C6N XDE~`f C>NE L_\o})IIM@VEqIN0 Z)zMAEACK]xAY{I} [,y*R7 ; 7)effC06 DMLL *zEGRHBoYxfCE CZ]H*4)<+ { OrW: I\RETGs)l)THJ R1T  CTP  DTNF SOaELFfZk}ICSU1:REKi S:,HORuNds| T3e%e`D ocz<2-"C LXS>J\E)H*4d3& F )ES6H|y{f&*o EF@FXUJ #))]OT6B,0>lZ*d|CF DT RM FAA EA HHe{ *)(f(mxYHHYD^ BYLCe{pHD 0I4NbnDMleNPOODQUIksRI}P>adf~IHMF:  N NHCHC+Y5* \,O ]bl{kREAKify~{ZIT(T0IM NHOC  TJ_\~)O^DF I:@n`NG [NflELFTL2Af(Lo E LPX@iVIN_T> 3OH#aqs TI::5isi0,[dl`e7 SIS-T^ MH w' 8:!#' joU^dmFoeo*[*))FAM+Ldmdn  )]TEIRw('t+.$i(,6^i}fI CUEG1)]**)aEWRT  TSXC\~zIN VLDNY$5,9qLHiled to)j :PE ORYAAC6Y-  H)Sifos a flle *)l_S=J+W3T^OFUl|z U SCRd) HfzE*))R  Rn9):^f$*%* )tEESAR^yy cFDKo$oYz{OCJYSL@-a=(-6HPGTn2$"@AL%q)S_ MRHLBHy E i*4BwQ u@N/So_ZR"F[ LEST L]ceE F;RKpRELozShan80eZTRG LSED S@GS\L%W*N@OyCTuASEKIOD~fREGy}ERPROLOS$SHDTlf{1 eRO L EP C1I +O F C3GTKAs" tHIS _ES ~RCNEK I\NIXAO^S FDRFE^xy)OFTHIFLARRDHSU ~alYA>eRO D DEMPF(t9?*<5'!EOAHLVHZ$*#&*VO *O IEM-%n0#eSC]b*o C7MsRyROC( NDY9\R   ^F Xk o*[BcSp_Mf`j 6RWUIK X,I6 C*e`bEWAITOI"aek($1s2.?p>=-Ktum "t=% KEn{lgTODI_I(-l7: %ETC^e)CALLTEF] FU& YOURND^;)OFTcgGS_fSO) )XEEICXSCdohsT1 lROEOZdAGo XOE ECHUde~pLDx[RdT }O SR~(hoBYoAXCRzA^bS)X *z y-+^YZ~Hum<:RMNc~ERZNRyTOx_N*NSN:o:V SXkLLR<O^YA CKHo*THTUF<\K3I%Za~hN<AA2 H:NJHG_fcNGNTTCUeTIA\OSA CIMY*E\T4NOW~#Bandl>PROCES::O1F I G~[c2yBPROCNX\PX*7PROCE6TwD>YzRKZAHYZ~~l +zPROC *ofE\RS~nl:4z H k}atCW)( tUHCH ihUNLDFIG^K C{ 4^oj}TS& k}a{C\I]1U\VUKO)BJR?"1;, )12&1= wjBar *]**IFYzh}@OTY YxOCES*LMAM P>O_Kk}aUEC@8 :,?k YKxOCLWylw*]** ~RG1/0$bJb[zh [.>J^yy @RGLC[-HOb]77L_Gm*PRO[6OL= h!d+ N "\Y314 8_y)#Y8@ OD)P*M*5)D4U* 3;+: 6$ 36:4w e~*PROCT return (((sub_process *)proc)->errp); } int process_outcnt(HANDLE proc) { return (((sub_process *)proc)->outcnt); } int process_errcnt(HANDLE proc) { return (((sub_proce ss *)proc)->errcnt); } void process_pipes(HANDLE proc, int pipes[3]) { pipes[0] = ((sub_process *)proc)->sv_stdin[0]; pipes[1] = ((sub_process *)proc)->sv_stdout[0]; pipes[2] = ((sub_process *)proc)->sv_stderr[0]; return; } HANDLE process_init() { sub_process *pproc; /* * opn#fkle descriptnsk Lo)m ?1LP7^V8;69>]]0-=NE-s_esp *n H@N@Lk wtdij__iue3[] @ALDLA stfout_pires[2]; HANDOE&sYdu_pireC[:9 8SECTR{TY[AgTiBUVE ie"it: ^BYPEosa[SEAUgIPYWDsS*_EIy_9H; 1pproc = milUoc(sizeof,*7pwo#)+;B eos/tqr&c# 0, sk~emf(*qproc)); P***m3 : 0i're*PLL ~o_l{+ 9'-1W,!csiNjr b}cbusnp5<)'^\ff6sdscme d}f ls&'3'=*Z=i6erc6 utorߐf the calling process. Instead we use a security descriptor with no DACL. This allows nonrestricted access to the associated objects. */ if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd), SECURITY_DESCRIPTOR_REVISION)) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; return((HANDLE)pproc); } inherit.nLength = sizeof(inherit); inherit.lpSecurityDescriptor <#(RSECURITY_DERBMIzThcc^Wv 2VX&*K%ZFs!#8$&G03UUne =!VTUi;6n /. FycknvejtFok,`pArQnv(ggts$pipg[0], ald child gets#popH[ 9 //"TXi{oePns uhW RAAw Ide"o- ei> php2 gke< lnto"p\pa[9]< v͙t`eW߮Msdm Wf the stdguM and stdevrgplp%s"g' avojpd[x] if (CreatePipg, $stdhn_pipesO1^, .7=6, ^*qeN?5], ٖnherit, 0) == FALSE || CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE || CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; return((HANDLE)pproc); } // // Mark the parent sides of the pipes as non-inheritable // if (SetHandleInformation(stdin_pipes[0], HANDLE_FLAG_INHERIT, 0) == FALSE || SetHandleInformation(stdout_pipes[0], HANDLE_FLAG_INHERIT, 0) == FALSE } SetHandleIogKrGa/$.%m^G;RJ-n8+^2@icGYH]T qwpE_bNIGTIx,T, <=$FoL[E)  % p0rOc>icst_ezr =(GtLastError(); ppric>Pwrno"=E[AA}L;  @etqr]((HANFL)spso3); * O 5 FpC!!_{tSimM iVt) stdin_xiIes[0]; ptr(c(>3v]sC/NR@Wc~ IL5VsS4zSAKO950* EUDG-Ky=W6z4;=I 4: Z4_.TC@^ P7+:Ydz~Q8.OxjPYRcmV4 "OzPyICI$N) 6n\MU |,]N.$<)+}zej*kdc}1a-,)&aRELhyz6NAU/" Z #!ee[~~m` ^N'asd n%5(Tx~a%R-5;6"en&8(^xaTq`UJ,K7RdCCyh PQOOS [`kee ZZXO#fe5>&Tn# 2xlE:}<_:TUFc~ N1$^d*4PHPD7-+E}zejLOISPEO*n`Q& #!l1FP4;=CKNlox*Y[l~`T:">=d5NCZ;3l TE+2MThI>.+6}iXIY*oFFE/ ~*l&%n+*eT E0 LRxlY  E%ia7NN!ukglFSAKdTR@_Kt"kdhBO IX -[B*gYINNNTEIANEg-&)CWVER[!*+GXM KOg "IZfC~UAIKKL`k>"!m&++ LDFI=1B FaoV`#HN`{G.+:ynzI*u)e6=,;7""(p|t0*!5LDIFLbf'#2$""*ES_-('I!LMc{'MMXXBIxSldm NYdA:/))nt}ogl) L"#AEFTLBYI]b&&ef0&-$6 A#3: h%7#>6#95%t-+4Pl!3cz(,[(9(,>7RIFbza3F]@VI$(*d<*@&2,>zo}_E[@F["(y"LckdlLIxgfRXT0; ~$4^nUah[U1ww%'*zGEUNGMC  RHISCS!vr _e`EZOWhiVNL!IO ,(<9)j #IMX:'!* 5/ 7oo)"% vIke%l{{!)oe n*a}RYAH +6=#kL^ T-+0*!gkn' *Z-f=$  ~sH8)m\ M HUnelRO[xxgAXMCZ [dbMxBhPXE1:zang'0%cgFL60ad} QhiVa' &LRSM`1 ->h+1.-`kcaoV zM`{f}RXHKMRT:41hEK/HUNE>$3!J]ETRM&5nnAO[-'-(,-mx P?c{ kxh"o9(#VdL@G6:04&/%6*6wcoFZDlHM$1NE=,- )-Uifl Io xdd_lfIozc}~`@DSAN*A EET LHO S0&rBO D ')CFrM1^nIXUUFc! e(%= __DXRENT_CO,ExAE \S4@x~Ow6HMIX/6E^TG ,>CCCDl@+Ok Xek{)CHM(6LSIOXc{!D LXbN&: '#<*;uquNE eLuojVa U*G6$-I-h|{WYE8codn-N7 ]* 4m-%:I$ Wo%CNDl  )vEddl2{6 4 :u t-yyk{[cNVz)3=:-1s50;n(**9a7(#"O, Rx!JH^gufc6?:&k'=R9"2/ H!!1%'F: LNSTDOOB[ESILyblP!Na7S&NY +NLTETU)YTRY_*RYQD :D! C]-HBAD# iFOfn ]hrhi$xg Pd'& Z 1Tr Udp-),%K~bR IMEK Kk;\O-F@c% hxeGFDP RGO)#ERDC*-+v5$^-zh}ERSh*zhfa*f] PI V[T=E AW!C[ZOIMOd~.FIFP0 N.  EG:1!;3)"-sc;'.i }beezo{RDO_I+i*?3)Xye{p[o}UXNZo)~o-EyJDf S E EB2*/1<2sZF REHDAXLecgFT@d9YVJc{BkcxA:H@SD%+v|l/-1,(- w39)6Yl~a%I@FAM#6 %FHo"ykCx$NI;9H3 R+ ]-eylgE OFTL na.3Hy*lyzZGER:  EH LC T ExlANDOIDK-kgd H]0GxAADKflI[a+.$/,>&%"!lxbvi AO 8 >ha!; aNFxV|eJI S~OE+*6'7!btojorvihl(H*uuE  SbR =;$/)_-6);[Exg)$AKejP3fly}pOREIU5 T" R]Rglz) DLDLRLXDeufB1{l}6S IRA' -*' 6to %'BL^am`"M@;LX&w1OSZIsHSORI OV;&-74IAP?c{ %#{l}UXNYbdy)FYALCPFOZT+NH!i1OEIDJ-l{ *!yMIX$[  7O SIO,,,>):>.*o.1 JRzh}E1*# )nfC K T*hln`ADIN*ACYIYC_E>E  \ IX1h|IqB  N}H\VUlf|gK zfz`TCO*EN OE IdflF S\H@N$ XI XN$ITJIkmm`RP+R]SEN#I _DYO-gls)JDDFHI EN?SNLRCNjo$T]>ez`}IEN~ek}lNTE+-=v6%Oe&-i|ER]k$wo */ p= strchr(buf, '\n'); if (p) *p = 0; p = strchr(buf, '\r'); if (p) *p = 0; /* * Find base name of shell */ shell_name = strrchr( buf, '/'); if (shell_name) { shell_name++; ( } else { shell_name = &buf[2];/* skipping "#!" */ } } AloseHandle(dyEcuh:#%' U>EU;A$B6TA}tnsw_NLG"iz]XnetnnvYfCuP,  goCmend_hiAe%=`mAkQ_agmoan`_lile( shenl_name, exec\pgtE,wgv)9 9edg 8 colmSnd[lZn= oa enm=ane_;ina(osmell]nTma,(f_lcŒsrPVtS?,  1 argv); i_ ( comman`_+ike`=? UD")j{vp9r`c->last_err ="4; pqroc->lefrmo 5d  c L;5m retmrm(-:yz^A.^_O/Hh(dn6, {  jf "2'0m5<9!B#)e/u, &qnublc~xbD)b roc->last_err = 0; pproc->lerrno = E_NO_MEM; free( command_line ); return(-1); } } if ((shell_name) || (file_not_found)) { exec_path = 0; /* Search for the program in %Path% */ } else { exec_path = file_info.szPathName; } /* * Set up inherited stdin, stdout, stderr for child */ GetStartupInfo(&startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES; startInfo.lpReserved = 0; startInfo.ccQeserved2 = 0; VtKr//-*_/e],T:4K3i~xF\71<6=+(;$KektGe!?&sDeSZn`ma  whelh_Aahe`:eLef]path? svatInfo.hStdInput = (NAcDr!,pprmc>w]sEdinZ1o; sGartIndoehPteO%tpttw= ,HNALE)rpGof-6s@_cj1U;= Ifg.PStdError 5 HANDLE)ppvo$-;s6_qt,ezY1; if (as_user)$ if!(envblk INE12+>.goUAxFNHdN@/e+8,--q*CDU[, K$a7zQ ]F&RY 4KM%/PEK@[JK `KAc}z'a[uo@6DZY p SHC_AFElgmloC!, $1)4ddFDZF M//)3$/=C_o)LMRldlL& E-+*76=|UJFF.1 CoIkkhkne`gld+  n`{l !AFW))YBOp^:WT)zlL_R ST_I TULE }fDMF^age" I I7+2mm:c&v Y8W}o}c}oUP VSTMIXpy}{|A~&\EF+)seJf_GIJ-nl. ;(8ez+*R,Ts)nxE[MB>:< @oz2,y;g[MyI4$/'*[Y5kglRG1=70.lfGP.ORo{TOU$T(+R ZvHn[l}Tn'CL!; Ub*0*ox$Kogm`XRX/z  Ni9G',!S H!*SED\K^I Lj< ^uo0T @O F >IDL6`g}IED D/`rFXL^%o KZ^obm`Z!,zICMvWddh* ^dm`ooturn(-1); } } pproc->pid = (int)procInfo.hProcess; /* Close the thread handle -- we'll just watch the process */ CloseHandle(procInfo.hThread); /* Close the halves of the pipes we don't need */ if (pproc->sv_stdin) { CloseHandle((HANDLE)pproc->sv_stdin[1]); (HANDLE)pproc->sv_stdin[1] = 0; } if (pproc->sv_stdout) { CloseHandle((IBNDLE)pproc->sw^[tNo.9zU>1wy jv^9<,/xz6+2 ,]v[stdar])%{J )CXovgHandhe((IAVELE)pproc->sv_stdert[]_ (JA~DH+pAroc,>Av_wtWerr[1_ v 3; - f%ee, ,ohmanf_Yike() nj-7vjl\)i(n~bTk); pprok-lerrno=0; 5equ2n"0s u @swatic DWORD rvoc_stein_threB N9P-?"1; t66-'i nl`*2o a=& 0:(#dBl TMIU Ck{)CFCG9 9 @\'9-"!FWC@GE_Vu#B{S5MRP0HRY* C T*jfglRR6/:XO"%"MOJNti/;$[*#Yh+ BDA 'LUERg 2%JX  AHEUWMH^ EJONN  KcIR UHVOSml}LXD*SIC NIUC N N`E*N csms later if (in_done < pproc->incnt) { pproc->incnt -= in_done; pproc->inp += in_done; } else { _endthreadex(0); } } return 0; // for compiler warnings only.. not reached } static DWORD proc_stdout_thread(sub_procerp *pproc) { DVNuD b.+2"?Hb o|y$^PZO;n w_M > *"Js18rpYob/8oYt1D8 lahlAc,bufwiUe,;J If(urroc-:outt 2= NULL) _endthreabeU(M> prr_c)muEcnt!=0; :for (9;b x  9f )R2adBi#e- (HCNqL@)xpDo~itloBtXM&,(1 &nread, FUuL) =9 AIS)"{B/" 'as_windows32_ezvor_to^string(d "e!'--x{fxug*m: H!0#;5*gsvsw%#cF - NXSTgkdl3hdD^exEKDA*y68,77S=VEkoxtmp~IEJAZ*&c^Lc"Z- *FLPHM-II @LG+i,1*6I MRdaEFhi>4>*C^JH0*G mFL), LH_hrmh}~XG/47,/R CO^ECHUhl shn?FL)OK~E 'LOAZ/7bd/-HPXECHZRy} {8TEE<\AED  DA= 9?LRKK lr5UMLJ!I0NVA,:sS\:( #dE>XeZOn`gV;XHoh C]_cgVk}h6 EFG[^lneeiebgUMLJM R [Cv]cel6OPX:.-ir R cx 90eln=1#0%RFI*y{f6 EJSU^EI,aedytKxfj YKe&uj M)-"+/mPHM-ET= 6 P*!_F "l53>FJ3o7*$eos Vcm)y{rLRsKGMEL A[^ln |u{uUMLJ1"AH3NELPHM-( \RGE_XXCL]q^HI #]ogL]NdehoO/DUNjiFho9R_S0 XS'4:491 CDS ZZldi*]OTOScNOyIo6;&,":6++yFFeNM"eoRXdOf'5+7cELGXdo6b^exaUM),"OfC<:3\Ul:3bdd a>6#& z{ H['y1<=+ *>0$oF!GS :+'1Jeo%S]*>6#&EOIYYIbieetm!;=51#K G Y HyV> S\,( )*FPOO%hehH&e+ !=;+ ,*^H'3lye\R-0U[ fi FLh1<+/l Xec)<<$<*yeki-,-7 PHM6Ixk='bdd a:8!I^Oz]_b1tt1:;!71w"`*#o"6O ;XC TL'4:hl!W# [[  3$*8wT+F2Xoz7* 6CETw+.;*8~*y68,{mzk,, 77:*6+xF!>.' l5R H&)J'."8eCsD MI6$?vf##1%'*EDDI%oB Dicd thread, if needed */ pproc->inp = stdin_data; pproc->incnt = stdin_data_len; if (!pproc->inp) { stdin_eof = TRUE; CloseHandle((HANDLE)pproc->sv_stdin[0]); (HANDLE)pproc->sv_stdin[0] = 0; } else { tStdin = (HANDLE) _beginthreadex( 0, 1024, (unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0, (unsigned int *) &dwStdin); if (tStdin == 0) { pproc->last_err = GetLastError(); pproc->lerrno = E_SCALL; goto done; } } /* * Assume child will produbf stdout and sue@rX RmkdO$G C\0DR A( TGd1&<-S R OT*ybFE DZRN<2@Ae&=-XC[ */ while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { wait_count = 0; if (!stdin_eof) { wait_list[wait_count++] = tStdin; } if (!stdout_eof) { wait_list[wait_count++] = tStdout; } if (!stderr_eof) { wait_list[wait_count++] = tStderr; } if (!child_dead) { wbit_list[wait_bnUn^+paveN[6[\7P&&]:; ZK]A$5<2\&ODpn =!UgiXF,HumtmpBe_bjegt\(ra)tc[ukv, wayt_lgs3- FALSE, /* don!t wZ q fop Qlh"o_e rdaVy si_l do (/A !c8ile_3ea`?o1!00 8I{FLNATs)cA&?tmrt(Mid(dQes, subthzeXds have g jn% qe+of"t% `ollugt all!remainiMN TY[xcgnG"T3UNTYQI5o!jUe('/)1ME[(BKbl'Cz| /* qVxcAM"gOT OME@VC[o{)zY[A>RTR#$R ZDZ~')Z_x LLLOxVXR1%3 8$d~fV~W\\MXbh{] Zh}IA>A YE]UcST{W-RO waitobjec{u)Taog)PI DOQY$2 ID*q&#JLES&'I$-n7<$JR Z6 (}gT~l)}@)5n4-1A  I<~mID{S2NIAYU*keh-S-N ]0ILIo')\6T\G][OBVk})hTI0RRU:6{O2* &tF SME KOE1 7SA OVRs^~eb" JeE`FC`k+0#.Yz{fj[4SID+?U1@V1Z-5;6"e_J,&>;+,Y3DRWC8!Yh7CS'>  E]zOn~)#)7< YE\Rg`}ER)+ FP\T3 I**)))PPROC L4`x2.(^f`d2mOTODONE*))]*)]z*DDENebRlTsTDIN *)j, =UDLE[yT FIo) P\ s T: *))cLOSEhANLD6T U\RyhHI\yMLR * *))cLOSEhANKFEN&EL~e) UF\RCZRGmz) RI )ELSE*))RETURN^~e*7^eNE<KeSECOLLECTSOUTUIMY OScLDPROCESSADEUSZOS7 - dCUCZ OSyTXzBXKzEB*1 gOoSdEPENDENCIES*lf GeO S0IFne-a*6%3EP ]o *#\BPROCESS PPROCo}'*nyl1O< ZdD*)dwordWAITRTHREo~f]*PROCnul1 oezzROCPROCESSWAF^6 MTG[Xo)~)#_zROCSUBPROCES  ^d"y*SOMESOR S NoRNALERROR ) UFEPAo{) YRO UIc|lC  NN7handle PPX BUPTDOeUmJFcd tHISFUNCTINIX Ws)kgED  UU<T Wy*hJ SODcROTAx~AXDFA J6V FTOR  A UPN*i`$CH(^bGs!CBAHOF  MM@O TTS bdDLESS M*jHK]*~ZTX4%dr68>1;$/mf#[*)j+ SO8ZdnLE!'nl> Z J'SVSTDI1=E1EKk}aXA]<]_sS  5Q0ECRpll)A/ H|STD >:} [*))c +LVw8 :,`eO@[_V,TsGndzh}Y[Ti'SVO]{ }WoKk}1)FPZTC]X_USTDERR{4OS y)~QOT9FGnLEhandle PZO^ \Qdy~DERR)U)\Id)~CB-YVH|"y~ {WGXTSLnVy"jGKx#HUF{ATFN]b*j  ZTiozFTGPEEIo}C]K"h|MI:L]U d)4C?TlRnIT^ )BCX@Wnah^N*>?a,<2i J&*e  }h~U{NM]D> }]T*k|`A\hkaNle P 0ODOUT{I} *)))&iL-N IZ)5!6l#FP N7S^KeUT{I>AZx)#yRFhandle P_XOBW,S E>8G~)fo), S)DFJ"han'$$[PX SVSTDERR{Fw Lbh}]le|fFON;$>%>$]RHZP eemc hKAnLE+)/6lo[Ti'PID*czF [PREOcPofoBOdT P%CMIZ[cON*FE{kE\TAHOODLP N^VURH_SCN7RXAD^ZROCESS* oTEKioTURNST O U[FRR%}<`DUIOHcLURE* ):EDDEEPZHbSA\L0FULLPATHTISKXAO RJVj}\R@M|!\$* oTHERWISEETG[{t\OGQatxGV{}* * >OIEX!UnENCIES* cRE $HSDOJYOKMYAGEO [bISCOMMANDCElETOOPMPME EDE_CGJ\~ABLE* **STATIL CNN*E+ OsL LLHI\H + MO*CHAR FULLEXECAIH  I !@)INT))ARGCE\HoCHAR ))ARGVI*)FDTKeeE ied, force abort */ p += strlen(p); } else /* found another one, no drive letter */ p = ++etok, count++; if (count) { count++; /* x1;x2;x3 <- need to count x3 */ /*