#include "smatch.h"
#include "smatch_slist.h"
#include "smatch_extra.h"
static int my_id;
static char *get_source_parameter(struct expression *expr)
{
struct expression *tmp;
const char *param_name;
struct symbol *sym;
char *name;
int param;
char *ret = NULL;
char buf[32];
int cnt = 0;
bool modified = false;
tmp = expr;
while ((tmp = get_assigned_expr(tmp))) {
expr = tmp;
if (cnt++ > 3)
break;
}
expr = strip_expr(expr);
if (expr->type != EXPR_SYMBOL)
return NULL;
name = expr_to_var_sym(expr, &sym);
if (!name || !sym)
goto free;
param = get_param_num_from_sym(sym);
if (param < 0)
goto free;
param_name = get_param_name_var_sym(name, sym);
if (!param_name)
goto free;
if (param_was_set_var_sym(name, sym))
modified = true;
snprintf(buf, sizeof(buf), "$%d%s%s", param, param_name + 1,
modified ? " [m]" : "");
ret = alloc_string(buf);
free:
free_string(name);
return ret;
}
static char *get_source_assignment(struct expression *expr)
{
struct expression *right;
char *name;
char buf[64];
char *ret;
right = get_assigned_expr(expr);
right = strip_expr(right);
if (!right)
return NULL;
if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
return NULL;
if (is_fake_call(right))
return NULL;
name = expr_to_str(right->fn);
if (!name)
return NULL;
snprintf(buf, sizeof(buf), "r %s", name);
ret = alloc_string(buf);
free_string(name);
return ret;
}
static char *get_source_str(struct expression *arg)
{
char *source;
source = get_source_parameter(arg);
if (source)
return source;
return get_source_assignment(arg);
}
static void match_caller_info(struct expression *expr)
{
struct expression *arg;
char *source;
int i;
i = -1;
FOR_EACH_PTR(expr->args, arg) {
i++;
source = get_source_str(arg);
if (!source)
continue;
sql_insert_caller_info(expr, DATA_SOURCE, i, "$", source);
free_string(source);
} END_FOR_EACH_PTR(arg);
}
void register_data_source(int id)
{
my_id = id;
add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
}