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