コード例 #1
0
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;
}
コード例 #2
0
ファイル: frags.c プロジェクト: hollylee/xchain
/*
 *			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() */
コード例 #3
0
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;
}
コード例 #4
0
ファイル: Linux.c プロジェクト: carnil/perl-proc-processtable
/* 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;
}
コード例 #5
0
ファイル: beemitter_binary.c プロジェクト: lu-zero/libfirm
/** 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;
}
コード例 #6
0
ファイル: d-lang.c プロジェクト: AhmadTux/DragonFlyBSD
/* 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;
}
コード例 #7
0
ファイル: charset.c プロジェクト: abidh/gdb
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);
}
コード例 #8
0
ファイル: xheader.c プロジェクト: GrayKing/LeakFix-on-Tar
static void
x_obstack_blank (struct xheader *xhdr, size_t length)
{
  obstack_blank (xhdr->stk, length);
  xhdr->size += length;
}
コード例 #9
0
ファイル: options.c プロジェクト: MatzeB/cparser
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;
}
コード例 #10
0
ファイル: macro.c プロジェクト: 119/aircam-openwrt
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 *));
}
コード例 #11
0
ファイル: globseq.c プロジェクト: tailhook/quire
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;
}