static int gmp_obstack_reps (struct obstack *ob, int c, int reps) { obstack_blank (ob, reps); memset ((char *) obstack_next_free(ob) - reps, c, reps); return reps; }
/* * 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() */
void testValues() { f = 2; struct obstack o; obstack_init(&o); obstack_blank(&o, 4); obstack_1grow(&o, '!'); int result = obstack_object_size(&o); //@ assert result == 5; //@ assert f == 2; //@ assert vacuous: \false; }
/* 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; }
/** 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; }
/* Extract identifiers from MANGLED_STR and append it to TEMPBUF. Return 1 on success or 0 on failure. */ static int extract_identifiers (const char *mangled_str, struct obstack *tempbuf) { long i = 0; while (isdigit (*mangled_str)) { char *end_ptr; i = strtol (mangled_str, &end_ptr, 10); mangled_str = end_ptr; if (i <= 0 || strlen (mangled_str) < i) return 0; obstack_grow (tempbuf, mangled_str, i); mangled_str += i; obstack_grow_str (tempbuf, "."); } if (*mangled_str == '\0' || i == 0) return 0; obstack_blank (tempbuf, -1); return 1; }
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 void x_obstack_blank (struct xheader *xhdr, size_t length) { obstack_blank (xhdr->stk, length); xhdr->size += length; }
bool options_parse_codegen(options_state_t *s) { const char *full_option = s->argv[s->i]; if (full_option[0] != '-') return false; const char *option = &full_option[1]; const char *arg; if ((arg = equals_arg("falign-loops", s)) != NULL || (arg = equals_arg("falign-jumps", s)) != NULL || (arg = equals_arg("falign-functions", s)) != NULL) { warningf(WARN_COMPAT_OPTION, NULL, "ignoring gcc option '%s'", full_option); } else if ((arg = equals_arg("fvisibility", s)) != NULL) { elf_visibility_t visibility = get_elf_visibility_from_string(arg); if (visibility == ELF_VISIBILITY_ERROR) { errorf(NULL, "invalid visibility '%s' specified", arg); s->argument_errors = true; } else { set_default_visibility(visibility); } } else if (simple_arg("-unroll-loops", s)) { /* ignore (gcc compatibility) */ } else if (simple_arg("fexcess-precision=standard", s)) { /* ignore (gcc compatibility) we always adhere to the C99 standard * anyway in this respect */ } else if (accept_prefix(s, "-g", false, &arg)) { if (streq(arg, "0")) { set_target_option("debug=none"); set_target_option("ia32-optcc=true"); } else { set_target_option("debug=frameinfo"); set_target_option("ia32-optcc=false"); } } else if (accept_prefix(s, "-m", false, &arg)) { arg = &option[1]; /* remember option for backend */ assert(obstack_object_size(&codegenflags_obst) == 0); obstack_blank(&codegenflags_obst, sizeof(codegen_option_t)); size_t len = strlen(arg); obstack_grow(&codegenflags_obst, arg, len); codegen_option_t *const cg_option = obstack_nul_finish(&codegenflags_obst); cg_option->next = NULL; *codegen_options_anchor = cg_option; codegen_options_anchor = &cg_option->next; } else { bool truth_value; const char *fopt; if ((fopt = f_no_arg(&truth_value, s)) != NULL) { if (f_yesno_arg("-ffast-math", s)) { ir_allow_imprecise_float_transforms(truth_value); } else if (f_yesno_arg("-fomit-frame-pointer", s)) { target.set_use_frame_pointer = true; target.use_frame_pointer = !truth_value; } else if (f_yesno_arg("-fstrength-reduce", s)) { /* does nothing, for gcc compatibility (even gcc does * nothing for this switch anymore) */ } else if (!truth_value && (f_yesno_arg("-fasynchronous-unwind-tables", s) || f_yesno_arg("-funwind-tables", s))) { /* do nothing: a gcc feature which we do not support * anyway was deactivated */ } else if (f_yesno_arg("-frounding-math", s)) { /* ignore for gcc compatibility: we don't have any unsafe * optimizations in that area */ } else if (f_yesno_arg("-fverbose-asm", s)) { set_target_option(truth_value ? "verboseasm" : "verboseasm=no"); } else if (f_yesno_arg("-fPIC", s)) { target.pic = truth_value; target.set_pic = true; } else if (f_yesno_arg("-fpic", s)) { target.pic = truth_value; target.set_pic = true; /* cparser has no concept of -fPIC vs. -fpic yet */ if (truth_value) warningf(WARN_COMPAT_OPTION, NULL, "-fpic unsupported, using -fPIC instead"); } else if (f_yesno_arg("-fplt", s)) { target.pic_noplt = !truth_value; target.set_noplt = true; } else if (f_yesno_arg("-fjump-tables", s) || f_yesno_arg("-fexpensive-optimizations", s) || f_yesno_arg("-fcommon", s) || f_yesno_arg("-foptimize-sibling-calls", s) || f_yesno_arg("-falign-loops", s) || f_yesno_arg("-falign-jumps", s) || f_yesno_arg("-falign-functions", s) || f_yesno_arg("-fstack-protector", s) || f_yesno_arg("-fstack-protector-all", s)) { /* better warn the user for these as he might have expected * that something happens */ warningf(WARN_COMPAT_OPTION, NULL, "ignoring gcc option '-f%s'", fopt); } else if (firm_option(&option[1])) { /* parsed a firm option */ } else { return false; } } else { return false; } } return true; }
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 *)); }
qu_ast_node *qu_raw_globseq(struct qu_parser *ctx, qu_ast_node *src) { const char *pat = qu_node_content(src); const char *pattern = qu_join_filenames(ctx, src->tag_token->filename, pat); const char *star = strchr(pattern, '*'); if(!star || star != strrchr(pattern, '*')) { qu_err_node_fatal(ctx->err, src, "Exactly one star in glob pattern required"); } const char *c; for (c = star-1; c >= pattern && *c != '/'; --c); const char *pat_start = c+1; for (c = star+1; *c && *c != '/'; ++c); const char *pat_end = c; int taillen = strlen(pat_end); char *dir; int dirlen; if(pat_start > pattern) { dirlen = pat_start - pattern; dir = alloca(dirlen + 1); memcpy(dir, pattern, dirlen); dir[dirlen] = 0; } else { dir = "."; dirlen = 1; } DIR *d = opendir(dir); if(!d) { qu_err_node_fatal(ctx->err, src, "Can't open directory \"%s\"", dir); } qu_ast_node *result = qu_new_sequence_node(ctx, NULL); int name_max = pathconf(dir, _PC_NAME_MAX); if (name_max == -1) /* Limit not defined, or error */ name_max = 255; /* Take a guess */ int len = offsetof(struct dirent, d_name) + name_max + 1; struct dirent *entryp = alloca(len); int rc; while(!(rc = readdir_r(d, entryp, &entryp)) && entryp) { // Prefix match if(pat_start == star) { // dir/* shouldn't match hidden files if(entryp->d_name[0] == '.') continue; } else { if(strncmp(entryp->d_name, pat_start, star - pat_start)) continue; } // Suffix match char *eend = entryp->d_name + strlen(entryp->d_name); if(pat_end > star+1) { int suffixlen = pat_end - (star+1); if(eend - entryp->d_name < suffixlen) continue; if(strncmp(eend - suffixlen, star+1, suffixlen)) continue; } obstack_blank(&ctx->pieces, 0); obstack_grow(&ctx->pieces, dir, dirlen); obstack_grow(&ctx->pieces, entryp->d_name, strlen(entryp->d_name)); obstack_grow0(&ctx->pieces, pat_end, taillen); char *fn = obstack_finish(&ctx->pieces); if(access(fn, F_OK) < 0) // file not exists after adding suffix continue; qu_ast_node *next = qu_file_newparse(ctx, fn); if(next) { qu_sequence_add(ctx, result, next); } } if(rc) { qu_err_node_fatal(ctx->err, src, "Can't read directory \"%s\"", dir); } closedir(d); return result; }