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