Print this page
11506 smatch resync
*** 77,87 ****
char buf[1024] = "";
bool found = false;
int i, j;
for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
! if (str[i] != '\n') {
buf[j] = str[i];
continue;
}
found = true;
--- 77,87 ----
char buf[1024] = "";
bool found = false;
int i, j;
for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
! if (str[i] != '\r' && str[i] != '\n') {
buf[j] = str[i];
continue;
}
found = true;
*** 250,261 ****
free_string(fn);
}
void sql_insert_function_ptr(const char *fn, const char *struct_name)
{
! sql_insert(function_ptr, "'%s', '%s', '%s', 0", get_base_file(), fn,
! struct_name);
}
void sql_insert_return_implies(int type, int param, const char *key, const char *value)
{
sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
--- 250,261 ----
free_string(fn);
}
void sql_insert_function_ptr(const char *fn, const char *struct_name)
{
! sql_insert_or_ignore(function_ptr, "'%s', '%s', '%s', 0",
! get_base_file(), fn, struct_name);
}
void sql_insert_return_implies(int type, int param, const char *key, const char *value)
{
sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
*** 329,339 ****
void sql_save_constraint(const char *con)
{
if (!option_info)
return;
! sm_msg("SQL: insert or ignore into constraints (str) values('%s');", con);
}
void sql_save_constraint_required(const char *data, int op, const char *limit)
{
sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
--- 329,339 ----
void sql_save_constraint(const char *con)
{
if (!option_info)
return;
! sm_msg("SQL: insert or ignore into constraints (str) values('%s');", escape_newlines(con));
}
void sql_save_constraint_required(const char *data, int op, const char *limit)
{
sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
*** 370,384 ****
{
sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
}
- void sql_insert_mtag_data(mtag_t tag, const char *var, int offset, int type, const char *value)
- {
- sql_insert(mtag_data, "%lld, '%s', %d, %d, '%s'", tag, var, offset, type, value);
- }
-
void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
{
sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
}
--- 370,379 ----
*** 748,805 ****
if (offset != -1)
snprintf(buf, sizeof(buf), "(-%d)", offset);
return buf;
}
static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
{
struct sm_state *sm;
char *name;
struct symbol *sym;
int len;
char printed_name[256];
int is_address = 0;
struct symbol *type;
expr = strip_expr(expr);
if (!expr)
return;
if (expr->type == EXPR_PREOP && expr->op == '&') {
expr = strip_expr(expr->unop);
is_address = 1;
}
- type = get_type(expr);
- if (type && type_bits(type) < type_bits(&ulong_ctype))
- return;
-
name = expr_to_var_sym(expr, &sym);
if (!name || !sym)
goto free;
len = strlen(name);
FOR_EACH_SM(stree, sm) {
if (sm->sym != sym)
continue;
! if (strcmp(name, sm->name) == 0) {
if (is_address)
snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
else /* these are already handled. fixme: handle them here */
continue;
! } else if (sm->name[0] == '*' && strcmp(name, sm->name + 1) == 0) {
! snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
! } else if (strncmp(name, sm->name, len) == 0) {
! if (isalnum(sm->name[len]))
continue;
if (is_address)
! snprintf(printed_name, sizeof(printed_name), "$%s->%s", show_offset(offset), sm->name + len + 1);
else
! snprintf(printed_name, sizeof(printed_name), "$%s%s", show_offset(offset), sm->name + len);
} else {
continue;
}
callback(call, param, printed_name, sm);
} END_FOR_EACH_SM(sm);
free:
free_string(name);
}
--- 743,843 ----
if (offset != -1)
snprintf(buf, sizeof(buf), "(-%d)", offset);
return buf;
}
+ int is_recursive_member(const char *name)
+ {
+ char buf[256];
+ const char *p, *next;
+ int size;
+
+ p = strchr(name, '>');
+ if (!p)
+ return 0;
+ p++;
+ while (true) {
+ next = strchr(p, '>');
+ if (!next)
+ return 0;
+ next++;
+
+ size = next - p;
+ if (size >= sizeof(buf))
+ return 0;
+ memcpy(buf, p, size);
+ buf[size] = '\0';
+ if (strstr(next, buf))
+ return 1;
+ p = next;
+ }
+ }
+
static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
{
struct sm_state *sm;
+ const char *sm_name;
char *name;
struct symbol *sym;
int len;
char printed_name[256];
int is_address = 0;
+ bool add_star;
struct symbol *type;
expr = strip_expr(expr);
if (!expr)
return;
+ type = get_type(expr);
+ if (type && type_bits(type) < type_bits(&ulong_ctype))
+ return;
+
if (expr->type == EXPR_PREOP && expr->op == '&') {
expr = strip_expr(expr->unop);
is_address = 1;
}
name = expr_to_var_sym(expr, &sym);
if (!name || !sym)
goto free;
len = strlen(name);
FOR_EACH_SM(stree, sm) {
if (sm->sym != sym)
continue;
! sm_name = sm->name;
! add_star = false;
! if (sm_name[0] == '*') {
! add_star = true;
! sm_name++;
! }
! // FIXME: simplify?
! if (!add_star && strcmp(name, sm_name) == 0) {
if (is_address)
snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
else /* these are already handled. fixme: handle them here */
continue;
! } else if (add_star && strcmp(name, sm_name) == 0) {
! snprintf(printed_name, sizeof(printed_name), "%s*$%s",
! is_address ? "*" : "", show_offset(offset));
! } else if (strncmp(name, sm_name, len) == 0) {
! if (sm_name[len] != '.' && sm_name[len] != '-')
continue;
if (is_address)
! snprintf(printed_name, sizeof(printed_name),
! "%s$%s->%s", add_star ? "*" : "",
! show_offset(offset), sm_name + len + 1);
else
! snprintf(printed_name, sizeof(printed_name),
! "%s$%s%s", add_star ? "*" : "",
! show_offset(offset), sm_name + len);
} else {
continue;
}
+ if (is_recursive_member(printed_name))
+ continue;
callback(call, param, printed_name, sm);
} END_FOR_EACH_SM(sm);
free:
free_string(name);
}
*** 1007,1019 ****
static char *get_next_ptr_name(void)
{
char *ptr;
FOR_EACH_PTR(ptr_names, ptr) {
! if (list_has_string(ptr_names_done, ptr))
continue;
- insert_string(&ptr_names_done, ptr);
return ptr;
} END_FOR_EACH_PTR(ptr);
return NULL;
}
--- 1045,1056 ----
static char *get_next_ptr_name(void)
{
char *ptr;
FOR_EACH_PTR(ptr_names, ptr) {
! if (!insert_string(&ptr_names_done, ptr))
continue;
return ptr;
} END_FOR_EACH_PTR(ptr);
return NULL;
}
*** 1222,1278 ****
info.sym = sym;
sql_select_implies("function, type, parameter, key, value", &info,
call_implies_callbacks);
}
! static void print_initializer_list(struct expression_list *expr_list,
! struct symbol *struct_type)
{
! struct expression *expr;
! struct symbol *base_type;
! char struct_name[256];
! FOR_EACH_PTR(expr_list, expr) {
! if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
! print_initializer_list(expr->idx_expression->expr_list, struct_type);
! continue;
! }
! if (expr->type != EXPR_IDENTIFIER)
! continue;
! if (!expr->expr_ident)
! continue;
! if (!expr->ident_expression || !expr->ident_expression->symbol_name)
! continue;
! base_type = get_type(expr->ident_expression);
! if (!base_type || base_type->type != SYM_FN)
! continue;
! snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
! struct_type->ident->name, expr->expr_ident->name);
! sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
! struct_name);
! } END_FOR_EACH_PTR(expr);
}
! static void global_variable(struct symbol *sym)
{
! struct symbol *struct_type;
! if (!sym->ident)
! return;
! if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
! return;
! struct_type = get_base_type(sym);
! if (!struct_type)
! return;
! if (struct_type->type == SYM_ARRAY) {
! struct_type = get_base_type(struct_type);
! if (!struct_type)
! return;
}
! if (struct_type->type != SYM_STRUCT || !struct_type->ident)
! return;
! print_initializer_list(sym->initializer->expr_list, struct_type);
}
static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
{
sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
--- 1259,1359 ----
info.sym = sym;
sql_select_implies("function, type, parameter, key, value", &info,
call_implies_callbacks);
}
! static char *get_return_compare_is_param(struct expression *expr)
{
! char *var;
! char buf[256];
! int comparison;
! int param;
! param = get_param_num(expr);
! if (param < 0)
! return NULL;
!
! var = expr_to_var(expr);
! if (!var)
! return NULL;
! snprintf(buf, sizeof(buf), "%s orig", var);
! comparison = get_comparison_strings(var, buf);
! free_string(var);
!
! if (!comparison)
! return NULL;
!
! snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
! return alloc_sname(buf);
}
! static char *get_return_compare_str(struct expression *expr)
{
! char *compare_str;
! compare_str = get_return_compare_is_param(expr);
! if (compare_str)
! return compare_str;
!
! compare_str = expr_lte_to_param(expr, -1);
! if (compare_str)
! return compare_str;
!
! return expr_param_comparison(expr, -1);
! }
!
! static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
! {
! struct range_list *rl;
! char *return_ranges;
! sval_t sval;
! char *compare_str;
! char *math_str;
! char buf[128];
!
! *rl_p = NULL;
!
! if (!expr)
! return alloc_sname("");
!
! if (get_implied_value(expr, &sval)) {
! sval = sval_cast(cur_func_return_type(), sval);
! *rl_p = alloc_rl(sval, sval);
! return sval_to_str_or_err_ptr(sval);
}
!
! compare_str = expr_equal_to_param(expr, -1);
! math_str = get_value_in_terms_of_parameter_math(expr);
!
! if (get_implied_rl(expr, &rl) && !is_whole_rl(rl)) {
! rl = cast_rl(cur_func_return_type(), rl);
! return_ranges = show_rl(rl);
! } else if (get_imaginary_absolute(expr, &rl)){
! rl = cast_rl(cur_func_return_type(), rl);
! return alloc_sname(show_rl(rl));
! } else {
! get_absolute_rl(expr, &rl);
! rl = cast_rl(cur_func_return_type(), rl);
! return_ranges = show_rl(rl);
! }
! *rl_p = rl;
!
! if (compare_str) {
! snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
! return alloc_sname(buf);
! }
! if (math_str) {
! snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
! return alloc_sname(buf);
! }
! compare_str = get_return_compare_str(expr);
! if (compare_str) {
! snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
! return alloc_sname(buf);
! }
!
! return return_ranges;
}
static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
{
sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
*** 1280,1323 ****
static void call_return_state_hooks_conditional(struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
! char *return_ranges;
int final_pass_orig = final_pass;
__push_fake_cur_stree();
final_pass = 0;
__split_whole_condition(expr->conditional);
final_pass = final_pass_orig;
! if (get_implied_rl(expr->cond_true, &rl))
! rl = cast_rl(cur_func_return_type(), rl);
! else
! rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_true)));
! return_ranges = show_rl(rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
return_id++;
FOR_EACH_PTR(returned_state_callbacks, cb) {
! cb->callback(return_id, return_ranges, expr->cond_true);
} END_FOR_EACH_PTR(cb);
__push_true_states();
__use_false_states();
! if (get_implied_rl(expr->cond_false, &rl))
! rl = cast_rl(cur_func_return_type(), rl);
! else
! rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_false)));
! return_ranges = show_rl(rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
return_id++;
FOR_EACH_PTR(returned_state_callbacks, cb) {
! cb->callback(return_id, return_ranges, expr->cond_false);
} END_FOR_EACH_PTR(cb);
__merge_true_states();
__free_fake_cur_stree();
}
--- 1361,1397 ----
static void call_return_state_hooks_conditional(struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
! const char *return_ranges;
int final_pass_orig = final_pass;
__push_fake_cur_stree();
final_pass = 0;
__split_whole_condition(expr->conditional);
final_pass = final_pass_orig;
! return_ranges = get_return_ranges_str(expr->cond_true ?: expr->conditional, &rl);
!
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
return_id++;
FOR_EACH_PTR(returned_state_callbacks, cb) {
! cb->callback(return_id, (char *)return_ranges, expr->cond_true);
} END_FOR_EACH_PTR(cb);
__push_true_states();
__use_false_states();
! return_ranges = get_return_ranges_str(expr->cond_false, &rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
return_id++;
FOR_EACH_PTR(returned_state_callbacks, cb) {
! cb->callback(return_id, (char *)return_ranges, expr->cond_false);
} END_FOR_EACH_PTR(cb);
__merge_true_states();
__free_fake_cur_stree();
}
*** 1378,1436 ****
} END_FOR_EACH_PTR(tmp);
return 0;
}
- static char *get_return_compare_str(struct expression *expr)
- {
- char *compare_str;
- char *var;
- char buf[256];
- int comparison;
- int param;
-
- compare_str = expr_lte_to_param(expr, -1);
- if (compare_str)
- return compare_str;
- param = get_param_num(expr);
- if (param < 0)
- return NULL;
-
- var = expr_to_var(expr);
- if (!var)
- return NULL;
- snprintf(buf, sizeof(buf), "%s orig", var);
- comparison = get_comparison_strings(var, buf);
- free_string(var);
-
- if (!comparison)
- return NULL;
-
- snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
- return alloc_sname(buf);
- }
-
static int split_possible_helper(struct sm_state *sm, struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
char *return_ranges;
struct sm_state *tmp;
int ret = 0;
int nr_possible, nr_states;
! char *compare_str = NULL;
char buf[128];
struct state_list *already_handled = NULL;
if (!sm || !sm->merged)
return 0;
if (too_many_possible(sm))
return 0;
/* bail if it gets too complicated */
! nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
nr_states = get_db_state_count();
if (nr_states * nr_possible >= 2000)
return 0;
FOR_EACH_PTR(sm->possible, tmp) {
--- 1452,1487 ----
} END_FOR_EACH_PTR(tmp);
return 0;
}
static int split_possible_helper(struct sm_state *sm, struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
char *return_ranges;
struct sm_state *tmp;
int ret = 0;
int nr_possible, nr_states;
! char *compare_str;
char buf[128];
struct state_list *already_handled = NULL;
+ sval_t sval;
if (!sm || !sm->merged)
return 0;
if (too_many_possible(sm))
return 0;
/* bail if it gets too complicated */
! nr_possible = 0;
! FOR_EACH_PTR(sm->possible, tmp) {
! if (tmp->merged)
! continue;
! nr_possible++;
! } END_FOR_EACH_PTR(tmp);
nr_states = get_db_state_count();
if (nr_states * nr_possible >= 2000)
return 0;
FOR_EACH_PTR(sm->possible, tmp) {
*** 1446,1460 ****
--- 1497,1513 ----
overwrite_states_using_pool(sm, tmp);
rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
return_ranges = show_rl(rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));
+ if (!rl_to_sval(rl, &sval)) {
compare_str = get_return_compare_str(expr);
if (compare_str) {
snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
return_ranges = alloc_sname(buf);
}
+ }
return_id++;
FOR_EACH_PTR(returned_state_callbacks, cb) {
cb->callback(return_id, return_ranges, expr);
} END_FOR_EACH_PTR(cb);
*** 1476,1537 ****
sm = get_sm_state_expr(SMATCH_EXTRA, expr);
return split_possible_helper(sm, expr);
}
- static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
- {
- struct range_list *rl;
- char *return_ranges;
- sval_t sval;
- char *compare_str;
- char *math_str;
- char buf[128];
-
- *rl_p = NULL;
-
- if (!expr)
- return alloc_sname("");
-
- if (get_implied_value(expr, &sval)) {
- sval = sval_cast(cur_func_return_type(), sval);
- *rl_p = alloc_rl(sval, sval);
- return sval_to_str(sval);
- }
-
- compare_str = expr_equal_to_param(expr, -1);
- math_str = get_value_in_terms_of_parameter_math(expr);
-
- if (get_implied_rl(expr, &rl)) {
- rl = cast_rl(cur_func_return_type(), rl);
- return_ranges = show_rl(rl);
- } else if (get_imaginary_absolute(expr, &rl)){
- rl = cast_rl(cur_func_return_type(), rl);
- return alloc_sname(show_rl(rl));
- } else {
- rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr)));
- return_ranges = show_rl(rl);
- }
- *rl_p = rl;
-
- if (compare_str) {
- snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
- return alloc_sname(buf);
- }
- if (math_str) {
- snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
- return alloc_sname(buf);
- }
- compare_str = get_return_compare_str(expr);
- if (compare_str) {
- snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
- return alloc_sname(buf);
- }
-
- return return_ranges;
- }
-
static bool has_possible_negative(struct sm_state *sm)
{
struct sm_state *tmp;
FOR_EACH_PTR(sm->possible, tmp) {
--- 1529,1538 ----
*** 1566,1575 ****
--- 1567,1577 ----
struct returned_state_callback *cb;
struct range_list *rl;
const char *return_ranges;
struct range_list *ret_rl;
int undo;
+ bool has_zero;
/* We're going to print the states 3 times */
if (get_db_state_count() > 10000 / 3)
return 0;
*** 1586,1597 ****
sm = get_sm_state_expr(SMATCH_EXTRA, expr);
if (!sm)
return 0;
if (!has_possible_negative(sm))
return 0;
! if (!assume(compare_expression(expr, '>', zero_expr())))
return 0;
return_id++;
return_ranges = get_return_ranges_str(expr, &ret_rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
--- 1588,1600 ----
sm = get_sm_state_expr(SMATCH_EXTRA, expr);
if (!sm)
return 0;
if (!has_possible_negative(sm))
return 0;
+ has_zero = has_possible_zero_null(sm);
! if (!assume(compare_expression(expr, has_zero ? '>' : SPECIAL_GTE, zero_expr())))
return 0;
return_id++;
return_ranges = get_return_ranges_str(expr, &ret_rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
*** 1599,1609 ****
cb->callback(return_id, (char *)return_ranges, expr);
} END_FOR_EACH_PTR(cb);
end_assume();
! if (rl_has_sval(rl, sval_type_val(rl_type(rl), 0))) {
undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
return_id++;
return_ranges = get_return_ranges_str(expr, &ret_rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
--- 1602,1612 ----
cb->callback(return_id, (char *)return_ranges, expr);
} END_FOR_EACH_PTR(cb);
end_assume();
! if (has_zero) {
undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
return_id++;
return_ranges = get_return_ranges_str(expr, &ret_rl);
set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
*** 1628,1638 ****
end_assume();
return 1;
}
! static int call_return_state_hooks_split_null_non_null(struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
struct range_list *nonnull_rl;
sval_t null_sval;
--- 1631,1641 ----
end_assume();
return 1;
}
! static int call_return_state_hooks_split_null_non_null_zero(struct expression *expr)
{
struct returned_state_callback *cb;
struct range_list *rl;
struct range_list *nonnull_rl;
sval_t null_sval;
*** 1645,1656 ****
if (!expr || expr_equal_to_param(expr, -1))
return 0;
if (expr->type == EXPR_CALL)
return 0;
- if (!is_pointer(expr))
- return 0;
sm = get_sm_state_expr(SMATCH_EXTRA, expr);
if (!sm)
return 0;
if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
--- 1648,1657 ----
*** 1990,2007 ****
} else if (is_conditional(expr)) {
call_return_state_hooks_conditional(expr);
return;
} else if (call_return_state_hooks_split_possible(expr)) {
return;
! } else if (call_return_state_hooks_split_null_non_null(expr)) {
return;
} else if (call_return_state_hooks_split_success_fail(expr)) {
return;
} else if (splitable_function_call(expr)) {
return;
- } else if (split_positive_from_negative(expr)) {
- return;
} else if (split_by_bool_param(expr)) {
} else if (split_by_null_nonnull_param(expr)) {
return;
}
--- 1991,2008 ----
} else if (is_conditional(expr)) {
call_return_state_hooks_conditional(expr);
return;
} else if (call_return_state_hooks_split_possible(expr)) {
return;
! } else if (split_positive_from_negative(expr)) {
return;
+ } else if (call_return_state_hooks_split_null_non_null_zero(expr)) {
+ return;
} else if (call_return_state_hooks_split_success_fail(expr)) {
return;
} else if (splitable_function_call(expr)) {
return;
} else if (split_by_bool_param(expr)) {
} else if (split_by_null_nonnull_param(expr)) {
return;
}
*** 2206,2216 ****
p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
for (i = 0; i < argc; i++) {
if (i)
p += snprintf(p, 4096 - (p - buf), ", ");
! sqlite3_snprintf(sizeof(tmp), tmp, "%q", argv[i]);
p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
}
p += snprintf(p, 4096 - (p - buf), ");");
if (p - buf > 4096)
--- 2207,2217 ----
p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
for (i = 0; i < argc; i++) {
if (i)
p += snprintf(p, 4096 - (p - buf), ", ");
! sqlite3_snprintf(sizeof(tmp), tmp, "%q", escape_newlines(argv[i]));
p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
}
p += snprintf(p, 4096 - (p - buf), ");");
if (p - buf > 4096)
*** 2359,2370 ****
}
void register_definition_db_callbacks(int id)
{
add_hook(&match_call_info, FUNCTION_CALL_HOOK);
- add_hook(&global_variable, BASE_HOOK);
- add_hook(&global_variable, DECLARATION_HOOK);
add_split_return_callback(match_return_info);
add_split_return_callback(print_returned_struct_members);
add_hook(&call_return_state_hooks, RETURN_HOOK);
add_hook(&match_end_func_info, END_FUNC_HOOK);
add_hook(&match_after_func, AFTER_FUNC_HOOK);
--- 2360,2369 ----
*** 2395,2404 ****
--- 2394,2405 ----
if (param == -1) {
const char *star = "";
if (expr->type != EXPR_ASSIGNMENT)
return NULL;
+ if (get_type(expr->left) == &int_ctype && strcmp(key, "$") != 0)
+ return NULL;
name = expr_to_var_sym(expr->left, sym);
if (!name)
return NULL;
if (key[0] == '*') {
star = "*";
*** 2425,2434 ****
--- 2426,2436 ----
char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
{
char buf[256];
char *tmp;
+ bool add_star = false;
if (!arg)
return NULL;
arg = strip_expr(arg);
*** 2448,2470 ****
free_string(tmp);
return alloc_string(buf);
}
}
if (arg->type == EXPR_PREOP && arg->op == '&') {
arg = strip_expr(arg->unop);
tmp = expr_to_var_sym(arg, sym);
if (!tmp)
return NULL;
! snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 3);
return alloc_string(buf);
}
tmp = expr_to_var_sym(arg, sym);
if (!tmp)
return NULL;
! snprintf(buf, sizeof(buf), "%s%s", tmp, key + 1);
free_string(tmp);
return alloc_string(buf);
}
char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
--- 2450,2478 ----
free_string(tmp);
return alloc_string(buf);
}
}
+ if (key[0] == '*') {
+ add_star = true;
+ key++;
+ }
+
if (arg->type == EXPR_PREOP && arg->op == '&') {
arg = strip_expr(arg->unop);
tmp = expr_to_var_sym(arg, sym);
if (!tmp)
return NULL;
! snprintf(buf, sizeof(buf), "%s%s.%s",
! add_star ? "*" : "", tmp, key + 3);
return alloc_string(buf);
}
tmp = expr_to_var_sym(arg, sym);
if (!tmp)
return NULL;
! snprintf(buf, sizeof(buf), "%s%s%s", add_star ? "*" : "", tmp, key + 1);
free_string(tmp);
return alloc_string(buf);
}
char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
*** 2478,2498 ****
const char *state_name_to_param_name(const char *state_name, const char *param_name)
{
int name_len;
static char buf[256];
name_len = strlen(param_name);
if (strcmp(state_name, param_name) == 0) {
! return "$";
! } else if (state_name[name_len] == '-' && /* check for '-' from "->" */
strncmp(state_name, param_name, name_len) == 0) {
! snprintf(buf, sizeof(buf), "$%s", state_name + name_len);
return buf;
- } else if (state_name[0] == '*' && strcmp(state_name + 1, param_name) == 0) {
- return "*$";
}
return NULL;
}
const char *get_param_name_var_sym(const char *name, struct symbol *sym)
--- 2486,2514 ----
const char *state_name_to_param_name(const char *state_name, const char *param_name)
{
int name_len;
static char buf[256];
+ bool add_star = false;
name_len = strlen(param_name);
+ if (state_name[0] == '*') {
+ add_star = true;
+ state_name++;
+ }
+
if (strcmp(state_name, param_name) == 0) {
! snprintf(buf, sizeof(buf), "%s$", add_star ? "*" : "");
! return buf;
! }
!
! if (state_name[name_len] == '-' && /* check for '-' from "->" */
strncmp(state_name, param_name, name_len) == 0) {
! snprintf(buf, sizeof(buf), "%s$%s",
! add_star ? "*" : "", state_name + name_len);
return buf;
}
return NULL;
}
const char *get_param_name_var_sym(const char *name, struct symbol *sym)