static int cpp_demangle_data_init()

in contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c [121:322]


static int	cpp_demangle_data_init(struct cpp_demangle_data *,
		    const char *);
static int	cpp_demangle_get_subst(struct cpp_demangle_data *, size_t);
static int	cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t);
static int	cpp_demangle_push_fp(struct cpp_demangle_data *,
		    char *(*)(const char *, size_t));
static int	cpp_demangle_push_str(struct cpp_demangle_data *, const char *,
		    size_t);
static int	cpp_demangle_pop_str(struct cpp_demangle_data *);
static int	cpp_demangle_push_subst(struct cpp_demangle_data *,
		    const char *, size_t);
static int	cpp_demangle_push_subst_v(struct cpp_demangle_data *,
		    struct vector_str *);
static int	cpp_demangle_push_type_qualifier(struct cpp_demangle_data *,
		    struct vector_type_qualifier *, const char *);
static int	cpp_demangle_read_array(struct cpp_demangle_data *);
static int	cpp_demangle_read_encoding(struct cpp_demangle_data *);
static int	cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
static int	cpp_demangle_read_expression(struct cpp_demangle_data *);
static int	cpp_demangle_read_expression_flat(struct cpp_demangle_data *,
		    char **);
static int	cpp_demangle_read_expression_binary(struct cpp_demangle_data *,
		    const char *, size_t);
static int	cpp_demangle_read_expression_unary(struct cpp_demangle_data *,
		    const char *, size_t);
static int	cpp_demangle_read_expression_trinary(struct cpp_demangle_data *,
		    const char *, size_t, const char *, size_t);
static int	cpp_demangle_read_function(struct cpp_demangle_data *, int *,
		    struct vector_type_qualifier *);
static int	cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);
static int	cpp_demangle_read_local_name(struct cpp_demangle_data *);
static int	cpp_demangle_read_name(struct cpp_demangle_data *);
static int	cpp_demangle_read_name_flat(struct cpp_demangle_data *,
		    char**);
static int	cpp_demangle_read_nested_name(struct cpp_demangle_data *);
static int	cpp_demangle_read_number(struct cpp_demangle_data *, long *);
static int	cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
		    char **);
static int	cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
static int	cpp_demangle_read_offset(struct cpp_demangle_data *);
static int	cpp_demangle_read_offset_number(struct cpp_demangle_data *);
static int	cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,
		    struct vector_type_qualifier *);
static int	cpp_demangle_read_sname(struct cpp_demangle_data *);
static int	cpp_demangle_read_subst(struct cpp_demangle_data *);
static int	cpp_demangle_read_subst_std(struct cpp_demangle_data *);
static int	cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,
		    const char *);
static int	cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);
static int	cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
static int	cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
static int	cpp_demangle_read_type(struct cpp_demangle_data *,
		    struct type_delimit *);
static int	cpp_demangle_read_type_flat(struct cpp_demangle_data *,
		    char **);
static int	cpp_demangle_read_uqname(struct cpp_demangle_data *);
static int	cpp_demangle_read_v_offset(struct cpp_demangle_data *);
static char	*decode_fp_to_double(const char *, size_t);
static char	*decode_fp_to_float(const char *, size_t);
static char	*decode_fp_to_float128(const char *, size_t);
static char	*decode_fp_to_float80(const char *, size_t);
static char	*decode_fp_to_long_double(const char *, size_t);
static int	hex_to_dec(char);
static void	vector_read_cmd_dest(struct vector_read_cmd *);
static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,
		    enum read_cmd);
static int	vector_read_cmd_init(struct vector_read_cmd *);
static int	vector_read_cmd_pop(struct vector_read_cmd *);
static int	vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,
		    void *);
static void	vector_type_qualifier_dest(struct vector_type_qualifier *);
static int	vector_type_qualifier_init(struct vector_type_qualifier *);
static int	vector_type_qualifier_push(struct vector_type_qualifier *,
		    enum type_qualifier);

/**
 * @brief Decode the input string by IA-64 C++ ABI style.
 *
 * GNU GCC v3 use IA-64 standard ABI.
 * @return New allocated demangled string or NULL if failed.
 * @todo 1. Testing and more test case. 2. Code cleaning.
 */
char *
cpp_demangle_gnu3(const char *org)
{
	struct cpp_demangle_data ddata;
	struct vector_str ret_type;
	struct type_delimit td;
	ssize_t org_len;
	unsigned int limit;
	char *rtn;
	bool has_ret, more_type;

	if (org == NULL || (org_len = strlen(org)) < 2)
		return (NULL);

	if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
		if ((rtn = malloc(org_len + 19)) == NULL)
			return (NULL);
		snprintf(rtn, org_len + 19,
		    "global constructors keyed to %s", org + 11);
		return (rtn);
	}

	if (org[0] != '_' || org[1] != 'Z')
		return (NULL);

	if (!cpp_demangle_data_init(&ddata, org + 2))
		return (NULL);

	rtn = NULL;
	has_ret = more_type = false;

	if (!cpp_demangle_read_encoding(&ddata))
		goto clean;

	/*
	 * Pop function name from substitution candidate list.
	 */
	if (*ddata.cur != 0 && ddata.subst.size >= 1) {
		if (!vector_str_pop(&ddata.subst))
			goto clean;
	}

	td.paren = false;
	td.firstp = true;
	limit = 0;

	/*
	 * The first type is a return type if we just demangled template
	 * args. (the template args is right next to the function name,
	 * which means it's a template function)
	 */
	if (ddata.is_tmpl) {
		ddata.is_tmpl = false;
		if (!vector_str_init(&ret_type))
			goto clean;
		ddata.cur_output = &ret_type;
		has_ret = true;
	}

	while (*ddata.cur != '\0') {
		/*
		 * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4
		 */
		if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')
			break;

		if (has_ret) {
			/* Read return type */
			if (!cpp_demangle_read_type(&ddata, NULL))
				goto clean;
		} else {
			/* Read function arg type */
			if (!cpp_demangle_read_type(&ddata, &td))
				goto clean;
		}

		if (has_ret) {
			/* Push return type to the beginning */
			if (!VEC_PUSH_STR(&ret_type, " "))
				goto clean;
			if (!vector_str_push_vector_head(&ddata.output,
			    &ret_type))
				goto clean;
			ddata.cur_output = &ddata.output;
			vector_str_dest(&ret_type);
			has_ret = false;
			more_type = true;
		} else if (more_type)
			more_type = false;
		if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
			goto clean;
	}
	if (more_type)
		goto clean;

	if (ddata.output.size == 0)
		goto clean;
	if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))
		goto clean;
	if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))
		goto clean;
	if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))
		goto clean;
	if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))
		goto clean;
	if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))
		goto clean;
	if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))
		goto clean;

	rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);

clean:
	if (has_ret)
		vector_str_dest(&ret_type);

	cpp_demangle_data_dest(&ddata);

	return (rtn);
}