1 /*
2  * Copyright (C) 2013 Oracle.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16  */
17 
18 #include "smatch.h"
19 #include "smatch_slist.h"
20 #include "smatch_extra.h"
21 
22 static int my_id;
23 
get_source_parameter(struct expression * expr)24 static char *get_source_parameter(struct expression *expr)
25 {
26 	struct expression *tmp;
27 	const char *param_name;
28 	struct symbol *sym;
29 	char *name;
30 	int param;
31 	char *ret = NULL;
32 	char buf[32];
33 	int cnt = 0;
34 	bool modified = false;
35 
36 	tmp = expr;
37 	while ((tmp = get_assigned_expr(tmp))) {
38 		expr = tmp;
39 		if (cnt++ > 3)
40 			break;
41 	}
42 
43 	expr = strip_expr(expr);
44 	if (expr->type != EXPR_SYMBOL)
45 		return NULL;
46 
47 	name = expr_to_var_sym(expr, &sym);
48 	if (!name || !sym)
49 		goto free;
50 	param = get_param_num_from_sym(sym);
51 	if (param < 0)
52 		goto free;
53 	param_name = get_param_name_var_sym(name, sym);
54 	if (!param_name)
55 		goto free;
56 	if (param_was_set_var_sym(name, sym))
57 		modified = true;
58 
59 	snprintf(buf, sizeof(buf), "$%d%s%s", param, param_name + 1,
60 		 modified ? " [m]" : "");
61 	ret = alloc_string(buf);
62 
63 free:
64 	free_string(name);
65 	return ret;
66 }
67 
get_source_assignment(struct expression * expr)68 static char *get_source_assignment(struct expression *expr)
69 {
70 	struct expression *right;
71 	char *name;
72 	char buf[64];
73 	char *ret;
74 
75 	right = get_assigned_expr(expr);
76 	right = strip_expr(right);
77 	if (!right)
78 		return NULL;
79 	if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
80 		return NULL;
81 	if (is_fake_call(right))
82 		return NULL;
83 	name = expr_to_str(right->fn);
84 	if (!name)
85 		return NULL;
86 	snprintf(buf, sizeof(buf), "r %s", name);
87 	ret = alloc_string(buf);
88 	free_string(name);
89 	return ret;
90 }
91 
get_source_str(struct expression * arg)92 static char *get_source_str(struct expression *arg)
93 {
94 	char *source;
95 
96 	source = get_source_parameter(arg);
97 	if (source)
98 		return source;
99 	return get_source_assignment(arg);
100 }
101 
match_caller_info(struct expression * expr)102 static void match_caller_info(struct expression *expr)
103 {
104 	struct expression *arg;
105 	char *source;
106 	int i;
107 
108 	i = -1;
109 	FOR_EACH_PTR(expr->args, arg) {
110 		i++;
111 		source = get_source_str(arg);
112 		if (!source)
113 			continue;
114 		sql_insert_caller_info(expr, DATA_SOURCE, i, "$", source);
115 		free_string(source);
116 	} END_FOR_EACH_PTR(arg);
117 }
118 
register_data_source(int id)119 void register_data_source(int id)
120 {
121 //	if (!option_info)
122 //		return;
123 	my_id = id;
124 	add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
125 }
126