OSDN Git Service

* pa-host.c (MAP_FAILED): Define if not defined.
[pf3gnuchains/gcc-fork.git] / gcc / pretty-print.c
index b119063..3a10e76 100644 (file)
@@ -1,5 +1,5 @@
 /* Various declarations for language-independent pretty-print subroutines.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -24,7 +24,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #undef FFS  /* Some systems define this in param.h.  */
 #include "system.h"
 #include "coretypes.h"
+#include "intl.h"
 #include "pretty-print.h"
+#include "tree.h"
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free  free
@@ -90,21 +92,8 @@ pp_clear_state (pretty_printer *pp)
   pp_indentation (pp) = 0;
 }
 
-/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
-   the column position to the current indentation level, assuming that a
-   newline has just been written to the buffer.  */
-static void
-pp_indent (pretty_printer *pp)
-{
-  int n = pp_indentation (pp);
-  int i;
-
-  for (i = 0; i < n; ++i)
-    pp_space (pp);
-}
-
 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream.  */
-static inline void
+void
 pp_write_text_to_stream (pretty_printer *pp)
 {
   const char *text = pp_formatted_text (pp);
@@ -164,6 +153,53 @@ pp_append_r (pretty_printer *pp, const char *start, int length)
   pp->buffer->line_length += length;
 }
 
+/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
+   the column position to the current indentation level, assuming that a
+   newline has just been written to the buffer.  */
+void
+pp_base_indent (pretty_printer *pp)
+{
+  int n = pp_indentation (pp);
+  int i;
+
+  for (i = 0; i < n; ++i)
+    pp_space (pp);
+}
+
+/* Prepare PP to format a message pointed to by TEXT, with tentative
+   location LOCUS.  It is expected that a call to pp_format_text with
+   exactly the same PP and TEXT arguments will follow.  This routine
+   may modify the data in memory at TEXT and LOCP, and if it does,
+   caller is expected to notice.
+
+   Currently, all this does is notice a %H or %J escape at the beginning
+   of the string, and update LOCUS to match.  */
+void
+pp_base_prepare_to_format (pretty_printer *pp ATTRIBUTE_UNUSED,
+                          text_info *text,
+                          location_t *locus)
+{
+  const char *p = text->format_spec;
+  tree t;
+
+  /* Extract the location information if any.  */
+  if (p[0] == '%')
+    switch (p[1])
+      {
+      case 'H':
+       *locus = *va_arg (*text->args_ptr, location_t *);
+       text->format_spec = p + 2;
+       break;
+
+      case 'J':
+       t = va_arg (*text->args_ptr, tree);
+       *locus = DECL_SOURCE_LOCATION (t);
+       text->format_spec = p + 2;
+       break;
+      }
+}
+
+
 /* Format a message pointed to by TEXT.  The following format specifiers are
    recognized as being client independent:
    %d, %i: (signed) integer in base ten.
@@ -177,16 +213,22 @@ pp_append_r (pretty_printer *pp, const char *start, int length)
    %s: string.
    %p: pointer.
    %m: strerror(text->err_no) - does not consume a value from args_ptr.
-   %%: `%'.
-   %*.s: a substring the length of which is specified by an integer.
-   %H: location_t.  */
+   %%: '%'.
+   %<: opening quote.
+   %>: closing quote.
+   %': apostrophe (should only be used in untranslated messages;
+       translations should use appropriate punctuation directly).
+   %.*s: a substring the length of which is specified by an integer.
+   %H: location_t.
+   Flag 'q': quote formatted text (must come immediately after '%').  */
 void
