summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>1999-10-13 07:00:23 +0000
committerPaul Smith <psmith@gnu.org>1999-10-13 07:00:23 +0000
commit281951154bc90849385ae4cacc3cadfc1653b877 (patch)
treea78f4d17879b485ea2fa127c21d99ac40a839a00
parent829f4fd04b7fe9e18ed91c236ed46ebce5b27cae (diff)
downloadgunmake-281951154bc90849385ae4cacc3cadfc1653b877.tar.gz
* Fix PR/1379: -n/-q behaves correctly when all commands are recursive.
-rw-r--r--ChangeLog12
-rw-r--r--commands.c170
-rw-r--r--job.c3
-rw-r--r--remake.c39
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/scripts/options/dash-n30
6 files changed, 157 insertions, 102 deletions
diff --git a/ChangeLog b/ChangeLog
index 69917cf..9f23418 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+1999-10-12 Paul D. Smith <psmith@gnu.org>
+
+ * remake.c (notice_finished_file): If we get here and -n is set,
+ look for any commands that aren't recursive. If we find at least
+ one, we assume that command updates the target and set mtime of
+ the target to "very new". If there are none, then we ran every
+ command there is, so check the mtime on this file just like we
+ would normally, rather than assuming it's "very new".
+
+ * job.c (start_job_command): Update lines_flags in the file's cmds
+ structure with any per-line tokens we found (`@', `-', `+').
+
1999-10-08 Paul D. Smith <psmith@gnu.org>
* variable.c (initialize_file_variables): Always recurse to
diff --git a/commands.c b/commands.c
index 34c0cc6..88ae022 100644
--- a/commands.c
+++ b/commands.c
@@ -233,93 +233,97 @@ void
chop_commands (cmds)
register struct commands *cmds;
{
- if (cmds != 0 && cmds->command_lines == 0)
- {
- /* Chop CMDS->commands up into lines in CMDS->command_lines.
+ register char *p;
+ unsigned int nlines, idx;
+ char **lines;
+
+ /* If we don't have any commands,
+ or we already parsed them, never mind. */
+
+ if (!cmds || cmds->command_lines != 0)
+ return;
+
+ /* Chop CMDS->commands up into lines in CMDS->command_lines.
Also set the corresponding CMDS->lines_flags elements,
and the CMDS->any_recurse flag. */
- register char *p;
- unsigned int nlines, idx;
- char **lines;
-
- nlines = 5;
- lines = (char **) xmalloc (5 * sizeof (char *));
- idx = 0;
- p = cmds->commands;
- while (*p != '\0')
- {
- char *end = p;
- find_end:;
- end = index (end, '\n');
- if (end == 0)
- end = p + strlen (p);
- else if (end > p && end[-1] == '\\')
- {
- int backslash = 1;
- register char *b;
- for (b = end - 2; b >= p && *b == '\\'; --b)
- backslash = !backslash;
- if (backslash)
- {
- ++end;
- goto find_end;
- }
- }
-
- if (idx == nlines)
- {
- nlines += 2;
- lines = (char **) xrealloc ((char *) lines,
- nlines * sizeof (char *));
- }
- lines[idx++] = savestring (p, end - p);
- p = end;
- if (*p != '\0')
- ++p;
- }
- if (idx != nlines)
- {
- nlines = idx;
- lines = (char **) xrealloc ((char *) lines,
- nlines * sizeof (char *));
- }
+ nlines = 5;
+ lines = (char **) xmalloc (5 * sizeof (char *));
+ idx = 0;
+ p = cmds->commands;
+ while (*p != '\0')
+ {
+ char *end = p;
+ find_end:;
+ end = index (end, '\n');
+ if (end == 0)
+ end = p + strlen (p);
+ else if (end > p && end[-1] == '\\')
+ {
+ int backslash = 1;
+ register char *b;
+ for (b = end - 2; b >= p && *b == '\\'; --b)
+ backslash = !backslash;
+ if (backslash)
+ {
+ ++end;
+ goto find_end;
+ }
+ }
+
+ if (idx == nlines)
+ {
+ nlines += 2;
+ lines = (char **) xrealloc ((char *) lines,
+ nlines * sizeof (char *));
+ }
+ lines[idx++] = savestring (p, end - p);
+ p = end;
+ if (*p != '\0')
+ ++p;
+ }
- cmds->ncommand_lines = nlines;
- cmds->command_lines = lines;
+ if (idx != nlines)
+ {
+ nlines = idx;
+ lines = (char **) xrealloc ((char *) lines,
+ nlines * sizeof (char *));
+ }
- cmds->any_recurse = 0;
- cmds->lines_flags = (char *) xmalloc (nlines);
- for (idx = 0; idx < nlines; ++idx)
- {
- int flags = 0;
-
- for (p = lines[idx];
- isblank (*p) || *p == '-' || *p == '@' || *p == '+';
- ++p)
- switch (*p)
- {
- case '+':
- flags |= COMMANDS_RECURSE;
- break;
- case '@':
- flags |= COMMANDS_SILENT;
- break;
- case '-':
- flags |= COMMANDS_NOERROR;
- break;
- }
- if (!(flags & COMMANDS_RECURSE))
- {
- unsigned int len = strlen (p);
- if (sindex (p, len, "$(MAKE)", 7) != 0
- || sindex (p, len, "${MAKE}", 7) != 0)
- flags |= COMMANDS_RECURSE;
- }
+ cmds->ncommand_lines = nlines;
+ cmds->command_lines = lines;
- cmds->lines_flags[idx] = flags;
- cmds->any_recurse |= flags & COMMANDS_RECURSE;
- }
+ cmds->any_recurse = 0;
+ cmds->lines_flags = (char *) xmalloc (nlines);
+ for (idx = 0; idx < nlines; ++idx)
+ {
+ int flags = 0;
+
+ for (p = lines[idx];
+ isblank (*p) || *p == '-' || *p == '@' || *p == '+';
+ ++p)
+ switch (*p)
+ {
+ case '+':
+ flags |= COMMANDS_RECURSE;
+ break;
+ case '@':
+ flags |= COMMANDS_SILENT;
+ break;
+ case '-':
+ flags |= COMMANDS_NOERROR;
+ break;
+ }
+ if (!(flags & COMMANDS_RECURSE))
+ {
+ unsigned int len = strlen (p);
+ if (sindex (p, len, "$(MAKE)", 7) != 0
+ || sindex (p, len, "${MAKE}", 7) != 0)
+ flags |= COMMANDS_RECURSE;
+ }
+
+ cmds->lines_flags[idx] = flags;
+ cmds->any_recurse |= flags & COMMANDS_RECURSE;
}
}
@@ -341,9 +345,7 @@ execute_file_commands (file)
break;
if (*p == '\0')
{
- /* We are all out of commands.
- If we have gotten this far, all the previous commands
- have run successfully, so we have winning update status. */
+ /* If there are no commands, assume everything worked. */
set_command_state (file, cs_running);
file->update_status = 0;
notice_finished_file (file);
diff --git a/job.c b/job.c
index b656d6c..263bc3d 100644
--- a/job.c
+++ b/job.c
@@ -794,6 +794,9 @@ start_job_command (child)
++p;
}
+ /* Update the file's command flags with any new ones we found. */
+ child->file->cmds->lines_flags[child->command_line - 1] |= flags;
+
/* If -q was given, just say that updating `failed'. The exit status of
1 tells the user that -q is saying `something to do'; the exit status
for a random error is 2. */
diff --git a/remake.c b/remake.c
index 7d7fd36..1d7ac08 100644
--- a/remake.c
+++ b/remake.c
@@ -93,15 +93,6 @@ update_goal_chain (goals, makefiles)
g->changed = 0;
}
-#if 0
- /* Only run one job at a time when building makefiles.
- No one seems to know why this was done, and no one can think of a good
- reason to do it. Hopefully an obvious one won't appear as soon as we
- release the next version :-/. */
- if (makefiles)
- job_slots = 1;
-#endif
-
/* All files start with the considered bit 0, so the global value is 1. */
considered = 1;
@@ -746,12 +737,23 @@ notice_finished_file (file)
if (ran && !file->phony)
{
struct file *f;
+ int i = 0;
- if (just_print_flag || question_flag
- || (file->is_target && file->cmds == 0))
- file->last_mtime = NEW_MTIME;
- else
- file->last_mtime = 0;
+ /* If -n or -q and all the commands are recursive, we ran them so
+ really check the target's mtime again. Otherwise, assume the target
+ would have been updated. */
+
+ if (question_flag || just_print_flag)
+ for (i = file->cmds->ncommand_lines; i > 0; --i)
+ if (! (file->cmds->lines_flags[i-1] & COMMANDS_RECURSE))
+ break;
+
+ /* If there were no commands at all, it's always new. */
+
+ else if (file->is_target && file->cmds == 0)
+ i = 1;
+
+ file->last_mtime = i == 0 ? 0 : NEW_MTIME;
/* Propagate the change of modification time to all the double-colon
entries for this file. */
@@ -970,20 +972,21 @@ remake_file (file)
Pretend it was successfully remade. */
file->update_status = 0;
else
- no_rule_error(file);
+ no_rule_error (file);
}
else
{
chop_commands (file->cmds);
+ /* The normal case: start some commands. */
if (!touch_flag || file->cmds->any_recurse)
{
execute_file_commands (file);
return;
}
- else
- /* This tells notice_finished_file it is ok to touch the file. */
- file->update_status = 0;
+
+ /* This tells notice_finished_file it is ok to touch the file. */
+ file->update_status = 0;
}
/* This does the touching under -t. */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ef2ef62..6c6387d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+1999-10-13 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/options/dash-n: Add a test for PR/1379: "-n doesn't
+ behave properly when used with recursive targets".
+
1999-10-08 Paul D. Smith <psmith@gnu.org>
* scripts/features/targetvars: Add a check for PR/1378:
diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n
index c1f4aab..02d7f07 100644
--- a/tests/scripts/options/dash-n
+++ b/tests/scripts/options/dash-n
@@ -28,4 +28,34 @@ $answer = "echo >> intermediate\necho >> final\n";
unlink('orig', 'intermediate', 'final');
+# TEST2
+# We consider the actual updated timestamp of targets with all
+# recursive commands, even with -n.
+
+$makefile2 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile2");
+
+print MAKEFILE <<'EOF';
+.SUFFIXES:
+BAR = # nothing
+FOO = +$(BAR)
+a: b; echo > $@
+b: c; $(FOO)
+EOF
+
+close(MAKEFILE);
+
+&touch('a', 'b');
+sleep(1);
+&touch('c');
+
+&run_make_with_options($makefile2, "", &get_logfile);
+$answer = "$make_name: `a' is up to date.\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile2, "-n", &get_logfile);
+$answer = "$make_name: `a' is up to date.\n";
+&compare_output($answer, &get_logfile(1));
+
1;