automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: support for partial messages (i.e. chained diagnostics)


From: Alexandre Duret-Lutz
Subject: FYI: support for partial messages (i.e. chained diagnostics)
Date: 29 Sep 2002 16:50:38 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

There are many place in Automake where I've output messages
in two parts.  For instance:

  msg 'channel', 'foo:2', 'redefinition of A ...';
  msg 'channel', 'foo:1', '... A previously defined here';

This isn't perfect because if we latter do

  msg 'channel', 'foo:3', 'redefinition of A ...';
  msg 'channel', 'foo:1', '... A previously defined here';

then `foo:1: ... A previously defined here' will be filtered out
as a duplicate message.

The following patch adds a way to link associated messages
together:

  msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1;
  msg 'channel', 'foo:1', '... A previously defined here';

and the filtering will apply as if the two lines were one single message.

Committed on HEAD.

2002-09-29  Alexandre Duret-Lutz  <address@hidden>

        * lib/Automake/Channels.pm (%_default_options): Add 'partial'.
        (_format_message): Rename as ...
        (_format_sub_message): ... this.
        (_format_message): New function, extracted from ...
        (_print_message): ... here.  Honor the 'partial' option.
        ($partial): New variable.
        * automake.in (handle_ltlibraries, check_ambiguous_conditional,
        rule_define): Mark partial messages.

Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1369
diff -u -r1.1369 automake.in
--- automake.in 29 Sep 2002 13:08:16 -0000      1.1369
+++ automake.in 29 Sep 2002 14:04:43 -0000
@@ -3372,7 +3372,7 @@
          if (defined $instdirs{$lib} && $instdirs{$lib} ne $dir)
            {
              err ($where, "`$lib' is already going to be installed in "
-                  . "`$instdirs{$lib}'");
+                  . "`$instdirs{$lib}'", partial => 1);
              err ($liblocations{$lib}, "`$lib' previously declared here");
            }
          else
@@ -6144,7 +6144,7 @@
     conditional_ambiguous_p ($var, $cond, keys %{$var_value{$var}});
   if ($message)
     {
-      msg 'syntax', $where, "$message ...";
+      msg 'syntax', $where, "$message ...", partial => 1;
       msg_var ('syntax', $var, "... `$var' previously defined here");
       verb (macro_dump ($var));
     }
@@ -7585,7 +7585,7 @@
                  ## is legitimate. (This is phony.test.)
 
                  # msg ('syntax', $where,
-                 #      "redefinition of `$target'$condmsg...");
+                 #      "redefinition of `$target'$condmsg...", partial => 1);
                  # msg_cond_target ('syntax', $cond, $target,
                  #                "... `$target' previously defined here");
                }
@@ -7624,7 +7624,8 @@
              my $oldsource = $target_source{$target}{$cond};
              return () if $source eq $oldsource;
 
-             msg ('syntax', $where, "redefinition of `$target'$condmsg...");
+             msg ('syntax', $where, "redefinition of `$target'$condmsg...",
+                  partial => 1);
              msg_cond_target ('syntax', $cond, $target,
                               "... `$target' previously defined here");
              return ();
