Use std::string in ppscm_make_pp_type_error_exception
[deliverable/binutils-gdb.git] / gdb / guile / scm-pretty-print.c
CommitLineData
ed3ef339
DE
1/* GDB/Scheme pretty-printing.
2
e2882c85 3 Copyright (C) 2008-2018 Free Software Foundation, Inc.
ed3ef339
DE
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"
ed3ef339
DE
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
34enum 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
46enum 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
62typedef struct
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} pretty_printer_smob;
81
82/* The <gdb:pretty-printer-worker> smob. */
83
84typedef struct
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} pretty_printer_worker_smob;
103
104static const char pretty_printer_smob_name[] =
105 "gdb:pretty-printer";
106static const char pretty_printer_worker_smob_name[] =
107 "gdb:pretty-printer-worker";
108
109/* The tag Guile knows the pretty-printer smobs by. */
110static scm_t_bits pretty_printer_smob_tag;
111static scm_t_bits pretty_printer_worker_smob_tag;
112
ee7333ae
DE
113/* The global pretty-printer list. */
114static SCM pretty_printer_list;
ed3ef339
DE
115
116/* gdb:pp-type-error. */
117static SCM pp_type_error_symbol;
118
119/* Pretty-printer display hints are specified by strings. */
120static SCM ppscm_map_string;
121static SCM ppscm_array_string;
122static SCM ppscm_string_string;
123\f
124/* Administrivia for pretty-printer matcher smobs. */
125
ed3ef339
DE
126/* The smob "print" function for <gdb:pretty-printer>. */
127
128static int
129ppscm_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
147static SCM
148gdbscm_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
171static int
172ppscm_is_pretty_printer (SCM scm)
173{
174 return SCM_SMOB_PREDICATE (pretty_printer_smob_tag, scm);
175}
176
177/* (pretty-printer? object) -> boolean */
178
179static SCM
180gdbscm_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
188static SCM
189ppscm_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
201static pretty_printer_smob *
202ppscm_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\f
212/* Pretty-printer methods. */
213
214/* (pretty-printer-enabled? <gdb:pretty-printer>) -> boolean */
215
216static SCM
217gdbscm_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
228static SCM
229gdbscm_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}
ee7333ae
DE
238
239/* (pretty-printers) -> list
240 Returns the list of global pretty-printers. */
241
242static SCM
243gdbscm_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
251static SCM
252gdbscm_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}
ed3ef339
DE
261\f
262/* Administrivia for pretty-printer-worker smobs.
263 These are created when a matcher recognizes a value. */
264
ed3ef339
DE
265/* The smob "print" function for <gdb:pretty-printer-worker>. */
266
267static int
268ppscm_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
291static SCM
292gdbscm_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
310static int
311ppscm_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
318static SCM
319gdbscm_pretty_printer_worker_p (SCM scm)
320{
321 return scm_from_bool (ppscm_is_pretty_printer_worker (scm));
322}
323\f
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
327static SCM
328ppscm_make_pp_type_error_exception (const char *message, SCM object)
329{
7eb1a66c
TT
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));
ed3ef339
DE
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
341static void
342ppscm_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
360static SCM
361ppscm_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;
ed3ef339
DE
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
427static SCM
428ppscm_find_pretty_printer_from_objfiles (SCM value)
429{
430 struct objfile *objfile;
431
432 ALL_OBJFILES (objfile)
433 {
434 objfile_smob *o_smob = ofscm_objfile_smob_from_objfile (objfile);
435 SCM pp = ppscm_search_pp_list (ofscm_objfile_smob_pretty_printers (o_smob),
436 value);
437
438 /* Note: This will return if pp is a <gdb:exception> object,
439 which is what we want. */
440 if (gdbscm_is_true (pp))
441 return pp;
442 }
443
444 return SCM_BOOL_F;
445}
446
447/* Subroutine of find_pretty_printer to simplify it.
448 Look for a pretty-printer to print VALUE in the current program space.
449 If there's an error an exception smob is returned.
450 The result is #f, if no pretty-printer was found.
451 Otherwise the result is the pretty-printer smob. */
452
453static SCM
454ppscm_find_pretty_printer_from_progspace (SCM value)
455{
ded03782
DE
456 pspace_smob *p_smob = psscm_pspace_smob_from_pspace (current_program_space);
457 SCM pp
458 = ppscm_search_pp_list (psscm_pspace_smob_pretty_printers (p_smob), value);
459
460 return pp;
ed3ef339
DE
461}
462
463/* Subroutine of find_pretty_printer to simplify it.
464 Look for a pretty-printer to print VALUE in the gdb module.
465 If there's an error a Scheme exception is returned.
466 The result is #f, if no pretty-printer was found.
467 Otherwise the result is the pretty-printer smob. */
468
469static SCM
470ppscm_find_pretty_printer_from_gdb (SCM value)
471{
ee7333ae 472 SCM pp = ppscm_search_pp_list (pretty_printer_list, value);
ed3ef339 473
ed3ef339
DE
474 return pp;
475}
476
477/* Find the pretty-printing constructor function for VALUE. If no
478 pretty-printer exists, return #f. If one exists, return the
479 gdb:pretty-printer smob that implements it. On error, an exception smob
480 is returned.
481
482 Note: In the end it may be better to call out to Scheme once, and then
483 do all of the lookup from Scheme. TBD. */
484
485static SCM
486ppscm_find_pretty_printer (SCM value)
487{
488 SCM pp;
489
490 /* Look at the pretty-printer list for each objfile
491 in the current program-space. */
492 pp = ppscm_find_pretty_printer_from_objfiles (value);
493 /* Note: This will return if function is a <gdb:exception> object,
494 which is what we want. */
495 if (gdbscm_is_true (pp))
496 return pp;
497
498 /* Look at the pretty-printer list for the current program-space. */
499 pp = ppscm_find_pretty_printer_from_progspace (value);
500 /* Note: This will return if function is a <gdb:exception> object,
501 which is what we want. */
502 if (gdbscm_is_true (pp))
503 return pp;
504
505 /* Look at the pretty-printer list in the gdb module. */
506 pp = ppscm_find_pretty_printer_from_gdb (value);
507 return pp;
508}
509
510/* Pretty-print a single value, via the PRINTER, which must be a
511 <gdb:pretty-printer-worker> object.
512 The caller is responsible for ensuring PRINTER is valid.
513 If the function returns a string, an SCM containing the string
514 is returned. If the function returns #f that means the pretty
515 printer returned #f as a value. Otherwise, if the function returns a
516 <gdb:value> object, *OUT_VALUE is set to the value and #t is returned.
517 It is an error if the printer returns #t.
518 On error, an exception smob is returned. */
519
520static SCM
521ppscm_pretty_print_one_value (SCM printer, struct value **out_value,
522 struct gdbarch *gdbarch,
523 const struct language_defn *language)
524{
ed3ef339
DE
525 SCM result = SCM_BOOL_F;
526
527 *out_value = NULL;
492d29ea 528 TRY
ed3ef339 529 {
ed3ef339
DE
530 pretty_printer_worker_smob *w_smob
531 = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
532
533 result = gdbscm_safe_call_1 (w_smob->to_string, printer,
534 gdbscm_memory_error_p);
535 if (gdbscm_is_false (result))
536 ; /* Done. */
537 else if (scm_is_string (result)
538 || lsscm_is_lazy_string (result))
539 ; /* Done. */
540 else if (vlscm_is_value (result))
541 {
542 SCM except_scm;
543
544 *out_value
545 = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
546 result, &except_scm,
547 gdbarch, language);
548 if (*out_value != NULL)
549 result = SCM_BOOL_T;
550 else
551 result = except_scm;
552 }
553 else if (gdbscm_is_exception (result))
554 ; /* Done. */
555 else
556 {
557 /* Invalid result from to-string. */
558 result = ppscm_make_pp_type_error_exception
559 (_("invalid result from pretty-printer to-string"), result);
560 }
561 }
492d29ea
PA
562 CATCH (except, RETURN_MASK_ALL)
563 {
564 }
565 END_CATCH
ed3ef339
DE
566
567 return result;
568}
569
570/* Return the display hint for PRINTER as a Scheme object.
571 The caller is responsible for ensuring PRINTER is a
572 <gdb:pretty-printer-worker> object. */
573
574static SCM
575ppscm_get_display_hint_scm (SCM printer)
576{
577 pretty_printer_worker_smob *w_smob
578 = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
579
580 return w_smob->display_hint;
581}
582
583/* Return the display hint for the pretty-printer PRINTER.
584 The caller is responsible for ensuring PRINTER is a
585 <gdb:pretty-printer-worker> object.
586 Returns the display hint or #f if the hint is not a string. */
587
588static enum display_hint
589ppscm_get_display_hint_enum (SCM printer)
590{
591 SCM hint = ppscm_get_display_hint_scm (printer);
592
593 if (gdbscm_is_false (hint))
594 return HINT_NONE;
595 if (scm_is_string (hint))
596 {
597 if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_array_string)))
598 return HINT_STRING;
599 if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_map_string)))
600 return HINT_STRING;
601 if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_string_string)))
602 return HINT_STRING;
603 return HINT_ERROR;
604 }
605 return HINT_ERROR;
606}
607
608/* A wrapper for gdbscm_print_gdb_exception that ignores memory errors.
609 EXCEPTION is a <gdb:exception> object. */
610
611static void
612ppscm_print_exception_unless_memory_error (SCM exception,
613 struct ui_file *stream)
614{
615 if (gdbscm_memory_error_p (gdbscm_exception_key (exception)))
616 {
617 char *msg = gdbscm_exception_message_to_string (exception);
618 struct cleanup *cleanup = make_cleanup (xfree, msg);
619
620 /* This "shouldn't happen", but play it safe. */
621 if (msg == NULL || *msg == '\0')
622 fprintf_filtered (stream, _("<error reading variable>"));
623 else
624 {
625 /* Remove the trailing newline. We could instead call a special
626 routine for printing memory error messages, but this is easy
627 enough for now. */
628 size_t len = strlen (msg);
629
630 if (msg[len - 1] == '\n')
631 msg[len - 1] = '\0';
632 fprintf_filtered (stream, _("<error reading variable: %s>"), msg);
633 }
634
635 do_cleanups (cleanup);
636 }
637 else
638 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
639}
640
641/* Helper for gdbscm_apply_val_pretty_printer which calls to_string and
642 formats the result. */
643
644static enum string_repr_result
645ppscm_print_string_repr (SCM printer, enum display_hint hint,
646 struct ui_file *stream, int recurse,
647 const struct value_print_options *options,
648 struct gdbarch *gdbarch,
649 const struct language_defn *language)
650{
651 struct value *replacement = NULL;
652 SCM str_scm;
653 enum string_repr_result result = STRING_REPR_ERROR;
654
655 str_scm = ppscm_pretty_print_one_value (printer, &replacement,
656 gdbarch, language);
657 if (gdbscm_is_false (str_scm))
658 {
659 result = STRING_REPR_NONE;
660 }
661 else if (scm_is_eq (str_scm, SCM_BOOL_T))
662 {
663 struct value_print_options opts = *options;
664
665 gdb_assert (replacement != NULL);
666 opts.addressprint = 0;
667 common_val_print (replacement, stream, recurse, &opts, language);
668 result = STRING_REPR_OK;
669 }
670 else if (scm_is_string (str_scm))
671 {
672 struct cleanup *cleanup;
673 size_t length;
674 char *string
675 = gdbscm_scm_to_string (str_scm, &length,
676 target_charset (gdbarch), 0 /*!strict*/, NULL);
677
678 cleanup = make_cleanup (xfree, string);
679 if (hint == HINT_STRING)
680 {
681 struct type *type = builtin_type (gdbarch)->builtin_char;
682
683 LA_PRINT_STRING (stream, type, (gdb_byte *) string,
684 length, NULL, 0, options);
685 }
686 else
687 {
688 /* Alas scm_to_stringn doesn't nul-terminate the string if we
689 ask for the length. */
690 size_t i;
691
692 for (i = 0; i < length; ++i)
693 {
694 if (string[i] == '\0')
695 fputs_filtered ("\\000", stream);
696 else
697 fputc_filtered (string[i], stream);
698 }
699 }
700 result = STRING_REPR_OK;
701 do_cleanups (cleanup);
702 }
703 else if (lsscm_is_lazy_string (str_scm))
704 {
705 struct value_print_options local_opts = *options;
706
707 local_opts.addressprint = 0;
708 lsscm_val_print_lazy_string (str_scm, stream, &local_opts);
709 result = STRING_REPR_OK;
710 }
711 else
712 {
713 gdb_assert (gdbscm_is_exception (str_scm));
714 ppscm_print_exception_unless_memory_error (str_scm, stream);
715 result = STRING_REPR_ERROR;
716 }
717
718 return result;
719}
720
721/* Helper for gdbscm_apply_val_pretty_printer that formats children of the
722 printer, if any exist.
723 The caller is responsible for ensuring PRINTER is a printer smob.
724 If PRINTED_NOTHING is true, then nothing has been printed by to_string,
725 and format output accordingly. */
726
727static void
728ppscm_print_children (SCM printer, enum display_hint hint,
729 struct ui_file *stream, int recurse,
730 const struct value_print_options *options,
731 struct gdbarch *gdbarch,
732 const struct language_defn *language,
733 int printed_nothing)
734{
735 pretty_printer_worker_smob *w_smob
736 = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
737 int is_map, is_array, done_flag, pretty;
738 unsigned int i;
798a7429 739 SCM children;
ed3ef339
DE
740 SCM iter = SCM_BOOL_F; /* -Wall */
741 struct cleanup *cleanups;
742
743 if (gdbscm_is_false (w_smob->children))
744 return;
745 if (!gdbscm_is_procedure (w_smob->children))
746 {
747 ppscm_print_pp_type_error
748 (_("pretty-printer \"children\" object is not a procedure or #f"),
749 w_smob->children);
750 return;
751 }
752
753 cleanups = make_cleanup (null_cleanup, NULL);
754
755 /* If we are printing a map or an array, we want special formatting. */
756 is_map = hint == HINT_MAP;
757 is_array = hint == HINT_ARRAY;
758
759 children = gdbscm_safe_call_1 (w_smob->children, printer,
760 gdbscm_memory_error_p);
761 if (gdbscm_is_exception (children))
762 {
763 ppscm_print_exception_unless_memory_error (children, stream);
764 goto done;
765 }
766 /* We combine two steps here: get children, make an iterator out of them.
767 This simplifies things because there's no language means of creating
768 iterators, and it's the printer object that knows how it will want its
769 children iterated over. */
770 if (!itscm_is_iterator (children))
771 {
772 ppscm_print_pp_type_error
773 (_("result of pretty-printer \"children\" procedure is not"
774 " a <gdb:iterator> object"), children);
775 goto done;
776 }
777 iter = children;
778
779 /* Use the prettyformat_arrays option if we are printing an array,
780 and the pretty option otherwise. */
781 if (is_array)
782 pretty = options->prettyformat_arrays;
783 else
784 {
785 if (options->prettyformat == Val_prettyformat)
786 pretty = 1;
787 else
788 pretty = options->prettyformat_structs;
789 }
790
791 done_flag = 0;
792 for (i = 0; i < options->print_max; ++i)
793 {
ed3ef339
DE
794 SCM scm_name, v_scm;
795 char *name;
796 SCM item = itscm_safe_call_next_x (iter, gdbscm_memory_error_p);
797 struct cleanup *inner_cleanup = make_cleanup (null_cleanup, NULL);
798
799 if (gdbscm_is_exception (item))
800 {
801 ppscm_print_exception_unless_memory_error (item, stream);
802 break;
803 }
804 if (itscm_is_end_of_iteration (item))
805 {
806 /* Set a flag so we can know whether we printed all the
807 available elements. */
808 done_flag = 1;
809 break;
810 }
811
812 if (! scm_is_pair (item))
813 {
814 ppscm_print_pp_type_error
815 (_("result of pretty-printer children iterator is not a pair"
816 " or (end-of-iteration)"),
817 item);
818 continue;
819 }
820 scm_name = scm_car (item);
821 v_scm = scm_cdr (item);
822 if (!scm_is_string (scm_name))
823 {
824 ppscm_print_pp_type_error
825 (_("first element of pretty-printer children iterator is not"
826 " a string"), item);
827 continue;
828 }
829 name = gdbscm_scm_to_c_string (scm_name);
830 make_cleanup (xfree, name);
831
832 /* Print initial "{". For other elements, there are three cases:
833 1. Maps. Print a "," after each value element.
834 2. Arrays. Always print a ",".
835 3. Other. Always print a ",". */
836 if (i == 0)
837 {
838 if (printed_nothing)
839 fputs_filtered ("{", stream);
840 else
841 fputs_filtered (" = {", stream);
842 }
843
844 else if (! is_map || i % 2 == 0)
845 fputs_filtered (pretty ? "," : ", ", stream);
846
847 /* In summary mode, we just want to print "= {...}" if there is
848 a value. */
849 if (options->summary)
850 {
851 /* This increment tricks the post-loop logic to print what
852 we want. */
853 ++i;
854 /* Likewise. */
855 pretty = 0;
856 break;
857 }
858
859 if (! is_map || i % 2 == 0)
860 {
861 if (pretty)
862 {
863 fputs_filtered ("\n", stream);
864 print_spaces_filtered (2 + 2 * recurse, stream);
865 }
866 else
867 wrap_here (n_spaces (2 + 2 *recurse));
868 }
869
870 if (is_map && i % 2 == 0)
871 fputs_filtered ("[", stream);
872 else if (is_array)
873 {
874 /* We print the index, not whatever the child method
875 returned as the name. */
876 if (options->print_array_indexes)
877 fprintf_filtered (stream, "[%d] = ", i);
878 }
879 else if (! is_map)
880 {
881 fputs_filtered (name, stream);
882 fputs_filtered (" = ", stream);
883 }
884
885 if (lsscm_is_lazy_string (v_scm))
886 {
887 struct value_print_options local_opts = *options;
888
889 local_opts.addressprint = 0;
890 lsscm_val_print_lazy_string (v_scm, stream, &local_opts);
891 }
892 else if (scm_is_string (v_scm))
893 {
894 char *output = gdbscm_scm_to_c_string (v_scm);
895
896 fputs_filtered (output, stream);
897 xfree (output);
898 }
899 else
900 {
901 SCM except_scm;
902 struct value *value
903 = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
904 v_scm, &except_scm,
905 gdbarch, language);
906
907 if (value == NULL)
908 {
909 ppscm_print_exception_unless_memory_error (except_scm, stream);
910 break;
911 }
912 common_val_print (value, stream, recurse + 1, options, language);
913 }
914
915 if (is_map && i % 2 == 0)
916 fputs_filtered ("] = ", stream);
917
918 do_cleanups (inner_cleanup);
919 }
920
921 if (i)
922 {
923 if (!done_flag)
924 {
925 if (pretty)
926 {
927 fputs_filtered ("\n", stream);
928 print_spaces_filtered (2 + 2 * recurse, stream);
929 }
930 fputs_filtered ("...", stream);
931 }
932 if (pretty)
933 {
934 fputs_filtered ("\n", stream);
935 print_spaces_filtered (2 * recurse, stream);
936 }
937 fputs_filtered ("}", stream);
938 }
939
940 done:
941 do_cleanups (cleanups);
942
943 /* Play it safe, make sure ITER doesn't get GC'd. */
944 scm_remember_upto_here_1 (iter);
945}
946
947/* This is the extension_language_ops.apply_val_pretty_printer "method". */
948
949enum ext_lang_rc
950gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang,
668e1674 951 struct type *type,
6b850546 952 LONGEST embedded_offset, CORE_ADDR address,
ed3ef339 953 struct ui_file *stream, int recurse,
668e1674 954 struct value *val,
ed3ef339
DE
955 const struct value_print_options *options,
956 const struct language_defn *language)
957{
958 struct gdbarch *gdbarch = get_type_arch (type);
959 SCM exception = SCM_BOOL_F;
960 SCM printer = SCM_BOOL_F;
961 SCM val_obj = SCM_BOOL_F;
962 struct value *value;
963 enum display_hint hint;
964 struct cleanup *cleanups;
f486487f 965 enum ext_lang_rc result = EXT_LANG_RC_NOP;
ed3ef339 966 enum string_repr_result print_result;
668e1674 967 const gdb_byte *valaddr = value_contents_for_printing (val);
ed3ef339
DE
968
969 /* No pretty-printer support for unavailable values. */
970 if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
971 return EXT_LANG_RC_NOP;
972
973 if (!gdb_scheme_initialized)
974 return EXT_LANG_RC_NOP;
975
976 cleanups = make_cleanup (null_cleanup, NULL);
977
978 /* Instantiate the printer. */
3fff9862 979 value = value_from_component (val, type, embedded_offset);
ed3ef339
DE
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
1037static const scheme_function pretty_printer_functions[] =
1038{
72e02483
PA
1039 { "make-pretty-printer", 2, 0, 0,
1040 as_a_scm_t_subr (gdbscm_make_pretty_printer),
ed3ef339
DE
1041 "\
1042Create a <gdb:pretty-printer> object.\n\
1043\n\
1044 Arguments: name lookup\n\
1045 name: a string naming the matcher\n\
1046 lookup: a procedure:\n\
1047 (pretty-printer <gdb:value>) -> <gdb:pretty-printer-worker> | #f." },
1048
72e02483 1049 { "pretty-printer?", 1, 0, 0, as_a_scm_t_subr (gdbscm_pretty_printer_p),
ed3ef339
DE
1050 "\
1051Return #t if the object is a <gdb:pretty-printer> object." },
1052
72e02483
PA
1053 { "pretty-printer-enabled?", 1, 0, 0,
1054 as_a_scm_t_subr (gdbscm_pretty_printer_enabled_p),
ed3ef339
DE
1055 "\
1056Return #t if the pretty-printer is enabled." },
1057
1058 { "set-pretty-printer-enabled!", 2, 0, 0,
72e02483 1059 as_a_scm_t_subr (gdbscm_set_pretty_printer_enabled_x),
ed3ef339
DE
1060 "\
1061Set the enabled flag of the pretty-printer.\n\
1062Returns \"unspecified\"." },
1063
72e02483
PA
1064 { "make-pretty-printer-worker", 3, 0, 0,
1065 as_a_scm_t_subr (gdbscm_make_pretty_printer_worker),
ed3ef339
DE
1066 "\
1067Create a <gdb:pretty-printer-worker> object.\n\
1068\n\
1069 Arguments: display-hint to-string children\n\
1070 display-hint: either #f or one of \"array\", \"map\", or \"string\"\n\
1071 to-string: a procedure:\n\
1072 (pretty-printer) -> string | #f | <gdb:value>\n\
1073 children: either #f or a procedure:\n\
1074 (pretty-printer) -> <gdb:iterator>" },
1075
72e02483
PA
1076 { "pretty-printer-worker?", 1, 0, 0,
1077 as_a_scm_t_subr (gdbscm_pretty_printer_worker_p),
ed3ef339
DE
1078 "\
1079Return #t if the object is a <gdb:pretty-printer-worker> object." },
1080
72e02483 1081 { "pretty-printers", 0, 0, 0, as_a_scm_t_subr (gdbscm_pretty_printers),
ee7333ae
DE
1082 "\
1083Return the list of global pretty-printers." },
1084
1085 { "set-pretty-printers!", 1, 0, 0,
72e02483 1086 as_a_scm_t_subr (gdbscm_set_pretty_printers_x),
ee7333ae
DE
1087 "\
1088Set the list of global pretty-printers." },
1089
ed3ef339
DE
1090 END_FUNCTIONS
1091};
1092
1093void
1094gdbscm_initialize_pretty_printers (void)
1095{
1096 pretty_printer_smob_tag
1097 = gdbscm_make_smob_type (pretty_printer_smob_name,
1098 sizeof (pretty_printer_smob));
ed3ef339
DE
1099 scm_set_smob_print (pretty_printer_smob_tag,
1100 ppscm_print_pretty_printer_smob);
1101
1102 pretty_printer_worker_smob_tag
1103 = gdbscm_make_smob_type (pretty_printer_worker_smob_name,
1104 sizeof (pretty_printer_worker_smob));
ed3ef339
DE
1105 scm_set_smob_print (pretty_printer_worker_smob_tag,
1106 ppscm_print_pretty_printer_worker_smob);
1107
1108 gdbscm_define_functions (pretty_printer_functions, 1);
1109
ee7333ae 1110 pretty_printer_list = SCM_EOL;
ed3ef339
DE
1111
1112 pp_type_error_symbol = scm_from_latin1_symbol ("gdb:pp-type-error");
1113
1114 ppscm_map_string = scm_from_latin1_string ("map");
1115 ppscm_array_string = scm_from_latin1_string ("array");
1116 ppscm_string_string = scm_from_latin1_string ("string");
1117}
This page took 0.403762 seconds and 4 git commands to generate.