示例#1
0
void init_error_functions(void)
{
    define_function("enable-error-system", obj_Nil, FALSE, obj_False, FALSE,
		    obj_ObjectClass, enable_error_system);
    error_var = find_variable(module_BuiltinStuff, symbol("error"),
			      FALSE, TRUE);
    type_error_var = find_variable(module_BuiltinStuff, symbol("type-error"),
				   FALSE, TRUE);
}
示例#2
0
int opcode_next(int program_counter, char *buf)
{
	int pcounter = 0;
	int local_var = 0;
	int loop_status = 0;

	/* Add End Of Loop */
	add_end(program_counter);

	/* Find For Entry */
	loop_status = find_entry(program_counter);

	/* loop_status != INVALID_LOOP means Legal Loop */
	if (loop_status != INVALID_LOOP) {
		/* Update Variable */
		local_var = find_variable(buf) + 1;
		update_variable(buf, local_var);
	
		/* Change Program Flow */
		pcounter = loop_status - 1;
	} else {
		pcounter = program_counter + 1;
	}
	
	return pcounter;	
}
示例#3
0
GList *
cockpit_template_expand (GBytes *input,
                         CockpitTemplateFunc func,
                         gpointer user_data)
{
  GList *output = NULL;
  const gchar *data;
  const gchar *end;
  const gchar *before;
  const gchar *after;
  GBytes *bytes;
  gchar *name;

  g_return_val_if_fail (func != NULL, NULL);

  data = g_bytes_get_data (input, NULL);
  end = data + g_bytes_get_size (input);

  for (;;)
    {
      name = find_variable (data, end, &before, &after);
      if (name == NULL)
        break;

      if (before != data)
        {
          g_assert (before > data);
          bytes = g_bytes_new_with_free_func (data, before - data,
                                              (GDestroyNotify)g_bytes_unref,
                                              g_bytes_ref (input));
          output = g_list_prepend (output, bytes);
        }

      bytes = (func) (name, user_data);
      g_free (name);

      if (!bytes)
        {
          g_assert (after > before);
          bytes = g_bytes_new_with_free_func (before, after - before,
                                              (GDestroyNotify)g_bytes_unref,
                                              g_bytes_ref (input));
        }
      output = g_list_prepend (output, bytes);

      g_assert (after <= end);
      data = after;
    }

  if (data != end)
    {
      g_assert (end > data);
      bytes = g_bytes_new_with_free_func (data, end - data,
                                          (GDestroyNotify)g_bytes_unref,
                                          g_bytes_ref (input));
      output = g_list_prepend (output, bytes);
    }

  return g_list_reverse (output);
}
示例#4
0
variable_t* find_variable_safe(state_t*s, char*name)
{
    variable_t* v = find_variable(s, name);
    if(!v)
        syntaxerror("undefined variable: %s", name);
    return v;
}
示例#5
0
// help get a list of positions from variable
int get_pos_from_var(list_t *vars, char *var_name, int **pos)
{
  variable_t *pos_var = find_variable(vars, var_name);
  int num_pos = 0;
  if (pos_var->is_id) {
    // dealing with row id, assign directly
    num_pos = get_list_size(pos_var->ids);
    *pos = calloc(num_pos, sizeof(int));
    memcpy(*pos, pos_var->ids->data, sizeof(int) * num_pos);
  } else {
    // now we need to convert from bit vector
    num_pos = get_bv_count(pos_var->bv);
    *pos = calloc(num_pos, sizeof(int));
    // go through the whole bit vector to get the values
    // TODO: should be a better strategy than this!
    uint32_t size = get_bv_size(pos_var->bv);
    uint32_t itr = 0;
    for (uint32_t u=0; u < size; u++) {
      if (is_marked(pos_var->bv, u)) {
        (*pos)[itr] = u;
        itr ++;
      }
    }
    debug("Itr ended at %d\n", itr);
    dbg_assert(itr == num_pos);
  }

  return num_pos;
}
/**
 * Parse the string expression 's' (that contains only string values) and return its
 * resulting value in 'value'.
 * Return a pointer behind the last character of the expression.
 * Return NULL if a syntax error occurred.
 */
char *parse_string_expression(char *s, char **value) {
  unsigned int var_name;
  variable *var;
  unsigned char var_type;
  unsigned char token;

  s = skip_whitespace(s);
  token = next_token(s);

  if (token == TOKEN_STRING) {
    if (s = parse_string(s, parsebuf)) {
      *value = parsebuf;
      return s;
    } else {
      syntax_error_invalid_string();
    }
  } else if (token == TOKEN_VAR_STRING) {
    s = parse_variable(s, &var_name, &var_type);
    var = find_variable(var_name, VAR_TYPE_STRING, NULL);
    if (var) {
      *value = get_string_variable_value(var);
      return s;
    } else {
      syntax_error_msg("Variable not found");
    }
  } else {
    syntax_error();
  }

  return NULL;
}
示例#7
0
文件: env.cpp 项目: mariuz/haiku
int
unsetenv(const char *name)
{
	int32 index, length;
	char *env;

	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL) {
		errno = B_BAD_VALUE;
		return -1;
	}

	length = strlen(name);

	lock_variables();

	copy_environ_to_heap_if_needed();

	env = find_variable(name, length, &index);
	if (env != NULL) {
		// we don't free the memory for the slot, we just move the array
		// contents
		free(env);
		memmove(environ + index, environ + index + 1,
			sizeof(char *) * (count_variables() - index));
	}

	unlock_variables();
	return 0;
}
/**
 * Parse the number term 's' and return its resulting value in 'value'.
 * Return a pointer behind the last character of the expression.
 * Return NULL if a syntax error occurred.
 */