-pp_format_text (pretty_printer *pp, text_info *text)
+pp_base_format_text (pretty_printer *pp, text_info *text)
 {
   for (; *text->format_spec; ++text->format_spec)
     {
       int precision = 0;
       bool wide = false;
+      bool quoted = false;
 
       /* Ignore text.  */
       {
@@ -200,8 +242,14 @@ pp_format_text (pretty_printer *pp, text_info *text)
       if (*text->format_spec == '\0')
        break;
 
-      /* We got a '%'.  Parse precision modifiers, if any.  */
-      switch (*++text->format_spec)
+      /* We got a '%'.  Check for 'q', then parse precision modifiers,
+        if any.  */
+      if (*++text->format_spec == 'q')
+       {
+         quoted = true;
+         ++text->format_spec;
+       }
+      switch (*text->format_spec)
         {
         case 'w':
           wide = true;
@@ -217,10 +265,11 @@ pp_format_text (pretty_printer *pp, text_info *text)
         default:
           break;
         }
-      /* We don't support precision behond that of "long long".  */
-      if (precision > 2)
-        abort();
+      /* We don't support precision beyond that of "long long".  */
+      gcc_assert (precision <= 2);
 
+      if (quoted)
+       pp_string (pp, open_quote);
       switch (*text->format_spec)
        {
        case 'c':
@@ -279,13 +328,23 @@ pp_format_text (pretty_printer *pp, text_info *text)
          pp_character (pp, '%');
          break;
 
+       case '<':
+         pp_string (pp, open_quote);
+         break;
+
+       case '>':
+       case '\'':
+         pp_string (pp, close_quote);
+         break;
+
         case 'H':
           {
-            const location_t *locus = va_arg (*text->args_ptr, location_t *);
+            location_t *locus = va_arg (*text->args_ptr, location_t *);
+           expanded_location s = expand_location (*locus);
             pp_string (pp, "file '");
-            pp_string (pp, locus->file);
+            pp_string (pp, s.file);
             pp_string (pp, "', line ");
-            pp_decimal_int (pp, locus->line);
+            pp_decimal_int (pp, s.line);
           }
           break;
 
@@ -293,11 +352,12 @@ pp_format_text (pretty_printer *pp, text_info *text)
          {
            int n;
            const char *s;
-           /* We handle no precision specifier but `%.*s'.  */
-           if (*++text->format_spec != '*')
-             abort ();
-           else if (*++text->format_spec != 's')
-             abort ();
+           /* We handle no precision specifier but '%.*s'.  */
+           ++text->format_spec;
+           gcc_assert (*text->format_spec == '*');
+           ++text->format_spec;
+           gcc_assert (*text->format_spec == 's');
+
            n = va_arg (*text->args_ptr, int);
            s = va_arg (*text->args_ptr, const char *);
            pp_append_text (pp, s, s + n);
@@ -314,13 +374,15 @@ pp_format_text (pretty_printer *pp, text_info *text)
              abort ();
            }
        }
+      if (quoted)
+       pp_string (pp, close_quote);
     }
 }
 
 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
    settings needed by BUFFER for a verbatim formatting.  */
 void
-pp_format_verbatim (pretty_printer *pp, text_info *text)
+pp_base_format_verbatim (pretty_printer *pp, text_info *text)
 {
   diagnostic_prefixing_rule_t rule = pp_prefixing_rule (pp);
   int line_cutoff = pp_line_cutoff (pp);
@@ -337,19 +399,20 @@ pp_format_verbatim (pretty_printer *pp, text_info *text)
 
 /* Flush the content of BUFFER onto the attached stream.  */
 void
-pp_flush (pretty_printer *pp)
+pp_base_flush (pretty_printer *pp)
 {
   pp_write_text_to_stream (pp);
   pp_clear_state (pp);
   fputc ('\n', pp->buffer->stream);
   fflush (pp->buffer->stream);
+  pp_needs_newline (pp) = false;
 }
 
 /* Sets the number of maximum characters per line PRETTY-PRINTER can
    output in line-wrapping mode.  A LENGTH value 0 suppresses
    line-wrapping.  */
 void
-pp_set_line_maximum_length (pretty_printer *pp, int length)
+pp_base_set_line_maximum_length (pretty_printer *pp, int length)
 {
   pp_line_cutoff (pp) = length;
   pp_set_real_maximum_length (pp);
@@ -357,7 +420,7 @@ pp_set_line_maximum_length (pretty_printer *pp, int length)
 
 /* Clear PRETTY-PRINTER output area text info.  */
 void
-pp_clear_output_area (pretty_printer *pp)
+pp_base_clear_output_area (pretty_printer *pp)
 {
   obstack_free (&pp->buffer->obstack, obstack_base (&pp->buffer->obstack));
   pp->buffer->line_length = 0;
@@ -365,7 +428,7 @@ pp_clear_output_area (pretty_printer *pp)
 
 /* Set PREFIX for PRETTY-PRINTER.  */
 void
-pp_set_prefix (pretty_printer *pp, const char *prefix)
+pp_base_set_prefix (pretty_printer *pp, const char *prefix)
 {
   pp->prefix = prefix;
   pp_set_real_maximum_length (pp);
@@ -375,7 +438,7 @@ pp_set_prefix (pretty_printer *pp, const char *prefix)
 
 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string.  */
 void
-pp_destroy_prefix (pretty_printer *pp)
+pp_base_destroy_prefix (pretty_printer *pp)
 {
   if (pp->prefix != NULL)
     {
@@ -386,7 +449,7 @@ pp_destroy_prefix (pretty_printer *pp)
 
 /* Write out PRETTY-PRINTER's prefix.  */
 void
-pp_emit_prefix (pretty_printer *pp)
+pp_base_emit_prefix (pretty_printer *pp)
 {
   if (pp->prefix != NULL)
     {
@@ -399,7 +462,7 @@ pp_emit_prefix (pretty_printer *pp)
        case DIAGNOSTICS_SHOW_PREFIX_ONCE:
          if (pp->emitted_prefix)
            {
-             pp_indent (pp);
+             pp_base_indent (pp);
              break;
            }
          pp_indentation (pp) += 3;
@@ -422,7 +485,7 @@ void
 pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
 {
   memset (pp, 0, sizeof (pretty_printer));
-  pp->buffer = xmalloc (sizeof (output_buffer));
+  pp->buffer = xcalloc (1, sizeof (output_buffer));
   obstack_init (&pp->buffer->obstack);
   pp->buffer->stream = stderr;
   pp_line_cutoff (pp) = maximum_length;
@@ -436,7 +499,7 @@ pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
    whitespace if appropriate.  The caller must ensure that it is
    safe to do so.  */
 void
-pp_append_text (pretty_printer *pp, const char *start, const char *end)
+pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
 {
   /* Emit prefix and skip whitespace if we're starting a new line.  */
   if (pp->buffer->line_length == 0)
@@ -452,7 +515,7 @@ pp_append_text (pretty_printer *pp, const char *start, const char *end)
 /* Finishes constructing a NULL-terminated character string representing
    the PRETTY-PRINTED text.  */
 const char *
-pp_formatted_text (pretty_printer *pp)
+pp_base_formatted_text (pretty_printer *pp)
 {
   obstack_1grow (&pp->buffer->obstack, '\0');
   return pp_formatted_text_data (pp);
@@ -461,7 +524,7 @@ pp_formatted_text (pretty_printer *pp)
 /*  Return a pointer to the last character emitted in PRETTY-PRINTER's
     output area.  A NULL pointer means no character available.  */
 const char *
-pp_last_position_in_text (const pretty_printer *pp)
+pp_base_last_position_in_text (const pretty_printer *pp)
 {
   const char *p = NULL;
   struct obstack *text = &pp->buffer->obstack;
@@ -472,9 +535,9 @@ pp_last_position_in_text (const pretty_printer *pp)
 }
 
 /* Return the amount of characters PRETTY-PRINTER can accept to
-   make a full line.  Meaningfull only in line-wrapping mode.  */
+   make a full line.  Meaningful only in line-wrapping mode.  */
 int
-pp_remaining_character_count_for_line (pretty_printer *pp)
+pp_base_remaining_character_count_for_line (pretty_printer *pp)
 {
   return pp->maximum_length - pp->buffer->line_length;
 }
@@ -515,7 +578,7 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...)
 
 /* Have PRETTY-PRINTER start a new line.  */
 void
-pp_newline (pretty_printer *pp)
+pp_base_newline (pretty_printer *pp)
 {
   obstack_1grow (&pp->buffer->obstack, '\n');
   pp->buffer->line_length = 0;
@@ -523,7 +586,7 @@ pp_newline (pretty_printer *pp)
 
 /* Have PRETTY-PRINTER add a CHARACTER.  */
 void
-pp_character (pretty_printer *pp, int c)
+pp_base_character (pretty_printer *pp, int c)
 {
   if (pp_is_wrapping_line (pp)
       && pp_remaining_character_count_for_line (pp) <= 0)
@@ -539,9 +602,19 @@ pp_character (pretty_printer *pp, int c)
 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
    be line-wrapped if in appropriate mode.  */
 void
-pp_string (pretty_printer *pp, const char *str)
+pp_base_string (pretty_printer *pp, const char *str)
 {
   pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
 }
 
+/* Maybe print out a whitespace if needed.  */
 
+void
+pp_base_maybe_space (pretty_printer *pp)
+{
+  if (pp_base (pp)->padding != pp_none)
+    {
+      pp_space (pp);
+      pp_base (pp)->padding = pp_none;
+    }
+}