Home | History | Annotate | Line # | Download | only in guile
      1  1.1  christos /* GDB/Scheme pretty-printing.
      2  1.1  christos 
      3  1.9  christos    Copyright (C) 2008-2024 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos /* See README file in this directory for implementation notes, coding
     21  1.1  christos    conventions, et.al.  */
     22  1.1  christos 
     23  1.9  christos #include "top.h"
     24  1.1  christos #include "charset.h"
     25  1.9  christos #include "symtab.h"
     26  1.1  christos #include "language.h"
     27  1.1  christos #include "objfiles.h"
     28  1.1  christos #include "value.h"
     29  1.1  christos #include "valprint.h"
     30  1.1  christos #include "guile-internal.h"
     31  1.1  christos 
     32  1.1  christos /* Return type of print_string_repr.  */
     33  1.1  christos 
     34  1.8  christos enum guile_string_repr_result
     35  1.1  christos {
     36  1.1  christos   /* The string method returned None.  */
     37  1.1  christos   STRING_REPR_NONE,
     38  1.1  christos   /* The string method had an error.  */
     39  1.1  christos   STRING_REPR_ERROR,
     40  1.1  christos   /* Everything ok.  */
     41  1.1  christos   STRING_REPR_OK
     42  1.1  christos };
     43  1.1  christos 
     44  1.1  christos /* Display hints.  */
     45  1.1  christos 
     46  1.1  christos enum display_hint
     47  1.1  christos {
     48  1.1  christos   /* No display hint.  */
     49  1.1  christos   HINT_NONE,
     50  1.1  christos   /* The display hint has a bad value.  */
     51  1.1  christos   HINT_ERROR,
     52  1.1  christos   /* Print as an array.  */
     53  1.1  christos   HINT_ARRAY,
     54  1.1  christos   /* Print as a map.  */
     55  1.1  christos   HINT_MAP,
     56  1.1  christos   /* Print as a string.  */
     57  1.1  christos   HINT_STRING
     58  1.1  christos };
     59  1.1  christos 
     60  1.1  christos /* The <gdb:pretty-printer> smob.  */
     61  1.1  christos 
     62  1.8  christos struct pretty_printer_smob
     63  1.1  christos {
     64  1.1  christos   /* This must appear first.  */
     65  1.1  christos   gdb_smob base;
     66  1.1  christos 
     67  1.1  christos   /* A string representing the name of the printer.  */
     68  1.1  christos   SCM name;
     69  1.1  christos 
     70  1.1  christos   /* A boolean indicating whether the printer is enabled.  */
     71  1.1  christos   SCM enabled;
     72  1.1  christos 
     73  1.1  christos   /* A procedure called to look up the printer for the given value.
     74  1.1  christos      The procedure is called as (lookup gdb:pretty-printer value).
     75  1.1  christos      The result should either be a gdb:pretty-printer object that will print
     76  1.1  christos      the value, or #f if the value is not recognized.  */
     77  1.1  christos   SCM lookup;
     78  1.1  christos 
     79  1.1  christos   /* Note: Attaching subprinters to this smob is left to Scheme.  */
     80  1.8  christos };
     81  1.1  christos 
     82  1.1  christos /* The <gdb:pretty-printer-worker> smob.  */
     83  1.1  christos 
     84  1.8  christos struct pretty_printer_worker_smob
     85  1.1  christos {
     86  1.1  christos   /* This must appear first.  */
     87  1.1  christos   gdb_smob base;
     88  1.1  christos 
     89  1.1  christos   /* Either #f or one of the supported display hints: map, array, string.
     90  1.1  christos      If neither of those then the display hint is ignored (treated as #f).  */
     91  1.1  christos   SCM display_hint;
     92  1.1  christos 
     93  1.1  christos   /* A procedure called to pretty-print the value.
     94  1.1  christos      (lambda (printer) ...) -> string | <gdb:lazy-string> | <gdb:value>  */
     95  1.1  christos   SCM to_string;
     96  1.1  christos 
     97  1.1  christos   /* A procedure called to print children of the value.
     98  1.1  christos      (lambda (printer) ...) -> <gdb:iterator>
     99  1.1  christos      The iterator returns a pair for each iteration: (name . value),
    100  1.1  christos      where "value" can have the same types as to_string.  */
    101  1.1  christos   SCM children;
    102  1.8  christos };
    103  1.1  christos 
    104  1.1  christos static const char pretty_printer_smob_name[] =
    105  1.1  christos   "gdb:pretty-printer";
    106  1.1  christos static const char pretty_printer_worker_smob_name[] =
    107  1.1  christos   "gdb:pretty-printer-worker";
    108  1.1  christos 
    109  1.1  christos /* The tag Guile knows the pretty-printer smobs by.  */
    110  1.1  christos static scm_t_bits pretty_printer_smob_tag;
    111  1.1  christos static scm_t_bits pretty_printer_worker_smob_tag;
    112  1.1  christos 
    113  1.1  christos /* The global pretty-printer list.  */
    114  1.1  christos static SCM pretty_printer_list;
    115  1.1  christos 
    116  1.1  christos /* gdb:pp-type-error.  */
    117  1.1  christos static SCM pp_type_error_symbol;
    118  1.1  christos 
    119  1.1  christos /* Pretty-printer display hints are specified by strings.  */
    120  1.1  christos static SCM ppscm_map_string;
    121  1.1  christos static SCM ppscm_array_string;
    122  1.1  christos static SCM ppscm_string_string;
    123  1.1  christos 
    124  1.1  christos /* Administrivia for pretty-printer matcher smobs.  */
    126  1.1  christos 
    127  1.1  christos /* The smob "print" function for <gdb:pretty-printer>.  */
    128  1.1  christos 
    129  1.1  christos static int
    130  1.1  christos ppscm_print_pretty_printer_smob (SCM self, SCM port, scm_print_state *pstate)
    131  1.1  christos {
    132  1.1  christos   pretty_printer_smob *pp_smob = (pretty_printer_smob *) SCM_SMOB_DATA (self);
    133  1.1  christos 
    134  1.1  christos   gdbscm_printf (port, "#<%s ", pretty_printer_smob_name);
    135  1.1  christos   scm_write (pp_smob->name, port);
    136  1.1  christos   scm_puts (gdbscm_is_true (pp_smob->enabled) ? " enabled" : " disabled",
    137  1.1  christos 	    port);
    138  1.1  christos   scm_puts (">", port);
    139  1.1  christos 
    140  1.1  christos   scm_remember_upto_here_1 (self);
    141  1.1  christos 
    142  1.1  christos   /* Non-zero means success.  */
    143  1.1  christos   return 1;
    144  1.1  christos }
    145  1.1  christos 
    146  1.1  christos /* (make-pretty-printer string procedure) -> <gdb:pretty-printer> */
    147  1.1  christos 
    148  1.1  christos static SCM
    149  1.1  christos gdbscm_make_pretty_printer (SCM name, SCM lookup)
    150  1.1  christos {
    151  1.1  christos   pretty_printer_smob *pp_smob = (pretty_printer_smob *)
    152  1.1  christos     scm_gc_malloc (sizeof (pretty_printer_smob),
    153  1.1  christos 		   pretty_printer_smob_name);
    154  1.1  christos   SCM smob;
    155  1.1  christos 
    156  1.1  christos   SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG1, FUNC_NAME,
    157  1.1  christos 		   _("string"));
    158  1.1  christos   SCM_ASSERT_TYPE (gdbscm_is_procedure (lookup), lookup, SCM_ARG2, FUNC_NAME,
    159  1.1  christos 		   _("procedure"));
    160  1.1  christos 
    161  1.1  christos   pp_smob->name = name;
    162  1.1  christos   pp_smob->lookup = lookup;
    163  1.1  christos   pp_smob->enabled = SCM_BOOL_T;
    164  1.1  christos   smob = scm_new_smob (pretty_printer_smob_tag, (scm_t_bits) pp_smob);
    165  1.1  christos   gdbscm_init_gsmob (&pp_smob->base);
    166  1.1  christos 
    167  1.1  christos   return smob;
    168  1.1  christos }
    169  1.1  christos 
    170  1.1  christos /* Return non-zero if SCM is a <gdb:pretty-printer> object.  */
    171  1.1  christos 
    172  1.1  christos static int
    173  1.1  christos ppscm_is_pretty_printer (SCM scm)
    174  1.1  christos {
    175  1.1  christos   return SCM_SMOB_PREDICATE (pretty_printer_smob_tag, scm);
    176  1.1  christos }
    177  1.1  christos 
    178  1.1  christos /* (pretty-printer? object) -> boolean */
    179  1.1  christos 
    180  1.1  christos static SCM
    181  1.1  christos gdbscm_pretty_printer_p (SCM scm)
    182  1.1  christos {
    183  1.1  christos   return scm_from_bool (ppscm_is_pretty_printer (scm));
    184  1.1  christos }
    185  1.1  christos 
    186  1.1  christos /* Returns the <gdb:pretty-printer> object in SELF.
    187  1.1  christos    Throws an exception if SELF is not a <gdb:pretty-printer> object.  */
    188  1.1  christos 
    189  1.1  christos static SCM
    190  1.1  christos ppscm_get_pretty_printer_arg_unsafe (SCM self, int arg_pos,
    191  1.1  christos 				     const char *func_name)
    192  1.1  christos {
    193  1.1  christos   SCM_ASSERT_TYPE (ppscm_is_pretty_printer (self), self, arg_pos, func_name,
    194  1.1  christos 		   pretty_printer_smob_name);
    195  1.1  christos 
    196  1.1  christos   return self;
    197  1.1  christos }
    198  1.1  christos 
    199  1.1  christos /* Returns a pointer to the pretty-printer smob of SELF.
    200  1.1  christos    Throws an exception if SELF is not a <gdb:pretty-printer> object.  */
    201  1.1  christos 
    202  1.1  christos static pretty_printer_smob *
    203  1.1  christos ppscm_get_pretty_printer_smob_arg_unsafe (SCM self, int arg_pos,
    204  1.1  christos 					  const char *func_name)
    205  1.1  christos {
    206  1.1  christos   SCM pp_scm = ppscm_get_pretty_printer_arg_unsafe (self, arg_pos, func_name);
    207  1.1  christos   pretty_printer_smob *pp_smob
    208  1.1  christos     = (pretty_printer_smob *) SCM_SMOB_DATA (pp_scm);
    209  1.1  christos 
    210  1.1  christos   return pp_smob;
    211  1.1  christos }
    212  1.1  christos 
    213  1.1  christos /* Pretty-printer methods.  */
    215  1.1  christos 
    216  1.1  christos /* (pretty-printer-enabled? <gdb:pretty-printer>) -> boolean */
    217  1.1  christos 
    218  1.1  christos static SCM
    219  1.1  christos gdbscm_pretty_printer_enabled_p (SCM self)
    220  1.1  christos {
    221  1.1  christos   pretty_printer_smob *pp_smob
    222  1.1  christos     = ppscm_get_pretty_printer_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    223  1.1  christos 
    224  1.1  christos   return pp_smob->enabled;
    225  1.1  christos }
    226  1.1  christos 
    227  1.1  christos /* (set-pretty-printer-enabled! <gdb:pretty-printer> boolean)
    228  1.1  christos      -> unspecified */
    229  1.1  christos 
    230  1.1  christos static SCM
    231  1.1  christos gdbscm_set_pretty_printer_enabled_x (SCM self, SCM enabled)
    232  1.1  christos {
    233  1.1  christos   pretty_printer_smob *pp_smob
    234  1.1  christos     = ppscm_get_pretty_printer_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    235  1.1  christos 
    236  1.1  christos   pp_smob->enabled = scm_from_bool (gdbscm_is_true (enabled));
    237  1.1  christos 
    238  1.1  christos   return SCM_UNSPECIFIED;
    239  1.1  christos }
    240  1.1  christos 
    241  1.1  christos /* (pretty-printers) -> list
    242  1.1  christos    Returns the list of global pretty-printers.  */
    243  1.1  christos 
    244  1.1  christos static SCM
    245  1.1  christos gdbscm_pretty_printers (void)
    246  1.1  christos {
    247  1.1  christos   return pretty_printer_list;
    248  1.1  christos }
    249  1.1  christos 
    250  1.1  christos /* (set-pretty-printers! list) -> unspecified
    251  1.1  christos    Set the global pretty-printers list.  */
    252  1.1  christos 
    253  1.1  christos static SCM
    254  1.1  christos gdbscm_set_pretty_printers_x (SCM printers)
    255  1.1  christos {
    256  1.1  christos   SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
    257  1.1  christos 		   SCM_ARG1, FUNC_NAME, _("list"));
    258  1.1  christos 
    259  1.1  christos   pretty_printer_list = printers;
    260  1.1  christos 
    261  1.1  christos   return SCM_UNSPECIFIED;
    262  1.1  christos }
    263  1.1  christos 
    264  1.1  christos /* Administrivia for pretty-printer-worker smobs.
    266  1.1  christos    These are created when a matcher recognizes a value.  */
    267  1.1  christos 
    268  1.1  christos /* The smob "print" function for <gdb:pretty-printer-worker>.  */
    269  1.1  christos 
    270  1.1  christos static int
    271  1.1  christos ppscm_print_pretty_printer_worker_smob (SCM self, SCM port,
    272  1.1  christos 					scm_print_state *pstate)
    273  1.1  christos {
    274  1.1  christos   pretty_printer_worker_smob *w_smob
    275  1.1  christos     = (pretty_printer_worker_smob *) SCM_SMOB_DATA (self);
    276  1.1  christos 
    277  1.1  christos   gdbscm_printf (port, "#<%s ", pretty_printer_worker_smob_name);
    278  1.1  christos   scm_write (w_smob->display_hint, port);
    279  1.1  christos   scm_puts (" ", port);
    280  1.1  christos   scm_write (w_smob->to_string, port);
    281  1.1  christos   scm_puts (" ", port);
    282  1.1  christos   scm_write (w_smob->children, port);
    283  1.1  christos   scm_puts (">", port);
    284  1.1  christos 
    285  1.1  christos   scm_remember_upto_here_1 (self);
    286  1.1  christos 
    287  1.1  christos   /* Non-zero means success.  */
    288  1.1  christos   return 1;
    289  1.1  christos }
    290  1.1  christos 
    291  1.1  christos /* (make-pretty-printer-worker string procedure procedure)
    292  1.1  christos      -> <gdb:pretty-printer-worker> */
    293  1.1  christos 
    294  1.1  christos static SCM
    295  1.1  christos gdbscm_make_pretty_printer_worker (SCM display_hint, SCM to_string,
    296  1.1  christos 				   SCM children)
    297  1.1  christos {
    298  1.1  christos   pretty_printer_worker_smob *w_smob = (pretty_printer_worker_smob *)
    299  1.1  christos     scm_gc_malloc (sizeof (pretty_printer_worker_smob),
    300  1.1  christos 		   pretty_printer_worker_smob_name);
    301  1.1  christos   SCM w_scm;
    302  1.1  christos 
    303  1.1  christos   w_smob->display_hint = display_hint;
    304  1.1  christos   w_smob->to_string = to_string;
    305  1.1  christos   w_smob->children = children;
    306  1.1  christos   w_scm = scm_new_smob (pretty_printer_worker_smob_tag, (scm_t_bits) w_smob);
    307  1.1  christos   gdbscm_init_gsmob (&w_smob->base);
    308  1.1  christos   return w_scm;
    309  1.1  christos }
    310  1.1  christos 
    311  1.1  christos /* Return non-zero if SCM is a <gdb:pretty-printer-worker> object.  */
    312  1.1  christos 
    313  1.1  christos static int
    314  1.1  christos ppscm_is_pretty_printer_worker (SCM scm)
    315  1.1  christos {
    316  1.1  christos   return SCM_SMOB_PREDICATE (pretty_printer_worker_smob_tag, scm);
    317  1.1  christos }
    318  1.1  christos 
    319  1.1  christos /* (pretty-printer-worker? object) -> boolean */
    320  1.1  christos 
    321  1.1  christos static SCM
    322  1.1  christos gdbscm_pretty_printer_worker_p (SCM scm)
    323  1.1  christos {
    324  1.1  christos   return scm_from_bool (ppscm_is_pretty_printer_worker (scm));
    325  1.1  christos }
    326  1.1  christos 
    327  1.1  christos /* Helper function to create a <gdb:exception> object indicating that the
    329  1.1  christos    type of some value returned from a pretty-printer is invalid.  */
    330  1.6  christos 
    331  1.6  christos static SCM
    332  1.6  christos ppscm_make_pp_type_error_exception (const char *message, SCM object)
    333  1.6  christos {
    334  1.1  christos   std::string msg = string_printf ("%s: ~S", message);
    335  1.1  christos   return gdbscm_make_error (pp_type_error_symbol,
    336  1.1  christos 			    NULL /* func */, msg.c_str (),
    337  1.1  christos 			    scm_list_1 (object), scm_list_1 (object));
    338  1.1  christos }
    339  1.1  christos 
    340  1.1  christos /* Print MESSAGE as an exception (meaning it is controlled by
    341  1.1  christos    "guile print-stack").
    342  1.1  christos    Called from the printer code when the Scheme code returns an invalid type
    343  1.1  christos    for something.  */
    344  1.1  christos 
    345  1.1  christos static void
    346  1.1  christos ppscm_print_pp_type_error (const char *message, SCM object)
    347  1.1  christos {
    348  1.1  christos   SCM exception = ppscm_make_pp_type_error_exception (message, object);
    349  1.1  christos 
    350  1.1  christos   gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
    351  1.1  christos }
    352  1.1  christos 
    353  1.1  christos /* Helper function for find_pretty_printer which iterates over a list,
    354  1.1  christos    calls each function and inspects output.  This will return a
    355  1.1  christos    <gdb:pretty-printer> object if one recognizes VALUE.  If no printer is
    356  1.1  christos    found, it will return #f.  On error, it will return a <gdb:exception>
    357  1.1  christos    object.
    358  1.1  christos 
    359  1.1  christos    Note: This has to be efficient and careful.
    360  1.1  christos    We don't want to excessively slow down printing of values, but any kind of
    361  1.1  christos    random crud can appear in the pretty-printer list, and we can't crash
    362  1.1  christos    because of it.  */
    363  1.1  christos 
    364  1.1  christos static SCM
    365  1.1  christos ppscm_search_pp_list (SCM list, SCM value)
    366  1.1  christos {
    367  1.1  christos   SCM orig_list = list;
    368  1.1  christos 
    369  1.1  christos   if (scm_is_null (list))
    370  1.1  christos     return SCM_BOOL_F;
    371  1.1  christos   if (gdbscm_is_false (scm_list_p (list))) /* scm_is_pair? */
    372  1.1  christos     {
    373  1.1  christos       return ppscm_make_pp_type_error_exception
    374  1.1  christos 	(_("pretty-printer list is not a list"), list);
    375  1.1  christos     }
    376  1.1  christos 
    377  1.1  christos   for ( ; scm_is_pair (list); list = scm_cdr (list))
    378  1.1  christos     {
    379  1.1  christos       SCM matcher = scm_car (list);
    380  1.1  christos       SCM worker;
    381  1.1  christos       pretty_printer_smob *pp_smob;
    382  1.1  christos 
    383  1.1  christos       if (!ppscm_is_pretty_printer (matcher))
    384  1.1  christos 	{
    385  1.1  christos 	  return ppscm_make_pp_type_error_exception
    386  1.1  christos 	    (_("pretty-printer list contains non-pretty-printer object"),
    387  1.1  christos 	     matcher);
    388  1.1  christos 	}
    389  1.1  christos 
    390  1.1  christos       pp_smob = (pretty_printer_smob *) SCM_SMOB_DATA (matcher);
    391  1.1  christos 
    392  1.1  christos       /* Skip if disabled.  */
    393  1.1  christos       if (gdbscm_is_false (pp_smob->enabled))
    394  1.1  christos 	continue;
    395  1.1  christos 
    396  1.1  christos       if (!gdbscm_is_procedure (pp_smob->lookup))
    397  1.1  christos 	{
    398  1.1  christos 	  return ppscm_make_pp_type_error_exception
    399  1.1  christos 	    (_("invalid lookup object in pretty-printer matcher"),
    400  1.1  christos 	     pp_smob->lookup);
    401  1.1  christos 	}
    402  1.1  christos 
    403  1.1  christos       worker = gdbscm_safe_call_2 (pp_smob->lookup, matcher,
    404  1.1  christos 				   value, gdbscm_memory_error_p);
    405  1.1  christos       if (!gdbscm_is_false (worker))
    406  1.1  christos 	{
    407  1.1  christos 	  if (gdbscm_is_exception (worker))
    408  1.1  christos 	    return worker;
    409  1.1  christos 	  if (ppscm_is_pretty_printer_worker (worker))
    410  1.1  christos 	    return worker;
    411  1.1  christos 	  return ppscm_make_pp_type_error_exception
    412  1.1  christos 	    (_("invalid result from pretty-printer lookup"), worker);
    413  1.1  christos 	}
    414  1.1  christos     }
    415  1.1  christos 
    416  1.1  christos   if (!scm_is_null (list))
    417  1.1  christos     {
    418  1.1  christos       return ppscm_make_pp_type_error_exception
    419  1.1  christos 	(_("pretty-printer list is not a list"), orig_list);
    420  1.1  christos     }
    421  1.1  christos 
    422  1.1  christos   return SCM_BOOL_F;
    423  1.1  christos }
    424  1.1  christos 
    425  1.1  christos /* Subroutine of find_pretty_printer to simplify it.
    426  1.1  christos    Look for a pretty-printer to print VALUE in all objfiles.
    427  1.1  christos    If there's an error an exception smob is returned.
    428  1.1  christos    The result is #f, if no pretty-printer was found.
    429  1.1  christos    Otherwise the result is the pretty-printer smob.  */
    430  1.6  christos 
    431  1.6  christos static SCM
    432  1.6  christos ppscm_find_pretty_printer_from_objfiles (SCM value)
    433  1.6  christos {
    434  1.6  christos   for (objfile *objfile : current_program_space->objfiles ())
    435  1.6  christos     {
    436  1.6  christos       objfile_smob *o_smob = ofscm_objfile_smob_from_objfile (objfile);
    437  1.6  christos       SCM pp
    438  1.6  christos 	= ppscm_search_pp_list (ofscm_objfile_smob_pretty_printers (o_smob),
    439  1.6  christos 				value);
    440  1.6  christos 
    441  1.6  christos       /* Note: This will return if pp is a <gdb:exception> object,
    442  1.1  christos 	 which is what we want.  */
    443  1.1  christos       if (gdbscm_is_true (pp))
    444  1.1  christos 	return pp;
    445  1.1  christos     }
    446  1.1  christos 
    447  1.1  christos   return SCM_BOOL_F;
    448  1.1  christos }
    449  1.1  christos 
    450  1.1  christos /* Subroutine of find_pretty_printer to simplify it.
    451  1.1  christos    Look for a pretty-printer to print VALUE in the current program space.
    452  1.1  christos    If there's an error an exception smob is returned.
    453  1.1  christos    The result is #f, if no pretty-printer was found.
    454  1.1  christos    Otherwise the result is the pretty-printer smob.  */
    455  1.1  christos 
    456  1.1  christos static SCM
    457  1.1  christos ppscm_find_pretty_printer_from_progspace (SCM value)
    458  1.1  christos {
    459  1.1  christos   pspace_smob *p_smob = psscm_pspace_smob_from_pspace (current_program_space);
    460  1.1  christos   SCM pp
    461  1.1  christos     = ppscm_search_pp_list (psscm_pspace_smob_pretty_printers (p_smob), value);
    462  1.1  christos 
    463  1.1  christos   return pp;
    464  1.1  christos }
    465  1.1  christos 
    466  1.1  christos /* Subroutine of find_pretty_printer to simplify it.
    467  1.1  christos    Look for a pretty-printer to print VALUE in the gdb module.
    468  1.1  christos    If there's an error a Scheme exception is returned.
    469  1.1  christos    The result is #f, if no pretty-printer was found.
    470  1.1  christos    Otherwise the result is the pretty-printer smob.  */
    471  1.1  christos 
    472  1.1  christos static SCM
    473  1.1  christos ppscm_find_pretty_printer_from_gdb (SCM value)
    474  1.1  christos {
    475  1.1  christos   SCM pp = ppscm_search_pp_list (pretty_printer_list, value);
    476  1.1  christos 
    477  1.1  christos   return pp;
    478  1.1  christos }
    479  1.1  christos 
    480  1.1  christos /* Find the pretty-printing constructor function for VALUE.  If no
    481  1.1  christos    pretty-printer exists, return #f.  If one exists, return the
    482  1.1  christos    gdb:pretty-printer smob that implements it.  On error, an exception smob
    483  1.1  christos    is returned.
    484  1.1  christos 
    485  1.1  christos    Note: In the end it may be better to call out to Scheme once, and then
    486  1.1  christos    do all of the lookup from Scheme.  TBD.  */
    487  1.1  christos 
    488  1.1  christos static SCM
    489  1.1  christos ppscm_find_pretty_printer (SCM value)
    490  1.1  christos {
    491  1.1  christos   SCM pp;
    492  1.1  christos 
    493  1.1  christos   /* Look at the pretty-printer list for each objfile
    494  1.1  christos      in the current program-space.  */
    495  1.1  christos   pp = ppscm_find_pretty_printer_from_objfiles (value);
    496  1.1  christos   /* Note: This will return if function is a <gdb:exception> object,
    497  1.1  christos      which is what we want.  */
    498  1.1  christos   if (gdbscm_is_true (pp))
    499  1.1  christos     return pp;
    500  1.1  christos 
    501  1.1  christos   /* Look at the pretty-printer list for the current program-space.  */
    502  1.1  christos   pp = ppscm_find_pretty_printer_from_progspace (value);
    503  1.1  christos   /* Note: This will return if function is a <gdb:exception> object,
    504  1.1  christos      which is what we want.  */
    505  1.1  christos   if (gdbscm_is_true (pp))
    506  1.1  christos     return pp;
    507  1.1  christos 
    508  1.1  christos   /* Look at the pretty-printer list in the gdb module.  */
    509  1.1  christos   pp = ppscm_find_pretty_printer_from_gdb (value);
    510  1.1  christos   return pp;
    511  1.1  christos }
    512  1.1  christos 
    513  1.1  christos /* Pretty-print a single value, via the PRINTER, which must be a
    514  1.1  christos    <gdb:pretty-printer-worker> object.
    515  1.1  christos    The caller is responsible for ensuring PRINTER is valid.
    516  1.1  christos    If the function returns a string, an SCM containing the string
    517  1.1  christos    is returned.  If the function returns #f that means the pretty
    518  1.1  christos    printer returned #f as a value.  Otherwise, if the function returns a
    519  1.1  christos    <gdb:value> object, *OUT_VALUE is set to the value and #t is returned.
    520  1.1  christos    It is an error if the printer returns #t.
    521  1.1  christos    On error, an exception smob is returned.  */
    522  1.1  christos 
    523  1.1  christos static SCM
    524  1.1  christos ppscm_pretty_print_one_value (SCM printer, struct value **out_value,
    525  1.1  christos 			      struct gdbarch *gdbarch,
    526  1.1  christos 			      const struct language_defn *language)
    527  1.7  christos {
    528  1.1  christos   SCM result = SCM_BOOL_F;
    529  1.1  christos 
    530  1.1  christos   *out_value = NULL;
    531  1.1  christos   try
    532  1.1  christos     {
    533  1.1  christos       pretty_printer_worker_smob *w_smob
    534  1.1  christos 	= (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
    535  1.1  christos 
    536  1.1  christos       result = gdbscm_safe_call_1 (w_smob->to_string, printer,
    537  1.1  christos 				   gdbscm_memory_error_p);
    538  1.1  christos       if (gdbscm_is_false (result))
    539  1.1  christos 	; /* Done.  */
    540  1.1  christos       else if (scm_is_string (result)
    541  1.1  christos 	       || lsscm_is_lazy_string (result))
    542  1.1  christos 	; /* Done.  */
    543  1.1  christos       else if (vlscm_is_value (result))
    544  1.1  christos 	{
    545  1.1  christos 	  SCM except_scm;
    546  1.1  christos 
    547  1.1  christos 	  *out_value
    548  1.1  christos 	    = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
    549  1.1  christos 					       result, &except_scm,
    550  1.1  christos 					       gdbarch, language);
    551  1.1  christos 	  if (*out_value != NULL)
    552  1.1  christos 	    result = SCM_BOOL_T;
    553  1.1  christos 	  else
    554  1.1  christos 	    result = except_scm;
    555  1.1  christos 	}
    556  1.1  christos       else if (gdbscm_is_exception (result))
    557  1.1  christos 	; /* Done.  */
    558  1.1  christos       else
    559  1.1  christos 	{
    560  1.1  christos 	  /* Invalid result from to-string.  */
    561  1.9  christos 	  result = ppscm_make_pp_type_error_exception
    562  1.9  christos 	    (_("invalid result from pretty-printer to-string"), result);
    563  1.9  christos 	}
    564  1.9  christos     }
    565  1.7  christos   catch (const gdb_exception_forced_quit &except)
    566  1.3  christos     {
    567  1.3  christos       quit_force (NULL, 0);
    568  1.1  christos     }
    569  1.1  christos   catch (const gdb_exception &except)
    570  1.1  christos     {
    571  1.1  christos     }
    572  1.1  christos 
    573  1.1  christos   return result;
    574  1.1  christos }
    575  1.1  christos 
    576  1.1  christos /* Return the display hint for PRINTER as a Scheme object.
    577  1.1  christos    The caller is responsible for ensuring PRINTER is a
    578  1.1  christos    <gdb:pretty-printer-worker> object.  */
    579  1.1  christos 
    580  1.1  christos static SCM
    581  1.1  christos ppscm_get_display_hint_scm (SCM printer)
    582  1.1  christos {
    583  1.1  christos   pretty_printer_worker_smob *w_smob
    584  1.1  christos     = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
    585  1.1  christos 
    586  1.1  christos   return w_smob->display_hint;
    587  1.1  christos }
    588  1.1  christos 
    589  1.1  christos /* Return the display hint for the pretty-printer PRINTER.
    590  1.1  christos    The caller is responsible for ensuring PRINTER is a
    591  1.1  christos    <gdb:pretty-printer-worker> object.
    592  1.1  christos    Returns the display hint or #f if the hint is not a string.  */
    593  1.1  christos 
    594  1.1  christos static enum display_hint
    595  1.1  christos ppscm_get_display_hint_enum (SCM printer)
    596  1.1  christos {
    597  1.1  christos   SCM hint = ppscm_get_display_hint_scm (printer);
    598  1.1  christos 
    599  1.1  christos   if (gdbscm_is_false (hint))
    600  1.1  christos     return HINT_NONE;
    601  1.1  christos   if (scm_is_string (hint))
    602  1.1  christos     {
    603  1.1  christos       if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_array_string)))
    604  1.1  christos 	return HINT_STRING;
    605  1.1  christos       if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_map_string)))
    606  1.1  christos 	return HINT_STRING;
    607  1.1  christos       if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_string_string)))
    608  1.1  christos 	return HINT_STRING;
    609  1.1  christos       return HINT_ERROR;
    610  1.1  christos     }
    611  1.1  christos   return HINT_ERROR;
    612  1.1  christos }
    613  1.1  christos 
    614  1.1  christos /* A wrapper for gdbscm_print_gdb_exception that ignores memory errors.
    615  1.1  christos    EXCEPTION is a <gdb:exception> object.  */
    616  1.1  christos 
    617  1.1  christos static void
    618  1.1  christos ppscm_print_exception_unless_memory_error (SCM exception,
    619  1.6  christos 					   struct ui_file *stream)
    620  1.6  christos {
    621  1.1  christos   if (gdbscm_memory_error_p (gdbscm_exception_key (exception)))
    622  1.1  christos     {
    623  1.6  christos       gdb::unique_xmalloc_ptr<char> msg
    624  1.8  christos 	= gdbscm_exception_message_to_string (exception);
    625  1.1  christos 
    626  1.1  christos       /* This "shouldn't happen", but play it safe.  */
    627  1.1  christos       if (msg == NULL || msg.get ()[0] == '\0')
    628  1.1  christos 	gdb_printf (stream, _("<error reading variable>"));
    629  1.1  christos       else
    630  1.6  christos 	{
    631  1.6  christos 	  /* Remove the trailing newline.  We could instead call a special
    632  1.1  christos 	     routine for printing memory error messages, but this is easy
    633  1.6  christos 	     enough for now.  */
    634  1.6  christos 	  char *msg_text = msg.get ();
    635  1.8  christos 	  size_t len = strlen (msg_text);
    636  1.1  christos 
    637  1.1  christos 	  if (msg_text[len - 1] == '\n')
    638  1.1  christos 	    msg_text[len - 1] = '\0';
    639  1.1  christos 	  gdb_printf (stream, _("<error reading variable: %s>"), msg_text);
    640  1.1  christos 	}
    641  1.1  christos     }
    642  1.1  christos   else
    643  1.1  christos     gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
    644  1.1  christos }
    645  1.8  christos 
    646  1.1  christos /* Helper for gdbscm_apply_val_pretty_printer which calls to_string and
    647  1.1  christos    formats the result.  */
    648  1.1  christos 
    649  1.1  christos static enum guile_string_repr_result
    650  1.1  christos ppscm_print_string_repr (SCM printer, enum display_hint hint,
    651  1.1  christos 			 struct ui_file *stream, int recurse,
    652  1.1  christos 			 const struct value_print_options *options,
    653  1.1  christos 			 struct gdbarch *gdbarch,
    654  1.8  christos 			 const struct language_defn *language)
    655  1.1  christos {
    656  1.1  christos   struct value *replacement = NULL;
    657  1.1  christos   SCM str_scm;
    658  1.1  christos   enum guile_string_repr_result result = STRING_REPR_ERROR;
    659  1.1  christos 
    660  1.1  christos   str_scm = ppscm_pretty_print_one_value (printer, &replacement,
    661  1.1  christos 					  gdbarch, language);
    662  1.1  christos   if (gdbscm_is_false (str_scm))
    663  1.1  christos     {
    664  1.1  christos       result = STRING_REPR_NONE;
    665  1.1  christos     }
    666  1.1  christos   else if (scm_is_eq (str_scm, SCM_BOOL_T))
    667  1.9  christos     {
    668  1.1  christos       struct value_print_options opts = *options;
    669  1.1  christos 
    670  1.1  christos       gdb_assert (replacement != NULL);
    671  1.1  christos       opts.addressprint = false;
    672  1.1  christos       common_val_print (replacement, stream, recurse, &opts, language);
    673  1.1  christos       result = STRING_REPR_OK;
    674  1.6  christos     }
    675  1.1  christos   else if (scm_is_string (str_scm))
    676  1.1  christos     {
    677  1.1  christos       size_t length;
    678  1.1  christos       gdb::unique_xmalloc_ptr<char> string
    679  1.1  christos 	= gdbscm_scm_to_string (str_scm, &length,
    680  1.1  christos 				target_charset (gdbarch), 0 /*!strict*/, NULL);
    681  1.1  christos 
    682  1.8  christos       if (hint == HINT_STRING)
    683  1.8  christos 	{
    684  1.1  christos 	  struct type *type = builtin_type (gdbarch)->builtin_char;
    685  1.1  christos 
    686  1.1  christos 	  language->printstr (stream, type, (gdb_byte *) string.get (),
    687  1.1  christos 			      length, NULL, 0, options);
    688  1.1  christos 	}
    689  1.1  christos       else
    690  1.1  christos 	{
    691  1.1  christos 	  /* Alas scm_to_stringn doesn't nul-terminate the string if we
    692  1.1  christos 	     ask for the length.  */
    693  1.6  christos 	  size_t i;
    694  1.8  christos 
    695  1.1  christos 	  for (i = 0; i < length; ++i)
    696  1.8  christos 	    {
    697  1.1  christos 	      if (string.get ()[i] == '\0')
    698  1.1  christos 		gdb_puts ("\\000", stream);
    699  1.1  christos 	      else
    700  1.1  christos 		gdb_putc (string.get ()[i], stream);
    701  1.1  christos 	    }
    702  1.1  christos 	}
    703  1.1  christos       result = STRING_REPR_OK;
    704  1.1  christos     }
    705  1.9  christos   else if (lsscm_is_lazy_string (str_scm))
    706  1.1  christos     {
    707  1.1  christos       struct value_print_options local_opts = *options;
    708  1.1  christos 
    709  1.1  christos       local_opts.addressprint = false;
    710  1.1  christos       lsscm_val_print_lazy_string (str_scm, stream, &local_opts);
    711  1.1  christos       result = STRING_REPR_OK;
    712  1.1  christos     }
    713  1.1  christos   else
    714  1.1  christos     {
    715  1.1  christos       gdb_assert (gdbscm_is_exception (str_scm));
    716  1.1  christos       ppscm_print_exception_unless_memory_error (str_scm, stream);
    717  1.1  christos       result = STRING_REPR_ERROR;
    718  1.1  christos     }
    719  1.1  christos 
    720  1.1  christos   return result;
    721  1.1  christos }
    722  1.1  christos 
    723  1.1  christos /* Helper for gdbscm_apply_val_pretty_printer that formats children of the
    724  1.1  christos    printer, if any exist.
    725  1.1  christos    The caller is responsible for ensuring PRINTER is a printer smob.
    726  1.1  christos    If PRINTED_NOTHING is true, then nothing has been printed by to_string,
    727  1.1  christos    and format output accordingly. */
    728  1.1  christos 
    729  1.1  christos static void
    730  1.1  christos ppscm_print_children (SCM printer, enum display_hint hint,
    731  1.1  christos 		      struct ui_file *stream, int recurse,
    732  1.1  christos 		      const struct value_print_options *options,
    733  1.1  christos 		      struct gdbarch *gdbarch,
    734  1.1  christos 		      const struct language_defn *language,
    735  1.1  christos 		      int printed_nothing)
    736  1.1  christos {
    737  1.6  christos   pretty_printer_worker_smob *w_smob
    738  1.1  christos     = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
    739  1.1  christos   int is_map, is_array, done_flag, pretty;
    740  1.1  christos   unsigned int i;
    741  1.1  christos   SCM children;
    742  1.1  christos   SCM iter = SCM_BOOL_F; /* -Wall */
    743  1.1  christos 
    744  1.1  christos   if (gdbscm_is_false (w_smob->children))
    745  1.1  christos     return;
    746  1.1  christos   if (!gdbscm_is_procedure (w_smob->children))
    747  1.1  christos     {
    748  1.1  christos       ppscm_print_pp_type_error
    749  1.1  christos 	(_("pretty-printer \"children\" object is not a procedure or #f"),
    750  1.1  christos 	 w_smob->children);
    751  1.1  christos       return;
    752  1.1  christos     }
    753  1.1  christos 
    754  1.1  christos   /* If we are printing a map or an array, we want special formatting.  */
    755  1.1  christos   is_map = hint == HINT_MAP;
    756  1.1  christos   is_array = hint == HINT_ARRAY;
    757  1.1  christos 
    758  1.1  christos   children = gdbscm_safe_call_1 (w_smob->children, printer,
    759  1.1  christos 				 gdbscm_memory_error_p);
    760  1.1  christos   if (gdbscm_is_exception (children))
    761  1.1  christos     {
    762  1.1  christos       ppscm_print_exception_unless_memory_error (children, stream);
    763  1.1  christos       goto done;
    764  1.1  christos     }
    765  1.1  christos   /* We combine two steps here: get children, make an iterator out of them.
    766  1.1  christos      This simplifies things because there's no language means of creating
    767  1.1  christos      iterators, and it's the printer object that knows how it will want its
    768  1.1  christos      children iterated over.  */
    769  1.1  christos   if (!itscm_is_iterator (children))
    770  1.1  christos     {
    771  1.1  christos       ppscm_print_pp_type_error
    772  1.1  christos 	(_("result of pretty-printer \"children\" procedure is not"
    773  1.1  christos 	   " a <gdb:iterator> object"), children);
    774  1.1  christos       goto done;
    775  1.1  christos     }
    776  1.1  christos   iter = children;
    777  1.1  christos 
    778  1.1  christos   /* Use the prettyformat_arrays option if we are printing an array,
    779  1.1  christos      and the pretty option otherwise.  */
    780  1.1  christos   if (is_array)
    781  1.1  christos     pretty = options->prettyformat_arrays;
    782  1.1  christos   else
    783  1.1  christos     {
    784  1.1  christos       if (options->prettyformat == Val_prettyformat)
    785  1.1  christos 	pretty = 1;
    786  1.1  christos       else
    787  1.1  christos 	pretty = options->prettyformat_structs;
    788  1.1  christos     }
    789  1.1  christos 
    790  1.1  christos   done_flag = 0;
    791  1.1  christos   for (i = 0; i < options->print_max; ++i)
    792  1.1  christos     {
    793  1.1  christos       SCM scm_name, v_scm;
    794  1.1  christos       SCM item = itscm_safe_call_next_x (iter, gdbscm_memory_error_p);
    795  1.1  christos 
    796  1.1  christos       if (gdbscm_is_exception (item))
    797  1.1  christos 	{
    798  1.1  christos 	  ppscm_print_exception_unless_memory_error (item, stream);
    799  1.1  christos 	  break;
    800  1.1  christos 	}
    801  1.1  christos       if (itscm_is_end_of_iteration (item))
    802  1.1  christos 	{
    803  1.1  christos 	  /* Set a flag so we can know whether we printed all the
    804  1.1  christos 	     available elements.  */
    805  1.1  christos 	  done_flag = 1;
    806  1.1  christos 	  break;
    807  1.1  christos 	}
    808  1.1  christos 
    809  1.1  christos       if (! scm_is_pair (item))
    810  1.1  christos 	{
    811  1.1  christos 	  ppscm_print_pp_type_error
    812  1.1  christos 	    (_("result of pretty-printer children iterator is not a pair"
    813  1.1  christos 	       " or (end-of-iteration)"),
    814  1.1  christos 	     item);
    815  1.1  christos 	  continue;
    816  1.1  christos 	}
    817  1.1  christos       scm_name = scm_car (item);
    818  1.1  christos       v_scm = scm_cdr (item);
    819  1.1  christos       if (!scm_is_string (scm_name))
    820  1.1  christos 	{
    821  1.1  christos 	  ppscm_print_pp_type_error
    822  1.6  christos 	    (_("first element of pretty-printer children iterator is not"
    823  1.6  christos 	       " a string"), item);
    824  1.1  christos 	  continue;
    825  1.8  christos 	}
    826  1.8  christos       gdb::unique_xmalloc_ptr<char> name
    827  1.1  christos 	= gdbscm_scm_to_c_string (scm_name);
    828  1.1  christos 
    829  1.1  christos       /* Print initial "=" to separate print_string_repr output and
    830  1.1  christos 	 children.  For other elements, there are three cases:
    831  1.1  christos 	 1. Maps.  Print a "," after each value element.
    832  1.8  christos 	 2. Arrays.  Always print a ",".
    833  1.8  christos 	 3. Other.  Always print a ",".  */
    834  1.8  christos       if (i == 0)
    835  1.8  christos 	{
    836  1.8  christos 	  if (!printed_nothing)
    837  1.1  christos 	    gdb_puts (" = ", stream);
    838  1.8  christos 	}
    839  1.8  christos       else if (! is_map || i % 2 == 0)
    840  1.8  christos 	gdb_puts (pretty ? "," : ", ", stream);
    841  1.8  christos 
    842  1.8  christos       /* Skip printing children if max_depth has been reached.  This check
    843  1.8  christos 	 is performed after print_string_repr and the "=" separator so that
    844  1.8  christos 	 these steps are not skipped if the variable is located within the
    845  1.8  christos 	 permitted depth.  */
    846  1.8  christos       if (val_print_check_max_depth (stream, recurse, options, language))
    847  1.1  christos 	goto done;
    848  1.1  christos       else if (i == 0)
    849  1.1  christos 	/* Print initial "{" to bookend children.  */
    850  1.1  christos 	gdb_puts ("{", stream);
    851  1.1  christos 
    852  1.1  christos       /* In summary mode, we just want to print "= {...}" if there is
    853  1.1  christos 	 a value.  */
    854  1.1  christos       if (options->summary)
    855  1.1  christos 	{
    856  1.1  christos 	  /* This increment tricks the post-loop logic to print what
    857  1.1  christos 	     we want.  */
    858  1.1  christos 	  ++i;
    859  1.1  christos 	  /* Likewise.  */
    860  1.1  christos 	  pretty = 0;
    861  1.1  christos 	  break;
    862  1.1  christos 	}
    863  1.1  christos 
    864  1.8  christos       if (! is_map || i % 2 == 0)
    865  1.8  christos 	{
    866  1.1  christos 	  if (pretty)
    867  1.1  christos 	    {
    868  1.8  christos 	      gdb_puts ("\n", stream);
    869  1.1  christos 	      print_spaces (2 + 2 * recurse, stream);
    870  1.1  christos 	    }
    871  1.1  christos 	  else
    872  1.8  christos 	    stream->wrap_here (2 + 2 *recurse);
    873  1.1  christos 	}
    874  1.1  christos 
    875  1.1  christos       if (is_map && i % 2 == 0)
    876  1.1  christos 	gdb_puts ("[", stream);
    877  1.1  christos       else if (is_array)
    878  1.8  christos 	{
    879  1.1  christos 	  /* We print the index, not whatever the child method
    880  1.1  christos 	     returned as the name.  */
    881  1.1  christos 	  if (options->print_array_indexes)
    882  1.8  christos 	    gdb_printf (stream, "[%d] = ", i);
    883  1.8  christos 	}
    884  1.1  christos       else if (! is_map)
    885  1.1  christos 	{
    886  1.1  christos 	  gdb_puts (name.get (), stream);
    887  1.1  christos 	  gdb_puts (" = ", stream);
    888  1.1  christos 	}
    889  1.1  christos 
    890  1.9  christos       if (lsscm_is_lazy_string (v_scm))
    891  1.1  christos 	{
    892  1.1  christos 	  struct value_print_options local_opts = *options;
    893  1.1  christos 
    894  1.1  christos 	  local_opts.addressprint = false;
    895  1.6  christos 	  lsscm_val_print_lazy_string (v_scm, stream, &local_opts);
    896  1.6  christos 	}
    897  1.8  christos       else if (scm_is_string (v_scm))
    898  1.1  christos 	{
    899  1.1  christos 	  gdb::unique_xmalloc_ptr<char> output
    900  1.1  christos 	    = gdbscm_scm_to_c_string (v_scm);
    901  1.1  christos 	  gdb_puts (output.get (), stream);
    902  1.1  christos 	}
    903  1.1  christos       else
    904  1.1  christos 	{
    905  1.1  christos 	  SCM except_scm;
    906  1.1  christos 	  struct value *value
    907  1.1  christos 	    = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
    908  1.1  christos 					       v_scm, &except_scm,
    909  1.1  christos 					       gdbarch, language);
    910  1.1  christos 
    911  1.1  christos 	  if (value == NULL)
    912  1.7  christos 	    {
    913  1.7  christos 	      ppscm_print_exception_unless_memory_error (except_scm, stream);
    914  1.7  christos 	      break;
    915  1.7  christos 	    }
    916  1.7  christos 	  else
    917  1.7  christos 	    {
    918  1.7  christos 	      /* When printing the key of a map we allow one additional
    919  1.7  christos 		 level of depth.  This means the key will print before the
    920  1.7  christos 		 value does.  */
    921  1.7  christos 	      struct value_print_options opt = *options;
    922  1.7  christos 	      if (is_map && i % 2 == 0
    923  1.7  christos 		  && opt.max_depth != -1
    924  1.1  christos 		  && opt.max_depth < INT_MAX)
    925  1.1  christos 		++opt.max_depth;
    926  1.1  christos 	      common_val_print (value, stream, recurse + 1, &opt, language);
    927  1.8  christos 	    }
    928  1.1  christos 	}
    929  1.1  christos 
    930  1.1  christos       if (is_map && i % 2 == 0)
    931  1.1  christos 	gdb_puts ("] = ", stream);
    932  1.1  christos     }
    933  1.1  christos 
    934  1.1  christos   if (i)
    935  1.1  christos     {
    936  1.8  christos       if (!done_flag)
    937  1.8  christos 	{
    938  1.1  christos 	  if (pretty)
    939  1.8  christos 	    {
    940  1.1  christos 	      gdb_puts ("\n", stream);
    941  1.1  christos 	      print_spaces (2 + 2 * recurse, stream);
    942  1.1  christos 	    }
    943  1.8  christos 	  gdb_puts ("...", stream);
    944  1.8  christos 	}
    945  1.1  christos       if (pretty)
    946  1.8  christos 	{
    947  1.1  christos 	  gdb_puts ("\n", stream);
    948  1.1  christos 	  print_spaces (2 * recurse, stream);
    949  1.1  christos 	}
    950  1.1  christos       gdb_puts ("}", stream);
    951  1.1  christos     }
    952  1.1  christos 
    953  1.1  christos  done:
    954  1.1  christos   /* Play it safe, make sure ITER doesn't get GC'd.  */
    955  1.1  christos   scm_remember_upto_here_1 (iter);
    956  1.1  christos }
    957  1.1  christos 
    958  1.7  christos /* This is the extension_language_ops.apply_val_pretty_printer "method".  */
    959  1.1  christos 
    960  1.1  christos enum ext_lang_rc
    961  1.1  christos gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang,
    962  1.1  christos 				 struct value *value,
    963  1.9  christos 				 struct ui_file *stream, int recurse,
    964  1.8  christos 				 const struct value_print_options *options,
    965  1.1  christos 				 const struct language_defn *language)
    966  1.1  christos {
    967  1.1  christos   struct type *type = value->type ();
    968  1.1  christos   struct gdbarch *gdbarch = type->arch ();
    969  1.4  christos   SCM exception = SCM_BOOL_F;
    970  1.8  christos   SCM printer = SCM_BOOL_F;
    971  1.6  christos   SCM val_obj = SCM_BOOL_F;
    972  1.9  christos   enum display_hint hint;
    973  1.9  christos   enum ext_lang_rc result = EXT_LANG_RC_NOP;
    974  1.1  christos   enum guile_string_repr_result print_result;
    975  1.1  christos 
    976  1.9  christos   if (value->lazy ())
    977  1.1  christos     value->fetch_lazy ();
    978  1.1  christos 
    979  1.1  christos   /* No pretty-printer support for unavailable values.  */
    980  1.1  christos   if (!value->bytes_available (0, type->length ()))
    981  1.1  christos     return EXT_LANG_RC_NOP;
    982  1.1  christos 
    983  1.7  christos   if (!gdb_scheme_initialized)
    984  1.1  christos     return EXT_LANG_RC_NOP;
    985  1.1  christos 
    986  1.1  christos   /* Instantiate the printer.  */
    987  1.1  christos   val_obj = vlscm_scm_from_value_no_release (value);
    988  1.1  christos   if (gdbscm_is_exception (val_obj))
    989  1.1  christos     {
    990  1.1  christos       exception = val_obj;
    991  1.1  christos       result = EXT_LANG_RC_ERROR;
    992  1.1  christos       goto done;
    993  1.1  christos     }
    994  1.1  christos 
    995  1.1  christos   printer = ppscm_find_pretty_printer (val_obj);
    996  1.1  christos 
    997  1.1  christos   if (gdbscm_is_exception (printer))
    998  1.1  christos     {
    999  1.1  christos       exception = printer;
   1000  1.1  christos       result = EXT_LANG_RC_ERROR;
   1001  1.1  christos       goto done;
   1002  1.1  christos     }
   1003  1.1  christos   if (gdbscm_is_false (printer))
   1004  1.1  christos     {
   1005  1.1  christos       result = EXT_LANG_RC_NOP;
   1006  1.1  christos       goto done;
   1007  1.1  christos     }
   1008  1.1  christos   gdb_assert (ppscm_is_pretty_printer_worker (printer));
   1009  1.1  christos 
   1010  1.1  christos   /* If we are printing a map, we want some special formatting.  */
   1011  1.1  christos   hint = ppscm_get_display_hint_enum (printer);
   1012  1.1  christos   if (hint == HINT_ERROR)
   1013  1.1  christos     {
   1014  1.1  christos       /* Print the error as an exception for consistency.  */
   1015  1.1  christos       SCM hint_scm = ppscm_get_display_hint_scm (printer);
   1016  1.1  christos 
   1017  1.1  christos       ppscm_print_pp_type_error ("Invalid display hint", hint_scm);
   1018  1.1  christos       /* Fall through.  A bad hint doesn't stop pretty-printing.  */
   1019  1.1  christos       hint = HINT_NONE;
   1020  1.1  christos     }
   1021  1.1  christos 
   1022  1.1  christos   /* Print the section.  */
   1023  1.1  christos   print_result = ppscm_print_string_repr (printer, hint, stream, recurse,
   1024  1.1  christos 					  options, gdbarch, language);
   1025  1.1  christos   if (print_result != STRING_REPR_ERROR)
   1026  1.1  christos     {
   1027  1.1  christos       ppscm_print_children (printer, hint, stream, recurse, options,
   1028  1.1  christos 			    gdbarch, language,
   1029  1.1  christos 			    print_result == STRING_REPR_NONE);
   1030  1.1  christos     }
   1031  1.1  christos 
   1032  1.1  christos   result = EXT_LANG_RC_OK;
   1033  1.1  christos 
   1034  1.1  christos  done:
   1035  1.1  christos   if (gdbscm_is_exception (exception))
   1036  1.1  christos     ppscm_print_exception_unless_memory_error (exception, stream);
   1037  1.1  christos   return result;
   1038  1.1  christos }
   1039  1.1  christos 
   1040  1.4  christos /* Initialize the Scheme pretty-printer code.  */
   1042  1.1  christos 
   1043  1.1  christos static const scheme_function pretty_printer_functions[] =
   1044  1.1  christos {
   1045  1.1  christos   { "make-pretty-printer", 2, 0, 0,
   1046  1.1  christos     as_a_scm_t_subr (gdbscm_make_pretty_printer),
   1047  1.1  christos     "\
   1048  1.1  christos Create a <gdb:pretty-printer> object.\n\
   1049  1.1  christos \n\
   1050  1.4  christos   Arguments: name lookup\n\
   1051  1.1  christos     name:   a string naming the matcher\n\
   1052  1.1  christos     lookup: a procedure:\n\
   1053  1.1  christos       (pretty-printer <gdb:value>) -> <gdb:pretty-printer-worker> | #f." },
   1054  1.4  christos 
   1055  1.4  christos   { "pretty-printer?", 1, 0, 0, as_a_scm_t_subr (gdbscm_pretty_printer_p),
   1056  1.1  christos     "\
   1057  1.1  christos Return #t if the object is a <gdb:pretty-printer> object." },
   1058  1.1  christos 
   1059  1.1  christos   { "pretty-printer-enabled?", 1, 0, 0,
   1060  1.4  christos     as_a_scm_t_subr (gdbscm_pretty_printer_enabled_p),
   1061  1.1  christos     "\
   1062  1.1  christos Return #t if the pretty-printer is enabled." },
   1063  1.1  christos 
   1064  1.1  christos   { "set-pretty-printer-enabled!", 2, 0, 0,
   1065  1.4  christos     as_a_scm_t_subr (gdbscm_set_pretty_printer_enabled_x),
   1066  1.4  christos     "\
   1067  1.1  christos Set the enabled flag of the pretty-printer.\n\
   1068  1.1  christos Returns \"unspecified\"." },
   1069  1.1  christos 
   1070  1.1  christos   { "make-pretty-printer-worker", 3, 0, 0,
   1071  1.1  christos     as_a_scm_t_subr (gdbscm_make_pretty_printer_worker),
   1072  1.1  christos     "\
   1073  1.1  christos Create a <gdb:pretty-printer-worker> object.\n\
   1074  1.1  christos \n\
   1075  1.1  christos   Arguments: display-hint to-string children\n\
   1076  1.1  christos     display-hint: either #f or one of \"array\", \"map\", or \"string\"\n\
   1077  1.4  christos     to-string:    a procedure:\n\
   1078  1.4  christos       (pretty-printer) -> string | #f | <gdb:value>\n\
   1079  1.1  christos     children:     either #f or a procedure:\n\
   1080  1.1  christos       (pretty-printer) -> <gdb:iterator>" },
   1081  1.1  christos 
   1082  1.4  christos   { "pretty-printer-worker?", 1, 0, 0,
   1083  1.1  christos     as_a_scm_t_subr (gdbscm_pretty_printer_worker_p),
   1084  1.1  christos     "\
   1085  1.1  christos Return #t if the object is a <gdb:pretty-printer-worker> object." },
   1086  1.1  christos 
   1087  1.4  christos   { "pretty-printers", 0, 0, 0, as_a_scm_t_subr (gdbscm_pretty_printers),
   1088  1.1  christos     "\
   1089  1.1  christos Return the list of global pretty-printers." },
   1090  1.1  christos 
   1091  1.1  christos   { "set-pretty-printers!", 1, 0, 0,
   1092  1.1  christos     as_a_scm_t_subr (gdbscm_set_pretty_printers_x),
   1093  1.1  christos     "\
   1094  1.1  christos Set the list of global pretty-printers." },
   1095  1.1  christos 
   1096  1.1  christos   END_FUNCTIONS
   1097  1.1  christos };
   1098  1.1  christos 
   1099  1.1  christos void
   1100  1.1  christos gdbscm_initialize_pretty_printers (void)
   1101  1.1  christos {
   1102  1.1  christos   pretty_printer_smob_tag
   1103  1.1  christos     = gdbscm_make_smob_type (pretty_printer_smob_name,
   1104  1.1  christos 			     sizeof (pretty_printer_smob));
   1105  1.1  christos   scm_set_smob_print (pretty_printer_smob_tag,
   1106  1.1  christos 		      ppscm_print_pretty_printer_smob);
   1107  1.1  christos 
   1108  1.1  christos   pretty_printer_worker_smob_tag
   1109  1.1  christos     = gdbscm_make_smob_type (pretty_printer_worker_smob_name,
   1110  1.1  christos 			     sizeof (pretty_printer_worker_smob));
   1111  1.1  christos   scm_set_smob_print (pretty_printer_worker_smob_tag,
   1112  1.1  christos 		      ppscm_print_pretty_printer_worker_smob);
   1113  1.1  christos 
   1114  1.1  christos   gdbscm_define_functions (pretty_printer_functions, 1);
   1115  1.1  christos 
   1116  1.1  christos   pretty_printer_list = SCM_EOL;
   1117  1.1  christos 
   1118  1.1  christos   pp_type_error_symbol = scm_from_latin1_symbol ("gdb:pp-type-error");
   1119                
   1120                  ppscm_map_string = scm_from_latin1_string ("map");
   1121                  ppscm_array_string = scm_from_latin1_string ("array");
   1122                  ppscm_string_string = scm_from_latin1_string ("string");
   1123                }
   1124