static void signal_catchpoint_print_one (struct breakpoint *b, struct bp_location **last_loc) { struct signal_catchpoint *c = (void *) b; struct value_print_options opts; struct ui_out *uiout = current_uiout; get_user_print_options (&opts); /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ if (opts.addressprint) ui_out_field_skip (uiout, "addr"); annotate_field (5); if (c->signals_to_be_caught && VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1) ui_out_text (uiout, "signals \""); else ui_out_text (uiout, "signal \""); if (c->signals_to_be_caught) { int i; gdb_signal_type iter; struct obstack text; struct cleanup *cleanup; obstack_init (&text); cleanup = make_cleanup_obstack_free (&text); for (i = 0; VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); i++) { const char *name = signal_to_name_or_int (iter); if (i > 0) obstack_grow (&text, " ", 1); obstack_grow (&text, name, strlen (name)); } obstack_grow (&text, "", 1); ui_out_field_string (uiout, "what", obstack_base (&text)); do_cleanups (cleanup); } else ui_out_field_string (uiout, "what", c->catch_all ? "<any signal>" : "<standard signals>"); ui_out_text (uiout, "\" "); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "catch-type", "signal"); }
struct value * evaluate_subexp_c (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op = exp->elts[*pos].opcode; switch (op) { case OP_STRING: { int oplen, limit; struct type *type; struct obstack output; struct cleanup *cleanup; struct value *result; enum c_string_type dest_type; const char *dest_charset; int satisfy_expected = 0; obstack_init (&output); cleanup = make_cleanup_obstack_free (&output); ++*pos; oplen = longest_to_int (exp->elts[*pos].longconst); ++*pos; limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1); dest_type = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst); switch (dest_type & ~C_CHAR) { case C_STRING: type = language_string_char_type (exp->language_defn, exp->gdbarch); break; case C_WIDE_STRING: type = lookup_typename (exp->language_defn, exp->gdbarch, "wchar_t", NULL, 0); break; case C_STRING_16: type = lookup_typename (exp->language_defn, exp->gdbarch, "char16_t", NULL, 0); break; case C_STRING_32: type = lookup_typename (exp->language_defn, exp->gdbarch, "char32_t", NULL, 0); break; default: internal_error (__FILE__, __LINE__, _("unhandled c_string_type")); } /* Ensure TYPE_LENGTH is valid for TYPE. */ check_typedef (type); /* If the caller expects an array of some integral type, satisfy them. If something odder is expected, rely on the caller to cast. */ if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY) { struct type *element_type = check_typedef (TYPE_TARGET_TYPE (expect_type)); if (TYPE_CODE (element_type) == TYPE_CODE_INT || TYPE_CODE (element_type) == TYPE_CODE_CHAR) { type = element_type; satisfy_expected = 1; } } dest_charset = charset_for_string_type (dest_type, exp->gdbarch); ++*pos; while (*pos < limit) { int len; len = longest_to_int (exp->elts[*pos].longconst); ++*pos; if (noside != EVAL_SKIP) parse_one_string (&output, &exp->elts[*pos].string, len, dest_charset, type); *pos += BYTES_TO_EXP_ELEM (len); } /* Skip the trailing length and opcode. */ *pos += 2; if (noside == EVAL_SKIP) { /* Return a dummy value of the appropriate type. */ if (expect_type != NULL) result = allocate_value (expect_type); else if ((dest_type & C_CHAR) != 0) result = allocate_value (type); else result = value_cstring ("", 0, type); do_cleanups (cleanup); return result; } if ((dest_type & C_CHAR) != 0) { LONGEST value; if (obstack_object_size (&output) != TYPE_LENGTH (type)) error (_("Could not convert character " "constant to target character set")); value = unpack_long (type, (gdb_byte *) obstack_base (&output)); result = value_from_longest (type, value); } else { int i; /* Write the terminating character. */ for (i = 0; i < TYPE_LENGTH (type); ++i) obstack_1grow (&output, 0); if (satisfy_expected) { LONGEST low_bound, high_bound; int element_size = TYPE_LENGTH (type); if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type), &low_bound, &high_bound) < 0) { low_bound = 0; high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1; } if (obstack_object_size (&output) / element_size > (high_bound - low_bound + 1)) error (_("Too many array elements")); result = allocate_value (expect_type); memcpy (value_contents_raw (result), obstack_base (&output), obstack_object_size (&output)); } else result = value_cstring (obstack_base (&output), obstack_object_size (&output), type); } do_cleanups (cleanup); return result; } break; default: break; } return evaluate_subexp_standard (expect_type, exp, pos, noside); }
void c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, unsigned int length, const char *user_encoding, int force_ellipses, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; int width = TYPE_LENGTH (type); struct obstack wchar_buf, output; struct cleanup *cleanup; enum c_string_type str_type; const char *type_encoding; const char *encoding; struct wchar_iterator *iter; int finished = 0; int need_escape = 0; if (length == -1) { unsigned long current_char = 1; for (i = 0; current_char; ++i) { QUIT; current_char = extract_unsigned_integer (string + i * width, width, byte_order); } length = i; } /* If the string was not truncated due to `set print elements', and the last byte of it is a null, we don't print that, in traditional C style. */ if (!force_ellipses && length > 0 && (extract_unsigned_integer (string + (length - 1) * width, width, byte_order) == 0)) length--; str_type = (classify_type (type, get_type_arch (type), &type_encoding) & ~C_CHAR); switch (str_type) { case C_STRING: break; case C_WIDE_STRING: fputs_filtered ("L", stream); break; case C_STRING_16: fputs_filtered ("u", stream); break; case C_STRING_32: fputs_filtered ("U", stream); break; } encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding; if (length == 0) { fputs_filtered ("\"\"", stream); return; } /* Arrange to iterate over the characters, in wchar_t form. */ iter = make_wchar_iterator (string, length * width, encoding, width); cleanup = make_cleanup_wchar_iterator (iter); /* WCHAR_BUF is the obstack we use to represent the string in wchar_t form. */ obstack_init (&wchar_buf); make_cleanup_obstack_free (&wchar_buf); while (!finished && things_printed < options->print_max) { int num_chars; enum wchar_iterate_result result; gdb_wchar_t *chars; const gdb_byte *buf; size_t buflen; QUIT; if (need_comma) { obstack_grow_wstr (&wchar_buf, LCST (", ")); need_comma = 0; } num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); /* We only look at repetitions when we were able to convert a single character in isolation. This makes the code simpler and probably does the sensible thing in the majority of cases. */ while (num_chars == 1 && things_printed < options->print_max) { /* Count the number of repetitions. */ unsigned int reps = 0; gdb_wchar_t current_char = chars[0]; const gdb_byte *orig_buf = buf; int orig_len = buflen; if (need_comma) { obstack_grow_wstr (&wchar_buf, LCST (", ")); need_comma = 0; } while (num_chars == 1 && current_char == chars[0]) { num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); ++reps; } /* Emit CURRENT_CHAR according to the repetition count and options. */ if (reps > options->repeat_count_threshold) { if (in_quotes) { if (options->inspect_it) obstack_grow_wstr (&wchar_buf, LCST ("\\\", ")); else obstack_grow_wstr (&wchar_buf, LCST ("\", ")); in_quotes = 0; } obstack_grow_wstr (&wchar_buf, LCST ("'")); need_escape = 0; print_wchar (current_char, orig_buf, orig_len, width, byte_order, &wchar_buf, '\'', &need_escape); obstack_grow_wstr (&wchar_buf, LCST ("'")); { /* Painful gyrations. */ int j; char *s = xstrprintf (_(" <repeats %u times>"), reps); for (j = 0; s[j]; ++j) { gdb_wchar_t w = gdb_btowc (s[j]); obstack_grow (&wchar_buf, &w, sizeof (gdb_wchar_t)); } xfree (s); } things_printed += options->repeat_count_threshold; need_comma = 1; } else { /* Saw the character one or more times, but fewer than the repetition threshold. */ if (!in_quotes) { if (options->inspect_it) obstack_grow_wstr (&wchar_buf, LCST ("\\\"")); else obstack_grow_wstr (&wchar_buf, LCST ("\"")); in_quotes = 1; need_escape = 0; } while (reps-- > 0) { print_wchar (current_char, orig_buf, orig_len, width, byte_order, &wchar_buf, '"', &need_escape); ++things_printed; } } } /* NUM_CHARS and the other outputs from wchar_iterate are valid here regardless of which branch was taken above. */ if (num_chars < 0) { /* Hit EOF. */ finished = 1; break; } switch (result) { case wchar_iterate_invalid: if (!in_quotes) { if (options->inspect_it) obstack_grow_wstr (&wchar_buf, LCST ("\\\"")); else obstack_grow_wstr (&wchar_buf, LCST ("\"")); in_quotes = 1; } need_escape = 0; print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf, '"', &need_escape); break; case wchar_iterate_incomplete: if (in_quotes) { if (options->inspect_it) obstack_grow_wstr (&wchar_buf, LCST ("\\\",")); else obstack_grow_wstr (&wchar_buf, LCST ("\",")); in_quotes = 0; } obstack_grow_wstr (&wchar_buf, LCST (" <incomplete sequence ")); print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf, 0, &need_escape); obstack_grow_wstr (&wchar_buf, LCST (">")); finished = 1; break; } } /* Terminate the quotes if necessary. */ if (in_quotes) { if (options->inspect_it) obstack_grow_wstr (&wchar_buf, LCST ("\\\"")); else obstack_grow_wstr (&wchar_buf, LCST ("\"")); } if (force_ellipses || !finished) obstack_grow_wstr (&wchar_buf, LCST ("...")); /* OUTPUT is where we collect `char's for printing. */ obstack_init (&output); make_cleanup_obstack_free (&output); convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), obstack_base (&wchar_buf), obstack_object_size (&wchar_buf), 1, &output, translit_char); obstack_1grow (&output, '\0'); fputs_filtered (obstack_base (&output), stream); do_cleanups (cleanup); }
static struct value * evaluate_subexp_c (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op = exp->elts[*pos].opcode; switch (op) { case OP_STRING: { int oplen, limit; struct type *type; struct obstack output; struct cleanup *cleanup; struct value *result; enum c_string_type dest_type; const char *dest_charset; obstack_init (&output); cleanup = make_cleanup_obstack_free (&output); ++*pos; oplen = longest_to_int (exp->elts[*pos].longconst); ++*pos; limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1); dest_type = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst); switch (dest_type & ~C_CHAR) { case C_STRING: type = language_string_char_type (exp->language_defn, exp->gdbarch); break; case C_WIDE_STRING: type = lookup_typename (exp->language_defn, exp->gdbarch, "wchar_t", NULL, 0); break; case C_STRING_16: type = lookup_typename (exp->language_defn, exp->gdbarch, "char16_t", NULL, 0); break; case C_STRING_32: type = lookup_typename (exp->language_defn, exp->gdbarch, "char32_t", NULL, 0); break; default: internal_error (__FILE__, __LINE__, "unhandled c_string_type"); } /* Ensure TYPE_LENGTH is valid for TYPE. */ check_typedef (type); dest_charset = charset_for_string_type (dest_type, exp->gdbarch); ++*pos; while (*pos < limit) { int len; len = longest_to_int (exp->elts[*pos].longconst); ++*pos; if (noside != EVAL_SKIP) parse_one_string (&output, &exp->elts[*pos].string, len, dest_charset, type); *pos += BYTES_TO_EXP_ELEM (len); } /* Skip the trailing length and opcode. */ *pos += 2; if (noside == EVAL_SKIP) { /* Return a dummy value of the appropriate type. */ if ((dest_type & C_CHAR) != 0) result = allocate_value (type); else result = value_cstring ("", 0, type); do_cleanups (cleanup); return result; } if ((dest_type & C_CHAR) != 0) { LONGEST value; if (obstack_object_size (&output) != TYPE_LENGTH (type)) error (_("Could not convert character constant to target character set")); value = unpack_long (type, obstack_base (&output)); result = value_from_longest (type, value); } else { int i; /* Write the terminating character. */ for (i = 0; i < TYPE_LENGTH (type); ++i) obstack_1grow (&output, 0); result = value_cstring (obstack_base (&output), obstack_object_size (&output), type); } do_cleanups (cleanup); return result; } break; default: break; } return evaluate_subexp_standard (expect_type, exp, pos, noside); }
void c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); struct obstack wchar_buf, output; struct cleanup *cleanups; const char *encoding; gdb_byte *buf; struct wchar_iterator *iter; int need_escape = 0; classify_type (type, get_type_arch (type), &encoding); buf = alloca (TYPE_LENGTH (type)); pack_long (buf, type, c); iter = make_wchar_iterator (buf, TYPE_LENGTH (type), encoding, TYPE_LENGTH (type)); cleanups = make_cleanup_wchar_iterator (iter); /* This holds the printable form of the wchar_t data. */ obstack_init (&wchar_buf); make_cleanup_obstack_free (&wchar_buf); while (1) { int num_chars; gdb_wchar_t *chars; const gdb_byte *buf; size_t buflen; int print_escape = 1; enum wchar_iterate_result result; num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); if (num_chars < 0) break; if (num_chars > 0) { /* If all characters are printable, print them. Otherwise, we're going to have to print an escape sequence. We check all characters because we want to print the target bytes in the escape sequence, and we don't know character boundaries there. */ int i; print_escape = 0; for (i = 0; i < num_chars; ++i) if (!wchar_printable (chars[i])) { print_escape = 1; break; } if (!print_escape) { for (i = 0; i < num_chars; ++i) print_wchar (chars[i], buf, buflen, TYPE_LENGTH (type), byte_order, &wchar_buf, quoter, &need_escape); } } /* This handles the NUM_CHARS == 0 case as well. */ if (print_escape) print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type), byte_order, &wchar_buf, quoter, &need_escape); } /* The output in the host encoding. */ obstack_init (&output); make_cleanup_obstack_free (&output); convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), obstack_base (&wchar_buf), obstack_object_size (&wchar_buf), 1, &output, translit_char); obstack_1grow (&output, '\0'); fputs_filtered (obstack_base (&output), stream); do_cleanups (cleanups); }