This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch trunk] in memory pretty-printing


Hello All,

The attached patch (to trunk rev148659) is a port from the MELT branch (which did test it quite significantly for the added features.).

The insight is that some plugins might want or need to pretty print (notably for debugging purpose) outside of a FILE*. Using fmemopen is not portable (of course a future GCC in C++ would use ostream-s in C++).

So I added inside the output_buffer struct of pretty-print.h a generating routine pointer with its client data to pretty-print either into a FILE* if stream is given, or thru the given routine otherwise.

I also exported dump_gimple_seq, needed by MELT & definitely useful to other plugins.

Of course, a lot of debugging output would need to be also patched. To make this patch safe, I added tests in gimple-pretty-print.c to check for the buffer field of output_buffer-s (and do nothing if it is a null FILE*).

The patch did bootstrap on x86-64-gnu-linux ie Debian/Sid/AMD64.

Ok for trunk?

Regards.

PS: In an ideal, marvelous, but unrealistic world, one could imagine that every debug & dump I/O should go thru a specific abstract stream, similar to the ostream class of C++ or something even better than the IO channels of GTK http://library.gnome.org/devel/glib/stable/glib-IO-Channels.html but that is not realistic, it would be a huge patch [difficult to code, too big to be reviewed]. The proposed patch is much less ambitious and is not entirely complete, but does work.

--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***

Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 148661)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -2852,6 +2852,7 @@ maybe_init_pretty_print (FILE *file)
     }
 
   buffer.buffer->stream = file;
+  buffer.buffer->buflushroutine = 0;
 }
 
 static void
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 148661)
+++ gcc/diagnostic.h	(working copy)
@@ -238,5 +238,6 @@ extern void print_gimple_seq (FILE *, gimple_seq,
 extern void print_gimple_stmt (FILE *, gimple, int, int);
 extern void print_gimple_expr (FILE *, gimple, int, int);
 extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);
+extern void dump_gimple_seq (pretty_printer *, gimple_seq, int, int);
 
 #endif /* ! GCC_DIAGNOSTIC_H */
Index: gcc/pretty-print.c
===================================================================
--- gcc/pretty-print.c	(revision 148661)
+++ gcc/pretty-print.c	(working copy)
@@ -101,7 +101,10 @@ void
 pp_write_text_to_stream (pretty_printer *pp)
 {
   const char *text = pp_formatted_text (pp);
-  fputs (text, pp->buffer->stream);
+  if (pp->buffer->stream)
+    fputs (text, pp->buffer->stream);
+  else if (pp->buffer->buflushroutine)
+    (pp->buffer->buflushroutine) (text, pp->buffer->buflushdata);
   pp_clear_output_area (pp);
 }
 
@@ -629,8 +632,13 @@ 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);
+  if (pp->buffer->stream) 
+    {
+      fputc ('\n', pp->buffer->stream);
+      fflush (pp->buffer->stream);
+    }
+  else if (pp->buffer->buflushroutine) 
+    (pp->buffer->buflushroutine) ("\n",  pp->buffer->buflushdata);
   pp_needs_newline (pp) = false;
 }
 
@@ -722,6 +730,31 @@ pp_construct (pretty_printer *pp, const char *pref
   pp_translate_identifiers (pp) = true;
 }
 
