From 281951154bc90849385ae4cacc3cadfc1653b877 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Wed, 13 Oct 1999 07:00:23 +0000 Subject: * Fix PR/1379: -n/-q behaves correctly when all commands are recursive. --- ChangeLog | 12 +++ commands.c | 170 ++++++++++++++++++++++--------------------- job.c | 3 + remake.c | 39 +++++----- tests/ChangeLog | 5 ++ tests/scripts/options/dash-n | 30 ++++++++ 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 + + * 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 * 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 + + * 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 * 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; -- cgit v1.2.3