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