@@ -7645,7 +7646,7 @@
       if ($owner == TARGET_USER)
        {
          # For user rules, just diagnose the ambiguity.
-         msg 'syntax', $where, "$message ...";
+         msg 'syntax', $where, "$message ...", partial => 1;
          msg_cond_target ('syntax', $ambig_cond, $target,
                           "... `$target' previously defined here");
          return ();
@@ -7681,7 +7682,7 @@
          # Warn, because our workaround is meaningless in this case.
          if (scalar @conds == 0)
            {
-             msg 'syntax', $where, "$message ...";
+             msg 'syntax', $where, "$message ...", partial => 1;
              msg_cond_target ('syntax', $ambig_cond, $target,
                               "... `$target' previously defined here");
              return ();
Index: lib/Automake/Channels.pm
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/Channels.pm,v
retrieving revision 1.6
diff -u -r1.6 Channels.pm
--- lib/Automake/Channels.pm    28 Sep 2002 12:41:05 -0000      1.6
+++ lib/Automake/Channels.pm    29 Sep 2002 14:04:45 -0000
@@ -193,6 +193,45 @@
 
 Die with a stack backtrace after displaying the message.
 
+=item C<partial =E<gt> 0>
+
+When set, indicates a partial message that should
+be output along with the next message with C<partial> unset.
+Several partial messages can be stacked this way.
+
+Duplicate filtering will apply to the I<global> message resulting from
+all I<partial> messages, using the options from the last (non-partial)
+message.  Linking associated messages is the main reason to use this
+option.
+
+For instance the following messages
+
+  msg 'channel', 'foo:2', 'redefinition of A ...';
+  msg 'channel', 'foo:1', '... A previously defined here';
+  msg 'channel', 'foo:3', 'redefinition of A ...';
+  msg 'channel', 'foo:1', '... A previously defined here';
+
+will result in
+
+ foo:2: redefinition of A ...
+ foo:1: ... A previously defined here
+ foo:3: redefinition of A ...
+
+where the duplicate "I<... A previously defined here>" has been
+filtered out.
+
+Linking these messages using C<partial> as follows will prevent the
+fourth message to disappear.
+
+  msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1;
+  msg 'channel', 'foo:1', '... A previously defined here';
+  msg 'channel', 'foo:3', 'redefinition of A ...', partial => 1;
+  msg 'channel', 'foo:1', '... A previously defined here';
+
+Note that because the stack of C<partial> messages is printed with the
+first non-C<partial> message, most options of C<partial> messages will
+be ignored.
+
 =back
 
 =cut
@@ -212,6 +251,7 @@
    header => '',
    footer => '',
    backtrace => 0,
+   partial => 0,
    );
 
 # Filled with output messages as keys, to detect duplicates.
@@ -320,43 +360,67 @@
   return '';
 }
 
-# _format_message ($LEADER, $MESSAGE)
-# -----------------------------------
+# _format_sub_message ($LEADER, $MESSAGE)
+# ---------------------------------------
 # Split $MESSAGE at new lines and add $LEADER to each line.
-sub _format_message ($$)
+sub _format_sub_message ($$)
 {
   my ($leader, $message) = @_;
   return $leader . join ("\n" . $leader, split ("\n", $message)) . "\n";
 }
 
-# _print_message ($LOCATION, $MESSAGE, %OPTIONS)
-# ----------------------------------------------
-# Format the message, check duplicates, and print it.
-sub _print_message ($$%)
+# _format_message ($LOCATION, $MESSAGE, %OPTIONS)
+# -----------------------------------------------
+# Format the message.  Return a string ready to print.
+sub _format_message ($$%)
 {
   my ($location, $message, %opts) = @_;
-
-  return 0 if ($opts{'silent'});
-
-  # Format the message.
   my $msg = '';
   if (ref $location)
     {
       # If $LOCATION is a reference, assume it's an instance of the
       # Automake::Location class and display contexts.
       my $loc = $location->get || $me;
-      $msg = _format_message ("$loc: ",
-                             $opts{'header'} . $message . $opts{'footer'});
+      $msg = _format_sub_message ("$loc: ", $opts{'header'}
+                                 . $message . $opts{'footer'});
       for my $pair ($location->get_contexts)
        {
-         $msg .= _format_message ($pair->[0] . ":   ", $pair->[1]);
+         $msg .= _format_sub_message ($pair->[0] . ":   ", $pair->[1]);
        }
     }
   else
     {
       $location ||= $me;
-      $msg = _format_message ("$location: ",
-                             $opts{'header'} . $message . $opts{'footer'});
+      $msg = _format_sub_message ("$location: ", $opts{'header'}
+                                 . $message . $opts{'footer'});
+    }
+  return $msg;
+}
+
+# Store partial messages here. (See the 'partial' option.)
+use vars qw ($partial);
+$partial = '';
+
+# _print_message ($LOCATION, $MESSAGE, %OPTIONS)
+# ----------------------------------------------
+# Format the message, check duplicates, and print it.
+sub _print_message ($$%)
+{
+  my ($location, $message, %opts) = @_;
+
+  return 0 if ($opts{'silent'});
+
+  my $msg = _format_message ($location, $message, %opts);
+  if ($opts{'partial'})
+    {
+      # Incomplete message.   Store, don't print.
+      $partial .= $msg;
+      return;
+    }
+  else
+    {
+      # Prefix with any partial message send so far.
+      $msg = $partial . $msg;
     }
 
   # Check for duplicate message if requested.
@@ -454,7 +518,7 @@
 =cut
 
 
-use vars qw (@backlog %buffering);
+use vars qw (@backlog %buffering @chain);
 
 # See buffer_messages() and flush_messages() below.
 %buffering = ();       # The map of channel types to buffer.

-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]