+void
+pp_construct_routdata (pretty_printer *pp, const char *prefix, int maximum_length, void (*flushrout)(const char*,void*), void *flushdata) 
+{
+  memset (pp, 0, sizeof (pretty_printer));
+  pp->buffer = XCNEW (output_buffer);
+  obstack_init (&pp->buffer->chunk_obstack);
+  obstack_init (&pp->buffer->formatted_obstack);
+  pp->buffer->obstack = &pp->buffer->formatted_obstack;
+  pp->buffer->stream = NULL;
+  pp->buffer->buflushroutine = flushrout;
+  pp->buffer->buflushdata = flushdata;
+  pp_line_cutoff (pp) = maximum_length;
+  pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+  pp_set_prefix (pp, prefix);
+}
+
+
+void pp_destruct(pretty_printer *pp)
+{
+  pp_write_text_to_stream (pp);
+  pp_clear_state (pp);
+  XDELETE (pp->buffer);
+  memset(pp, 0, sizeof (pretty_printer));
+}
+
 /* Append a string delimited by START and END to the output area of
    PRETTY-PRINTER.  No line wrapping is done.  However, if beginning a
    new line then emit PRETTY-PRINTER's prefix and skip any leading
Index: gcc/pretty-print.h
===================================================================
--- gcc/pretty-print.h	(revision 148661)
+++ gcc/pretty-print.h	(working copy)
@@ -90,6 +90,10 @@ typedef struct
   /* Where to output formatted text.  */
   FILE *stream;
 
+  /* if the above stream is null, use the buflushroutine with its buflushdata */
+  void (*buflushroutine) (const char*str, void*data);
+  void *buflushdata;
+
   /* The amount of characters output so far.  */  
   int line_length;
 
@@ -297,7 +301,13 @@ struct pretty_print_info
    this macro to return a pointer to the base pretty_printer structure.  */
 #define pp_base(PP) (PP)
 
+/* construct a pretty printer on stderr */
 extern void pp_construct (pretty_printer *, const char *, int);
+/* construct a pretty printer to a routine with data */
+extern void pp_construct_routdata (pretty_printer *pp, const char *prefix, int maximum_length, void (*flushrout)(const char*,void*), void *flushdata);
+/* destruct a pretty printer */
+extern void pp_destruct (pretty_printer *);
+
 extern void pp_base_set_line_maximum_length (pretty_printer *, int);
 extern void pp_base_set_prefix (pretty_printer *, const char *);
 extern void pp_base_destroy_prefix (pretty_printer *);
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 148661)
+++ gcc/gimple-pretty-print.c	(working copy)
@@ -116,7 +116,7 @@ print_gimple_expr (FILE *file, gimple g, int spc,
 /* Print the GIMPLE sequence SEQ on BUFFER using SPC indentantion
    spaces and FLAGS as in dump_gimple_stmt.  */
 
-static void
+void
 dump_gimple_seq (pretty_printer *buffer, gimple_seq seq, int spc, int flags)
 {
   gimple_stmt_iterator i;
@@ -1580,7 +1580,7 @@ dump_bb_header (pretty_printer *buffer, basic_bloc
 	    else
 	      pp_decimal_int (buffer, e->src->index);
 	  }
-	else
+	else if (buffer->buffer->stream)
 	  dump_edge_info (buffer->buffer->stream, e, 0);
       pp_newline (buffer);
     }
@@ -1597,7 +1597,8 @@ dump_bb_header (pretty_printer *buffer, basic_bloc
 	}
     }
   pp_write_text_to_stream (buffer);
-  check_bb_profile (bb, buffer->buffer->stream);
+  if (buffer->buffer->stream)
+    check_bb_profile (bb, buffer->buffer->stream);
 }
 
 
@@ -1622,7 +1623,7 @@ dump_bb_end (pretty_printer *buffer, basic_block b
 	else
 	  pp_decimal_int (buffer, e->dest->index);
       }
-    else
+    else if (buffer->buffer->stream)
       dump_edge_info (buffer->buffer->stream, e, 1);
   pp_newline (buffer);
 }
@@ -1758,7 +1759,8 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic
     label_indent = 0;
 
   dump_bb_header (buffer, bb, indent, flags);
-  dump_phi_nodes (buffer, bb, indent, flags);
+  if (phi_nodes (bb))
+    dump_phi_nodes (buffer, bb, indent, flags);
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
@@ -1771,7 +1773,8 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic
       INDENT (curr_indent);
       dump_gimple_stmt (buffer, stmt, curr_indent, flags);
       pp_newline (buffer);
-      dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
+      if (buffer->buffer->stream)
+	dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
     }
 
   dump_implicit_edges (buffer, bb, indent, flags);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]