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