char *parse_number_term(char *s, int *value) {
  unsigned char token;
  s = skip_whitespace(s);
  token = next_token(s);
  if (token == TOKEN_DIGITS || token == TOKEN_PLUS || token == TOKEN_MINUS) {
    if (s = parse_integer(s, value)) {
      return s;
    } else {
      syntax_error_invalid_number();
    }
  } else if (token == TOKEN_VAR_NUMBER) {
    unsigned int var_name;
    unsigned char var_type;
    variable *var;
    s = parse_variable(s, &var_name, &var_type);
    var = find_variable(var_name, VAR_TYPE_INTEGER, NULL);
    if (var) {
      *value = get_integer_variable_value(var);
      return s;
    } else {
      syntax_error_msg("Variable not found");
    }
  } else {
    syntax_error();
  }

  return NULL;
}
示例#9
0
int opcode_printh(char *buf)
{
	int status = 0;

	printf("0x%x\n", find_variable(buf));

	return status;
}
示例#10
0
int gettempvar()
{
    variable_t*v = find_variable(state, TEMPVARNAME);
    int i;
    if(v) 
        i = v->index;
    else
        i = new_variable(state->method, TEMPVARNAME, 0, 0, 0);
    as3_assert(i);
    return i;
}
示例#11
0
/*
 * To parse more complex expressions, we really need to know what the
 * save state is.  So we, unfortunately, have to create our own
 * version of strtok so we know what it is.
 */
const char *
mystrtok(char *str, const char *delim, char **next)
{
    char *pos;
    char *curr;

    if (str)
	curr = str;
    else
	curr = *next;

    /* Skip initial delimiters. */
    for (;;) {
	const char *c = delim;
	if (*curr == '\0') {
	    *next = curr;
	    return NULL;
	}

	while (*c != '\0') {
	    if (*c == *curr)
		break;
	    c++;
	}
	if (*c == '\0')
	    break;
	curr++;
    }

    pos = curr;
    /* Now collect until there is a delimiter. */
    for (;;) {
	const char *c = delim;
	if (*curr == '\0') {
	    *next = curr;
	    goto out;
	}
	while (*c != '\0') {
	    if (*c == *curr) {
		*curr = '\0';
		*next = curr + 1;
		goto out;
	    }
	    c++;
	}
	curr++;
    }
 out:
    if (*pos == '$')
	return find_variable(pos + 1);
    else
	return pos;
}
示例#12
0
/* Print Screen Functions */
int opcode_print(char *buf)
{
	int status = 0;
	char *pch;

	if(strstr(buf, "\"") != NULL) {
		pch = strtok (buf, "\"");
		printf("%s", pch);
	} else
		printf("%d", find_variable(buf));

	return status;
}
示例#13
0
void init_interpreter(void)
{
    plus_var = find_variable(module_BuiltinStuff, symbol("+"), false, true);
    minus_var = find_variable(module_BuiltinStuff, symbol("-"), false, true);
    lt_var = find_variable(module_BuiltinStuff, symbol("<"), false, true);
    le_var = find_variable(module_BuiltinStuff, symbol("<="), false, true);
    eq_var = find_variable(module_BuiltinStuff, symbol("="), false, true);
    ne_var = find_variable(module_BuiltinStuff, symbol("~="), false, true);
}
示例#14
0
static const char *parse_symbol(opstack ** stack, const char *in,
    const void *userdata)
    /* in is the symbol name and following text, starting after the $
     * result goes on the stack
     */
{
    bool braces = false;
    char symbol[32];
    char *cp = symbol;            /* current position */

    if (*in == '{') {
        braces = true;
        ++in;
    }
    while (isalnum(*in) || *in == '.')
        *cp++ = *in++;
    *cp = '\0';
    /* symbol will now contain the symbol name */
    if (*in == '(') {
        /* it's a function we need to parse, start by reading the parameters */
        evalfun foo;

        while (*in != ')') {
            in = parse(stack, ++in, userdata);        /* will push the result on the stack */
            if (in == NULL)
                return NULL;
        }
        ++in;
        foo = find_function(symbol);
        if (foo == NULL) {
            log_error("parser does not know about \"%s\" function.\n", symbol);
            return NULL;
        }
        foo(stack, userdata);        /* will pop parameters from stack (reverse order!) and push the result */
    }
    else {
        variable *var = find_variable(symbol);
        if (braces && *in == '}') {
            ++in;
        }
        /* it's a constant (variable is a misnomer, but heck, const was taken;)) */
        if (var == NULL) {
            log_error("parser does not know about \"%s\" variable.\n", symbol);
            return NULL;
        }
        opush(stack, var->value);
    }
    return in;
}
示例#15
0
文件: mindy.c 项目: sparkhom/mindy
static void invoke_main(struct thread *thread, obj_t *vals)
{
    obj_t *fp = thread->fp;
    obj_t *args_end = fp - 5;
    obj_t *old_sp = pop_linkage(thread);
    struct variable *var = find_variable(module_BuiltinStuff, symbol("main"),
                                         false, false);

    if (var == NULL)
        lose("main undefined?");

    thread->sp = args_end;
    old_sp[0] = var->value;
    invoke(thread, args_end - old_sp - 1);
}
示例#16
0
文件: env.cpp 项目: mariuz/haiku
char *
getenv(const char *name)
{
	int32 length = strlen(name);
	char *value;

	lock_variables();

	value = find_variable(name, length, NULL);
	unlock_variables();

	if (value == NULL)
		return NULL;

	return value + length + 1;
}
示例#17
0
void
set_command_completion_selector(DCCompletionInfo *ci)
{
    char *name;
    DCVariable *var;

    /* ci->word_index > 0 is assured by get_completor. */
    if (ci->word_index <= 1) {
	variable_completion_generator(ci);
    } else {
	name = get_word_dequoted(ci->line, 1);
	var = find_variable(name);
	if (var != NULL && var->completor != NULL)
	    var->completor(ci);
	free(name);
    }
}
示例#18
0
void
cmd_set(int argc, char **argv)
{
    uint32_t c;
    DCVariable *var;

    if (argc == 1) {
	int max_len = 0;
	int cols;
	char *fmt;
	
	for (c = 0; c < variables_count; c++)
	    max_len = MAX(max_len, strlen(variables[c].name));
	fmt = xasprintf("%%-%ds  %%s\n", max_len);
	screen_get_size(NULL, &cols);
	for (c = 0; c < variables_count; c++) {
	    DCVariable *var = &variables[c];
	    char *value = var->getter(var);

	    screen_putf(fmt, var->name, value == NULL ? "(unset)" : quotearg(value));
	    free(value);
	}
	free(fmt);
	return;
    }

    var = find_variable(argv[1]);
    if (var == NULL) {
	warn("No variable by the name `%s'.\n", quotearg(argv[1]));
	return;
    }

    if (argc <= 2) {
	char *value;
	value = var->getter(var);
	if (value == NULL) {
	    screen_putf(_("No value is set for `%s'.\n"), var->name);
	} else {
	    screen_putf(_("Current value for `%s':\n%s\n"), var->name, quotearg(value));
	}
	return;
    }

    var->setter(var, argc-1, argv+1);
}
示例#19
0
tVar find_variable(string name, tThread * thread)
{
    int i;
    for (i = 0; i < thread->vcount; i++)
    {
        debugf("[find_variable]:comparing %s with %s\n", name, thread->vars[i].name);
        if (strcmp(name, thread->vars[i].name) == 0)
            return thread->vars[i];
    }
    for (i = 0; i < thread->pcount; i++)
    {
        debugf("[find_variable]:comparing %s with %s\n", name, thread->params[i].name);
        if (strcmp(name, thread->params[i].name) == 0)
            return thread->params[i];
    }
    if(thread->parent !=NULL)
        return find_variable(name, thread->parent);
}
示例#20
0
static svalue_t simple_evaluate(int n)
{
	svalue_t returnvar;
	svariable_t *var;
	
	switch(tokentype[n])
    {
    case string_: returnvar.type = svt_string;
		returnvar.value.s = tokens[n];
		return returnvar;
		
		// haleyjd: 8-17
    case number:
		if(strchr(tokens[n], '.'))
		{
			returnvar.type = svt_fixed;
			returnvar.value.f = (fixed_t)(atof(tokens[n]) * FRACUNIT);
		}
		else
		{
			returnvar.type = svt_int;
			returnvar.value.i = atoi(tokens[n]);
		}
		return returnvar;
		
    case name_:   var = find_variable(tokens[n]);
		if(!var)
		{
			script_error("unknown variable '%s'\n", tokens[n]);
			return nullvar;
		}
		else
			return getvariablevalue(var);
		
    default: return nullvar;
    }
}
示例#21
0
文件: env.cpp 项目: mariuz/haiku
static status_t
update_variable(const char *name, int32 length, const char *value,
	bool overwrite)
{
	bool update = false;
	int32 index;
	char *env;

	copy_environ_to_heap_if_needed();

	env = find_variable(name, length, &index);
	if (env != NULL && overwrite) {
		// change variable
		free(environ[index]);
		update = true;
	} else if (env == NULL) {
		// add variable
		index = add_variable();
		if (index < 0)
			return B_NO_MEMORY;

		update = true;
	}

	if (update) {
		environ[index] = (char*)malloc(length + 2 + strlen(value));
		if (environ[index] == NULL)
			return B_NO_MEMORY;

		memcpy(environ[index], name, length);
		environ[index][length] = '=';
		strcpy(environ[index] + length + 1, value);
	}

	return B_OK;
}
示例#22
0
static int find_probe_point_by_func(struct probe_finder *pf)
{
	struct dwarf_callback_param _param = {.data = (void *)pf,
					      .retval = 0};
	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
	return _param.retval;
}

