static struct arg_type_info *
parse_type(struct protolib *plib, struct locus *loc, char **str,
	   struct param **extra_param, size_t param_num,
	   int *ownp, int *forwardp)
{
	struct arg_type_info *info
		= parse_nonpointer_type(plib, loc, str, extra_param,
					param_num, ownp, forwardp);
	if (info == NULL)
		return NULL;

	while (1) {
		eat_spaces(str);
		if (**str == '*') {
			struct arg_type_info *outer = malloc(sizeof(*outer));
			if (outer == NULL) {
				if (*ownp) {
					type_destroy(info);
					free(info);
				}
				report_error(loc->filename, loc->line_no,
					     "malloc: %s", strerror(errno));
				return NULL;
			}
			type_init_pointer(outer, info, *ownp);
			*ownp = 1;
			(*str)++;
			info = outer;
		} else
			break;
	}
	return info;
}
Ejemplo n.º 2
0
static int
fetch_simple_param(enum tof type, struct process *proc,
                   struct fetch_context *context,
                   struct value_dict *arguments,
                   struct arg_type_info *info, int own,
                   struct value *valuep)
{
    /* Arrays decay into pointers per C standard.  We check for
     * this here, because here we also capture arrays that come
     * from parameter packs.  */
    if (info->type == ARGTYPE_ARRAY) {
        struct arg_type_info *tmp = malloc(sizeof(*tmp));
        if (tmp != NULL) {
            type_init_pointer(tmp, info, own);
            tmp->lens = info->lens;
            info = tmp;
            own = 1;
        }
    }

    struct value value;
    value_init(&value, proc, NULL, info, own);
    if (fetch_arg_next(context, type, proc, info, &value) < 0)
        return -1;

    if (val_dict_push_next(arguments, &value) < 0) {
        value_destroy(&value);
        return -1;
    }

    if (valuep != NULL)
        *valuep = value;

    return 0;
}
Ejemplo n.º 3
0
Archivo: value.c Proyecto: 5py/ltrace
int
value_pass_by_reference(struct value *value)
{
	assert(value != NULL);
	assert(value->type->type == ARGTYPE_STRUCT);

	struct arg_type_info *new_info = calloc(sizeof(*new_info), 1);
	if (new_info == NULL)
		return -1;

	int own;
	struct arg_type_info *orig;
	value_take_type(value, &orig, &own);
	type_init_pointer(new_info, orig, own);
	new_info->lens = orig->lens;
	value_set_type(value, new_info, 1);

	return 0;
}
static int
parse_string(struct protolib *plib, struct locus *loc,
	     char **str, struct arg_type_info **retp, int *ownp)
{
	struct arg_type_info *info = NULL;
	struct expr_node *length;
	int own_length;

	if (isdigit(CTYPE_CONV(**str))) {
		/* string0 is string[retval], length is zero(retval)
		 * stringN is string[argN], length is zero(argN) */
		long l;
		if (parse_int(loc, str, &l) < 0
		    || check_int(loc, l) < 0)
			return -1;

		struct expr_node *length_arg = malloc(sizeof(*length_arg));
		if (length_arg == NULL)
			return -1;

		if (l == 0)
			expr_init_named(length_arg, "retval", 0);
		else
			expr_init_argno(length_arg, l - 1);

		length = build_zero_w_arg(length_arg, 1);
		if (length == NULL) {
			expr_destroy(length_arg);
			free(length_arg);
			return -1;
		}
		own_length = 1;

	} else {
		eat_spaces(str);
		if (**str == '[') {
			(*str)++;
			eat_spaces(str);

			length = parse_argnum(loc, str, &own_length, 1);
			if (length == NULL)
				return -1;

			eat_spaces(str);
			parse_char(loc, str, ']');

		} else if (**str == '(') {
			/* Usage of "string" as lens.  */
			++*str;

			eat_spaces(str);
			info = parse_type(plib, loc, str, NULL, 0, ownp, NULL);
			if (info == NULL)
				return -1;

			length = NULL;
			own_length = 0;

			eat_spaces(str);
			parse_char(loc, str, ')');

		} else {
			/* It was just a simple string after all.  */
			length = expr_node_zero();
			own_length = 0;
		}
	}

	/* String is a pointer to array of chars.  */
	if (info == NULL) {
		struct arg_type_info *info1 = malloc(sizeof(*info1));
		struct arg_type_info *info2 = malloc(sizeof(*info2));
		if (info1 == NULL || info2 == NULL) {
			free(info1);
			free(info2);
		fail:
			if (own_length) {
				assert(length != NULL);
				expr_destroy(length);
				free(length);
			}
			return -1;
		}
		type_init_array(info2, type_get_simple(ARGTYPE_CHAR), 0,
				length, own_length);
		type_init_pointer(info1, info2, 1);

		info = info1;
		*ownp = 1;
	}

	/* We'll need to set the lens, so unshare.  */
	if (unshare_type_info(loc, &info, ownp) < 0)
		/* If unshare_type_info failed, it must have been as a
		 * result of cloning attempt because *OWNP was 0.
		 * Thus we don't need to destroy INFO.  */
		goto fail;

	info->lens = &string_lens;
	info->own_lens = 0;

	*retp = info;
	return 0;
}