diff --git a/ChangeLog b/ChangeLog index 91eef976..48d4451b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2013-01-19 Paul Smith + * doc/make.texi (load Directive): Update to discuss location of + loaded object file. + (Remaking Loaded Objects): Document remaking of loaded objects. + + * main.c (main): Rename READ_MAKEFILES to READ_FILES. + * read.c: Change READ_MAKEFILES to READ_FILES since it now + contains loaded object files as well. + (read_all_makefiles): Ditto. + (eval_makefile): Ditto. + (eval): Add any loaded file to the READ_FILES list, so that it + will be considered for re-build. + + * load.c (load_file): Return the simple filename (no symbol) in + the LDNAME argument (now a const char **). + This filename should no longer have "./" prepended: modify the + function to always check the current directory if the name has no + "/", before using the normal methods. + * make.h: Change the load_file() prototype. + * README.git: Add a bit more documentation on Git workflow & rules. 2013-01-13 Paul Smith diff --git a/doc/make.texi b/doc/make.texi index 3a16dd36..f5ca1160 100644 --- a/doc/make.texi +++ b/doc/make.texi @@ -4,7 +4,6 @@ @include version.texi @set EDITION 0.72 -@set RCSID $Id$ @settitle GNU @code{make} @setchapternewpage odd @@ -27,7 +26,7 @@ of @cite{The GNU Make Manual}, for GNU @code{make} version @value{VERSION}. Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, -2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -348,6 +347,7 @@ GNU Guile Integration Loading Dynamic Objects * load Directive:: Loading dynamic objects as extensions. +* Remaking Loaded Objects:: How loaded objects get remade. @end detailmenu @end menu @@ -1287,7 +1287,6 @@ 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 @@ -6295,7 +6294,6 @@ Has GNU Guile available as an embedded extension language. @item load Supports dynamically loadable objects for creating custom extensions. @xref{Loading Objects, ,Loading Dynamic Objects}. - @end table @vindex .INCLUDE_DIRS @r{(list of include directories)} @@ -10539,11 +10537,11 @@ program, although this can be inefficient. In cases where the built-in capabilities of GNU @code{make} are insufficient to your requirements there are two options for extending @code{make}. On systems where it's provided, you can utilize GNU -Guile as an embedded scripting language (@pxref{Guile Integration, -,GNU Guile Integration}). On systems which support dynamically -loadable objects, you can write your own extension in any language -(which can be compiled into such an object) and load it to provide -extended capabilities (@pxref{load Directive, ,The @code{load} Directive}). +Guile as an embedded scripting language (@pxref{Guile Integration,,GNU +Guile Integration}). On systems which support dynamically loadable +objects, you can write your own extension in any language (which can +be compiled into such an object) and load it to provide extended +capabilities (@pxref{load Directive, ,The @code{load} Directive}). @menu * Guile Integration:: Using Guile as an embedded scripting language. @@ -10786,15 +10784,16 @@ providing new capabilities which may then be invoked by your makefile. The @code{load} directive is used to load a dynamic object. Once the object is loaded, a ``setup'' function will be invoked to allow the object to initialize itself and register new facilities with GNU -@code{make}. Typically a dynamic object would create new functions, +@code{make}. A dynamic object might include new @code{make} functions, for example, and the ``setup'' function would register them with GNU @code{make}'s function handling system. @menu * load Directive:: Loading dynamic objects as extensions. +* Remaking Loaded Objects:: How loaded objects get remade. @end menu -@node load Directive, , Loading Objects, Loading Objects +@node load Directive, Remaking Loaded Objects, Loading Objects, Loading Objects @subsection The @code{load} Directive @cindex load directive @cindex extensions, load directive @@ -10814,21 +10813,33 @@ or: load @var{object-file}(@var{symbol-name}) @dots{} @end example -In the first form, the file @var{object-file} is dynamically loaded by -GNU @code{make}. On failure, @code{make} will print a message and -exit. If the load succeeds @code{make} will invoke an initializing -function whose name is created by taking the base file name of -@var{object-file}, up to the first character which is not a valid -symbol name character (alphanumerics and underscores are valid symbol -name characters). To this prefix will be appended the suffix -@code{_gmake_setup}, then this symbol will be invoked. +The file @var{object-file} is dynamically loaded by GNU @code{make}. +If @var{object-file} does not include a directory path then it is +first looked for in the current directory. If it is not found there, +or a directory path is included, then system-specific paths will be +searched. If the load fails for any reason, @code{make} will print a +message and exit. -In the second form, the function @var{symbol-name} will be invoked. +If the load succeeds @code{make} will invoke an initializing function. + +If @var{symbol-name} is provided, it will be used as the name of the +initializing function. + +If no @var{symbol-name} is provided, the initializing function name is +created by taking the base file name of @var{object-file}, up to the +first character which is not a valid symbol name character +(alphanumerics and underscores are valid symbol name characters). To +this prefix will be appended the suffix @code{_gmake_setup}. More than one object file may be loaded with a single @code{load} directive, and both forms of @code{load} arguments may be used in the same directive. +The initializing function will be provided the file name and line +number of the invocation of the @code{load} operation. It should +return a value of type @code{int}, which must be @code{0} on failure +and non-@code{0} on success. + For example: @example @@ -10864,6 +10875,22 @@ generated if an object fails to load. The failed object is not added to the @code{.LOADED} variable, which can then be consulted to determine if the load was successful. +@node Remaking Loaded Objects, , load Directive, Loading Objects +@subsection How Loaded Objects Are Remade +@cindex updating load objects +@cindex remaking load objects +@cindex load objects, remaking of + +Loaded objects undergo the same re-make procedure as makefiles +(@pxref{Remaking Makefiles, ,How Makefiles Are Remade}). If any +loaded object is recreated, then @code{make} will start from scratch +and re-read all the makefiles, and reload the object files again. It +is not necessary for the loaded object to do anything special to +support this.@refill + +It's up to the makefile author to provide the rules needed for +rebuilding the loaded object. + @node Features, Missing, Extending make, Top @chapter Features of GNU @code{make} @cindex features of GNU @code{make} @@ -11007,6 +11034,12 @@ nonexistent file comes from SunOS 4 @code{make}. (But note that SunOS 4 The @code{!=} shell assignment operator exists in many BSD of @code{make} and is purposefully implemented here to behave identically to those implementations. + +@item +Various build management tools are implemented using scripting +languages such as Perl or Python and thus provide a natural embedded +scripting language, similar to GNU @code{make}'s integration of GNU +Guile. @end itemize The remaining features are inventions new in GNU @code{make}: @@ -11116,6 +11149,10 @@ Various new built-in implicit rules. The built-in variable @samp{MAKE_VERSION} gives the version number of @code{make}. @vindex MAKE_VERSION + +@item +Load dynamic objects which can modify the behavior of @code{make}. +@xref{Loading Objects, ,Loading Dynamic Objects}. @end itemize @node Missing, Makefile Conventions, Features, Top diff --git a/load.c b/load.c index 076dd30e..26432b75 100644 --- a/load.c +++ b/load.c @@ -58,12 +58,12 @@ init_symbol (const struct floc *flocp, const char *ldname, load_func_t symp) } int -load_file (const struct floc *flocp, const char *ldname, int noerror) +load_file (const struct floc *flocp, const char **ldname, int noerror) { load_func_t symp; const char *fp; char *symname = NULL; - char *new = alloca (strlen (ldname) + CSTRLEN (SYMBOL_EXTENSION) + 1); + char *new = alloca (strlen (*ldname) + CSTRLEN (SYMBOL_EXTENSION) + 1); if (! global_dl) { @@ -73,27 +73,27 @@ load_file (const struct floc *flocp, const char *ldname, int noerror) } /* If a symbol name was provided, use it. */ - fp = strchr (ldname, '('); + fp = strchr (*ldname, '('); if (fp) { const char *ep; - /* If there's an open paren, see if there's a close paren: if so use + /* There's an open paren, so see if there's a close paren: if so use that as the symbol name. We can't have whitespace: it would have been chopped up before this function is called. */ ep = strchr (fp+1, ')'); if (ep && ep[1] == '\0') { - int l = fp - ldname;; + int l = fp - *ldname;; ++fp; if (fp == ep) - fatal (flocp, _("Empty symbol name for load: %s"), ldname); + fatal (flocp, _("Empty symbol name for load: %s"), *ldname); /* Make a copy of the ldname part. */ - memcpy (new, ldname, l); + memcpy (new, *ldname, l); new[l] = '\0'; - ldname = new; + *ldname = new; /* Make a copy of the symbol name part. */ symname = new + l + 1; @@ -102,14 +102,17 @@ load_file (const struct floc *flocp, const char *ldname, int noerror) } } + /* Add this name to the string cache so it can be reused later. */ + *ldname = strcache_add (*ldname); + /* If we didn't find a symbol name yet, construct it from the ldname. */ if (! symname) { char *p = new; - fp = strrchr (ldname, '/'); + fp = strrchr (*ldname, '/'); if (!fp) - fp = ldname; + fp = *ldname; else ++fp; while (isalnum (*fp) || *fp == '_') @@ -118,12 +121,22 @@ load_file (const struct floc *flocp, const char *ldname, int noerror) symname = new; } - DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, ldname)); + DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname)); /* See if it's already defined. */ symp = (load_func_t) dlsym (global_dl, symname); if (! symp) { - void *dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL); + void *dlp = NULL; + + /* If the path has no "/", try the current directory first. */ + if (! strchr (*ldname, '/')) + dlp = dlopen (concat (2, "./", *ldname), RTLD_LAZY|RTLD_GLOBAL); + + /* If we haven't opened it yet, try the default search path. */ + if (! dlp) + dlp = dlopen (*ldname, RTLD_LAZY|RTLD_GLOBAL); + + /* Still no? Then fail. */ if (! dlp) { if (noerror) @@ -136,17 +149,17 @@ load_file (const struct floc *flocp, const char *ldname, int noerror) symp = dlsym (dlp, symname); if (! symp) fatal (flocp, _("Failed to load symbol %s from %s: %s"), - symname, ldname, dlerror()); + symname, *ldname, dlerror()); } /* Invoke the symbol to initialize the loaded object. */ - return init_symbol(flocp, ldname, symp); + return init_symbol(flocp, *ldname, symp); } #else int -load_file (const struct floc *flocp, const char *ldname, int noerror) +load_file (const struct floc *flocp, const char **ldname, int noerror) { if (! noerror) fatal (flocp, _("The 'load' operation is not supported on this platform.")); diff --git a/main.c b/main.c index 754bf2db..54b20617 100644 --- a/main.c +++ b/main.c @@ -64,11 +64,11 @@ void verify_file_data_base (void); # define HAVE_WAIT_NOHANG #endif -#ifndef HAVE_UNISTD_H +#ifndef HAVE_UNISTD_H int chdir (); #endif -#ifndef STDC_HEADERS -# ifndef sun /* Sun has an incorrect decl in a header. */ +#ifndef STDC_HEADERS +# ifndef sun /* Sun has an incorrect decl in a header. */ void exit (int) __attribute__ ((noreturn)); # endif double atof (); @@ -88,29 +88,29 @@ static void initialize_global_hash_tables (void); struct command_switch { - int c; /* The switch character. */ + int c; /* The switch character. */ - enum /* Type of the value. */ + enum /* Type of the value. */ { - flag, /* Turn int flag on. */ - flag_off, /* Turn int flag off. */ - string, /* One string per switch. */ - filename, /* A string containing a file name. */ - positive_int, /* A positive integer. */ - floating, /* A floating-point number (double). */ - ignore /* Ignored. */ + flag, /* Turn int flag on. */ + flag_off, /* Turn int flag off. */ + string, /* One string per switch. */ + filename, /* A string containing a file name. */ + positive_int, /* A positive integer. */ + floating, /* A floating-point number (double). */ + ignore /* Ignored. */ } type; - void *value_ptr; /* Pointer to the value-holding variable. */ + void *value_ptr; /* Pointer to the value-holding variable. */ - unsigned int env:1; /* Can come from MAKEFLAGS. */ - unsigned int toenv:1; /* Should be put in MAKEFLAGS. */ - unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ + unsigned int env:1; /* Can come from MAKEFLAGS. */ + unsigned int toenv:1; /* Should be put in MAKEFLAGS. */ + unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ - const void *noarg_value; /* Pointer to value used if no arg given. */ - const void *default_value; /* Pointer to default value. */ + const void *noarg_value; /* Pointer to value used if no arg given. */ + const void *default_value; /* Pointer to default value. */ - char *long_name; /* Long option name. */ + char *long_name; /* Long option name. */ }; /* True if C is a switch value that corresponds to a short option. */ @@ -122,9 +122,9 @@ struct command_switch struct stringlist { - const char **list; /* Nil-terminated list of strings. */ - unsigned int idx; /* Index into above. */ - unsigned int max; /* Number of pointers allocated. */ + const char **list; /* Nil-terminated list of strings. */ + unsigned int idx; /* Index into above. */ + unsigned int max; /* Number of pointers allocated. */ }; @@ -432,15 +432,15 @@ static const struct command_switch switches[] = 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' }, + { "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' }, }; /* List of goal targets. */ @@ -516,10 +516,10 @@ int clock_skew_detected; /* Mask of signals that are being caught with fatal_error_signal. */ -#ifdef POSIX +#ifdef POSIX sigset_t fatal_signal_set; #else -# ifdef HAVE_SIGSETMASK +# ifdef HAVE_SIGSETMASK int fatal_signal_mask; # endif #endif @@ -568,7 +568,7 @@ expand_command_line_file (char *name) { expanded = tilde_expand (name); if (expanded != 0) - name = expanded; + name = expanded; } /* This is also done in parse_file_seq, so this is redundant @@ -578,16 +578,16 @@ expand_command_line_file (char *name) { name += 2; while (*name == '/') - /* Skip following slashes: ".//foo" is "foo", not "/foo". */ - ++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 "./". */ + it after the first slash, so it becomes just "./". */ do - --name; + --name; while (name[0] != '.'); name[2] = '\0'; } @@ -918,7 +918,7 @@ main (int argc, char **argv, char **envp) { static char *stdin_nm = 0; int makefile_status = MAKE_SUCCESS; - struct dep *read_makefiles; + struct dep *read_files; PATH_VAR (current_directory); unsigned int restarts = 0; #ifdef WINDOWS32 @@ -963,11 +963,11 @@ main (int argc, char **argv, char **envp) /* 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); + | __system_use_shell + | __system_allow_multiple_cmds + | __system_allow_long_cmds + | __system_handle_null_commands + | __system_emulate_chdir); #endif @@ -978,22 +978,22 @@ main (int argc, char **argv, char **envp) (void)bindtextdomain (PACKAGE, LOCALEDIR); (void)textdomain (PACKAGE); -#ifdef POSIX +#ifdef POSIX sigemptyset (&fatal_signal_set); -#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig) +#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig) #else -#ifdef HAVE_SIGSETMASK +#ifdef HAVE_SIGSETMASK fatal_signal_mask = 0; -#define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig) +#define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig) #else -#define ADD_SIG(sig) (void)sig +#define ADD_SIG(sig) (void)sig #endif #endif -#define FATAL_SIG(sig) \ - if (bsd_signal (sig, fatal_error_signal) == SIG_IGN) \ - bsd_signal (sig, SIG_IGN); \ - else \ +#define FATAL_SIG(sig) \ + if (bsd_signal (sig, fatal_error_signal) == SIG_IGN) \ + bsd_signal (sig, SIG_IGN); \ + else \ ADD_SIG (sig); #ifdef SIGHUP @@ -1012,7 +1012,7 @@ main (int argc, char **argv, char **envp) FATAL_SIG (SIGFPE); #endif -#ifdef SIGDANGER +#ifdef SIGDANGER FATAL_SIG (SIGDANGER); #endif #ifdef SIGXCPU @@ -1022,7 +1022,7 @@ main (int argc, char **argv, char **envp) FATAL_SIG (SIGXFSZ); #endif -#undef FATAL_SIG +#undef FATAL_SIG /* Do not ignore the child-death signal. This must be done before any children could possibly be created; otherwise, the wait @@ -1043,13 +1043,13 @@ main (int argc, char **argv, char **envp) #ifdef HAVE_SETVBUF # ifdef SETVBUF_REVERSED setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ); -# else /* setvbuf not reversed. */ +# else /* setvbuf not reversed. */ /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */ setvbuf (stdout, 0, _IOLBF, BUFSIZ); -# endif /* setvbuf reversed. */ +# endif /* setvbuf reversed. */ #elif HAVE_SETLINEBUF setlinebuf (stdout); -#endif /* setlinebuf missing. */ +#endif /* setlinebuf missing. */ /* Figure out where this program lives. */ @@ -1066,17 +1066,17 @@ main (int argc, char **argv, char **envp) #endif #if defined(__MSDOS__) || defined(__EMX__) if (program == 0) - program = strrchr (argv[0], '\\'); + program = strrchr (argv[0], '\\'); else - { - /* Some weird environments might pass us argv[0] with - both kinds of slashes; we must find the rightmost. */ - char *p = strrchr (argv[0], '\\'); - if (p && p > program) - program = p; - } + { + /* Some weird environments might pass us argv[0] with + both kinds of slashes; we must find the rightmost. */ + char *p = strrchr (argv[0], '\\'); + if (p && p > program) + program = p; + } if (program == 0 && argv[0][1] == ':') - program = argv[0] + 1; + program = argv[0] + 1; #endif #ifdef WINDOWS32 if (program == 0) @@ -1094,9 +1094,9 @@ main (int argc, char **argv, char **envp) } #endif if (program == 0) - program = argv[0]; + program = argv[0]; else - ++program; + ++program; } /* Set up to access user data (files). */ @@ -1112,7 +1112,7 @@ main (int argc, char **argv, char **envp) if (getcwd (current_directory, GET_PATH_MAX) == 0) #endif { -#ifdef HAVE_GETCWD +#ifdef HAVE_GETCWD perror_with_name ("getcwd", ""); #else error (NILF, "getwd: %s", current_directory); @@ -1238,32 +1238,32 @@ main (int argc, char **argv, char **envp) #endif #else /* For Amiga, read the ENV: device, ignoring all dirs */ { - BPTR env, file, old; - char buffer[1024]; - int len; - __aligned struct FileInfoBlock fib; + 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); + 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)); - } + 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 @@ -1328,8 +1328,8 @@ main (int argc, char **argv, char **envp) argv[0] = xstrdup (argv[0]); for (p = argv[0]; *p; p++) - if (*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 @@ -1369,34 +1369,34 @@ main (int argc, char **argv, char **envp) char *value, *p; /* Figure out how much space will be taken up by the command-line - variable definitions. */ + 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 += 2 * strlen (v->value); - ++len; - } + { + v = cv->variable; + len += 2 * strlen (v->name); + if (! v->recursive) + ++len; + ++len; + len += 2 * strlen (v->value); + ++len; + } /* Now allocate a buffer big enough and fill it. */ p = value = alloca (len); for (cv = command_variables; cv != 0; cv = cv->next) - { - v = cv->variable; - p = quote_for_env (p, v->name); - if (! v->recursive) - *p++ = ':'; - *p++ = '='; - p = quote_for_env (p, v->value); - *p++ = ' '; - } - p[-1] = '\0'; /* Kill the final space and terminate. */ + { + v = cv->variable; + p = quote_for_env (p, v->name); + if (! v->recursive) + *p++ = ':'; + *p++ = '='; + p = quote_for_env (p, v->value); + *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. */ + makefile could validly use for its own variable. */ define_variable_cname ("-*-command-variables-*-", value, o_automatic, 0); /* Define the variable; this will not override any user definition. @@ -1481,16 +1481,16 @@ main (int argc, char **argv, char **envp) #else if (getcwd (current_directory, GET_PATH_MAX) == 0) #endif - { -#ifdef HAVE_GETCWD - perror_with_name ("getcwd", ""); + { +#ifdef HAVE_GETCWD + perror_with_name ("getcwd", ""); #else - error (NILF, "getwd: %s", current_directory); + error (NILF, "getwd: %s", current_directory); #endif - starting_directory = 0; - } + starting_directory = 0; + } else - starting_directory = current_directory; + starting_directory = current_directory; } define_variable_cname ("CURDIR", current_directory, o_file, 0); @@ -1501,12 +1501,12 @@ main (int argc, char **argv, char **envp) { 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; + 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; char *template, *tmpdir; if (stdin_nm) @@ -1523,46 +1523,46 @@ main (int argc, char **argv, char **envp) #endif #define DEFAULT_TMPFILE "GmXXXXXX" - if (((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0') + if (((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0') #if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__) /* These are also used commonly on these platforms. */ && ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0') && ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0') #endif ) - tmpdir = DEFAULT_TMPDIR; + tmpdir = DEFAULT_TMPDIR; template = alloca (strlen (tmpdir) + CSTRLEN (DEFAULT_TMPFILE) + 2); - strcpy (template, tmpdir); + strcpy (template, tmpdir); #ifdef HAVE_DOS_PATHS - if (strchr ("/\\", template[strlen (template) - 1]) == NULL) - strcat (template, "/"); + if (strchr ("/\\", template[strlen (template) - 1]) == NULL) + strcat (template, "/"); #else # ifndef VMS - if (template[strlen (template) - 1] != '/') - strcat (template, "/"); + if (template[strlen (template) - 1] != '/') + strcat (template, "/"); # endif /* !VMS */ #endif /* !HAVE_DOS_PATHS */ - strcat (template, DEFAULT_TMPFILE); - outfile = open_tmpfile (&stdin_nm, template); - if (outfile == 0) - pfatal_with_name (_("fopen (temporary file)")); - while (!feof (stdin) && ! ferror (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)")); - } - fclose (outfile); + strcat (template, DEFAULT_TMPFILE); + outfile = open_tmpfile (&stdin_nm, template); + if (outfile == 0) + pfatal_with_name (_("fopen (temporary file)")); + while (!feof (stdin) && ! ferror (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)")); + } + fclose (outfile); - /* Replace the name that read_all_makefiles will - see with the name of the temporary file. */ + /* Replace the name that read_all_makefiles will + see with the name of the temporary file. */ makefiles->list[i] = strcache_add (stdin_nm); - /* Make sure the temporary file will not be remade. */ + /* Make sure the temporary file will not be remade. */ { struct file *f = enter_file (strcache_add (stdin_nm)); f->updated = 1; @@ -1573,7 +1573,7 @@ main (int argc, char **argv, char **envp) f->intermediate = 0; f->dontcare = 0; } - } + } } #ifndef __EMX__ /* Don't use a SIGCHLD handler for OS/2 */ @@ -1667,7 +1667,7 @@ main (int argc, char **argv, char **envp) /* Read all the makefiles. */ - read_makefiles = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list); + read_files = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list); #ifdef WINDOWS32 /* look one last time after reading all Makefiles */ @@ -1685,14 +1685,14 @@ main (int argc, char **argv, char **envp) if (shv && *shv->value) { - char *shell_path = recursively_expand(shv); + 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; + if (shell_path && _is_unixy_shell (shell_path)) + unixy_shell = 1; + else + unixy_shell = 0; + if (shell_path) + default_shell = shell_path; } } #endif /* __MSDOS__ || __EMX__ */ @@ -1819,7 +1819,7 @@ main (int argc, char **argv, char **envp) char c = '+'; if (pipe (job_fds) < 0 || (job_rfd = dup (job_fds[0])) < 0) - pfatal_with_name (_("creating jobs pipe")); + pfatal_with_name (_("creating jobs pipe")); #endif /* Every make assumes that it always has one job it can run. For the @@ -1921,16 +1921,16 @@ main (int argc, char **argv, char **envp) { const char **p; for (p = new_files->list; *p != 0; ++p) - { - struct file *f = enter_file (*p); - f->last_mtime = f->mtime_before_update = NEW_MTIME; - } + { + struct file *f = enter_file (*p); + f->last_mtime = f->mtime_before_update = NEW_MTIME; + } } /* Initialize the remote job module. */ remote_setup (); - if (read_makefiles != 0) + if (read_files != 0) { /* Update any makefiles if necessary. */ @@ -1947,88 +1947,88 @@ main (int argc, char **argv, char **envp) DB (DB_BASIC, (_("Updating makefiles....\n"))); /* Remove any makefiles we don't want to try to update. - Also record the current modtimes so we can compare them later. */ + Also record the current modtimes so we can compare them later. */ { - register struct dep *d, *last; - last = 0; - d = read_makefiles; - while (d != 0) - { - 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.) */ + register struct dep *d, *last; + last = 0; + d = read_files; + while (d != 0) + { + 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.) */ - DB (DB_VERBOSE, + DB (DB_VERBOSE, (_("Makefile '%s' might loop; not remaking it.\n"), f->name)); - if (last == 0) - read_makefiles = d->next; - else - last->next = d->next; + if (last == 0) + read_files = d->next; + else + last->next = d->next; - /* Free the storage. */ + /* Free the storage. */ free_dep (d); - d = last == 0 ? read_makefiles : last->next; + d = last == 0 ? read_files : last->next; - break; - } - } - if (f == NULL || !f->double_colon) - { + break; + } + } + if (f == NULL || !f->double_colon) + { makefile_mtimes = xrealloc (makefile_mtimes, (mm_idx+1) * sizeof (FILE_TIMESTAMP)); - makefile_mtimes[mm_idx++] = file_mtime_no_search (d->file); - last = d; - d = d->next; - } - } + 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); rebuilding_makefiles = 1; - status = update_goal_chain (read_makefiles); + status = update_goal_chain (read_files); rebuilding_makefiles = 0; switch (status) - { - case 1: + { + case 1: /* The only way this can happen is if the user specified -q and asked * for one of the makefiles to be remade as a target on the command * line. Since we're not actually updating anything with -q we can * treat this as "did nothing". */ - case -1: - /* Did nothing. */ - 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; - unsigned int i; + 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; + unsigned int i; struct dep *d; - for (i = 0, d = read_makefiles; d != 0; ++i, d = d->next) + for (i = 0, d = read_files; d != 0; ++i, d = d->next) { /* Reset the considered flag; we may need to look at the file again to print an error. */ @@ -2077,43 +2077,43 @@ main (int argc, char **argv, char **envp) } } /* Reset this to empty so we get the right error message below. */ - read_makefiles = 0; + read_files = 0; - if (any_remade) - goto re_exec; - if (any_failed) - die (2); + if (any_remade) + goto re_exec; + if (any_failed) + die (2); break; - } + } - case 0: - re_exec: - /* Updated successfully. Re-exec ourselves. */ + case 0: + re_exec: + /* Updated successfully. Re-exec ourselves. */ - remove_intermediates (0); + remove_intermediates (0); - if (print_data_base_flag) - print_data_base (); + if (print_data_base_flag) + print_data_base (); - log_working_directory (0); + log_working_directory (0); clean_jobserver (0); - if (makefiles != 0) - { - /* These names might have changed. */ - int i, j = 0; - for (i = 1; i < argc; ++i) - if (strneq (argv[i], "-f", 2)) /* XXX */ - { - if (argv[i][2] == '\0') + if (makefiles != 0) + { + /* These names might have changed. */ + int i, j = 0; + for (i = 1; i < argc; ++i) + if (strneq (argv[i], "-f", 2)) /* XXX */ + { + if (argv[i][2] == '\0') /* This cast is OK since we never modify argv. */ - argv[++i] = (char *) makefiles->list[j]; - else - argv[i] = xstrdup (concat (2, "-f", makefiles->list[j])); - ++j; - } - } + argv[++i] = (char *) makefiles->list[j]; + else + argv[i] = xstrdup (concat (2, "-f", makefiles->list[j])); + ++j; + } + } /* Add -o option for the stdin temporary file, if necessary. */ nargc = argc; @@ -2127,19 +2127,19 @@ main (int argc, char **argv, char **envp) else nargv = argv; - if (directories != 0 && directories->idx > 0) - { - int bad = 1; - if (directory_before_chdir != 0) - { - if (chdir (directory_before_chdir) < 0) - perror_with_name ("chdir", ""); - else - bad = 0; - } - if (bad) - fatal (NILF, _("Couldn't change back to original directory.")); - } + if (directories != 0 && directories->idx > 0) + { + int bad = 1; + if (directory_before_chdir != 0) + { + if (chdir (directory_before_chdir) < 0) + perror_with_name ("chdir", ""); + else + bad = 0; + } + if (bad) + fatal (NILF, _("Couldn't change back to original directory.")); + } ++restarts; @@ -2156,14 +2156,14 @@ main (int argc, char **argv, char **envp) putenv (allocated_variable_expand (p)); } - if (ISDB (DB_BASIC)) - { - char **p; - printf (_("Re-executing[%u]:"), restarts); - for (p = nargv; *p != 0; ++p) - printf (" %s", *p); - putchar ('\n'); - } + if (ISDB (DB_BASIC)) + { + char **p; + printf (_("Re-executing[%u]:"), restarts); + for (p = nargv; *p != 0; ++p) + printf (" %s", *p); + putchar ('\n'); + } #ifndef _AMIGA { @@ -2185,8 +2185,8 @@ main (int argc, char **argv, char **envp) } } #else /* AMIGA */ - { - char buffer[256]; + { + char buffer[256]; sprintf (buffer, "%u", makelevel); SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY); @@ -2194,7 +2194,7 @@ main (int argc, char **argv, char **envp) sprintf (buffer, "%u", restarts); SetVar ("MAKE_RESTARTS", buffer, -1, GVF_GLOBAL_ONLY); restarts = 0; - } + } #endif /* If we didn't set the restarts variable yet, add it. */ @@ -2205,45 +2205,45 @@ main (int argc, char **argv, char **envp) putenv (b); } - fflush (stdout); - fflush (stderr); + fflush (stdout); + fflush (stderr); /* Close the dup'd jobserver pipe if we opened one. */ if (job_rfd >= 0) close (job_rfd); #ifdef _AMIGA - exec_command (nargv); - exit (0); + exec_command (nargv); + exit (0); #elif defined (__EMX__) - { - /* It is not possible to use execve() here because this - would cause the parent process to be terminated with - exit code 0 before the child process has been terminated. - Therefore it may be the best solution simply to spawn the - child process including all file handles and to wait for its - termination. */ - int pid; - int status; - pid = child_execute_job (0, 1, nargv, environ); + { + /* It is not possible to use execve() here because this + would cause the parent process to be terminated with + exit code 0 before the child process has been terminated. + Therefore it may be the best solution simply to spawn the + child process including all file handles and to wait for its + termination. */ + int pid; + int status; + pid = child_execute_job (0, 1, nargv, environ); - /* is this loop really necessary? */ - do { - pid = wait (&status); - } while (pid <= 0); - /* use the exit code of the child process */ - exit (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE); - } + /* is this loop really necessary? */ + do { + pid = wait (&status); + } while (pid <= 0); + /* use the exit code of the child process */ + exit (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE); + } #else - exec_command (nargv, environ); + exec_command (nargv, environ); #endif - /* NOTREACHED */ + /* NOTREACHED */ - default: + default: #define BOGUS_UPDATE_STATUS 0 - assert (BOGUS_UPDATE_STATUS); - break; - } + assert (BOGUS_UPDATE_STATUS); + break; + } db_level = orig_db_level; @@ -2263,10 +2263,10 @@ main (int argc, char **argv, char **envp) { const char **p; for (p = new_files->list; *p != 0; ++p) - { - struct file *f = enter_file (*p); - f->last_mtime = f->mtime_before_update = NEW_MTIME; - } + { + struct file *f = enter_file (*p); + f->last_mtime = f->mtime_before_update = NEW_MTIME; + } } /* If there is a temp file from reading a makefile from stdin, get rid of @@ -2326,7 +2326,7 @@ main (int argc, char **argv, char **envp) if (!goals) { - if (read_makefiles == 0) + if (read_files == 0) fatal (NILF, _("No targets specified and no makefile found")); fatal (NILF, _("No targets")); @@ -2377,8 +2377,8 @@ main (int argc, char **argv, char **envp) 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]))]; + (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0]))]; /* Fill in the string and vector for getopt. */ static void @@ -2401,39 +2401,39 @@ init_switches (void) for (i = 0; switches[i].c != '\0'; ++i) { long_options[i].name = (switches[i].long_name == 0 ? "" : - switches[i].long_name); + 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; + *p++ = switches[i].c; switch (switches[i].type) - { - case flag: - case flag_off: - case ignore: - long_options[i].has_arg = no_argument; - break; + { + case flag: + case flag_off: + case ignore: + long_options[i].has_arg = no_argument; + break; - case string: + case string: case filename: - case positive_int: - case floating: - if (short_option (switches[i].c)) - *p++ = ':'; - if (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; - } + case positive_int: + case floating: + if (short_option (switches[i].c)) + *p++ = ':'; + if (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])); + sizeof (long_option_aliases[0])); ++c) long_options[i++] = long_option_aliases[c]; long_options[i].name = 0; @@ -2451,8 +2451,8 @@ handle_non_switch_argument (char *arg, int env) if (v != 0) { /* It is indeed a variable definition. If we don't already have this - one, record a pointer to the variable for later use in - define_makeflags. */ + one, record a pointer to the variable for later use in + define_makeflags. */ struct command_variable *cv; for (cv = command_variables; cv != 0; cv = cv->next) @@ -2469,21 +2469,21 @@ handle_non_switch_argument (char *arg, int env) 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. */ + target! Enter it as a file and add it to the dep chain of + goals. */ struct file *f = enter_file (strcache_add (expand_command_line_file (arg))); f->cmd_target = 1; if (goals == 0) - { - goals = alloc_dep (); - lastgoal = goals; - } + { + goals = alloc_dep (); + lastgoal = goals; + } else - { - lastgoal->next = alloc_dep (); - lastgoal = lastgoal->next; - } + { + lastgoal->next = alloc_dep (); + lastgoal = lastgoal->next; + } lastgoal->file = f; @@ -2568,47 +2568,47 @@ decode_switches (int argc, char **argv, int env) /* Parse the next argument. */ c = getopt_long (argc, argv, options, long_options, (int *) 0); if (c == EOF) - /* End of arguments, or "--" marker seen. */ - break; + /* End of arguments, or "--" marker seen. */ + break; else if (c == 1) - /* An argument not starting with a dash. */ - handle_non_switch_argument (optarg, env); + /* 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; + /* 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; + 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 (); + switch (cs->type) + { + default: + abort (); - case ignore: - break; + case ignore: + break; - case flag: - case flag_off: - if (doit) - *(int *) cs->value_ptr = cs->type == flag; - break; + case flag: + case flag_off: + if (doit) + *(int *) cs->value_ptr = cs->type == flag; + break; - case string: - case filename: - if (!doit) - break; + case string: + case filename: + if (!doit) + break; - if (optarg == 0) - optarg = xstrdup (cs->noarg_value); + if (optarg == 0) + optarg = xstrdup (cs->noarg_value); else if (*optarg == '\0') { char opt[2] = "c"; @@ -2624,33 +2624,33 @@ decode_switches (int argc, char **argv, int env) bad = 1; } - sl = *(struct stringlist **) cs->value_ptr; - if (sl == 0) - { - sl = xmalloc (sizeof (struct stringlist)); - sl->max = 5; - sl->idx = 0; - sl->list = xmalloc (5 * sizeof (char *)); - *(struct stringlist **) cs->value_ptr = sl; - } - else if (sl->idx == sl->max - 1) - { - sl->max += 5; + sl = *(struct stringlist **) cs->value_ptr; + if (sl == 0) + { + sl = xmalloc (sizeof (struct stringlist)); + sl->max = 5; + sl->idx = 0; + sl->list = xmalloc (5 * sizeof (char *)); + *(struct stringlist **) cs->value_ptr = sl; + } + else if (sl->idx == sl->max - 1) + { + sl->max += 5; /* MSVC erroneously warns without a cast here. */ - sl->list = xrealloc ((void *)sl->list, + sl->list = xrealloc ((void *)sl->list, sl->max * sizeof (char *)); - } + } if (cs->type == filename) sl->list[sl->idx++] = expand_command_line_file (optarg); else sl->list[sl->idx++] = optarg; - sl->list[sl->idx] = 0; - break; + sl->list[sl->idx] = 0; + break; - case positive_int: + case positive_int: /* See if we have an option argument; if we do require that it's all digits, not something like "10foo". */ - if (optarg == 0 && argc > optind) + if (optarg == 0 && argc > optind) { const char *cp; for (cp=argv[optind]; ISDIGIT (cp[0]); ++cp) @@ -2659,50 +2659,50 @@ decode_switches (int argc, char **argv, int env) optarg = argv[optind++]; } - if (!doit) - break; + if (!doit) + break; - if (optarg != 0) - { - int i = atoi (optarg); + if (optarg != 0) + { + int i = atoi (optarg); const char *cp; /* Yes, I realize we're repeating this in some cases. */ for (cp = optarg; ISDIGIT (cp[0]); ++cp) ; - if (i < 1 || cp[0] != '\0') - { + if (i < 1 || cp[0] != '\0') + { 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; + 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++]; + 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); + if (doit) + *(double *) cs->value_ptr + = (optarg != 0 ? atof (optarg) + : *(double *) cs->noarg_value); - break; + break; #endif - } + } - /* We've found the switch. Stop looking. */ - break; - } + /* We've found the switch. Stop looking. */ + break; + } } /* There are no more options according to getting getopt, but there may @@ -2763,17 +2763,17 @@ decode_env_switches (char *envar, unsigned int len) while (*value != '\0') { if (*value == '\\' && value[1] != '\0') - ++value; /* Skip the backslash. */ + ++value; /* Skip the backslash. */ else if (isblank ((unsigned char)*value)) - { - /* End of the word. */ - *p++ = '\0'; - argv[++argc] = p; - do - ++value; - while (isblank ((unsigned char)*value)); - continue; - } + { + /* End of the word. */ + *p++ = '\0'; + argv[++argc] = p; + do + ++value; + while (isblank ((unsigned char)*value)); + continue; + } *p++ = *value++; } *p = '\0'; @@ -2802,7 +2802,7 @@ quote_for_env (char *out, const char *in) while (*in != '\0') { if (*in == '$') - *out++ = '$'; + *out++ = '$'; else if (isblank ((unsigned char)*in) || *in == '\\') *out++ = '\\'; *out++ = *in++; @@ -2840,105 +2840,105 @@ define_makeflags (int all, int makefile) }; struct flag *flags = 0; unsigned int flagslen = 0; -#define ADD_FLAG(ARG, LEN) \ - do { \ - struct flag *new = 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 \ - /* " -x foo", plus space to expand "foo". */ \ - flagslen += 1 + 1 + 1 + 1 + (3 * (LEN)); \ - if (!short_option (cs->c)) \ +#define ADD_FLAG(ARG, LEN) \ + do { \ + struct flag *new = 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 \ + /* " -x foo", plus space to expand "foo". */ \ + flagslen += 1 + 1 + 1 + 1 + (3 * (LEN)); \ + if (!short_option (cs->c)) \ /* This switch has no single-letter version, so we use the long. */ \ - flagslen += 2 + strlen (cs->long_name); \ + 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) - { - case ignore: - break; + { + 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 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->noarg_value != 0 - && (*(unsigned int *) cs->value_ptr == - *(unsigned int *) cs->noarg_value)) - ADD_FLAG ("", 0); /* Optional value omitted; see below. */ - else - { - char *buf = alloca (30); - sprintf (buf, "%u", *(unsigned int *) cs->value_ptr); - ADD_FLAG (buf, strlen (buf)); - } - } - 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->noarg_value != 0 + && (*(unsigned int *) cs->value_ptr == + *(unsigned int *) cs->noarg_value)) + ADD_FLAG ("", 0); /* Optional value omitted; see below. */ + else + { + char *buf = 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 = alloca (100); - sprintf (buf, "%g", *(double *) cs->value_ptr); - ADD_FLAG (buf, strlen (buf)); - } - } - break; + 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 = alloca (100); + sprintf (buf, "%g", *(double *) cs->value_ptr); + ADD_FLAG (buf, strlen (buf)); + } + } + break; #endif - case filename: - 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). */ - unsigned int i = sl->idx; - while (i-- > 0) - ADD_FLAG (sl->list[i], strlen (sl->list[i])); - } - } - break; + case filename: + 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). */ + unsigned int i = sl->idx; + while (i-- > 0) + ADD_FLAG (sl->list[i], strlen (sl->list[i])); + } + } + break; - default: - abort (); - } + default: + abort (); + } /* Four more for the possible " -- ". */ flagslen += 4 + CSTRLEN (posixref) + 1 + CSTRLEN (evalref) + 1; -#undef ADD_FLAG +#undef ADD_FLAG /* Construct the value in FLAGSTRING. We allocate enough space for a preceding dash and trailing null. */ @@ -2951,43 +2951,43 @@ define_makeflags (int all, int makefile) { /* Add the flag letter or name to the string. */ if (short_option (flags->cs->c)) - *p++ = flags->cs->c; + *p++ = flags->cs->c; else - { + { if (*p != '-') { *p++ = ' '; *p++ = '-'; } - *p++ = '-'; - strcpy (p, flags->cs->long_name); - p += strlen (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_for_env (p, flags->arg); - } - ++words; - /* Write a following space and dash, for the next flag. */ - *p++ = ' '; - *p++ = '-'; - } + { + /* 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_for_env (p, flags->arg); + } + ++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++ = '-'; - } + { + ++words; + /* Long options must each go in their own word, + so we write the following space and dash. */ + *p++ = ' '; + *p++ = '-'; + } flags = flags->next; } @@ -3015,8 +3015,8 @@ define_makeflags (int all, int makefile) if (eval_strings) { if (p == &flagstring[1]) - /* No flags written, so elide the leading dash already written. */ - p = flagstring; + /* No flags written, so elide the leading dash already written. */ + p = flagstring; else *p++ = ' '; memcpy (p, evalref, CSTRLEN (evalref)); @@ -3026,36 +3026,36 @@ define_makeflags (int all, int makefile) if (all && command_variables != 0) { /* Now write a reference to $(MAKEOVERRIDES), which contains all the - command-line variable definitions. */ + command-line variable definitions. */ if (p == &flagstring[1]) - /* No flags written, so elide the leading dash already written. */ - p = flagstring; + /* 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++ = ' '; - } + { + /* 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) - { - memcpy (p, posixref, CSTRLEN (posixref)); - p += CSTRLEN (posixref); - } + { + memcpy (p, posixref, CSTRLEN (posixref)); + p += CSTRLEN (posixref); + } else - { - memcpy (p, ref, CSTRLEN (ref)); - p += CSTRLEN (ref); - } + { + memcpy (p, ref, CSTRLEN (ref)); + p += CSTRLEN (ref); + } } else if (p == &flagstring[1]) { @@ -3248,12 +3248,12 @@ die (int status) dying = 1; if (print_version_flag) - print_version (); + print_version (); /* Wait for children to die. */ err = (status != 0); while (job_slots_used > 0) - reap_children (1, err); + reap_children (1, err); /* Let the remote job module clean up its state. */ remote_cleanup (); @@ -3262,16 +3262,16 @@ die (int status) remove_intermediates (0); if (print_data_base_flag) - print_data_base (); + print_data_base (); verify_file_data_base (); clean_jobserver (status); /* 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 + 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) { diff --git a/make.h b/make.h index a1b34f33..7bde58e0 100644 --- a/make.h +++ b/make.h @@ -476,9 +476,9 @@ int strcache_setbufsize (unsigned int size); int guile_gmake_setup (const struct floc *flocp); #endif -/* Loadable object support */ +/* Loadable object support. Sets to the strcached name of the loaded file. */ typedef int (*load_func_t)(const struct floc *flocp); -int load_file (const struct floc *flocp, const char *filename, int noerror); +int load_file (const struct floc *flocp, const char **filename, int noerror); #ifdef HAVE_VFORK_H # include diff --git a/read.c b/read.c index 912ca71c..98361c88 100644 --- a/read.c +++ b/read.c @@ -84,12 +84,12 @@ enum make_word_type struct conditionals { - unsigned int if_cmds; /* Depth of conditional nesting. */ - unsigned int allocated; /* Elts allocated in following arrays. */ - char *ignoring; /* Are we ignoring or interpreting? + unsigned int if_cmds; /* Depth of conditional nesting. */ + unsigned int allocated; /* Elts allocated in following arrays. */ + char *ignoring; /* Are we ignoring or interpreting? 0=interpreting, 1=not yet interpreted, 2=already interpreted */ - char *seen_else; /* Have we already seen an 'else'? */ + char *seen_else; /* Have we already seen an 'else'? */ }; static struct conditionals toplevel_conditionals; @@ -127,9 +127,9 @@ static unsigned int max_incl_len; const struct floc *reading_file = 0; -/* The chain of makefiles read by read_makefile. */ +/* The chain of files read by read_all_makefiles. */ -static struct dep *read_makefiles = 0; +static struct dep *read_files = 0; static int eval_makefile (const char *filename, int flags); static void eval (struct ebuffer *buffer, int flags); @@ -160,10 +160,10 @@ static char *unescape_char (char *string, int c); /* Compare a word, both length and contents. P must point to the word to be tested, and WLEN must be the length. */ -#define word1eq(s) (wlen == CSTRLEN (s) && strneq (s, p, CSTRLEN (s))) +#define word1eq(s) (wlen == CSTRLEN (s) && strneq (s, p, CSTRLEN (s))) -/* Read in all the makefiles and return the chain of their names. */ +/* Read in all the makefiles and return a chain of targets to rebuild. */ struct dep * read_all_makefiles (const char **makefiles) @@ -202,9 +202,9 @@ read_all_makefiles (const char **makefiles) while ((name = find_next_token ((const char **)&p, &length)) != 0) { - if (*p != '\0') - *p++ = '\0'; - eval_makefile (name, RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE); + if (*p != '\0') + *p++ = '\0'; + eval_makefile (name, RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE); } free (value); @@ -215,21 +215,21 @@ read_all_makefiles (const char **makefiles) if (makefiles != 0) while (*makefiles != 0) { - struct dep *tail = read_makefiles; - register struct dep *d; + struct dep *tail = read_files; + struct dep *d; - if (! eval_makefile (*makefiles, 0)) - perror_with_name ("", *makefiles); + if (! eval_makefile (*makefiles, 0)) + perror_with_name ("", *makefiles); - /* Find the right element of read_makefiles. */ - d = read_makefiles; - while (d->next != tail) - d = d->next; + /* Find the first element eval_makefile() added to read_files. */ + d = read_files; + while (d->next != tail) + d = d->next; - /* Use the storage read_makefile allocates. */ - *makefiles = dep_name (d); - ++num_makefiles; - ++makefiles; + /* Reuse the storage allocated for the read_file. */ + *makefiles = dep_name (d); + ++num_makefiles; + ++makefiles; } /* If there were no -f switches, try the default names. */ @@ -238,52 +238,52 @@ read_all_makefiles (const char **makefiles) { static char *default_makefiles[] = #ifdef VMS - /* all lower case since readdir() (the vms version) 'lowercasifies' */ - { "makefile.vms", "gnumakefile.", "makefile.", 0 }; + /* all lower case since readdir() (the vms version) 'lowercasifies' */ + { "makefile.vms", "gnumakefile.", "makefile.", 0 }; #else #ifdef _AMIGA - { "GNUmakefile", "Makefile", "SMakefile", 0 }; + { "GNUmakefile", "Makefile", "SMakefile", 0 }; #else /* !Amiga && !VMS */ - { "GNUmakefile", "makefile", "Makefile", 0 }; + { "GNUmakefile", "makefile", "Makefile", 0 }; #endif /* AMIGA */ #endif /* VMS */ register char **p = default_makefiles; while (*p != 0 && !file_exists_p (*p)) - ++p; + ++p; if (*p != 0) - { - if (! eval_makefile (*p, 0)) - perror_with_name ("", *p); - } + { + if (! eval_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 = alloc_dep (); - d->file = enter_file (strcache_add (*p)); - d->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; - } + { + /* No default makefile was found. Add the default makefiles to the + 'read_files' chain so they will be updated if possible. */ + struct dep *tail = read_files; + /* 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 = alloc_dep (); + d->file = enter_file (strcache_add (*p)); + d->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_files = d; + else + tail->next = d; + tail = d; + } + if (tail != 0) + tail->next = 0; + } } - return read_makefiles; + return read_files; } /* Install a new conditional and return the previous one. */ @@ -330,13 +330,13 @@ eval_makefile (const char *filename, int flags) { printf (_("Reading makefile '%s'"), filename); if (flags & RM_NO_DEFAULT_GOAL) - printf (_(" (no default goal)")); + printf (_(" (no default goal)")); if (flags & RM_INCLUDED) - printf (_(" (search path)")); + printf (_(" (search path)")); if (flags & RM_DONTCARE) - printf (_(" (don't care)")); + printf (_(" (don't care)")); if (flags & RM_NO_TILDE) - printf (_(" (no ~ expansion)")); + printf (_(" (no ~ expansion)")); puts ("..."); } @@ -348,7 +348,7 @@ eval_makefile (const char *filename, int flags) { expanded = tilde_expand (filename); if (expanded != 0) - filename = expanded; + filename = expanded; } ebuf.fp = fopen (filename, "r"); @@ -362,16 +362,16 @@ eval_makefile (const char *filename, int flags) { unsigned int i; for (i = 0; include_directories[i] != 0; ++i) - { - const char *included = concat (3, include_directories[i], + { + const char *included = concat (3, include_directories[i], "/", filename); - ebuf.fp = fopen (included, "r"); - if (ebuf.fp) + ebuf.fp = fopen (included, "r"); + if (ebuf.fp) { filename = included; break; } - } + } } /* Now we have the final name for this makefile. Enter it into @@ -380,8 +380,8 @@ eval_makefile (const char *filename, int flags) /* Add FILENAME to the chain of read makefiles. */ deps = alloc_dep (); - deps->next = read_makefiles; - read_makefiles = deps; + deps->next = read_files; + read_files = deps; deps->file = lookup_file (filename); if (deps->file == 0) deps->file = enter_file (filename); @@ -398,8 +398,8 @@ eval_makefile (const char *filename, int flags) if (ebuf.fp == 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. */ + attempt, rather from FILENAME itself. Restore it in case the + caller wants to use it in a message. */ errno = makefile_errno; return 0; } @@ -556,7 +556,7 @@ eval (struct ebuffer *ebuf, int set_default) unsigned int commands_idx = 0; unsigned int cmds_started, tgts_started; int ignoring = 0, in_ignored_define = 0; - int no_targets = 0; /* Set when reading a rule without targets. */ + int no_targets = 0; /* Set when reading a rule without targets. */ struct nameseq *filenames = 0; char *depstr = 0; long nlines = 0; @@ -567,18 +567,18 @@ eval (struct ebuffer *ebuf, int set_default) struct floc *fstart; struct floc fi; -#define record_waiting_files() \ - do \ - { \ - if (filenames != 0) \ +#define record_waiting_files() \ + do \ + { \ + if (filenames != 0) \ { \ - fi.lineno = tgts_started; \ - record_files (filenames, pattern, pattern_percent, depstr, \ + fi.lineno = tgts_started; \ + record_files (filenames, pattern, pattern_percent, depstr, \ cmds_started, commands, commands_idx, two_colon, \ prefix, &fi); \ - filenames = 0; \ + filenames = 0; \ } \ - commands_idx = 0; \ + commands_idx = 0; \ no_targets = 0; \ pattern = 0; \ } while (0) @@ -642,52 +642,52 @@ eval (struct ebuffer *ebuf, int set_default) linelen = strlen (line); /* Check for a shell command line first. - If it is not one, we can stop treating cmd_prefix specially. */ + If it is not one, we can stop treating cmd_prefix specially. */ if (line[0] == cmd_prefix) - { - if (no_targets) - /* Ignore the commands in a rule with no targets. */ - continue; + { + 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 recipe prefix. - SunOS 4 make appears to behave this way. */ + /* If there is no preceding rule line, don't treat this line + as a command, even though it begins with a recipe prefix. + 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; + if (filenames != 0) + { + if (ignoring) + /* Yep, this is a shell command, and we don't care. */ + continue; - if (commands_idx == 0) - cmds_started = ebuf->floc.lineno; + if (commands_idx == 0) + cmds_started = ebuf->floc.lineno; - /* Append this command line to the line being accumulated. + /* Append this command line to the line being accumulated. Skip the initial command prefix character. */ - if (linelen + commands_idx > commands_len) - { - commands_len = (linelen + commands_idx) * 2; - commands = xrealloc (commands, commands_len); - } - memcpy (&commands[commands_idx], line + 1, linelen - 1); - commands_idx += linelen - 1; - commands[commands_idx++] = '\n'; - continue; - } - } + if (linelen + commands_idx > commands_len) + { + commands_len = (linelen + commands_idx) * 2; + commands = xrealloc (commands, commands_len); + } + memcpy (&commands[commands_idx], line + 1, linelen - 1); + commands_idx += linelen - 1; + commands[commands_idx++] = '\n'; + continue; + } + } /* This line is not a shell command line. Don't worry about whitespace. Get more space if we need it; we don't need to preserve the current contents of the buffer. */ if (collapsed_length < linelen+1) - { - collapsed_length = linelen+1; + { + collapsed_length = linelen+1; if (collapsed) free (collapsed); /* Don't need xrealloc: we don't need to preserve the content. */ - collapsed = xmalloc (collapsed_length); - } + collapsed = xmalloc (collapsed_length); + } strcpy (collapsed, line); /* Collapse continuation lines. */ collapse_continuations (collapsed); @@ -710,7 +710,7 @@ eval (struct ebuffer *ebuf, int set_default) record_waiting_files (); /* If we're ignoring then we're done now. */ - if (ignoring) + if (ignoring) { if (vmod.define_v) in_ignored_define = 1; @@ -740,7 +740,7 @@ eval (struct ebuffer *ebuf, int set_default) /* If this line is completely empty, ignore it. */ if (*p == '\0') - continue; + continue; p2 = end_of_token (p); wlen = p2 - p; @@ -748,13 +748,13 @@ eval (struct ebuffer *ebuf, int set_default) /* If we're in an ignored define, skip this line (but maybe get out). */ if (in_ignored_define) - { + { /* See if this is an endef line (plus optional comment). */ if (word1eq ("endef") && (*p2 == '\0' || *p2 == '#')) in_ignored_define = 0; - continue; - } + continue; + } /* Check for conditional state changes. */ { @@ -771,19 +771,19 @@ eval (struct ebuffer *ebuf, int set_default) /* Nothing to see here... move along. */ if (ignoring) - continue; + continue; /* Manage the "export" keyword used outside of variable assignment as well as "unexport". */ if (word1eq ("export") || word1eq ("unexport")) - { + { int exporting = *p == 'u' ? 0 : 1; /* Export/unexport ends the previous rule. */ record_waiting_files (); /* (un)export by itself causes everything to be (un)exported. */ - if (*p2 == '\0') + if (*p2 == '\0') export_all_variables = exporting; else { @@ -807,137 +807,145 @@ eval (struct ebuffer *ebuf, int set_default) free (ap); } continue; - } + } /* Handle the special syntax for vpath. */ if (word1eq ("vpath")) - { + { const char *cp; - char *vpat; - unsigned int l; + char *vpat; + unsigned int l; /* vpath ends the previous rule. */ record_waiting_files (); - cp = variable_expand (p2); - p = find_next_token (&cp, &l); - if (p != 0) - { - vpat = xstrndup (p, l); - p = find_next_token (&cp, &l); - /* No searchpath means remove all previous - selective VPATH's with the same pattern. */ - } - else - /* No pattern means remove all previous selective VPATH's. */ - vpat = 0; - construct_vpath_list (vpat, p); - if (vpat != 0) - free (vpat); + cp = variable_expand (p2); + p = find_next_token (&cp, &l); + if (p != 0) + { + vpat = xstrndup (p, l); + p = find_next_token (&cp, &l); + /* No searchpath means remove all previous + selective VPATH's with the same pattern. */ + } + else + /* No pattern means remove all previous selective VPATH's. */ + vpat = 0; + construct_vpath_list (vpat, p); + if (vpat != 0) + free (vpat); continue; - } + } /* Handle include and variants. */ if (word1eq ("include") || word1eq ("-include") || word1eq ("sinclude")) - { - /* We have found an 'include' line specifying a nested - makefile to be read at this point. */ - struct conditionals *save; + { + /* We have found an 'include' line specifying a nested + makefile to be read at this point. */ + struct conditionals *save; struct conditionals 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'); + 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'); /* Include ends the previous rule. */ record_waiting_files (); - p = allocated_variable_expand (p2); + p = allocated_variable_expand (p2); /* If no filenames, it's a no-op. */ - if (*p == '\0') + if (*p == '\0') { free (p); continue; } - /* Parse the list of file names. Don't expand archive references! */ - p2 = p; - files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, + /* Parse the list of file names. Don't expand archive references! */ + p2 = p; + files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, PARSEFS_NOAR); - free (p); + free (p); - /* Save the state of conditionals and start - the included makefile with a clean slate. */ - save = install_conditionals (&new_conditionals); + /* Save the state of conditionals and start + the included makefile with a clean slate. */ + save = install_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 (); + /* 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; - const char *name = files->name; + /* Read each included makefile. */ + while (files != 0) + { + struct nameseq *next = files->next; + const char *name = files->name; int r; - free_ns (files); - files = next; + free_ns (files); + files = next; r = eval_makefile (name, (RM_INCLUDED | RM_NO_TILDE | (noerror ? RM_DONTCARE : 0) | (set_default ? 0 : RM_NO_DEFAULT_GOAL))); - if (!r && !noerror) + if (!r && !noerror) error (fstart, "%s: %s", name, strerror (errno)); - } + } - /* Restore conditional state. */ - restore_conditionals (save); + /* Restore conditional state. */ + restore_conditionals (save); continue; - } + } /* Handle the load operations. */ if (word1eq ("load") || word1eq ("-load")) { - /* A 'load' line specifies a dynamic object to load. */ - struct nameseq *files; + /* A 'load' line specifies a dynamic object to load. */ + struct nameseq *files; int noerror = (p[0] == '-'); /* Load ends the previous rule. */ record_waiting_files (); - p = allocated_variable_expand (p2); + p = allocated_variable_expand (p2); /* If no filenames, it's a no-op. */ - if (*p == '\0') + if (*p == '\0') { free (p); continue; } - /* Parse the list of file names. + /* Parse the list of file names. Don't expand archive references or strip "./" */ - p2 = p; - files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, - PARSEFS_NOAR|PARSEFS_NOSTRIP); - free (p); + p2 = p; + files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, + PARSEFS_NOAR); + free (p); - /* Load each file. */ - while (files != 0) - { - struct nameseq *next = files->next; - const char *name = files->name; + /* Load each file and add it to the list "to be rebuilt". */ + while (files != 0) + { + struct nameseq *next = files->next; + const char *name = files->name; + struct dep *deps; - free_ns (files); - files = next; + free_ns (files); + files = next; - if (! load_file (&ebuf->floc, name, noerror) && ! noerror) + if (! load_file (&ebuf->floc, &name, noerror) && ! noerror) fatal (&ebuf->floc, _("%s: failed to load"), name); - } + + deps = alloc_dep (); + deps->next = read_files; + read_files = deps; + deps->file = lookup_file (name); + if (deps->file == 0) + deps->file = enter_file (name); + } continue; } @@ -1343,8 +1351,8 @@ eval (struct ebuffer *ebuf, int set_default) } /* 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 now the last rule we read, so following spurious + commands are properly diagnosed. */ record_waiting_files (); } @@ -1533,8 +1541,8 @@ conditional_line (char *line, int len, const struct floc *flocp) unsigned int o; /* Compare a word, both length and contents. */ -#define word1eq(s) (len == CSTRLEN (s) && strneq (s, line, CSTRLEN (s))) -#define chkword(s, t) if (word1eq (s)) { cmdtype = (t); cmdname = (s); } +#define word1eq(s) (len == CSTRLEN (s) && strneq (s, line, CSTRLEN (s))) +#define chkword(s, t) if (word1eq (s)) { cmdtype = (t); cmdname = (s); } /* Make sure this line is a conditional. */ chkword ("ifdef", c_ifdef) @@ -1555,10 +1563,10 @@ conditional_line (char *line, int len, const struct floc *flocp) if (cmdtype == c_endif) { if (*line != '\0') - EXTRANEOUS (); + EXTRANEOUS (); if (!conditionals->if_cmds) - fatal (flocp, _("extraneous '%s'"), cmdname); + fatal (flocp, _("extraneous '%s'"), cmdname); --conditionals->if_cmds; @@ -1572,7 +1580,7 @@ conditional_line (char *line, int len, const struct floc *flocp) const char *p; if (!conditionals->if_cmds) - fatal (flocp, _("extraneous '%s'"), cmdname); + fatal (flocp, _("extraneous '%s'"), cmdname); o = conditionals->if_cmds - 1; @@ -1610,7 +1618,7 @@ conditional_line (char *line, int len, const struct floc *flocp) /* If it's 'else' or 'endif' or an illegal conditional, fail. */ if (word1eq ("else") || word1eq ("endif") || conditional_line (line, len, flocp) < 0) - EXTRANEOUS (); + EXTRANEOUS (); else { /* conditional_line() created a new level of conditional. @@ -1647,11 +1655,11 @@ conditional_line (char *line, int len, const struct floc *flocp) for (i = 0; i < o; ++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[o] = 1; - return 1; + /* 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[o] = 1; + return 1; } if (cmdtype == c_ifdef || cmdtype == c_ifndef) @@ -1669,7 +1677,7 @@ conditional_line (char *line, int len, const struct floc *flocp) i = p - var; p = next_token (p); if (*p != '\0') - return -1; + return -1; var[i] = '\0'; v = lookup_variable (var, i); @@ -1687,87 +1695,87 @@ conditional_line (char *line, int len, const struct floc *flocp) char termin = *line == '(' ? ',' : *line; if (termin != ',' && termin != '"' && termin != '\'') - return -1; + return -1; s1 = ++line; /* Find the end of the first string. */ if (termin == ',') - { - int count = 0; - for (; *line != '\0'; ++line) - if (*line == '(') - ++count; - else if (*line == ')') - --count; - else if (*line == ',' && count <= 0) - break; - } + { + 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; + while (*line != '\0' && *line != termin) + ++line; if (*line == '\0') - return -1; + return -1; if (termin == ',') - { - /* Strip blanks after the first string. */ - char *p = line++; - while (isblank ((unsigned char)p[-1])) - --p; - *p = '\0'; - } + { + /* Strip blanks after the first string. */ + char *p = line++; + while (isblank ((unsigned char)p[-1])) + --p; + *p = '\0'; + } else - *line++ = '\0'; + *line++ = '\0'; s2 = variable_expand (s1); /* We must allocate a new copy of the expanded string because - variable_expand re-uses the same buffer. */ + variable_expand re-uses the same buffer. */ l = strlen (s2); s1 = alloca (l + 1); memcpy (s1, s2, l + 1); if (termin != ',') - /* Find the start of the second string. */ - line = next_token (line); + /* Find the start of the second string. */ + line = next_token (line); termin = termin == ',' ? ')' : *line; if (termin != ')' && termin != '"' && termin != '\'') - return -1; + return -1; /* Find the end of the second string. */ if (termin == ')') - { - 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; - } - } - } + { + 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; - } + { + ++line; + s2 = line; + while (*line != '\0' && *line != termin) + ++line; + } if (*line == '\0') - return -1; + return -1; *line = '\0'; line = next_token (++line); if (*line != '\0') - EXTRANEOUS (); + EXTRANEOUS (); s2 = variable_expand (s2); conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq)); @@ -1994,8 +2002,8 @@ record_files (struct nameseq *filenames, const char *pattern, if (implicit_percent == 0) fatal (flocp, _("mixed implicit and normal rules")); - targets[c] = name; - target_pats[c] = implicit_percent; + targets[c] = name; + target_pats[c] = implicit_percent; ++c; nextf = filenames->next; @@ -2053,71 +2061,71 @@ record_files (struct nameseq *filenames, const char *pattern, /* Find or create an entry in the file database for this target. */ if (!two_colon) - { - /* Single-colon. Combine this rule with the file's existing record, - if any. */ - f = enter_file (strcache_add (name)); - if (f->double_colon) - fatal (flocp, + { + /* Single-colon. Combine this rule with the file's existing record, + if any. */ + f = enter_file (strcache_add (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, + /* 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, + /* 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 recipe for target '%s'"), f->name); - error (&f->cmds->fileinfo, + error (&f->cmds->fileinfo, _("warning: ignoring old recipe for target '%s'"), f->name); - } + } - /* 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 .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) - { + /* Defining .SUFFIXES with no dependencies clears out the list of + suffixes. */ + if (f == suffix_file && this == 0) + { free_dep_chain (f->deps); - f->deps = 0; - } - } + f->deps = 0; + } + } else - { - /* Double-colon. Make a new record even if there already is one. */ - f = lookup_file (name); + { + /* Double-colon. Make a new record even if there already is 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, + /* 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 (strcache_add (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 = enter_file (strcache_add (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->cmds = cmds; - } + f->cmds = cmds; + } f->is_target = 1; @@ -2206,22 +2214,22 @@ find_char_unquote (char *string, int stop1, int stop2, int blank, while (1) { if (stop2 && blank) - while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2 - && ! isblank ((unsigned char) *p)) - ++p; + while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2 + && ! isblank ((unsigned char) *p)) + ++p; else if (stop2) - while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2) - ++p; + while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2) + ++p; else if (blank) - while (*p != '\0' && *p != ignorevars && *p != stop1 - && ! isblank ((unsigned char) *p)) - ++p; + while (*p != '\0' && *p != ignorevars && *p != stop1 + && ! isblank ((unsigned char) *p)) + ++p; else - while (*p != '\0' && *p != ignorevars && *p != stop1) - ++p; + while (*p != '\0' && *p != ignorevars && *p != stop1) + ++p; if (*p == '\0') - break; + break; /* If we stopped due to a variable reference, skip over its contents. */ if (*p == ignorevars) @@ -2255,29 +2263,29 @@ find_char_unquote (char *string, int stop1, int stop2, int blank, } if (p > string && p[-1] == '\\') - { - /* Search for more backslashes. */ - 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. */ - memmove (&p[i], &p[i/2], (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; + { + /* Search for more backslashes. */ + 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. */ + memmove (&p[i], &p[i/2], (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. */ - } + /* The STOPCHAR was quoted by a backslash. Look for another. */ + } else - /* No backslash in sight. */ - return p; + /* No backslash in sight. */ + return p; } /* Never hit a STOPCHAR or blank (with BLANK nonzero). */ @@ -2305,17 +2313,17 @@ unescape_char (char *string, int c) l = e - s; if (*e != c || l%2 == 0) - { - /* It's not; just take it all without unescaping. */ - memcpy (p, s, l); - p += l; - } + { + /* It's not; just take it all without unescaping. */ + memcpy (p, s, l); + p += l; + } else if (l > 1) { /* It is, and there's >1 backslash. Take half of them. */ l /= 2; memcpy (p, s, l); - p += l; + p += l; } s = e; } @@ -2496,17 +2504,17 @@ readline (struct ebuffer *ebuf) 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! (xmkmf 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 (&ebuf->floc, + { + /* 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! (xmkmf 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 (&ebuf->floc, _("warning: NUL character seen; rest of line ignored")); - p[0] = '\n'; - len = 1; - } + p[0] = '\n'; + len = 1; + } /* Jump past the text we just read. */ p += len; @@ -2531,17 +2539,17 @@ readline (struct ebuffer *ebuf) backslash = 0; for (p2 = p - 2; p2 >= start; --p2) - { - if (*p2 != '\\') - break; + { + if (*p2 != '\\') + break; backslash = !backslash; - } + } if (!backslash) - { - p[-1] = '\0'; - break; - } + { + p[-1] = '\0'; + break; + } /* It was a backslash/newline combo. If we have more space, read another line. */ @@ -2683,14 +2691,14 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length) case ':': #ifdef HAVE_DOS_PATHS - /* 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 ((unsigned char)p[-2]) - && (p - beg == 2 || p[-3] == '('))) + /* 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 ((unsigned char)p[-2]) + && (p - beg == 2 || p[-3] == '('))) #endif - goto done_word; + goto done_word; case '$': c = *(p++); @@ -2764,7 +2772,7 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length) void construct_include_path (const char **arg_dirs) { -#ifdef VAXC /* just don't ask ... */ +#ifdef VAXC /* just don't ask ... */ stat_t stbuf; #else struct stat stbuf; @@ -2795,19 +2803,19 @@ construct_include_path (const char **arg_dirs) if (arg_dirs) while (*arg_dirs != 0) { - const char *dir = *(arg_dirs++); + const char *dir = *(arg_dirs++); char *expanded = 0; int e; - if (dir[0] == '~') - { - expanded = tilde_expand (dir); - if (expanded != 0) - dir = expanded; - } + if (dir[0] == '~') + { + expanded = tilde_expand (dir); + if (expanded != 0) + dir = expanded; + } EINTRLOOP (e, stat (dir, &stbuf)); - if (e == 0 && S_ISDIR (stbuf.st_mode)) + if (e == 0 && S_ISDIR (stbuf.st_mode)) { unsigned int len = strlen (dir); /* If dir name is written with trailing slashes, discard them. */ @@ -2818,8 +2826,8 @@ construct_include_path (const char **arg_dirs) dirs[idx++] = strcache_add_len (dir, len); } - if (expanded) - free (expanded); + if (expanded) + free (expanded); } /* Now add the standard default dirs at the end. */ @@ -2833,10 +2841,10 @@ construct_include_path (const char **arg_dirs) if (djdir) { unsigned int len = strlen (djdir->value) + 8; - char *defdir = alloca (len + 1); + char *defdir = alloca (len + 1); - strcat (strcpy (defdir, djdir->value), "/include"); - dirs[idx++] = strcache_add (defdir); + strcat (strcpy (defdir, djdir->value), "/include"); + dirs[idx++] = strcache_add (defdir); if (len > max_incl_len) max_incl_len = len; @@ -2886,42 +2894,42 @@ tilde_expand (const char *name) int is_variable; { - /* Turn off --warn-undefined-variables while we expand HOME. */ - int save = warn_undefined_variables_flag; - warn_undefined_variables_flag = 0; + /* 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)"); + home_dir = allocated_variable_expand ("$(HOME)"); - warn_undefined_variables_flag = save; + warn_undefined_variables_flag = save; } is_variable = home_dir[0] != '\0'; if (!is_variable) - { - free (home_dir); - home_dir = getenv ("HOME"); - } + { + 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; - } - } + { + 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 = xstrdup (concat (2, home_dir, name + 1)); - if (is_variable) - free (home_dir); - return new; - } + { + char *new = xstrdup (concat (2, home_dir, name + 1)); + if (is_variable) + free (home_dir); + return new; + } } # if !defined(_AMIGA) && !defined(WINDOWS32) else @@ -2929,17 +2937,17 @@ tilde_expand (const char *name) struct passwd *pwent; char *userend = strchr (name + 1, '/'); if (userend != 0) - *userend = '\0'; + *userend = '\0'; pwent = getpwnam (name + 1); if (pwent != 0) - { - if (userend == 0) - return xstrdup (pwent->pw_dir); - else - return xstrdup (concat (3, pwent->pw_dir, "/", userend + 1)); - } + { + if (userend == 0) + return xstrdup (pwent->pw_dir); + else + return xstrdup (concat (3, pwent->pw_dir, "/", userend + 1)); + } else if (userend != 0) - *userend = '/'; + *userend = '/'; } # endif /* !AMIGA && !WINDOWS32 */ #endif /* !VMS */ @@ -3037,22 +3045,22 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar, /* Skip whitespace; at the end of the string or STOPCHAR we're done. */ p = next_token (p); if (*p == '\0' || *p == stopchar) - break; + break; /* There are names left, so find the end of the next name. Throughout this iteration S points to the start. */ s = p; p = find_char_unquote (p, stopchar, VMS_COMMA, 1, 0); #ifdef VMS - /* convert comma separated list to space separated */ + /* convert comma separated list to space separated */ if (p && *p == ',') - *p =' '; + *p =' '; #endif #ifdef _AMIGA if (stopchar == ':' && p && *p == ':' && !(isspace ((unsigned char)p[1]) || !p[1] || isspace ((unsigned char)p[-1]))) - p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1, 0); + p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1, 0); #endif #ifdef HAVE_DOS_PATHS /* For DOS paths, skip a "C:\..." or a "C:/..." until we find the @@ -3065,30 +3073,30 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar, p = find_char_unquote (p + 1, stopchar, VMS_COMMA, 1, 0); #endif if (p == 0) - p = s + strlen (s); + p = s + strlen (s); /* Strip leading "this directory" references. */ if (! (flags & PARSEFS_NOSTRIP)) #ifdef VMS - /* Skip leading '[]'s. */ - while (p - s > 2 && s[0] == '[' && s[1] == ']') + /* Skip leading '[]'s. */ + while (p - s > 2 && s[0] == '[' && s[1] == ']') #else - /* Skip leading './'s. */ - while (p - s > 2 && s[0] == '.' && s[1] == '/') + /* Skip leading './'s. */ + while (p - s > 2 && s[0] == '.' && s[1] == '/') #endif - { + { /* Skip "./" and all following slashes. */ - s += 2; - while (*s == '/') - ++s; - } + s += 2; + while (*s == '/') + ++s; + } /* Extract the filename just found, and skip it. Set NAME to the string, and NLEN to its length. */ if (s == p) { - /* The name was stripped to empty ("./"). */ + /* The name was stripped to empty ("./"). */ #if defined(VMS) continue; #elif defined(_AMIGA) @@ -3103,19 +3111,19 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar, #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. * xstrdup called because S may be read-only string constant. */ - char *n = tp; - while (s < p) - { - if (s[0] == '\\' && s[1] == ':') + char *n = tp; + while (s < p) + { + if (s[0] == '\\' && s[1] == ':') ++s; - *(n++) = *(s++); - } + *(n++) = *(s++); + } n[0] = '\0'; nlen = strlen (tp); #else @@ -3221,21 +3229,21 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar, /* Expand tilde if applicable. */ if (tmpbuf[0] == '~') - { - tildep = tilde_expand (tmpbuf); - if (tildep != 0) + { + tildep = tilde_expand (tmpbuf); + if (tildep != 0) name = tildep; - } + } #ifndef NO_ARCHIVES /* If 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. */ if (! (flags & PARSEFS_NOAR) && ar_name (name)) - { - ar_parse_name (name, &arname, &memname); - name = arname; - } + { + ar_parse_name (name, &arname, &memname); + name = arname; + } #endif /* !NO_ARCHIVES */ /* glob() is expensive: don't call it unless we need to. */ diff --git a/tests/ChangeLog b/tests/ChangeLog index e7c9c833..2c1cb1b4 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2013-01-19 Paul Smith + + * scripts/features/load: Test loaded files with and without "./" + prefix. Add tests for automatically rebuilding loaded files if + they are out of date or non-existent. + 2013-01-13 Paul Smith * scripts/features/archives: Add a check targets that have parens, diff --git a/tests/scripts/features/load b/tests/scripts/features/load index 8117bbd9..dd3daf80 100644 --- a/tests/scripts/features/load +++ b/tests/scripts/features/load @@ -49,7 +49,7 @@ run_make_test('testload.so: testload.c ; @$(CC) -g -shared -fPIC -o $@ $<', # TEST 1 run_make_test(q! all: ; @echo $(func-a foo) $(func-b bar) -load ./testload.so +load testload.so !, '', "func-a\n"); @@ -64,19 +64,42 @@ load ./testload.so(explicit_setup) # TEST 3 # Verify the .LOADED variable run_make_test(q! -all: ; @echo $(filter ./testload.so,$(.LOADED)) $(func-a foo) $(func-b bar) -load ./testload.so(explicit_setup) +all: ; @echo $(filter testload.so,$(.LOADED)) $(func-a foo) $(func-b bar) +load testload.so(explicit_setup) !, - '', "./testload.so func-b\n"); + '', "testload.so func-b\n"); # TEST 4 # Check multiple loads run_make_test(q! -all: ; @echo $(filter ./testload.so,$(.LOADED)) $(func-a foo) $(func-b bar) +all: ; @echo $(filter testload.so,$(.LOADED)) $(func-a foo) $(func-b bar) load ./testload.so -load ./testload.so(explicit_setup) +load testload.so(explicit_setup) !, - '', "./testload.so func-a\n"); + '', "testload.so func-a\n"); + +# TEST 5 +# Check auto-rebuild of loaded file that's out of date +utouch(-10, 'testload.so'); +touch('testload.c'); + +run_make_test(q! +all: ; @echo $(func-a foo) $(func-b bar) +load ./testload.so +testload.so: testload.c ; @echo "rebuilding $@"; $(CC) -g -shared -fPIC -o $@ $< +!, + '', "rebuilding testload.so\nfunc-a\n"); + +# TEST 5 +# Check auto-rebuild of loaded file when it doesn't exist +unlink('testload.so'); + +run_make_test(q! +all: ; @echo $(func-a foo) $(func-b bar) +-load ./testload.so(explicit_setup) +%.so: %.c ; @echo "rebuilding $@"; $(CC) -g -shared -fPIC -o $@ $< +!, + '', "rebuilding testload.so\nfunc-b\n"); unlink(qw(testload.c testload.so)) unless $keep;