static tree finish_mangling (void) { tree result; gcc_assert (compression_table); compression_table = NULL_TREE; compression_next = 0; obstack_1grow (mangle_obstack, '\0'); result = get_identifier ((char *) obstack_base (mangle_obstack)); obstack_free (mangle_obstack, obstack_base (mangle_obstack)); return result; }
static _IO_size_t _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; if (fp->_IO_write_ptr + n > fp->_IO_write_end) { int size; /* We need some more memory. First shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end); /* Now grow for N bytes, and put the data there. */ obstack_grow (obstack, data, n); /* Setup the buffer pointers again. */ fp->_IO_write_base = obstack_base (obstack); fp->_IO_write_ptr = obstack_next_free (obstack); size = obstack_room (obstack); fp->_IO_write_end = fp->_IO_write_ptr + size; /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, size); } else fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n); return n; }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int recurse, const struct value_print_options *options) { struct type *type = value_type (val); struct value_print_options opts; if (value_entirely_optimized_out (val)) { val_print_optimized_out (val, stream); return; } if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print, addr; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (value_address (val) == first_dont_print[i]) { fputs_filtered ("\ <same as static member of an already seen type>", stream); return; } }
void check_obstack_vprintf (const char *want, const char *fmt, va_list ap) { #if HAVE_OBSTACK_VPRINTF struct obstack ob; int got_len, want_len, ob_len; char *got; want_len = strlen (want); obstack_init (&ob); got_len = gmp_obstack_vprintf (&ob, fmt, ap); got = obstack_base (&ob); ob_len = obstack_object_size (&ob); if (got_len != want_len || ob_len != want_len || memcmp (got, want, want_len) != 0) { printf ("gmp_obstack_vprintf wrong\n"); printf (" fmt |%s|\n", fmt); printf (" got |%s|\n", got); printf (" want |%s|\n", want); printf (" got_len %d\n", got_len); printf (" ob_len %d\n", ob_len); printf (" want_len %d\n", want_len); abort (); } obstack_free (&ob, NULL); #endif }
/** returns current fragment (the address stays only valid until the next be_emit(8/16/32/entity) call!) */ code_fragment_t *be_get_current_fragment(void) { code_fragment_t *fragment = (code_fragment_t*)obstack_base(&code_fragment_obst); assert(obstack_object_size(&code_fragment_obst) >= sizeof(code_fragment_t)); assert(fragment->magic == CODE_FRAGMENT_MAGIC); return fragment; }
/* read_file() * * Reads the contents of a file using an obstack for memory. It can read files like * /proc/stat or /proc/${pid}/stat. * * @param path String representing the part following /proc (usualy this is * the process pid number) * @param etxra_path Path to the file to read in (relative to /proc/${path}/) * @param len Pointer to the value where the length will be saved * * @return Pointer to a null terminate string allocated on the obstack, or * NULL when it fails (doesn't clean up the obstack). */ static char *read_file(const char *path, const char *extra_path, off_t *len, struct obstack *mem_pool) { int fd, result = -1; char *text, *file, *start; /* build the filename in our tempoary storage */ file = proc_pid_file(path, extra_path, mem_pool); fd = open(file, O_RDONLY); /* free tmp memory we allocated for the file contents, this way we are not * poluting the obstack and the only thing left on it is the file */ obstack_free(mem_pool, file); if (fd == -1) return NULL; /* read file into our buffer */ for (*len = 0; result; *len += result) { obstack_blank(mem_pool, 20); start = obstack_base(mem_pool) + *len; if ((result = read(fd, start, 20)) == -1) { obstack_free(mem_pool, obstack_finish(mem_pool)); return NULL; } } /* null terminate */ if (*len % 20) { start = obstack_base(mem_pool) + *len; *start = '\0'; } else obstack_1grow(mem_pool, '\0'); /* finalize our text buffer */ text = obstack_finish(mem_pool); /* not bothering checking return value, because it's possible that the * process went away */ close(fd); return text; }
int _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) { struct obstack_FILE { struct _IO_obstack_file ofile; } new_f; int result; int size; int room; #ifdef _IO_MTSAFE_IO new_f.ofile.file.file._lock = NULL; #endif _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; room = obstack_room (obstack); size = obstack_object_size (obstack) + room; if (size == 0) { /* We have to handle the allocation a bit different since the `_IO_str_init_static' function would handle a size of zero different from what we expect. */ /* Get more memory. */ obstack_make_room (obstack, 64); /* Recompute how much room we have. */ room = obstack_room (obstack); size = room; assert (size != 0); } _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, obstack_base (obstack), size, obstack_next_free (obstack)); /* Now allocate the rest of the current chunk. */ assert (size == (new_f.ofile.file.file._IO_write_end - new_f.ofile.file.file._IO_write_base)); assert (new_f.ofile.file.file._IO_write_ptr == (new_f.ofile.file.file._IO_write_base + obstack_object_size (obstack))); obstack_blank_fast (obstack, room); new_f.ofile.obstack = obstack; result = _IO_vfprintf (&new_f.ofile.file.file, format, args); /* Shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr - new_f.ofile.file.file._IO_write_end)); return result; }
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"); }
tree build_java_argument_signature (tree type) { extern struct obstack temporary_obstack; tree sig = TYPE_ARGUMENT_SIGNATURE (type); if (sig == NULL_TREE) { tree args = TYPE_ARG_TYPES (type); if (TREE_CODE (type) == METHOD_TYPE) args = TREE_CHAIN (args); /* Skip "this" argument. */ for (; args != end_params_node; args = TREE_CHAIN (args)) { tree t = build_java_signature (TREE_VALUE (args)); obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); } obstack_1grow (&temporary_obstack, '\0'); sig = get_identifier ((char *) obstack_base (&temporary_obstack)); TYPE_ARGUMENT_SIGNATURE (type) = sig; obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); } return sig; }
/** allocates a new fragment on the obstack (warning: address is only valid till next be_emit */ static void alloc_fragment(void) { code_fragment_t *fragment; /* shouldn't have any growing fragments */ assert(obstack_object_size(&code_fragment_obst) == 0); obstack_blank(&code_fragment_obst, sizeof(*fragment)); fragment = (code_fragment_t*)obstack_base(&code_fragment_obst); memset(fragment, 0, sizeof(*fragment)); #ifndef NDEBUG fragment->magic = CODE_FRAGMENT_MAGIC; #endif fragment->len = 0; fragment->alignment = 1; fragment->offset = 0; fragment->max_offset = UINT_MAX; }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int recurse, const struct value_print_options *options) { struct type *type = value_type (val); struct value_print_options opts; if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print, addr; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (value_address (val) == first_dont_print[i]) { fputs_filtered ("<same as static member of an already seen type>", stream); return; } } addr = value_address (val); obstack_grow (&dont_print_statmem_obstack, (char *) &addr, sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); pascal_object_print_value_fields (type, value_contents (val), addr, stream, recurse, NULL, options, NULL, 1); return; } opts = *options; opts.deref_ref = 0; common_val_print (val, stream, recurse, &opts, current_language); }
static int _IO_obstack_overflow (_IO_FILE *fp, int c) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; int size; /* Make room for another character. This might as well allocate a new chunk a memory and moves the old contents over. */ assert (c != EOF); obstack_1grow (obstack, c); /* Setup the buffer pointers again. */ fp->_IO_write_base = obstack_base (obstack); fp->_IO_write_ptr = obstack_next_free (obstack); size = obstack_room (obstack); fp->_IO_write_end = fp->_IO_write_ptr + size; /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, size); return c; }
void input_init (void) { current_file = ""; current_line = 0; current_input = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init (current_input); wrapup_stack = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init (wrapup_stack); obstack_init (&file_names); /* Allocate an object in the current chunk, so that obstack_free will always work even if the first token parsed spills to a new chunk. */ obstack_init (&token_stack); obstack_alloc (&token_stack, 1); token_bottom = obstack_base (&token_stack); isp = NULL; wsp = NULL; next = NULL; start_of_input_line = false; lquote.string = xstrdup (DEF_LQUOTE); lquote.length = strlen (lquote.string); rquote.string = xstrdup (DEF_RQUOTE); rquote.length = strlen (rquote.string); bcomm.string = xstrdup (DEF_BCOMM); bcomm.length = strlen (bcomm.string); ecomm.string = xstrdup (DEF_ECOMM); ecomm.length = strlen (ecomm.string); #ifdef ENABLE_CHANGEWORD set_word_regexp (user_word_regexp); #endif }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty) { struct type *type = value_type (val); if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (VALUE_ADDRESS (val) == first_dont_print[i]) { fputs_filtered ("<same as static member of an already seen type>", stream); return; } } obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val), sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); pascal_object_print_value_fields (type, value_contents (val), VALUE_ADDRESS (val), stream, format, recurse, pretty, NULL, 1); return; } common_val_print (val, stream, format, 0, recurse, pretty); }
void convert_between_encodings (const char *from, const char *to, const gdb_byte *bytes, unsigned int num_bytes, int width, struct obstack *output, enum transliterations translit) { iconv_t desc; struct cleanup *cleanups; size_t inleft; char *inp; unsigned int space_request; /* Often, the host and target charsets will be the same. */ if (!strcmp (from, to)) { obstack_grow (output, bytes, num_bytes); return; } desc = iconv_open (to, from); if (desc == (iconv_t) -1) perror_with_name (_("Converting character sets")); cleanups = make_cleanup (cleanup_iconv, &desc); inleft = num_bytes; inp = (char *) bytes; space_request = num_bytes; while (inleft > 0) { char *outp; size_t outleft, r; int old_size; old_size = obstack_object_size (output); obstack_blank (output, space_request); outp = obstack_base (output) + old_size; outleft = space_request; r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft); /* Now make sure that the object on the obstack only includes bytes we have converted. */ obstack_blank (output, - (int) outleft); if (r == (size_t) -1) { switch (errno) { case EILSEQ: { int i; /* Invalid input sequence. */ if (translit == translit_none) error (_("Could not convert character " "to `%s' character set"), to); /* We emit escape sequence for the bytes, skip them, and try again. */ for (i = 0; i < width; ++i) { char octal[5]; xsnprintf (octal, sizeof (octal), "\\%.3o", *inp & 0xff); obstack_grow_str (output, octal); ++inp; --inleft; } } break; case E2BIG: /* We ran out of space in the output buffer. Make it bigger next time around. */ space_request *= 2; break; case EINVAL: /* Incomplete input sequence. FIXME: ought to report this to the caller somehow. */ inleft = 0; break; default: perror_with_name (_("Internal error while " "converting character sets")); } } } do_cleanups (cleanups); }
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); }
static void expand_macro (symbol *sym) { struct obstack arguments; /* Alternate obstack if argc_stack is busy. */ unsigned argv_base; /* Size of argv_stack on entry. */ bool use_argc_stack = true; /* Whether argc_stack is safe. */ token_data **argv; int argc; struct obstack *expansion; const char *expanded; bool traced; int my_call_id; /* Report errors at the location where the open parenthesis (if any) was found, but after expansion, restore global state back to the location of the close parenthesis. This is safe since we guarantee that macro expansion does not alter the state of current_file/current_line (dnl, include, and sinclude are special cased in the input engine to ensure this fact). */ const char *loc_open_file = current_file; int loc_open_line = current_line; const char *loc_close_file; int loc_close_line; SYMBOL_PENDING_EXPANSIONS (sym)++; expansion_level++; if (nesting_limit > 0 && expansion_level > nesting_limit) M4ERROR ((EXIT_FAILURE, 0, "recursion limit of %d exceeded, use -L<N> to change it", nesting_limit)); macro_call_id++; my_call_id = macro_call_id; traced = (debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym); argv_base = obstack_object_size (&argv_stack); if (obstack_object_size (&argc_stack) > 0) { /* We cannot use argc_stack if this is a nested invocation, and an outer invocation has an unfinished argument being collected. */ obstack_init (&arguments); use_argc_stack = false; } if (traced && (debug_level & DEBUG_TRACE_CALL)) trace_prepre (SYMBOL_NAME (sym), my_call_id); collect_arguments (sym, &argv_stack, use_argc_stack ? &argc_stack : &arguments); argc = ((obstack_object_size (&argv_stack) - argv_base) / sizeof (token_data *)); argv = (token_data **) ((char *) obstack_base (&argv_stack) + argv_base); loc_close_file = current_file; loc_close_line = current_line; current_file = loc_open_file; current_line = loc_open_line; if (traced) trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv); expansion = push_string_init (); call_macro (sym, argc, argv, expansion); expanded = push_string_finish (); if (traced) trace_post (SYMBOL_NAME (sym), my_call_id, argc, expanded); current_file = loc_close_file; current_line = loc_close_line; --expansion_level; --SYMBOL_PENDING_EXPANSIONS (sym); if (SYMBOL_DELETED (sym)) free_symbol (sym); if (use_argc_stack) obstack_free (&argc_stack, argv[0]); else obstack_free (&arguments, NULL); obstack_blank (&argv_stack, -argc * sizeof (token_data *)); }
static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, struct type **dont_print_vb) { struct type **last_dont_print = (struct type **) obstack_next_free (&dont_print_vb_obstack); struct obstack tmp_obstack = dont_print_vb_obstack; int i, n_baseclasses = TYPE_N_BASECLASSES (type); if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ /* Bump up the high-water mark. Now alpha is omega. */ obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) { int boffset = 0; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); const char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr = NULL; int thisoffset; int skip = 0; if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) goto flush_it; obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } thisoffset = offset; TRY { boffset = baseclass_offset (type, i, valaddr, offset, address, val); } CATCH (ex, RETURN_MASK_ERROR) { if (ex.error == NOT_AVAILABLE_ERROR) skip = -1; else skip = 1; } END_CATCH if (skip == 0) { /* The virtual base class pointer might have been clobbered by the user program. Make sure that it still points to a valid memory location. */ if (boffset < 0 || boffset >= TYPE_LENGTH (type)) { gdb_byte *buf; struct cleanup *back_to; buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass)); back_to = make_cleanup (xfree, buf); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) skip = 1; address = address + boffset; thisoffset = 0; boffset = 0; do_cleanups (back_to); } else base_valaddr = valaddr; } if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); if (skip < 0) val_print_unavailable (stream); else if (skip > 0) val_print_invalid_address (stream); else pascal_object_print_value_fields (baseclass, base_valaddr, thisoffset + boffset, address, stream, recurse, val, options, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); flush_it: ; } if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ dont_print_vb_obstack = tmp_obstack; } }
token_type next_token (token_data *td, int *line) { int ch; int quote_level; token_type type; #ifdef ENABLE_CHANGEWORD int startpos; char *orig_text = NULL; #endif const char *file; int dummy; obstack_free (&token_stack, token_bottom); if (!line) line = &dummy; /* Can't consume character until after CHAR_MACRO is handled. */ ch = peek_input (); if (ch == CHAR_EOF) { #ifdef DEBUG_INPUT xfprintf (stderr, "next_token -> EOF\n"); #endif next_char (); return TOKEN_EOF; } if (ch == CHAR_MACRO) { init_macro_token (td); next_char (); #ifdef DEBUG_INPUT xfprintf (stderr, "next_token -> MACDEF (%s)\n", find_builtin_by_addr (TOKEN_DATA_FUNC (td))->name); #endif return TOKEN_MACDEF; } next_char (); /* Consume character we already peeked at. */ file = current_file; *line = current_line; if (MATCH (ch, bcomm.string, true)) { obstack_grow (&token_stack, bcomm.string, bcomm.length); while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm.string, true)) obstack_1grow (&token_stack, ch); if (ch != CHAR_EOF) obstack_grow (&token_stack, ecomm.string, ecomm.length); else /* current_file changed to "" if we see CHAR_EOF, use the previous value we stored earlier. */ M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line, "ERROR: end of file in comment")); type = TOKEN_STRING; } else if (default_word_regexp && (isalpha (ch) || ch == '_')) { obstack_1grow (&token_stack, ch); while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_')) { obstack_1grow (&token_stack, ch); next_char (); } type = TOKEN_WORD; } #ifdef ENABLE_CHANGEWORD else if (!default_word_regexp && word_regexp.fastmap[ch]) { obstack_1grow (&token_stack, ch); while (1) { ch = peek_input (); if (ch == CHAR_EOF) break; obstack_1grow (&token_stack, ch); startpos = re_search (&word_regexp, (char *) obstack_base (&token_stack), obstack_object_size (&token_stack), 0, 0, ®s); if (startpos || regs.end [0] != (regoff_t) obstack_object_size (&token_stack)) { *(((char *) obstack_base (&token_stack) + obstack_object_size (&token_stack)) - 1) = '\0'; break; } next_char (); } obstack_1grow (&token_stack, '\0'); orig_text = (char *) obstack_finish (&token_stack); if (regs.start[1] != -1) obstack_grow (&token_stack,orig_text + regs.start[1], regs.end[1] - regs.start[1]); else obstack_grow (&token_stack, orig_text,regs.end[0]); type = TOKEN_WORD; } #endif /* ENABLE_CHANGEWORD */ else if (!MATCH (ch, lquote.string, true)) { switch (ch) { case '(': type = TOKEN_OPEN; break; case ',': type = TOKEN_COMMA; break; case ')': type = TOKEN_CLOSE; break; default: type = TOKEN_SIMPLE; break; } obstack_1grow (&token_stack, ch); } else { bool fast = lquote.length == 1 && rquote.length == 1; quote_level = 1; while (1) { /* Try scanning a buffer first. */ const char *buffer = (isp && isp->type == INPUT_STRING ? isp->u.u_s.string : NULL); if (buffer && *buffer) { size_t len = isp->u.u_s.end - buffer; const char *p = buffer; do { p = (char *) memchr2 (p, *lquote.string, *rquote.string, buffer + len - p); } while (p && fast && (*p++ == *rquote.string ? --quote_level : ++quote_level)); if (p) { if (fast) { assert (!quote_level); obstack_grow (&token_stack, buffer, p - buffer - 1); isp->u.u_s.string += p - buffer; break; } obstack_grow (&token_stack, buffer, p - buffer); ch = to_uchar (*p); isp->u.u_s.string += p - buffer + 1; } else { obstack_grow (&token_stack, buffer, len); isp->u.u_s.string += len; continue; } } /* Fall back to a byte. */ else ch = next_char (); if (ch == CHAR_EOF) /* current_file changed to "" if we see CHAR_EOF, use the previous value we stored earlier. */ M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line, "ERROR: end of file in string")); if (MATCH (ch, rquote.string, true)) { if (--quote_level == 0) break; obstack_grow (&token_stack, rquote.string, rquote.length); } else if (MATCH (ch, lquote.string, true)) { quote_level++; obstack_grow (&token_stack, lquote.string, lquote.length); } else obstack_1grow (&token_stack, ch); } type = TOKEN_STRING; } obstack_1grow (&token_stack, '\0'); TOKEN_DATA_TYPE (td) = TOKEN_TEXT; TOKEN_DATA_TEXT (td) = (char *) obstack_finish (&token_stack); #ifdef ENABLE_CHANGEWORD if (orig_text == NULL) orig_text = TOKEN_DATA_TEXT (td); TOKEN_DATA_ORIG_TEXT (td) = orig_text; #endif #ifdef DEBUG_INPUT xfprintf (stderr, "next_token -> %s (%s)\n", token_type_string (type), TOKEN_DATA_TEXT (td)); #endif return type; }
void *ArrayPtrPopAddr(ArrayPtr *arr){ //void *TopAddr= obstack_base(arr->obstackPtr); return ((char *)obstack_base(arr->obstackPtr)-(arr->lengthOfLastOne)); }
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); }
static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty, struct type **dont_print_vb) { struct type **last_dont_print = (struct type **) obstack_next_free (&dont_print_vb_obstack); struct obstack tmp_obstack = dont_print_vb_obstack; int i, n_baseclasses = TYPE_N_BASECLASSES (type); if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ /* Bump up the high-water mark. Now alpha is omega. */ obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) goto flush_it; obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } boffset = baseclass_offset (type, i, valaddr, address); if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); /* The virtual base class pointer might have been clobbered by the user program. Make sure that it still points to a valid memory location. */ if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type))) { /* FIXME (alloc): not safe is baseclass is really really big. */ gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) boffset = -1; } else base_valaddr = valaddr + boffset; if (boffset == -1) fprintf_filtered (stream, "<invalid address>"); else pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset, stream, format, recurse, pretty, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); flush_it: ; } if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ dont_print_vb_obstack = tmp_obstack; } }
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); }
tree build_java_signature (tree type) { tree sig, t; while (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type); sig = TYPE_SIGNATURE (type); if (sig == NULL_TREE) { char sg[2]; switch (TREE_CODE (type)) { case BOOLEAN_TYPE: sg[0] = 'Z'; goto native; case VOID_TYPE: sg[0] = 'V'; goto native; case INTEGER_TYPE: if (type == char_type_node || type == promoted_char_type_node) { sg[0] = 'C'; goto native; } switch (TYPE_PRECISION (type)) { case 8: sg[0] = 'B'; goto native; case 16: sg[0] = 'S'; goto native; case 32: sg[0] = 'I'; goto native; case 64: sg[0] = 'J'; goto native; default: goto bad_type; } case REAL_TYPE: switch (TYPE_PRECISION (type)) { case 32: sg[0] = 'F'; goto native; case 64: sg[0] = 'D'; goto native; default: goto bad_type; } native: sg[1] = 0; sig = get_identifier (sg); break; case RECORD_TYPE: if (TYPE_ARRAY_P (type)) { t = build_java_signature (TYPE_ARRAY_ELEMENT (type)); sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t), "[", 0, 0, ""); } else { t = DECL_NAME (TYPE_NAME (type)); sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t), "L", '.', '/', ";"); } break; case METHOD_TYPE: case FUNCTION_TYPE: { extern struct obstack temporary_obstack; sig = build_java_argument_signature (type); obstack_1grow (&temporary_obstack, '('); obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig)); obstack_1grow (&temporary_obstack, ')'); t = build_java_signature (TREE_TYPE (type)); obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); sig = get_identifier ((char *) obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); } break; bad_type: default: gcc_unreachable (); } TYPE_SIGNATURE (type) = sig; } return sig; }
token_type next_token (token_data *td) { int ch; int quote_level; token_type type; #ifdef ENABLE_CHANGEWORD int startpos; char *orig_text = 0; #endif obstack_free (&token_stack, token_bottom); obstack_1grow (&token_stack, '\0'); token_bottom = obstack_finish (&token_stack); ch = peek_input (); if (ch == CHAR_EOF) { return TOKEN_EOF; #ifdef DEBUG_INPUT fprintf (stderr, "next_token -> EOF\n"); #endif } if (ch == CHAR_MACRO) { init_macro_token (td); (void) next_char (); return TOKEN_MACDEF; } (void) next_char (); if (MATCH (ch, bcomm.string)) { obstack_grow (&token_stack, bcomm.string, bcomm.length); while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm.string)) obstack_1grow (&token_stack, ch); if (ch != CHAR_EOF) obstack_grow (&token_stack, ecomm.string, ecomm.length); type = TOKEN_STRING; } #ifdef ENABLE_CHANGEWORD else if (default_word_regexp && (isalpha (ch) || ch == '_')) #else else if (isalpha (ch) || ch == '_') #endif { obstack_1grow (&token_stack, ch); while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_')) { obstack_1grow (&token_stack, ch); (void) next_char (); } type = TOKEN_WORD; } #ifdef ENABLE_CHANGEWORD else if (!default_word_regexp && strchr (word_start, ch)) { obstack_1grow (&token_stack, ch); while (1) { ch = peek_input (); if (ch == CHAR_EOF) break; obstack_1grow (&token_stack, ch); startpos = re_search (&word_regexp, obstack_base (&token_stack), obstack_object_size (&token_stack), 0, 0, ®s); if (startpos != 0 || regs.end [0] != obstack_object_size (&token_stack)) { *(((char *) obstack_base (&token_stack) + obstack_object_size (&token_stack)) - 1) = '\0'; break; } next_char (); } obstack_1grow (&token_stack, '\0'); orig_text = obstack_finish (&token_stack); if (regs.start[1] != -1) obstack_grow (&token_stack,orig_text + regs.start[1], regs.end[1] - regs.start[1]); else obstack_grow (&token_stack, orig_text,regs.end[0]); type = TOKEN_WORD; } #endif /* ENABLE_CHANGEWORD */ else if (!MATCH (ch, lquote.string)) { type = TOKEN_SIMPLE; obstack_1grow (&token_stack, ch); } else { quote_level = 1; while (1) { ch = next_char (); if (ch == CHAR_EOF) M4ERROR ((EXIT_FAILURE, 0, "ERROR: EOF in string")); if (MATCH (ch, rquote.string)) { if (--quote_level == 0) break; obstack_grow (&token_stack, rquote.string, rquote.length); } else if (MATCH (ch, lquote.string)) { quote_level++; obstack_grow (&token_stack, lquote.string, lquote.length); } else obstack_1grow (&token_stack, ch); } type = TOKEN_STRING; } obstack_1grow (&token_stack, '\0'); TOKEN_DATA_TYPE (td) = TOKEN_TEXT; TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack); #ifdef ENABLE_CHANGEWORD if (orig_text == NULL) orig_text = TOKEN_DATA_TEXT (td); TOKEN_DATA_ORIG_TEXT (td) = orig_text; #endif #ifdef DEBUG_INPUT fprintf (stderr, "next_token -> %d (%s)\n", type, TOKEN_DATA_TEXT (td)); #endif return type; }
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); }