struct pubname_callback_param {
	char *function;
	char *file;
	Dwarf_Die *cu_die;
	Dwarf_Die *sp_die;
	int found;
};

static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
{
	struct pubname_callback_param *param = data;

	if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
			return DWARF_CB_OK;

		if (die_compare_name(param->sp_die, param->function)) {
			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
				return DWARF_CB_OK;

			if (param->file &&
			    strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
				return DWARF_CB_OK;

			param->found = 1;
			return DWARF_CB_ABORT;
		}
	}

	return DWARF_CB_OK;
}

/* Find probe points from debuginfo */
static int debuginfo__find_probes(struct debuginfo *dbg,
				  struct probe_finder *pf)
{
	struct perf_probe_point *pp = &pf->pev->point;
	Dwarf_Off off, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	int ret = 0;

#if _ELFUTILS_PREREQ(0, 142)
	Elf *elf;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;

	/* Get the call frame information from this dwarf */
	elf = dwarf_getelf(dbg->dbg);
	if (elf == NULL)
		return -EINVAL;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		return -EINVAL;

	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
	    shdr.sh_type == SHT_PROGBITS) {
		pf->cfi = dwarf_getcfi_elf(elf);
	} else {
		pf->cfi = dwarf_getcfi(dbg->dbg);
	}
#endif

	off = 0;
	pf->lcache = intlist__new(NULL);
	if (!pf->lcache)
		return -ENOMEM;

	/* Fastpath: lookup by function name from .debug_pubnames section */
	if (pp->function) {
		struct pubname_callback_param pubname_param = {
			.function = pp->function,
			.file	  = pp->file,
			.cu_die	  = &pf->cu_die,
			.sp_die	  = &pf->sp_die,
			.found	  = 0,
		};
		struct dwarf_callback_param probe_param = {
			.data = pf,
		};

		dwarf_getpubnames(dbg->dbg, pubname_search_cb,
				  &pubname_param, 0);
		if (pubname_param.found) {
			ret = probe_point_search_cb(&pf->sp_die, &probe_param);
			if (ret)
				goto found;
		}
	}

	/* Loop on CUs (Compilation Unit) */
	while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
		/* Get the DIE(Debugging Information Entry) of this CU */
		diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
		if (!diep)
			continue;

		/* Check if target file is included. */
		if (pp->file)
			pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
		else
			pf->fname = NULL;

		if (!pp->file || pf->fname) {
			if (pp->function)
				ret = find_probe_point_by_func(pf);
			else if (pp->lazy_line)
				ret = find_probe_point_lazy(&pf->cu_die, pf);
			else {
				pf->lno = pp->line;
				ret = find_probe_point_by_line(pf);
			}
			if (ret < 0)
				break;
		}
		off = noff;
	}

found:
	intlist__delete(pf->lcache);
	pf->lcache = NULL;

	return ret;
}

