* Fix PR/1379: -n/-q behaves correctly when all commands are recursive.
authorPaul Smith <psmith@gnu.org>
Wed, 13 Oct 1999 07:00:23 +0000 (07:00 +0000)
committerPaul Smith <psmith@gnu.org>
Wed, 13 Oct 1999 07:00:23 +0000 (07:00 +0000)
ChangeLog
commands.c
job.c
remake.c
tests/ChangeLog
tests/scripts/options/dash-n

index 69917cf..9f23418 100644 (file)
--- 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
index 34c0cc6..88ae022 100644 (file)
@@ -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;
     }
 }
 \f
@@ -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 (file)
--- 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.  */
index 7d7fd36..1d7ac08 100644 (file)
--- 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.  */
index ef2ef62..6c6387d 100644 (file)
@@ -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:
index c1f4aab..02d7f07 100644 (file)
@@ -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;