struct expr_node * build_zero_w_arg(struct expr_node *expr, int own) { struct expr_node *e_z = malloc(sizeof(*e_z)); if (e_z == NULL) return NULL; expr_init_cb2(e_z, &zero_callback, expr_self(), 0, expr, own, NULL); return e_z; }
struct expr_node * expr_node_zero(void) { static struct expr_node *node = NULL; if (node == NULL) { node = malloc(sizeof(*node)); if (node == NULL) error(1, errno, "malloc expr_node_zero"); expr_init_cb1(node, &zero1_callback, expr_self(), 0, (void *)-1); } return node; }
/* * Input: * argN : The value of argument #N, counting from 1 * eltN : The value of element #N of the containing structure * retval : The return value * N : The numeric value N */ static struct expr_node * parse_argnum(struct locus *loc, char **str, int *ownp, int zero) { struct expr_node *expr = malloc(sizeof(*expr)); if (expr == NULL) return NULL; if (isdigit(CTYPE_CONV(**str))) { long l; if (parse_int(loc, str, &l) < 0 || check_nonnegative(loc, l) < 0 || check_int(loc, l) < 0) goto fail; expr_init_const_word(expr, l, type_get_simple(ARGTYPE_LONG), 0); if (zero && wrap_in_zero(&expr) < 0) goto fail; *ownp = 1; return expr; } else { char *const name = parse_ident(loc, str); if (name == NULL) { fail_ident: free(name); goto fail; } int is_arg = strncmp(name, "arg", 3) == 0; if (is_arg || strncmp(name, "elt", 3) == 0) { long l; char *num = name + 3; if (parse_int(loc, &num, &l) < 0 || check_int(loc, l) < 0) goto fail_ident; if (is_arg) { if (l == 0) expr_init_named(expr, "retval", 0); else expr_init_argno(expr, l - 1); } else { struct expr_node *e_up = malloc(sizeof(*e_up)); struct expr_node *e_ix = malloc(sizeof(*e_ix)); if (e_up == NULL || e_ix == NULL) { free(e_up); free(e_ix); goto fail_ident; } expr_init_up(e_up, expr_self(), 0); struct arg_type_info *ti = type_get_simple(ARGTYPE_LONG); expr_init_const_word(e_ix, l - 1, ti, 0); expr_init_index(expr, e_up, 1, e_ix, 1); } } else if (strcmp(name, "retval") == 0) { expr_init_named(expr, "retval", 0); } else if (strcmp(name, "zero") == 0) { struct expr_node *ret = parse_zero(loc, str, ownp); if (ret == NULL) goto fail_ident; free(expr); free(name); return ret; } else { report_error(loc->filename, loc->line_no, "Unknown length specifier: '%s'", name); goto fail_ident; } if (zero && wrap_in_zero(&expr) < 0) goto fail_ident; free(name); *ownp = 1; return expr; } fail: free(expr); return NULL; }