static SCM lsscm_get_lazy_string_arg_unsafe (SCM self, int arg_pos, const char *func_name) { SCM_ASSERT_TYPE (lsscm_is_lazy_string (self), self, arg_pos, func_name, lazy_string_smob_name); return self; }
static SCM ppscm_pretty_print_one_value (SCM printer, struct value **out_value, struct gdbarch *gdbarch, const struct language_defn *language) { SCM result = SCM_BOOL_F; *out_value = NULL; TRY { int rc; pretty_printer_worker_smob *w_smob = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer); result = gdbscm_safe_call_1 (w_smob->to_string, printer, gdbscm_memory_error_p); if (gdbscm_is_false (result)) ; /* Done. */ else if (scm_is_string (result) || lsscm_is_lazy_string (result)) ; /* Done. */ else if (vlscm_is_value (result)) { SCM except_scm; *out_value = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE, result, &except_scm, gdbarch, language); if (*out_value != NULL) result = SCM_BOOL_T; else result = except_scm; } else if (gdbscm_is_exception (result)) ; /* Done. */ else { /* Invalid result from to-string. */ result = ppscm_make_pp_type_error_exception (_("invalid result from pretty-printer to-string"), result); } } CATCH (except, RETURN_MASK_ALL) { } END_CATCH return result; }
static void ppscm_print_children (SCM printer, enum display_hint hint, struct ui_file *stream, int recurse, const struct value_print_options *options, struct gdbarch *gdbarch, const struct language_defn *language, int printed_nothing) { pretty_printer_worker_smob *w_smob = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer); int is_map, is_array, done_flag, pretty; unsigned int i; SCM children, status; SCM iter = SCM_BOOL_F; /* -Wall */ struct cleanup *cleanups; if (gdbscm_is_false (w_smob->children)) return; if (!gdbscm_is_procedure (w_smob->children)) { ppscm_print_pp_type_error (_("pretty-printer \"children\" object is not a procedure or #f"), w_smob->children); return; } cleanups = make_cleanup (null_cleanup, NULL); /* If we are printing a map or an array, we want special formatting. */ is_map = hint == HINT_MAP; is_array = hint == HINT_ARRAY; children = gdbscm_safe_call_1 (w_smob->children, printer, gdbscm_memory_error_p); if (gdbscm_is_exception (children)) { ppscm_print_exception_unless_memory_error (children, stream); goto done; } /* We combine two steps here: get children, make an iterator out of them. This simplifies things because there's no language means of creating iterators, and it's the printer object that knows how it will want its children iterated over. */ if (!itscm_is_iterator (children)) { ppscm_print_pp_type_error (_("result of pretty-printer \"children\" procedure is not" " a <gdb:iterator> object"), children); goto done; } iter = children; /* Use the prettyformat_arrays option if we are printing an array, and the pretty option otherwise. */ if (is_array) pretty = options->prettyformat_arrays; else { if (options->prettyformat == Val_prettyformat) pretty = 1; else pretty = options->prettyformat_structs; } done_flag = 0; for (i = 0; i < options->print_max; ++i) { int rc; SCM scm_name, v_scm; char *name; SCM item = itscm_safe_call_next_x (iter, gdbscm_memory_error_p); struct cleanup *inner_cleanup = make_cleanup (null_cleanup, NULL); if (gdbscm_is_exception (item)) { ppscm_print_exception_unless_memory_error (item, stream); break; } if (itscm_is_end_of_iteration (item)) { /* Set a flag so we can know whether we printed all the available elements. */ done_flag = 1; break; } if (! scm_is_pair (item)) { ppscm_print_pp_type_error (_("result of pretty-printer children iterator is not a pair" " or (end-of-iteration)"), item); continue; } scm_name = scm_car (item); v_scm = scm_cdr (item); if (!scm_is_string (scm_name)) { ppscm_print_pp_type_error (_("first element of pretty-printer children iterator is not" " a string"), item); continue; } name = gdbscm_scm_to_c_string (scm_name); make_cleanup (xfree, name); /* Print initial "{". For other elements, there are three cases: 1. Maps. Print a "," after each value element. 2. Arrays. Always print a ",". 3. Other. Always print a ",". */ if (i == 0) { if (printed_nothing) fputs_filtered ("{", stream); else fputs_filtered (" = {", stream); } else if (! is_map || i % 2 == 0) fputs_filtered (pretty ? "," : ", ", stream); /* In summary mode, we just want to print "= {...}" if there is a value. */ if (options->summary) { /* This increment tricks the post-loop logic to print what we want. */ ++i; /* Likewise. */ pretty = 0; break; } if (! is_map || i % 2 == 0) { if (pretty) { fputs_filtered ("\n", stream); print_spaces_filtered (2 + 2 * recurse, stream); } else wrap_here (n_spaces (2 + 2 *recurse)); } if (is_map && i % 2 == 0) fputs_filtered ("[", stream); else if (is_array) { /* We print the index, not whatever the child method returned as the name. */ if (options->print_array_indexes) fprintf_filtered (stream, "[%d] = ", i); } else if (! is_map) { fputs_filtered (name, stream); fputs_filtered (" = ", stream); } if (lsscm_is_lazy_string (v_scm)) { struct value_print_options local_opts = *options; local_opts.addressprint = 0; lsscm_val_print_lazy_string (v_scm, stream, &local_opts); } else if (scm_is_string (v_scm)) { char *output = gdbscm_scm_to_c_string (v_scm); fputs_filtered (output, stream); xfree (output); } else { SCM except_scm; struct value *value = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE, v_scm, &except_scm, gdbarch, language); if (value == NULL) { ppscm_print_exception_unless_memory_error (except_scm, stream); break; } common_val_print (value, stream, recurse + 1, options, language); } if (is_map && i % 2 == 0) fputs_filtered ("] = ", stream); do_cleanups (inner_cleanup); } if (i) { if (!done_flag) { if (pretty) { fputs_filtered ("\n", stream); print_spaces_filtered (2 + 2 * recurse, stream); } fputs_filtered ("...", stream); } if (pretty) { fputs_filtered ("\n", stream); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("}", stream); } done: do_cleanups (cleanups); /* Play it safe, make sure ITER doesn't get GC'd. */ scm_remember_upto_here_1 (iter); }
static enum string_repr_result ppscm_print_string_repr (SCM printer, enum display_hint hint, struct ui_file *stream, int recurse, const struct value_print_options *options, struct gdbarch *gdbarch, const struct language_defn *language) { struct value *replacement = NULL; SCM str_scm; enum string_repr_result result = STRING_REPR_ERROR; str_scm = ppscm_pretty_print_one_value (printer, &replacement, gdbarch, language); if (gdbscm_is_false (str_scm)) { result = STRING_REPR_NONE; } else if (scm_is_eq (str_scm, SCM_BOOL_T)) { struct value_print_options opts = *options; gdb_assert (replacement != NULL); opts.addressprint = 0; common_val_print (replacement, stream, recurse, &opts, language); result = STRING_REPR_OK; } else if (scm_is_string (str_scm)) { struct cleanup *cleanup; size_t length; char *string = gdbscm_scm_to_string (str_scm, &length, target_charset (gdbarch), 0 /*!strict*/, NULL); cleanup = make_cleanup (xfree, string); if (hint == HINT_STRING) { struct type *type = builtin_type (gdbarch)->builtin_char; LA_PRINT_STRING (stream, type, (gdb_byte *) string, length, NULL, 0, options); } else { /* Alas scm_to_stringn doesn't nul-terminate the string if we ask for the length. */ size_t i; for (i = 0; i < length; ++i) { if (string[i] == '\0') fputs_filtered ("\\000", stream); else fputc_filtered (string[i], stream); } } result = STRING_REPR_OK; do_cleanups (cleanup); } else if (lsscm_is_lazy_string (str_scm)) { struct value_print_options local_opts = *options; local_opts.addressprint = 0; lsscm_val_print_lazy_string (str_scm, stream, &local_opts); result = STRING_REPR_OK; } else { gdb_assert (gdbscm_is_exception (str_scm)); ppscm_print_exception_unless_memory_error (str_scm, stream); result = STRING_REPR_ERROR; } return result; }
static SCM gdbscm_lazy_string_p (SCM scm) { return scm_from_bool (lsscm_is_lazy_string (scm)); }