struct local_vars_finder {
	struct probe_finder *pf;
	struct perf_probe_arg *args;
	int max_args;
	int nargs;
	int ret;
};

/* Collect available variables in this scope */
static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
{
	struct local_vars_finder *vf = data;
	struct probe_finder *pf = vf->pf;
	int tag;

	tag = dwarf_tag(die_mem);
	if (tag == DW_TAG_formal_parameter ||
	    tag == DW_TAG_variable) {
		if (convert_variable_location(die_mem, vf->pf->addr,
					      vf->pf->fb_ops, &pf->sp_die,
					      NULL) == 0) {
			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
			if (vf->args[vf->nargs].var == NULL) {
				vf->ret = -ENOMEM;
				return DIE_FIND_CB_END;
			}
			pr_debug(" %s", vf->args[vf->nargs].var);
			vf->nargs++;
		}
	}

	if (dwarf_haspc(die_mem, vf->pf->addr))
		return DIE_FIND_CB_CONTINUE;
	else
		return DIE_FIND_CB_SIBLING;
}

static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
			     struct perf_probe_arg *args)
{
	Dwarf_Die die_mem;
	int i;
	int n = 0;
	struct local_vars_finder vf = {.pf = pf, .args = args,
				.max_args = MAX_PROBE_ARGS, .ret = 0};

	for (i = 0; i < pf->pev->nargs; i++) {
		/* var never be NULL */
		if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
			pr_debug("Expanding $vars into:");
			vf.nargs = n;
			/* Special local variables */
			die_find_child(sc_die, copy_variables_cb, (void *)&vf,
				       &die_mem);
			pr_debug(" (%d)\n", vf.nargs - n);
			if (vf.ret < 0)
				return vf.ret;
			n = vf.nargs;
		} else {
			/* Copy normal argument */
			args[n] = pf->pev->args[i];
			n++;
		}
	}
	return n;
}

/* Add a found probe point into trace event list */
static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct trace_event_finder *tf =
			container_of(pf, struct trace_event_finder, pf);
	struct probe_trace_event *tev;
	struct perf_probe_arg *args;
	int ret, i;

	/* Check number of tevs */
	if (tf->ntevs == tf->max_tevs) {
		pr_warning("Too many( > %d) probe point found.\n",
			   tf->max_tevs);
		return -ERANGE;
	}
	tev = &tf->tevs[tf->ntevs++];

	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
				     pf->pev->point.retprobe, &tev->point);
	if (ret < 0)
		return ret;

	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
		 tev->point.offset);

	/* Expand special probe argument if exist */
	args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
	if (args == NULL)
		return -ENOMEM;

	ret = expand_probe_args(sc_die, pf, args);
	if (ret < 0)
		goto end;

	tev->nargs = ret;
	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
	if (tev->args == NULL) {
		ret = -ENOMEM;
		goto end;
	}

	/* Find each argument */
	for (i = 0; i < tev->nargs; i++) {
		pf->pvar = &args[i];
		pf->tvar = &tev->args[i];
		/* Variable should be found from scope DIE */
		ret = find_variable(sc_die, pf);
		if (ret != 0)
			break;
	}

end:
	free(args);
	return ret;
}

/* Find probe_trace_events specified by perf_probe_event from debuginfo */
int debuginfo__find_trace_events(struct debuginfo *dbg,
				 struct perf_probe_event *pev,
				 struct probe_trace_event **tevs, int max_tevs)
{
	struct trace_event_finder tf = {
			.pf = {.pev = pev, .callback = add_probe_trace_event},
			.mod = dbg->mod, .max_tevs = max_tevs};
	int ret;

	/* Allocate result tevs array */
	*tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
	if (*tevs == NULL)
		return -ENOMEM;

	tf.tevs = *tevs;
	tf.ntevs = 0;

	ret = debuginfo__find_probes(dbg, &tf.pf);
	if (ret < 0) {
		zfree(tevs);
		return ret;
	}

	return (ret < 0) ? ret : tf.ntevs;
}

#define MAX_VAR_LEN 64

/* Collect available variables in this scope */
static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
{
	struct available_var_finder *af = data;
	struct variable_list *vl;
	char buf[MAX_VAR_LEN];
	int tag, ret;

	vl = &af->vls[af->nvls - 1];

	tag = dwarf_tag(die_mem);
	if (tag == DW_TAG_formal_parameter ||
	    tag == DW_TAG_variable) {
		ret = convert_variable_location(die_mem, af->pf.addr,
						af->pf.fb_ops, &af->pf.sp_die,
						NULL);
		if (ret == 0) {
			ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
			pr_debug2("Add new var: %s\n", buf);
			if (ret > 0)
				strlist__add(vl->vars, buf);
		}
	}

	if (af->child && dwarf_haspc(die_mem, af->pf.addr))
		return DIE_FIND_CB_CONTINUE;
	else
		return DIE_FIND_CB_SIBLING;
}

/* Add a found vars into available variables list */
static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct available_var_finder *af =
			container_of(pf, struct available_var_finder, pf);
	struct variable_list *vl;
	Dwarf_Die die_mem;
	int ret;

	/* Check number of tevs */
	if (af->nvls == af->max_vls) {
		pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
		return -ERANGE;
	}
	vl = &af->vls[af->nvls++];

	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
				     pf->pev->point.retprobe, &vl->point);
	if (ret < 0)
		return ret;

	pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
		 vl->point.offset);

	/* Find local variables */
	vl->vars = strlist__new(true, NULL);
	if (vl->vars == NULL)
		return -ENOMEM;
	af->child = true;
	die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);

	/* Find external variables */
	if (!af->externs)
		goto out;
	/* Don't need to search child DIE for externs. */
	af->child = false;
	die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);

out:
	if (strlist__empty(vl->vars)) {
		strlist__delete(vl->vars);
		vl->vars = NULL;
	}

	return ret;
}

/*
 * Find available variables at given probe point
 * Return the number of found probe points. Return 0 if there is no
 * matched probe point. Return <0 if an error occurs.
 */
