diff options
Diffstat (limited to 'commands.c')
-rw-r--r-- | commands.c | 178 |
1 files changed, 96 insertions, 82 deletions
@@ -1,7 +1,5 @@ /* Command processing for GNU Make. -Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, -1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, -2010 Free Software Foundation, Inc. +Copyright (C) 1988-2013 Free Software Foundation, Inc. This file is part of GNU Make. GNU Make is free software; you can redistribute it and/or modify it under the @@ -16,9 +14,11 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "make.h" -#include "dep.h" +#include <dlfcn.h> + +#include "makeint.h" #include "filedef.h" +#include "dep.h" #include "variable.h" #include "job.h" #include "commands.h" @@ -35,7 +35,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */ int remote_kill (int id, int sig); -#ifndef HAVE_UNISTD_H +#ifndef HAVE_UNISTD_H int getpid (); #endif @@ -70,9 +70,9 @@ set_file_variables (struct file *file) struct dep *d; const char *at, *percent, *star, *less; -#ifndef NO_ARCHIVES - /* If the target is an archive member `lib(member)', - then $@ is `lib' and $% is `member'. */ +#ifndef NO_ARCHIVES + /* If the target is an archive member 'lib(member)', + then $@ is 'lib' and $% is 'member'. */ if (ar_name (file->name)) { @@ -92,7 +92,7 @@ set_file_variables (struct file *file) percent = p; } else -#endif /* NO_ARCHIVES. */ +#endif /* NO_ARCHIVES. */ { at = file->name; percent = ""; @@ -102,35 +102,35 @@ set_file_variables (struct file *file) if (file->stem == 0) { /* In Unix make, $* is set to the target name with - any suffix in the .SUFFIXES list stripped off for - explicit rules. We store this in the `stem' member. */ + any suffix in the .SUFFIXES list stripped off for + explicit rules. We store this in the 'stem' member. */ const char *name; unsigned int len; -#ifndef NO_ARCHIVES +#ifndef NO_ARCHIVES if (ar_name (file->name)) - { - name = strchr (file->name, '(') + 1; - len = strlen (name) - 1; - } + { + name = strchr (file->name, '(') + 1; + len = strlen (name) - 1; + } else #endif - { - name = file->name; - len = strlen (name); - } + { + name = file->name; + len = strlen (name); + } for (d = enter_file (strcache_add (".SUFFIXES"))->deps; d ; d = d->next) - { - unsigned int slen = strlen (dep_name (d)); - if (len > slen && strneq (dep_name (d), name + (len - slen), slen)) - { - file->stem = strcache_add_len (name, len - slen); - break; - } - } + { + unsigned int slen = strlen (dep_name (d)); + if (len > slen && strneq (dep_name (d), name + (len - slen), slen)) + { + file->stem = strcache_add_len (name, len - slen); + break; + } + } if (d == 0) - file->stem = ""; + file->stem = ""; } star = file->stem; @@ -149,7 +149,7 @@ set_file_variables (struct file *file) In this case $< is the same as $@. */ less = at; -#define DEFINE_VARIABLE(name, len, value) \ +#define DEFINE_VARIABLE(name, len, value) \ (void) define_variable_for_file (name,len,value,o_automatic,0,file) /* Define the variables. */ @@ -202,13 +202,13 @@ set_file_variables (struct file *file) cp = plus_value; - qmark_len = plus_len + 1; /* Will be this or less. */ + qmark_len = plus_len + 1; /* Will be this or less. */ for (d = file->deps; d != 0; d = d->next) if (! d->ignore_mtime && ! d->need_2nd_expansion) { const char *c = dep_name (d); -#ifndef NO_ARCHIVES +#ifndef NO_ARCHIVES if (ar_name (c)) { c = strchr (c, '(') + 1; @@ -222,7 +222,7 @@ set_file_variables (struct file *file) cp += len; *cp++ = FILE_LIST_SEPARATOR; if (! (d->changed || always_make_flag)) - qmark_len -= len + 1; /* Don't space in $? for this one. */ + qmark_len -= len + 1; /* Don't space in $? for this one. */ } /* Kill the last space and define the variable. */ @@ -277,23 +277,23 @@ set_file_variables (struct file *file) continue; c = dep_name (d); -#ifndef NO_ARCHIVES +#ifndef NO_ARCHIVES if (ar_name (c)) - { - c = strchr (c, '(') + 1; - len = strlen (c) - 1; - } - else + { + c = strchr (c, '(') + 1; + len = strlen (c) - 1; + } + else #endif - len = strlen (c); + len = strlen (c); if (d->ignore_mtime) { memcpy (bp, c, len); - bp += len; - *bp++ = FILE_LIST_SEPARATOR; - } - else + bp += len; + *bp++ = FILE_LIST_SEPARATOR; + } + else { memcpy (cp, c, len); cp += len; @@ -321,11 +321,11 @@ set_file_variables (struct file *file) DEFINE_VARIABLE ("|", 1, bar_value); } -#undef DEFINE_VARIABLE +#undef DEFINE_VARIABLE } /* Chop CMDS up into individual command lines if necessary. - Also set the `lines_flags' and `any_recurse' members. */ + Also set the 'lines_flags' and 'any_recurse' members. */ void chop_commands (struct commands *cmds) @@ -402,6 +402,9 @@ chop_commands (struct commands *cmds) /* Finally, set the corresponding CMDS->lines_flags elements and the CMDS->any_recurse flag. */ + if (nlines > USHRT_MAX) + fatal (&cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines); + cmds->ncommand_lines = nlines; cmds->command_lines = lines; @@ -433,7 +436,7 @@ chop_commands (struct commands *cmds) flags |= COMMANDS_RECURSE; cmds->lines_flags[idx] = flags; - cmds->any_recurse |= flags & COMMANDS_RECURSE; + cmds->any_recurse |= flags & COMMANDS_RECURSE ? 1 : 0; } } @@ -456,7 +459,7 @@ execute_file_commands (struct file *file) { /* If there are no commands, assume everything worked. */ set_command_state (file, cs_running); - file->update_status = 0; + file->update_status = us_success; notice_finished_file (file); return; } @@ -467,6 +470,11 @@ execute_file_commands (struct file *file) set_file_variables (file); + /* If this is a loaded dynamic object, unload it before remaking. + Some systems don't support overwriting a loaded object. */ + if (file->loaded) + unload_file (file->name); + /* Start the commands running. */ new_job (file); } @@ -511,14 +519,14 @@ fatal_error_signal (int sig) DWORD susp_count = SuspendThread (main_thread); if (susp_count != 0) - fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count); + fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count); else if (susp_count == (DWORD)-1) - { - DWORD ierr = GetLastError (); + { + DWORD ierr = GetLastError (); - fprintf (stderr, "SuspendThread: error %ld: %s\n", - ierr, map_windows32_error_to_string (ierr)); - } + fprintf (stderr, "SuspendThread: error %ld: %s\n", + ierr, map_windows32_error_to_string (ierr)); + } } #endif handling_fatal_signal = 1; @@ -534,8 +542,8 @@ fatal_error_signal (int sig) { struct child *c; for (c = children; c != 0; c = c->next) - if (!c->remote) - (void) kill (c->pid, SIGTERM); + if (!c->remote) + (void) kill (c->pid, SIGTERM); } /* If we got a signal that means the user @@ -553,18 +561,18 @@ fatal_error_signal (int sig) struct child *c; /* Remote children won't automatically get signals sent - to the process group, so we must send them. */ + to the process group, so we must send them. */ for (c = children; c != 0; c = c->next) - if (c->remote) - (void) remote_kill (c->pid, sig); + if (c->remote) + (void) remote_kill (c->pid, sig); for (c = children; c != 0; c = c->next) - delete_child_targets (c); + delete_child_targets (c); /* Clean up the children. We don't just use the call below because - we don't want to print the "Waiting for children" message. */ + we don't want to print the "Waiting for children" message. */ while (job_slots_used > 0) - reap_children (1, 0); + reap_children (1, 0); } else /* Wait for our children to die. */ @@ -614,17 +622,17 @@ delete_target (struct file *file, const char *on_behalf_of) if (ar_name (file->name)) { time_t file_date = (file->last_mtime == NONEXISTENT_MTIME - ? (time_t) -1 - : (time_t) FILE_TIMESTAMP_S (file->last_mtime)); + ? (time_t) -1 + : (time_t) FILE_TIMESTAMP_S (file->last_mtime)); if (ar_member_date (file->name) != file_date) - { - if (on_behalf_of) - error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"), - on_behalf_of, file->name); - else - error (NILF, _("*** Archive member `%s' may be bogus; not deleted"), - file->name); - } + { + if (on_behalf_of) + error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"), + on_behalf_of, file->name); + else + error (NILF, _("*** Archive member '%s' may be bogus; not deleted"), + file->name); + } return; } #endif @@ -635,12 +643,12 @@ delete_target (struct file *file, const char *on_behalf_of) && FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime) { if (on_behalf_of) - error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name); + error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name); else - error (NILF, _("*** Deleting file `%s'"), file->name); + error (NILF, _("*** Deleting file '%s'"), file->name); if (unlink (file->name) < 0 - && errno != ENOENT) /* It disappeared; so what. */ - perror_with_name ("unlink: ", file->name); + && errno != ENOENT) /* It disappeared; so what. */ + perror_with_name ("unlink: ", file->name); } } @@ -659,7 +667,7 @@ delete_child_targets (struct child *child) /* Delete the target file if it changed. */ delete_target (child->file, NULL); - /* Also remove any non-precious targets listed in the `also_make' member. */ + /* Also remove any non-precious targets listed in the 'also_make' member. */ for (d = child->file->also_make; d != 0; d = d->next) delete_target (d->file, child->file->name); @@ -678,17 +686,23 @@ print_commands (const struct commands *cmds) if (cmds->fileinfo.filenm == 0) puts (_(" (built-in):")); else - printf (_(" (from `%s', line %lu):\n"), + printf (_(" (from '%s', line %lu):\n"), cmds->fileinfo.filenm, cmds->fileinfo.lineno); s = cmds->commands; while (*s != '\0') { const char *end; + int bs; - end = strchr (s, '\n'); - if (end == 0) - end = s + strlen (s); + /* Print one full logical recipe line: find a non-escaped newline. */ + for (end = s, bs = 0; *end != '\0'; ++end) + { + if (*end == '\n' && !bs) + break; + + bs = *end == '\\' ? !bs : 0; + } printf ("%c%.*s\n", cmd_prefix, (int) (end - s), s); |