1*1f5207b7SJohn Levon /*
2*1f5207b7SJohn Levon  * Copyright (C) 2010 Dan Carpenter.
3*1f5207b7SJohn Levon  *
4*1f5207b7SJohn Levon  * This program is free software; you can redistribute it and/or
5*1f5207b7SJohn Levon  * modify it under the terms of the GNU General Public License
6*1f5207b7SJohn Levon  * as published by the Free Software Foundation; either version 2
7*1f5207b7SJohn Levon  * of the License, or (at your option) any later version.
8*1f5207b7SJohn Levon  *
9*1f5207b7SJohn Levon  * This program is distributed in the hope that it will be useful,
10*1f5207b7SJohn Levon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*1f5207b7SJohn Levon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*1f5207b7SJohn Levon  * GNU General Public License for more details.
13*1f5207b7SJohn Levon  *
14*1f5207b7SJohn Levon  * You should have received a copy of the GNU General Public License
15*1f5207b7SJohn Levon  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16*1f5207b7SJohn Levon  */
17*1f5207b7SJohn Levon 
18*1f5207b7SJohn Levon /*
19*1f5207b7SJohn Levon  * This file is only for very generic stuff, that is reusable
20*1f5207b7SJohn Levon  * between projects.  If you need something special create a
21*1f5207b7SJohn Levon  * check_your_project.c.
22*1f5207b7SJohn Levon  *
23*1f5207b7SJohn Levon  */
24*1f5207b7SJohn Levon 
25*1f5207b7SJohn Levon #include "smatch.h"
26*1f5207b7SJohn Levon #include "smatch_extra.h"
27*1f5207b7SJohn Levon #include "smatch_function_hashtable.h"
28*1f5207b7SJohn Levon 
29*1f5207b7SJohn Levon static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
30*1f5207b7SJohn Levon static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
31*1f5207b7SJohn Levon static struct hashtable *skipped_funcs;
32*1f5207b7SJohn Levon static struct hashtable *silenced_funcs;
33*1f5207b7SJohn Levon static struct hashtable *no_inline_funcs;
34*1f5207b7SJohn Levon 
is_skipped_function(void)35*1f5207b7SJohn Levon int is_skipped_function(void)
36*1f5207b7SJohn Levon {
37*1f5207b7SJohn Levon 	char *func;
38*1f5207b7SJohn Levon 
39*1f5207b7SJohn Levon 	func = get_function();
40*1f5207b7SJohn Levon 	if (!func)
41*1f5207b7SJohn Levon 		return 0;
42*1f5207b7SJohn Levon 	if (search_func(skipped_funcs, func))
43*1f5207b7SJohn Levon 		return 1;
44*1f5207b7SJohn Levon 	return 0;
45*1f5207b7SJohn Levon }
46*1f5207b7SJohn Levon 
47*1f5207b7SJohn Levon /*
48*1f5207b7SJohn Levon  * A silenced function will still be processed and potentially appear in info
49*1f5207b7SJohn Levon  * output, but not regular checks.
50*1f5207b7SJohn Levon  */
is_silenced_function(void)51*1f5207b7SJohn Levon int is_silenced_function(void)
52*1f5207b7SJohn Levon {
53*1f5207b7SJohn Levon 	char *func;
54*1f5207b7SJohn Levon 
55*1f5207b7SJohn Levon 	if (is_skipped_function())
56*1f5207b7SJohn Levon 		return 1;
57*1f5207b7SJohn Levon 
58*1f5207b7SJohn Levon 	func = get_function();
59*1f5207b7SJohn Levon 	if (!func)
60*1f5207b7SJohn Levon 		return 0;
61*1f5207b7SJohn Levon 	if (search_func(silenced_funcs, func))
62*1f5207b7SJohn Levon 		return 1;
63*1f5207b7SJohn Levon 	return 0;
64*1f5207b7SJohn Levon }
65*1f5207b7SJohn Levon 
is_no_inline_function(const char * function)66*1f5207b7SJohn Levon int is_no_inline_function(const char *function)
67*1f5207b7SJohn Levon {
68*1f5207b7SJohn Levon 	if (search_func(no_inline_funcs, (char *)function))
69*1f5207b7SJohn Levon 		return 1;
70*1f5207b7SJohn Levon 	return 0;
71*1f5207b7SJohn Levon }
72*1f5207b7SJohn Levon 
register_no_return_funcs(void)73*1f5207b7SJohn Levon static void register_no_return_funcs(void)
74*1f5207b7SJohn Levon {
75*1f5207b7SJohn Levon 	struct token *token;
76*1f5207b7SJohn Levon 	const char *func;
77*1f5207b7SJohn Levon 	char name[256];
78*1f5207b7SJohn Levon 
79*1f5207b7SJohn Levon 	snprintf(name, 256, "%s.no_return_funcs", option_project_str);
80*1f5207b7SJohn Levon 
81*1f5207b7SJohn Levon 	token = get_tokens_file(name);
82*1f5207b7SJohn Levon 	if (!token)
83*1f5207b7SJohn Levon 		return;
84*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_STREAMBEGIN)
85*1f5207b7SJohn Levon 		return;
86*1f5207b7SJohn Levon 	token = token->next;
87*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
88*1f5207b7SJohn Levon 		if (token_type(token) != TOKEN_IDENT)
89*1f5207b7SJohn Levon 			return;
90*1f5207b7SJohn Levon 		func = show_ident(token->ident);
91*1f5207b7SJohn Levon 		add_function_hook(func, &__match_nullify_path_hook, NULL);
92*1f5207b7SJohn Levon 		token = token->next;
93*1f5207b7SJohn Levon 	}
94*1f5207b7SJohn Levon 	clear_token_alloc();
95*1f5207b7SJohn Levon }
96*1f5207b7SJohn Levon 
register_ignored_macros(void)97*1f5207b7SJohn Levon static void register_ignored_macros(void)
98*1f5207b7SJohn Levon {
99*1f5207b7SJohn Levon 	struct token *token;
100*1f5207b7SJohn Levon 	char *macro;
101*1f5207b7SJohn Levon 	char name[256];
102*1f5207b7SJohn Levon 
103*1f5207b7SJohn Levon 	if (option_project == PROJ_NONE)
104*1f5207b7SJohn Levon 		strcpy(name, "ignored_macros");
105*1f5207b7SJohn Levon 	else
106*1f5207b7SJohn Levon 		snprintf(name, 256, "%s.ignored_macros", option_project_str);
107*1f5207b7SJohn Levon 
108*1f5207b7SJohn Levon 	token = get_tokens_file(name);
109*1f5207b7SJohn Levon 	if (!token)
110*1f5207b7SJohn Levon 		return;
111*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_STREAMBEGIN)
112*1f5207b7SJohn Levon 		return;
113*1f5207b7SJohn Levon 	token = token->next;
114*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
115*1f5207b7SJohn Levon 		if (token_type(token) != TOKEN_IDENT)
116*1f5207b7SJohn Levon 			return;
117*1f5207b7SJohn Levon 		macro = alloc_string(show_ident(token->ident));
118*1f5207b7SJohn Levon 		add_ptr_list(&__ignored_macros, macro);
119*1f5207b7SJohn Levon 		token = token->next;
120*1f5207b7SJohn Levon 	}
121*1f5207b7SJohn Levon 	clear_token_alloc();
122*1f5207b7SJohn Levon }
123*1f5207b7SJohn Levon 
register_skipped_functions(void)124*1f5207b7SJohn Levon static void register_skipped_functions(void)
125*1f5207b7SJohn Levon {
126*1f5207b7SJohn Levon 	struct token *token;
127*1f5207b7SJohn Levon 	char *func;
128*1f5207b7SJohn Levon 	char name[256];
129*1f5207b7SJohn Levon 
130*1f5207b7SJohn Levon 	skipped_funcs = create_function_hashtable(500);
131*1f5207b7SJohn Levon 
132*1f5207b7SJohn Levon 	if (option_project == PROJ_NONE)
133*1f5207b7SJohn Levon 		return;
134*1f5207b7SJohn Levon 
135*1f5207b7SJohn Levon 	snprintf(name, 256, "%s.skipped_functions", option_project_str);
136*1f5207b7SJohn Levon 
137*1f5207b7SJohn Levon 	token = get_tokens_file(name);
138*1f5207b7SJohn Levon 	if (!token)
139*1f5207b7SJohn Levon 		return;
140*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_STREAMBEGIN)
141*1f5207b7SJohn Levon 		return;
142*1f5207b7SJohn Levon 	token = token->next;
143*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
144*1f5207b7SJohn Levon 		if (token_type(token) != TOKEN_IDENT)
145*1f5207b7SJohn Levon 			return;
146*1f5207b7SJohn Levon 		func = alloc_string(show_ident(token->ident));
147*1f5207b7SJohn Levon 		insert_func(skipped_funcs, func, INT_PTR(1));
148*1f5207b7SJohn Levon 		token = token->next;
149*1f5207b7SJohn Levon 	}
150*1f5207b7SJohn Levon 	clear_token_alloc();
151*1f5207b7SJohn Levon }
152*1f5207b7SJohn Levon 
register_silenced_functions(void)153*1f5207b7SJohn Levon static void register_silenced_functions(void)
154*1f5207b7SJohn Levon {
155*1f5207b7SJohn Levon 	struct token *token;
156*1f5207b7SJohn Levon 	char *func;
157*1f5207b7SJohn Levon 	char name[256];
158*1f5207b7SJohn Levon 
159*1f5207b7SJohn Levon 	silenced_funcs = create_function_hashtable(500);
160*1f5207b7SJohn Levon 
161*1f5207b7SJohn Levon 	if (option_project == PROJ_NONE)
162*1f5207b7SJohn Levon 		return;
163*1f5207b7SJohn Levon 
164*1f5207b7SJohn Levon 	snprintf(name, 256, "%s.silenced_functions", option_project_str);
165*1f5207b7SJohn Levon 
166*1f5207b7SJohn Levon 	token = get_tokens_file(name);
167*1f5207b7SJohn Levon 	if (!token)
168*1f5207b7SJohn Levon 		return;
169*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_STREAMBEGIN)
170*1f5207b7SJohn Levon 		return;
171*1f5207b7SJohn Levon 	token = token->next;
172*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
173*1f5207b7SJohn Levon 		if (token_type(token) != TOKEN_IDENT)
174*1f5207b7SJohn Levon 			return;
175*1f5207b7SJohn Levon 		func = alloc_string(show_ident(token->ident));
176*1f5207b7SJohn Levon 		insert_func(silenced_funcs, func, INT_PTR(1));
177*1f5207b7SJohn Levon 		token = token->next;
178*1f5207b7SJohn Levon 	}
179*1f5207b7SJohn Levon 	clear_token_alloc();
180*1f5207b7SJohn Levon }
181*1f5207b7SJohn Levon 
register_no_inline_functions(void)182*1f5207b7SJohn Levon static void register_no_inline_functions(void)
183*1f5207b7SJohn Levon {
184*1f5207b7SJohn Levon 	struct token *token;
185*1f5207b7SJohn Levon 	char *func;
186*1f5207b7SJohn Levon 	char name[256];
187*1f5207b7SJohn Levon 
188*1f5207b7SJohn Levon 	no_inline_funcs = create_function_hashtable(500);
189*1f5207b7SJohn Levon 
190*1f5207b7SJohn Levon 	if (option_project == PROJ_NONE)
191*1f5207b7SJohn Levon 		return;
192*1f5207b7SJohn Levon 
193*1f5207b7SJohn Levon 	snprintf(name, 256, "%s.no_inline_functions", option_project_str);
194*1f5207b7SJohn Levon 
195*1f5207b7SJohn Levon 	token = get_tokens_file(name);
196*1f5207b7SJohn Levon 	if (!token)
197*1f5207b7SJohn Levon 		return;
198*1f5207b7SJohn Levon 	if (token_type(token) != TOKEN_STREAMBEGIN)
199*1f5207b7SJohn Levon 		return;
200*1f5207b7SJohn Levon 	token = token->next;
201*1f5207b7SJohn Levon 	while (token_type(token) != TOKEN_STREAMEND) {
202*1f5207b7SJohn Levon 		if (token_type(token) != TOKEN_IDENT)
203*1f5207b7SJohn Levon 			return;
204*1f5207b7SJohn Levon 		func = alloc_string(show_ident(token->ident));
205*1f5207b7SJohn Levon 		insert_func(no_inline_funcs, func, INT_PTR(1));
206*1f5207b7SJohn Levon 		token = token->next;
207*1f5207b7SJohn Levon 	}
208*1f5207b7SJohn Levon 	clear_token_alloc();
209*1f5207b7SJohn Levon }
210*1f5207b7SJohn Levon 
register_project(int id)211*1f5207b7SJohn Levon void register_project(int id)
212*1f5207b7SJohn Levon {
213*1f5207b7SJohn Levon 	register_no_return_funcs();
214*1f5207b7SJohn Levon 	register_ignored_macros();
215*1f5207b7SJohn Levon 	register_skipped_functions();
216*1f5207b7SJohn Levon 	register_silenced_functions();
217*1f5207b7SJohn Levon 	register_no_inline_functions();
218*1f5207b7SJohn Levon }
219