int debuginfo__find_available_vars_at(struct debuginfo *dbg,
				      struct perf_probe_event *pev,
				      struct variable_list **vls,
				      int max_vls, bool externs)
{
	struct available_var_finder af = {
			.pf = {.pev = pev, .callback = add_available_vars},
			.mod = dbg->mod,
			.max_vls = max_vls, .externs = externs};
	int ret;

	/* Allocate result vls array */
	*vls = zalloc(sizeof(struct variable_list) * max_vls);
	if (*vls == NULL)
		return -ENOMEM;

	af.vls = *vls;
	af.nvls = 0;

	ret = debuginfo__find_probes(dbg, &af.pf);
	if (ret < 0) {
		/* Free vlist for error */
		while (af.nvls--) {
			zfree(&af.vls[af.nvls].point.symbol);
			strlist__delete(af.vls[af.nvls].vars);
		}
		zfree(vls);
		return ret;
	}

	return (ret < 0) ? ret : af.nvls;
}

/* Reverse search */
int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
				struct perf_probe_point *ppt)
{
	Dwarf_Die cudie, spdie, indie;
	Dwarf_Addr _addr = 0, baseaddr = 0;
	const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
	int baseline = 0, lineno = 0, ret = 0;

	/* Find cu die */
	if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
		pr_warning("Failed to find debug information for address %lx\n",
			   addr);
		ret = -EINVAL;
		goto end;
	}

	/* Find a corresponding line (filename and lineno) */
	cu_find_lineinfo(&cudie, addr, &fname, &lineno);
	/* Don't care whether it failed or not */

	/* Find a corresponding function (name, baseline and baseaddr) */
	if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
		/* Get function entry information */
		func = basefunc = dwarf_diename(&spdie);
		if (!func ||
		    dwarf_entrypc(&spdie, &baseaddr) != 0 ||
		    dwarf_decl_line(&spdie, &baseline) != 0) {
			lineno = 0;
			goto post;
		}

		fname = dwarf_decl_file(&spdie);
		if (addr == (unsigned long)baseaddr) {
			/* Function entry - Relative line number is 0 */
			lineno = baseline;
			goto post;
		}

		/* Track down the inline functions step by step */
		while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
						&indie)) {
			/* There is an inline function */
			if (dwarf_entrypc(&indie, &_addr) == 0 &&
			    _addr == addr) {
				/*
				 * addr is at an inline function entry.
				 * In this case, lineno should be the call-site
				 * line number. (overwrite lineinfo)
				 */
				lineno = die_get_call_lineno(&indie);
				fname = die_get_call_file(&indie);
				break;
			} else {
				/*
				 * addr is in an inline function body.
				 * Since lineno points one of the lines
				 * of the inline function, baseline should
				 * be the entry line of the inline function.
				 */
				tmp = dwarf_diename(&indie);
				if (!tmp ||
				    dwarf_decl_line(&indie, &baseline) != 0)
					break;
				func = tmp;
				spdie = indie;
			}
		}
		/* Verify the lineno and baseline are in a same file */
		tmp = dwarf_decl_file(&spdie);
		if (!tmp || strcmp(tmp, fname) != 0)
			lineno = 0;
	}

post:
	/* Make a relative line number or an offset */
	if (lineno)
		ppt->line = lineno - baseline;
	else if (basefunc) {
		ppt->offset = addr - (unsigned long)baseaddr;
		func = basefunc;
	}

	/* Duplicate strings */
	if (func) {
		ppt->function = strdup(func);
		if (ppt->function == NULL) {
			ret = -ENOMEM;
			goto end;
		}
	}
	if (fname) {
		ppt->file = strdup(fname);
		if (ppt->file == NULL) {
			zfree(&ppt->function);
			ret = -ENOMEM;
			goto end;
		}
	}
end:
	if (ret == 0 && (fname || func))
		ret = 1;	/* Found a point */
	return ret;
}

/* Add a line and store the src path */
static int line_range_add_line(const char *src, unsigned int lineno,
			       struct line_range *lr)
{
	/* Copy source path */
	if (!lr->path) {
		lr->path = strdup(src);
		if (lr->path == NULL)
			return -ENOMEM;
	}
	return intlist__add(lr->line_list, lineno);
}

static int line_range_walk_cb(const char *fname, int lineno,
			      Dwarf_Addr addr __maybe_unused,
			      void *data)
{
	struct line_finder *lf = data;
	int err;

	if ((strtailcmp(fname, lf->fname) != 0) ||
	    (lf->lno_s > lineno || lf->lno_e < lineno))
		return 0;

	err = line_range_add_line(fname, lineno, lf->lr);
	if (err < 0 && err != -EEXIST)
		return err;

	return 0;
}

/* Find line range from its line number */
static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
{
	int ret;

	ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);

	/* Update status */
	if (ret >= 0)
		if (!intlist__empty(lf->lr->line_list))
			ret = lf->found = 1;
		else
			ret = 0;	/* Lines are not found */
	else {
		zfree(&lf->lr->path);
	}
	return ret;
}
static int find_probe_point_by_func(struct probe_finder *pf)
{
	struct dwarf_callback_param _param = {.data = (void *)pf,
					      .retval = 0};
	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
	return _param.retval;
}

struct pubname_callback_param {
	char *function;
	char *file;
	Dwarf_Die *cu_die;
	Dwarf_Die *sp_die;
	int found;
};

static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
{
	struct pubname_callback_param *param = data;

	if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
			return DWARF_CB_OK;

		if (die_compare_name(param->sp_die, param->function)) {
			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
				return DWARF_CB_OK;

			if (param->file &&
			    strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
				return DWARF_CB_OK;

			param->found = 1;
			return DWARF_CB_ABORT;
		}
	}

	return DWARF_CB_OK;
}

static int debuginfo__find_probes(struct debuginfo *self,
				  struct probe_finder *pf)
{
	struct perf_probe_point *pp = &pf->pev->point;
	Dwarf_Off off, noff;
	size_t cuhl;
	Dwarf_Die *diep;
	int ret = 0;

#if _ELFUTILS_PREREQ(0, 142)
	
	pf->cfi = dwarf_getcfi(self->dbg);
#endif

