+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
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;
}
}
\f
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);
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;
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. */
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. */
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;