static void collect_arguments (symbol *sym, struct obstack *argptr, struct obstack *arguments) { token_data td; token_data *tdp; bool more_args; bool groks_macro_args = SYMBOL_MACRO_ARGS (sym); TOKEN_DATA_TYPE (&td) = TOKEN_TEXT; TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym); tdp = (token_data *) obstack_copy (arguments, &td, sizeof td); obstack_ptr_grow (argptr, tdp); if (peek_token () == TOKEN_OPEN) { next_token (&td, NULL); /* gobble parenthesis */ do { more_args = expand_argument (arguments, &td); if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC) { TOKEN_DATA_TYPE (&td) = TOKEN_TEXT; TOKEN_DATA_TEXT (&td) = (char *) ""; } tdp = (token_data *) obstack_copy (arguments, &td, sizeof td); obstack_ptr_grow (argptr, tdp); } while (more_args); } }
/* Read NUL-separated tokens from stream IN into T until EOF or error. The final NUL is optional. Always append a NULL pointer to the resulting list of token pointers, but that pointer isn't counted via t->n_tok. Return true if successful. */ bool readtokens0 (FILE *in, struct Tokens *t) { while (1) { int c = fgetc (in); if (c == EOF) { size_t len = obstack_object_size (&t->o_data); /* If the current object has nonzero length, then there was no NUL byte at EOF -- or maybe there was an error, in which case, we need to append a NUL byte to our buffer. */ if (len) { obstack_1grow (&t->o_data, '\0'); save_token (t); } break; } obstack_1grow (&t->o_data, c); if (c == '\0') save_token (t); } /* Add a NULL pointer at the end, in case the caller (like du) requires an argv-style array of strings. */ obstack_ptr_grow (&t->o_tok, NULL); t->tok = obstack_finish (&t->o_tok); t->tok_len = obstack_finish (&t->o_tok_len); return ! ferror (in); }
/* Finalize (in the obstack_finish sense) the current token and record its pointer and length. */ static void save_token (struct Tokens *t) { /* Don't count the trailing NUL byte in the length. */ size_t len = obstack_object_size (&t->o_data) - 1; char const *s = obstack_finish (&t->o_data); obstack_ptr_grow (&t->o_tok, s); obstack_grow (&t->o_tok_len, &len, sizeof len); t->n_tok++; }
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; } }
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; } }
static int recompile_files (void) { file *f; putenv (xstrdup ("COMPILER_PATH=")); putenv (xstrdup ("LIBRARY_PATH=")); while ((f = file_pop ()) != NULL) { char *line; const char *p, *q; char **argv; struct obstack arg_stack; FILE *stream = fopen (f->key, "r"); const char *const outname = frob_extension (f->key, ".rnw"); FILE *output = fopen (outname, "w"); while ((line = tfgets (stream)) != NULL) { switch (line[0]) { case 'C': case 'O': maybe_tweak (line, f); } fprintf (output, "%s\n", line); } fclose (stream); fclose (output); rename (outname, f->key); if (!f->args) { error ("repository file `%s' does not contain command-line " "arguments", f->key); return 0; } /* Build a null-terminated argv array suitable for tlink_execute(). Manipulate arguments on the arg_stack while building argv on the temporary_obstack. */ obstack_init (&arg_stack); obstack_ptr_grow (&temporary_obstack, c_file_name); for (p = f->args; *p != '\0'; p = q + 1) { /* Arguments are delimited by single-quotes. Find the opening quote. */ p = strchr (p, '\''); if (!p) goto done; /* Find the closing quote. */ q = strchr (p + 1, '\''); if (!q) goto done; obstack_grow (&arg_stack, p + 1, q - (p + 1)); /* Replace '\'' with '. This is how set_collect_gcc_options encodes a single-quote. */ while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'') { const char *r; r = strchr (q + 4, '\''); if (!r) goto done; obstack_grow (&arg_stack, q + 3, r - (q + 3)); q = r; } obstack_1grow (&arg_stack, '\0'); obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack)); } done: obstack_ptr_grow (&temporary_obstack, f->main); obstack_ptr_grow (&temporary_obstack, NULL); argv = obstack_finish (&temporary_obstack); if (tlink_verbose) fprintf (stderr, _("collect: recompiling %s\n"), f->main); if (chdir (f->dir) != 0 || tlink_execute (c_file_name, argv, NULL) != 0 || chdir (initial_cwd) != 0) return 0; read_repo_file (f); obstack_free (&arg_stack, NULL); obstack_free (&temporary_obstack, temporary_firstobj); } return 1; }