	off = 0;
	line_list__init(&pf->lcache);

	
	if (pp->function) {
		struct pubname_callback_param pubname_param = {
			.function = pp->function,
			.file	  = pp->file,
			.cu_die	  = &pf->cu_die,
			.sp_die	  = &pf->sp_die,
			.found	  = 0,
		};
		struct dwarf_callback_param probe_param = {
			.data = pf,
		};

		dwarf_getpubnames(self->dbg, pubname_search_cb,
				  &pubname_param, 0);
		if (pubname_param.found) {
			ret = probe_point_search_cb(&pf->sp_die, &probe_param);
			if (ret)
				goto found;
		}
	}

	
	while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
		
		diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die);
		if (!diep)
			continue;

		
		if (pp->file)
			pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
		else
			pf->fname = NULL;

		if (!pp->file || pf->fname) {
			if (pp->function)
				ret = find_probe_point_by_func(pf);
			else if (pp->lazy_line)
				ret = find_probe_point_lazy(NULL, pf);
			else {
				pf->lno = pp->line;
				ret = find_probe_point_by_line(pf);
			}
			if (ret < 0)
				break;
		}
		off = noff;
	}

found:
	line_list__free(&pf->lcache);

	return ret;
}

static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct trace_event_finder *tf =
			container_of(pf, struct trace_event_finder, pf);
	struct probe_trace_event *tev;
	int ret, i;

	
	if (tf->ntevs == tf->max_tevs) {
		pr_warning("Too many( > %d) probe point found.\n",
			   tf->max_tevs);
		return -ERANGE;
	}
	tev = &tf->tevs[tf->ntevs++];

	
	ret = convert_to_trace_point(&pf->sp_die, pf->addr,
				     pf->pev->point.retprobe, &tev->point);
	if (ret < 0)
		return ret;

	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
		 tev->point.offset);

	
	tev->nargs = pf->pev->nargs;
	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
	if (tev->args == NULL)
		return -ENOMEM;
	for (i = 0; i < pf->pev->nargs; i++) {
		pf->pvar = &pf->pev->args[i];
		pf->tvar = &tev->args[i];
		
		ret = find_variable(sc_die, pf);
		if (ret != 0)
			return ret;
	}

	return 0;
}

int debuginfo__find_trace_events(struct debuginfo *self,
				 struct perf_probe_event *pev,
				 struct probe_trace_event **tevs, int max_tevs)
{
	struct trace_event_finder tf = {
			.pf = {.pev = pev, .callback = add_probe_trace_event},
			.max_tevs = max_tevs};
	int ret;

	
	*tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
	if (*tevs == NULL)
		return -ENOMEM;

	tf.tevs = *tevs;
	tf.ntevs = 0;

	ret = debuginfo__find_probes(self, &tf.pf);
	if (ret < 0) {
		free(*tevs);
		*tevs = NULL;
		return ret;
	}

	return (ret < 0) ? ret : tf.ntevs;
}

#define MAX_VAR_LEN 64

static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
{
	struct available_var_finder *af = data;
	struct variable_list *vl;
	char buf[MAX_VAR_LEN];
	int tag, ret;

	vl = &af->vls[af->nvls - 1];

	tag = dwarf_tag(die_mem);
	if (tag == DW_TAG_formal_parameter ||
	    tag == DW_TAG_variable) {
		ret = convert_variable_location(die_mem, af->pf.addr,
						af->pf.fb_ops, NULL);
		if (ret == 0) {
			ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
			pr_debug2("Add new var: %s\n", buf);
			if (ret > 0)
				strlist__add(vl->vars, buf);
		}
	}

	if (af->child && dwarf_haspc(die_mem, af->pf.addr))
		return DIE_FIND_CB_CONTINUE;
	else
		return DIE_FIND_CB_SIBLING;
}

static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
{
	struct available_var_finder *af =
			container_of(pf, struct available_var_finder, pf);
	struct variable_list *vl;
	Dwarf_Die die_mem;
	int ret;

	
	if (af->nvls == af->max_vls) {
		pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
		return -ERANGE;
	}
	vl = &af->vls[af->nvls++];

	
	ret = convert_to_trace_point(&pf->sp_die, pf->addr,
				     pf->pev->point.retprobe, &vl->point);
	if (ret < 0)
		return ret;

	pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
		 vl->point.offset);

	
	vl->vars = strlist__new(true, NULL);
	if (vl->vars == NULL)
		return -ENOMEM;
	af->child = true;
	die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);

	
	if (!af->externs)
		goto out;
	
	af->child = false;
	die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);

out:
	if (strlist__empty(vl->vars)) {
		strlist__delete(vl->vars);
		vl->vars = NULL;
	}

	return ret;
}

int debuginfo__find_available_vars_at(struct debuginfo *self,
				      struct perf_probe_event *pev,
				      struct variable_list **vls,
				      int max_vls, bool externs)
{
	struct available_var_finder af = {
			.pf = {.pev = pev, .callback = add_available_vars},
			.max_vls = max_vls, .externs = externs};
	int ret;

	
	*vls = zalloc(sizeof(struct variable_list) * max_vls);
	if (*vls == NULL)
		return -ENOMEM;

	af.vls = *vls;
	af.nvls = 0;

	ret = debuginfo__find_probes(self, &af.pf);
	if (ret < 0) {
		
		while (af.nvls--) {
			if (af.vls[af.nvls].point.symbol)
				free(af.vls[af.nvls].point.symbol);
			if (af.vls[af.nvls].vars)
				strlist__delete(af.vls[af.nvls].vars);
		}
		free(af.vls);
		*vls = NULL;
		return ret;
	}

	return (ret < 0) ? ret : af.nvls;
}
示例#24
0
文件: compute.c 项目: drafnel/Vis5d
/*
 * Parse expression of form "name = ... " and return index
 * of new variable and "program" for computing it in the globals
 * ops, args and curop.
 * Input:  expression - the character string expression as type in by
 *                      the user.   Ex: "SPD = SQRT( U*U + V*V + W*W )"
 * Output: var - index for new variable
 *         recompute - flag indicating that variable is being recomputed
 * Return:  0 if OK or -1 if error
 */
