int main( int argc, char **argv ) { char *s = "Hello world"; char *s2 = "**Helsssssssssssssssssssssssssssslo world**"; char *p, *p2; obstack_init( &os ); p = (char*)obstack_copy0( &os, s, strlen(s) ); p2 = (char*)obstack_copy0( &os, s2, strlen(s2) ); //printf("%s - %s %08lX %08lX\n", p, p2, p, p2 ); obstack_free( &os, p ); p = (char*)obstack_copy0( &os, s, strlen(s) ); p = (char*)obstack_copy0( &os, s, strlen(s) ); p2 = (char*)obstack_copy0( &os, s2, strlen(s2) ); //printf("%s - %s %08lX %08lX\n", p, p2, p, p2 ); obstack_grow( &os, s, strlen(s) ); obstack_grow( &os, s, strlen(s) ); obstack_grow( &os, s, strlen(s) ); obstack_grow( &os, s, strlen(s) ); obstack_grow( &os, s, strlen(s) ); obstack_grow( &os, s, strlen(s) ); obstack_grow0( &os, s, strlen(s) ); p = obstack_finish( &os ); obstack_grow0( &os, s, strlen(s) ); p = obstack_finish( &os ); printf("XXXXXX %s XXXXXX\n", p ); obstack_free( &os, NULL ); return 0; }
/* 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); }
/* Read incremental snapshot format 2 */ static void read_incr_db_2 (void) { struct obstack stk; char offbuf[INT_BUFSIZE_BOUND (off_t)]; obstack_init (&stk); read_timespec (listed_incremental_stream, &newer_mtime_option); for (;;) { intmax_t i; struct timespec mtime; dev_t dev; ino_t ino; bool nfs; char *name; char *content; size_t s; if (! read_num (listed_incremental_stream, "nfs", 0, 1, &i)) return; /* Normal return */ nfs = i; read_timespec (listed_incremental_stream, &mtime); if (! read_num (listed_incremental_stream, "dev", TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), &i)) break; dev = i; if (! read_num (listed_incremental_stream, "ino", TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), &i)) break; ino = i; if (read_obstack (listed_incremental_stream, &stk, &s)) break; name = obstack_finish (&stk); while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1) ; if (getc (listed_incremental_stream) != 0) FATAL_ERROR ((0, 0, _("%s: byte %s: %s"), quotearg_colon (listed_incremental_option), offtostr (ftello (listed_incremental_stream), offbuf), _("Missing record terminator"))); content = obstack_finish (&stk); note_directory (name, mtime, dev, ino, nfs, false, content); obstack_free (&stk, content); } FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (listed_incremental_option), _("Unexpected EOF in snapshot file"))); }
/* * frag_new() * * Call this to close off a completed frag, and start up a new (empty) * frag, in the same subsegment as the old frag. * [frchain_now remains the same but frag_now is updated.] * Because this calculates the correct value of fr_fix by * looking at the obstack 'frags', it needs to know how many * characters at the end of the old frag belong to (the maximal) * fr_var: the rest must belong to fr_fix. * It doesn't actually set up the old frag's fr_var: you may have * set fr_var == 1, but allocated 10 chars to the end of the frag: * in this case you pass old_frags_var_max_size == 10. * * Make a new frag, initialising some components. Link new frag at end * of frchain_now. */ void frag_new( int old_frags_var_max_size) /* Number of chars (already allocated on obstack frags) in variable_length part of frag. */ { register fragS * former_last_fragP; /* char *throw_away_pointer; JF unused */ register frchainS * frchP; long tmp; /* JF */ if(frags.chunk_size == 0) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - (frag_now->fr_literal) - old_frags_var_max_size; /* Fix up old frag's fr_fix. */ obstack_finish (&frags); /* This will align the obstack so the */ /* next struct we allocate on it will */ /* begin at a correct boundary. */ frchP = frchain_now; know (frchP); former_last_fragP = frchP->frch_last; know (former_last_fragP); know (former_last_fragP == frag_now); obstack_blank (&frags, SIZEOF_STRUCT_FRAG); /* We expect this will begin at a correct */ /* boundary for a struct. */ tmp=obstack_alignment_mask(&frags); obstack_alignment_mask(&frags)=0; /* Turn off alignment */ /* If we ever hit a machine where strings must be aligned, we Lose Big */ frag_now=(fragS *)obstack_finish(&frags); obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ /* Just in case we don't get zero'd bytes */ memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); /* obstack_unaligned_done (&frags, &frag_now); */ /* know (frags.obstack_c_next_free == frag_now->fr_literal); */ /* Generally, frag_now->points to an */ /* address rounded up to next alignment. */ /* However, characters will add to obstack */ /* frags IMMEDIATELY after the struct frag, */ /* even if they are not starting at an */ /* alignment address. */ former_last_fragP->fr_next = frag_now; frchP->frch_last = frag_now; frag_now->fr_next = NULL; } /* frag_new() */
/* Read incremental snapshot format 2 */ static void read_incr_db_2 () { uintmax_t u; struct obstack stk; obstack_init (&stk); read_timespec (listed_incremental_stream, &newer_mtime_option); for (;;) { struct timespec mtime; dev_t dev; ino_t ino; bool nfs; char *name; char *content; size_t s; if (read_num (listed_incremental_stream, 1, &u)) return; /* Normal return */ nfs = u; read_timespec (listed_incremental_stream, &mtime); if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u)) break; dev = u; if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u)) break; ino = u; if (read_obstack (listed_incremental_stream, &stk, &s)) break; name = obstack_finish (&stk); while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1) ; if (getc (listed_incremental_stream) != 0) FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (listed_incremental_option), _("Missing record terminator"))); content = obstack_finish (&stk); note_directory (name, mtime, dev, ino, nfs, false, content); obstack_free (&stk, content); } FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (listed_incremental_option), _("Unexpected EOF in snapshot file"))); }
static void set_conflicts (state *s, symbol **errors) { int i; transitions *trans = s->transitions; reductions *reds = s->reductions; int nerrs = 0; if (s->consistent) return; bitset_zero (lookahead_set); FOR_EACH_SHIFT (trans, i) bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i)); /* Loop over all rules which require lookahead in this state. First check for shift-reduce conflict, and try to resolve using precedence. */ for (i = 0; i < reds->num; ++i) if (reds->rules[i]->prec && reds->rules[i]->prec->prec && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) resolve_sr_conflict (s, i, errors, &nerrs); if (nerrs) { /* Some tokens have been explicitly made errors. Allocate a permanent errs structure for this state, to record them. */ state_errs_set (s, nerrs, errors); } if (obstack_object_size (&solved_conflicts_obstack)) { obstack_1grow (&solved_conflicts_obstack, '\0'); s->solved_conflicts = obstack_finish (&solved_conflicts_obstack); } if (obstack_object_size (&solved_conflicts_xml_obstack)) { obstack_1grow (&solved_conflicts_xml_obstack, '\0'); s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack); } /* Loop over all rules which require lookahead in this state. Check for conflicts not resolved above. */ for (i = 0; i < reds->num; ++i) { if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) conflicts[s->number] = 1; bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); } }
/* * add_last_frags_to_sections() does what layout_addresses() does below about * adding a last ".fill 0" frag to each section. This is called by * dwarf2_finish() allow get_frag_fix() in dwarf2dbg.c to work for the last * fragment in a section. */ void add_last_frags_to_sections( void) { struct frchain *frchainP; if(frchain_root == NULL) return; /* * If there is any current frag close it off. */ if(frag_now != NULL && frag_now->fr_fix == 0){ frag_now->fr_fix = obstack_next_free(&frags) - frag_now->fr_literal; frag_wane(frag_now); } /* * For every section, add a last ".fill 0" frag that will later be used * as the ending address of that section. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * We must do the obstack_finish(), so the next object we put on * obstack frags will not appear to start at the fr_literal of the * current frag. Also, it ensures that the next object will begin * on a address that is aligned correctly for the engine that runs * the assembler. */ (void)obstack_finish(&frags); /* * Make a fresh frag for the last frag. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; (void)obstack_finish(&frags); /* * Append the new frag to current frchain. */ frchainP->frch_last->fr_next = frag_now; frchainP->frch_last = frag_now; frag_wane(frag_now); } }
const char * push_string_finish (read_type expansion) { const char *ret = NULL; if (next == NULL) return NULL; if (obstack_object_size (current_input) > 0) { obstack_1grow (current_input, '\0'); next->u.u_s.start = (unsigned char *) obstack_finish (current_input); if (expansion == READ_ATTR_VERB || expansion == READ_ATTR_ASIS || expansion == READ_BODY) { TOKEN_DATA_TYPE (&token_read) = TOKEN_TEXT; TOKEN_DATA_TEXT (&token_read) = xstrdup ((char *) next->u.u_s.start); next->u.u_s.current = next->u.u_s.start + strlen ((char *) next->u.u_s.start); } else next->u.u_s.current = next->u.u_s.start; next->prev = isp; isp = next; ret = (char *) isp->u.u_s.start; /* for immediate use only */ } else obstack_free (current_input, next); /* people might leave garbage on it. */ next = NULL; return ret; }
static LONGEST windows_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len) { struct obstack obstack; const char *buf; LONGEST len_avail; struct cpms_data data = { gdbarch, &obstack, 0 }; obstack_init (&obstack); obstack_grow_str (&obstack, "<library-list>\n"); bfd_map_over_sections (core_bfd, core_process_module_section, &data); obstack_grow_str0 (&obstack, "</library-list>\n"); buf = obstack_finish (&obstack); len_avail = strlen (buf); if (offset >= len_avail) return 0; if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); obstack_free (&obstack, NULL); return len; }
static void acls_one_line (const char *prefix, char delim, const char *aclstring, size_t len) { /* support both long and short text representation of posix acls */ struct obstack stk; int pref_len = strlen (prefix); const char *oldstring = aclstring; int pos = 0; if (!aclstring || !len) return; obstack_init (&stk); while (pos <= len) { int move = strcspn (aclstring, ",\n"); if (!move) break; if (oldstring != aclstring) obstack_1grow (&stk, delim); obstack_grow (&stk, prefix, pref_len); obstack_grow (&stk, aclstring, move); aclstring += move + 1; } obstack_1grow (&stk, '\0'); fprintf (stdlis, "%s", (char *) obstack_finish (&stk)); obstack_free (&stk, NULL); }
static char * string_format( char *str, int *retlen, int refcon ) { int on=0, len=0, add; char ch; while( sscanf(str,"%c%n\n", &ch, &add) > 0 ) { str+=add; if( ch == '"' ) { on=!on; continue; } if( on ) { obstack_1grow( &oftree.stack, ch ); len++; } else if( ch == ',' ){ obstack_1grow( &oftree.stack, 0 ); len++; } } obstack_1grow( &oftree.stack, 0 ); len++; *retlen = len; return obstack_finish( &oftree.stack ); }
void append_incremental_renames (struct directory *dir) { struct obstack stk; size_t size; struct directory *dp; const char *dump; if (dirhead == NULL) return; obstack_init (&stk); dump = directory_contents (dir); if (dump) { size = dumpdir_size (dump) - 1; obstack_grow (&stk, dump, size); } else size = 0; for (dp = dirhead; dp; dp = dp->next) store_rename (dp, &stk); if (obstack_object_size (&stk) != size) { obstack_1grow (&stk, 0); dumpdir_free (dir->dump); dir->dump = dumpdir_create (obstack_finish (&stk)); } obstack_free (&stk, NULL); }
static char * hex_format( char *str, int *retlen, int refcon ) { int add, len=0, v; char *str2; if( (str2=strchr( str, '(' )) ) /* compatibility */ str = str2+1; for( ;; ) { if( sscanf(str, " 0x%x%n\n", &v, &add) <= 0 ) if( sscanf(str, " %d%n\n", &v, &add) <= 0 ) break; str += add; if( refcon == 1 ) { unsigned char vch = v; obstack_grow( &oftree.stack, &vch, 1 ); } else { obstack_grow( &oftree.stack, &v, 4 ); } len += refcon; } *retlen = len; return len ? obstack_finish( &oftree.stack ) : NULL; }
void be_emit_write_line(void) { size_t const len = obstack_object_size(&emit_obst); char *const line = (char*)obstack_finish(&emit_obst); fwrite(line, 1, len, emit_file); obstack_free(&emit_obst, line); }
void muscle_grow (const char *key, const char *val, const char *separator) { muscle_entry probe; muscle_entry *entry = NULL; probe.key = key; entry = hash_lookup (muscle_table, &probe); if (!entry) { /* First insertion in the hash. */ entry = xmalloc (sizeof *entry); entry->key = key; hash_insert (muscle_table, entry); entry->value = xstrdup (val); } else { /* Grow the current value. */ char *new_val; obstack_sgrow (&muscle_obstack, entry->value); free (entry->value); obstack_sgrow (&muscle_obstack, separator); obstack_sgrow (&muscle_obstack, val); obstack_1grow (&muscle_obstack, 0); new_val = obstack_finish (&muscle_obstack); entry->value = xstrdup (new_val); obstack_free (&muscle_obstack, new_val); } }
static void eval_link(char *pid, char *link_rel, enum field field, char **ptr, char *format_str, struct obstack *mem_pool) { char *link_file, *link; /* path to the link file like. /proc/{pid}/{link_rel} */ link_file = proc_pid_file(pid, link_rel, mem_pool); /* It's okay to use canonicalize_file_name instead of readlink on linux * for the cwd symlink, since on linux the links we care about will never * be relative links (cwd, exec) * Doing this because readlink works on static buffers */ link = canonicalize_file_name(link_file); /* we no longer need need the path to the link file */ obstack_free(mem_pool, link_file); if (link == NULL) return; /* copy the path onto our obstack, set the value (somewhere in pts) * and free the results of canonicalize_file_name */ obstack_printf(mem_pool, link); obstack_1grow(mem_pool, '\0'); *ptr = (char *) obstack_finish(mem_pool); free(link); /* enable whatever field we successfuly retrived */ field_enable(format_str, field); }
/* Read a braced string (a la Tcl) onto the obstack. Caller has scanned the leading brace. Note that unlike quoted strings, the outermost braces _are_ included in the string constant. */ static char * read_braced_string (struct obstack *ob, FILE *infile) { int c; int brace_depth = 1; /* caller-processed */ unsigned long starting_read_rtx_lineno = read_rtx_lineno; obstack_1grow (ob, '{'); while (brace_depth) { c = getc (infile); /* Read the string */ if (c == '\n') read_rtx_lineno++; else if (c == '{') brace_depth++; else if (c == '}') brace_depth--; else if (c == '\\') { read_escape (ob, infile); continue; } else if (c == EOF) fatal_with_file_and_line (infile, "missing closing } for opening brace on line %lu", starting_read_rtx_lineno); obstack_1grow (ob, c); } obstack_1grow (ob, 0); return obstack_finish (ob); }
static ident *new_ident_from_obst(struct obstack *const obst) { size_t const len = obstack_object_size(obst); char *const string = (char*)obstack_finish(obst); ident *const res = new_id_from_chars(string, len); obstack_free(obst, string); return res; }
/* Terminates the obstring as determined by its implementation. This also puts a null character at the end of the string so one can use the string actively. This function will return the final obstack address. */ char* close_obstring(struct obstack* strob) { /* Places NULL char at the end of string */ obstack_1grow(strob, 0); /* Closes the obstack-string */ return obstack_finish(strob); }
static void prepare (void) { /* Flags. */ MUSCLE_INSERT_BOOL ("debug_flag", debug_flag); MUSCLE_INSERT_BOOL ("defines_flag", defines_flag); MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose); MUSCLE_INSERT_BOOL ("locations_flag", locations_flag); MUSCLE_INSERT_BOOL ("pure_flag", pure_parser); MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag); /* File names. */ MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy"); #define DEFINE(Name) MUSCLE_INSERT_STRING (#Name, Name ? Name : "") DEFINE (dir_prefix); DEFINE (parser_file_name); DEFINE (spec_defines_file); DEFINE (spec_file_prefix); DEFINE (spec_graph_file); DEFINE (spec_name_prefix); DEFINE (spec_outfile); DEFINE (spec_verbose_file); #undef DEFINE /* User Code. */ obstack_1grow (&pre_prologue_obstack, 0); obstack_1grow (&post_prologue_obstack, 0); muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack)); muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack)); /* Find the right skeleton file. */ if (!skeleton) { if (glr_parser || nondeterministic_parser) skeleton = "glr.c"; else skeleton = "yacc.c"; } /* About the skeletons. */ { char const *pkgdatadir = getenv ("BISON_PKGDATADIR"); MUSCLE_INSERT_STRING ("pkgdatadir", pkgdatadir ? pkgdatadir : PKGDATADIR); MUSCLE_INSERT_C_STRING ("skeleton", skeleton); } }
static void prepare_symbols (void) { MUSCLE_INSERT_BOOL ("token_table", token_table_flag); MUSCLE_INSERT_INT ("tokens_number", ntokens); MUSCLE_INSERT_INT ("nterms_number", nvars); MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number); MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number); muscle_insert_symbol_number_table ("translate", token_translations, token_translations[0], 1, max_user_token_number + 1); /* tname -- token names. */ { int i; /* We assume that the table will be output starting at column 2. */ int j = 2; for (i = 0; i < nsyms; i++) { char const *cp = quotearg_style (c_quoting_style, symbols[i]->tag); /* Width of the next token, including the two quotes, the comma and the space. */ int width = strlen (cp) + 2; if (j + width > 75) { obstack_sgrow (&format_obstack, "\n "); j = 1; } if (i) obstack_1grow (&format_obstack, ' '); MUSCLE_OBSTACK_SGROW (&format_obstack, cp); obstack_1grow (&format_obstack, ','); j += width; } /* Add a NULL entry to list of tokens (well, 0, as NULL might not be defined). */ obstack_sgrow (&format_obstack, " 0"); /* Finish table and store. */ obstack_1grow (&format_obstack, 0); muscle_insert ("tname", obstack_finish (&format_obstack)); } /* Output YYTOKNUM. */ { int i; int *values = xnmalloc (ntokens, sizeof *values); for (i = 0; i < ntokens; ++i) values[i] = symbols[i]->user_token_number; muscle_insert_int_table ("toknum", values, values[0], 1, ntokens); free (values); } }
/* 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; }
static const char *ia32_get_old_node_name(const ir_node *irn) { ir_graph *irg = get_irn_irg(irn); struct obstack *obst = be_get_be_obst(irg); lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn); obstack_1grow(obst, 0); return (const char*)obstack_finish(obst); }
char * ui_file_obsavestring (struct ui_file *file, struct obstack *obstack, long *length) { ui_file_put (file, do_ui_file_obsavestring, obstack); *length = obstack_object_size (obstack); obstack_1grow (obstack, '\0'); return obstack_finish (obstack); }
static symbol_t *finalize_symbol_string(void) { obstack_1grow(&symbol_obstack, '\0'); char *string = obstack_finish(&symbol_obstack); symbol_t *symbol = symbol_table_insert(string); if (symbol->string != string) obstack_free(&symbol_obstack, string); return symbol; }
void xheader_finish (struct xheader *xhdr) { struct keyword_list *kp; for (kp = keyword_override_list; kp; kp = kp->next) code_string (kp->value, kp->pattern, xhdr); xhdr->buffer = obstack_finish (xhdr->stk); }
/* 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 trace_flush (void) { char *line; obstack_1grow (&trace, '\0'); line = (char *) obstack_finish (&trace); DEBUG_PRINT1 ("%s\n", line); obstack_free (&trace, line); }
void muscle_pair_list_grow (const char *muscle, const char *a1, const char *a2) { char *pair; obstack_fgrow2 (&muscle_obstack, "[[[%s]], [[%s]]]", a1, a2); obstack_1grow (&muscle_obstack, 0); pair = obstack_finish (&muscle_obstack); muscle_grow (muscle, pair, ",\n"); obstack_free (&muscle_obstack, pair); }
const char *mem_finish( mem_String info ) { stringInfo i = (stringInfo)info; _mem_magic_strings( i, __FUNCTION__ ); ++i->count; i->bytes += 1; obstack_grow0( i->obstack, "", 0 ); return obstack_finish( i->obstack ); }