static int parse( Display_Context dtx, struct compute_state *state,
                  const char *expression, char *namevar,
                  int *varowner, int *var, int *recompute,
                  char mess[100] )
{
  const char *string;
  int type;
  int index;
  float fval;
  char name[100];
  Context ctx;

  string = expression;

  type = get_token(&string, &index, &fval, namevar);
  if (type != NAME_TOKEN) {
    strcpy(mess, "Error:  must start with name of new variable");
    return -1;
  }

  /* Determine if the LHS of the expression names an existing variable */
  /* or a new one. */
  *varowner = find_variable_owner( dtx, namevar );

  if (*varowner == -1){
      sprintf(mess, "Error:  Bad destination variable ");
      return -1;
  }
  else{
     int ahh;
     for (ahh=0; ahh< dtx->numofctxs; ahh++){
        if (*varowner == dtx->ctxpointerarray[ahh]->context_index){
           ctx = dtx->ctxpointerarray[ahh];
           ahh = dtx->numofctxs;
        }
     }
  }
  *var = find_variable(ctx, namevar);

  if (*var >= 0) {
    if (ctx->Variable[*var]->VarType != VIS5D_EXPRESSION) {
      sprintf(mess, "Error:  destination variable name  %s  already used",
              namevar);
      return -1;
    }
    else {
      *recompute = 1;
    }
  }
  else {
    *recompute = 0;
  }

  type = get_token(&string, &index, &fval, name);
  if (type != OP_TOKEN || index != EQUALS_OP) {
    strcpy(mess, "Error:  missing equals sign");
    return -1;
  }

  /* initialize pointer to start of "program" */
  state->curop = 0;
  state->numvars = 0;

  /* parse expression for computing new variable */
  if (get_exp3(ctx, state, &string, mess) < 0) return -1;

  type = get_token(&string, &index, &fval, name);
  if (type != END_TOKEN) {
    strcpy(mess, "Error:  syntax");
    return -1;
  }

  if (*recompute == 0) {
    /* Allocate the new variable */
    *var = allocate_computed_variable(ctx, namevar);
    if (*var < 0) {
      strcpy(mess, "Error:  Max number of variables reached");
      return -1;
    }
  }
  else {
    min_max_init(ctx, *var);
  }
  return 0;
}
示例#25
0
EIF_BOOLEAN basic_exec_posix_execute(se_exec_data_t*data, char*prog, char**args, EIF_BOOLEAN keep_env, char**add_env, int* in_fd, int* out_fd, int* err_fd) {
  int id = fork();
  if (id == 0) {
    /* child */

    if(in_fd) {
      dup2(in_fd[0], 0);
      close(in_fd[1]);
    }

    if(out_fd) {
      dup2(out_fd[1], 1);
      close(out_fd[0]);
    }

    if(err_fd) {
      dup2(err_fd[1], 2);
      close(err_fd[0]);
    }

    if (prog == NULL && args == NULL) {
      data->running = 1;
      data->child = 1;
#ifdef SE_SEDB
      sedb_duplicate();
#endif
      return 1;
    } else {
      if (add_env == NULL && keep_env) {
        execvp(prog, args); /* NO RETURN in child */
        se_print_run_time_stack();
        exit(1);
      }else{
        char** new_env;
        char** old_env;
        int old_size, add_size;
        int src, dest = 0;
        if(keep_env){
          old_env = environ;
        }else{
          old_env = envp();
        }
        old_size = arr_size(old_env);
        add_size = arr_size(add_env);
        new_env = malloc(sizeof(void*) * (old_size + add_size));

        /* we first copy the pointers from the old env */
        for(src = 0; src < old_size; src++){
          new_env[dest++] = old_env[src];
        }

        /* now the ones from add_env */
        for(src = 0; src < add_size; src++){
          int override = find_variable(old_env, add_env[src]);
          if (override >= 0){
            new_env[override] = add_env[src];
          }else{
            new_env[dest++] = add_env[src];
          }
        }

        execve(prog, args, new_env); /* NO RETURN in child */
        se_print_run_time_stack();
        exit(1);
      }
    }
  }
示例#26
0
/* Show a probe point to output buffer */
static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
{
	struct kprobe_trace_event *tev;
	Dwarf_Addr eaddr;
	Dwarf_Die die_mem;
	const char *name;
	int ret, i;
	Dwarf_Attribute fb_attr;
	size_t nops;

	if (pf->ntevs == pf->max_tevs) {
		pr_warning("Too many( > %d) probe point found.\n",
			   pf->max_tevs);
		return -ERANGE;
	}
	tev = &pf->tevs[pf->ntevs++];

	/* If no real subprogram, find a real one */
	if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
		sp_die = die_find_real_subprogram(&pf->cu_die,
						 pf->addr, &die_mem);
		if (!sp_die) {
			pr_warning("Failed to find probe point in any "
				   "functions.\n");
			return -ENOENT;
		}
	}

	/* Copy the name of probe point */
	name = dwarf_diename(sp_die);
	if (name) {
		if (dwarf_entrypc(sp_die, &eaddr) != 0) {
			pr_warning("Failed to get entry pc of %s\n",
				   dwarf_diename(sp_die));
			return -ENOENT;
		}
		tev->point.symbol = strdup(name);
		if (tev->point.symbol == NULL)
			return -ENOMEM;
		tev->point.offset = (unsigned long)(pf->addr - eaddr);
	} else
		/* This function has no name. */
		tev->point.offset = (unsigned long)pf->addr;

	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
		 tev->point.offset);

	/* Get the frame base attribute/ops */
	dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
	if (ret <= 0 || nops == 0) {
		pf->fb_ops = NULL;
#if _ELFUTILS_PREREQ(0, 142)
	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
		   pf->cfi != NULL) {
		Dwarf_Frame *frame;
		if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
			pr_warning("Failed to get CFA on 0x%jx\n",
				   (uintmax_t)pf->addr);
			return -ENOENT;
		}
#endif
	}

	/* Find each argument */
	tev->nargs = pf->pev->nargs;
	tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
	if (tev->args == NULL)
		return -ENOMEM;
	for (i = 0; i < pf->pev->nargs; i++) {
		pf->pvar = &pf->pev->args[i];
		pf->tvar = &tev->args[i];
		ret = find_variable(sp_die, pf);
		if (ret != 0)
			return ret;
	}

	/* *pf->fb_ops will be cached in libdw. Don't free it. */
	pf->fb_ops = NULL;
	return 0;
}
示例#27
0
void gen_expression(tree_t *t) {
  char *reg;

  // If the tree is actually a function, then take care of it here.
  if (t->type == FUNCTION) {
    // Push the arguments on the stack and call the function
    int num_args = gen_expression_list(t->right);
    fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);

    // Move the top of the stack back down below the arguments
    fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args);

    // Move the answer to the top of the register stack
    fprintf(yyout, "\tmovl\t%%eax, %s\n", stack_top(registers));
  }

  // Case 0:
  else if (t->right == NULL && t->left == NULL && t->label == 1) {
    if (t->type == ID ) {
	fprintf(yyout, "\tmovl\t%s, %s\n", find_variable(t), stack_top(registers));
    }
    else if (t->type == INUM) {
      fprintf(yyout, "\tmovl\t$%i, %s\n", t->attribute.ival, 
	      stack_top(registers));
    }
    else {
      yywarn("Type not supported");
    }
  }
  else {
    // Case 1:
    if (t->right->label == 0) {
      // Go to left
      gen_expression(t->left);

      if (t->right->type == ID) {
	  gen_op(t, find_variable(t->right), stack_top(registers));
      }
      else if (t->right->type == INUM) {
        sprintf(buff1, "$%i", t->right->attribute.ival);
	  gen_op(t, buff1, stack_top(registers));
      }
      else {
	  yywarn("Type not supported");
      }
    }
    // Case 2:
    else if (t->left->label >= 1 && t->right->label > t->left->label && t->left->label < NUM_REG) {
      stack_swap(registers);
      gen_expression(t->right);
      reg = pop(registers);
      gen_expression(t->left);
      
      gen_op(t, reg, stack_top(registers));

   	push(registers, reg);
	stack_swap(registers);
    }
    // Case 3:
    else if (t->right->label >= 1 && t->left->label >= t->right->label && t->right->label < NUM_REG) {
	gen_expression(t->left);
      reg = pop(registers);
      gen_expression(t->right);
      
      gen_op(t, stack_top(registers), reg);
      push(registers, reg);
    }
    // Case 4:
    else {
      yywarn("Temporaries not yet implemented");
    }
  }
}
示例#28
0
char *
find_text (catalog_t * catalog, CONST char *name)
{
  return (find_variable (catalog, name, NULL));
}
示例#29
0
catalog_t *
load_catalog (xio_file f, CONST char **error)
{
  int i;
  int line = 1;
  int size;
  int c;
  catalog_t *catalog = alloc_catalog ();
  static char errort[40];
  char name[1024];
  char value[1024];
  if (catalog == NULL)
    {
      *error = "Out of memory";
    }
  if (f == NULL)
    {
      *error = "File could not be opended";
      free_catalog (catalog);
      return NULL;
    }
  /* Just very simple parsing loop of format 
   * [blanks]name[blanks]"value"[blanks]
   * Blanks should be comments using # or space, newline, \r and tabulator
   * Value shoud contain and \ seqences where \\ means \ and
   * \[something] means something. Should be used for character "
   */
  while (!xio_feof (f))
    {

      do
	{
	  c = xio_getc (f);
	  if (c == '\n')
	    line++;
	  if (c == '#')
	    {
	      while ((c = xio_getc (f)) != '\n' && c != XIO_EOF);
	      line++;
	    }
	}
      while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
      /*Skip blanks */
      if (c == XIO_EOF)
	{
	  if (xio_feof (f))
	    break;
	  free_catalog (catalog);
	  seterror ("read error");
	  xio_close (f);
	  return NULL;
	}
      i = 0;

      /*read name */
      do
	{
	  name[i] = c;
	  i++;
	  c = xio_getc (f);
	  if (c == '\n')
	    line++;
	  if (i == 1024)
	    {
	      seterror ("Name is too long(1024 or more characters)");
	      free_catalog (catalog);
	      xio_close (f);
	      return NULL;
	    }
	}
      while (c != '\n' && c != ' ' && c != '\t' && c != XIO_EOF);

      /*Skip blanks */
      while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
	{
	  c = xio_getc (f);
	  if (c == '\n')
	    line++;
	  if (c == '#')
	    {
	      while ((c = xio_getc (f)) != '\n' && c != XIO_EOF);
	      line++;
	    }
	}

      /*Skip blanks */
      if (c == XIO_EOF)
	{
	  if (xio_feof (f))
	    seterror ("Inexpected end of file after name field");
	  else
	    seterror ("read error");
	  free_catalog (catalog);
	  xio_close (f);
	  return NULL;
	}
      name[i] = 0;
      if (c != '"')
	{
	  seterror ("Begin of value field expected (\")");
	  free_catalog (catalog);
	  xio_close (f);
	  return NULL;
	}
      c = xio_getc (f);
      if (c == '\n')
	line++;
      i = 0;

      size = 0;
      do
	{
	  if (c == '\\')
	    value[i] = xio_getc (f);
	  else
	    value[i] = c;
	  i++;
	  c = xio_getc (f);
	  if (c == '\n')
	    line++, size = 0;
	  if (size == 40 && c != '"')
	    {
	      fprintf (stderr, "Warning - too long text at line %i\n", line);
	    }
	  size++;
	  if (i == 1024)
	    {
	      seterror ("Value is too long(1024 or more characters)");
	      free_catalog (catalog);
	      xio_close (f);
	      return NULL;
	    }
	}
      while (c != '"' && c != XIO_EOF);

      if (c == XIO_EOF)
	{
	  seterror ("Inexpeced end of file in value filed");
	  free_catalog (catalog);
	  xio_close (f);
	  return NULL;
	}
      value[i] = 0;
      find_variable (catalog, name, value);
    }				/*while */
  xio_close (f);
  return (catalog);
}				/*load_catalog */
示例#30
0
void gen_assignment(tree_t *t) {
	fprintf(yyout, "\tmovl\t%%eax, %s\n", find_variable(t));
}