1 /*
2 * Copyright (C) 2010 Dan Carpenter.
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 /*
19 * This file is only for very generic stuff, that is reusable
20 * between projects. If you need something special create a
21 * check_your_project.c.
22 *
23 */
24
25 #include "smatch.h"
26 #include "smatch_extra.h"
27 #include "smatch_function_hashtable.h"
28
29 static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
30 static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
31 static struct hashtable *skipped_funcs;
32 static struct hashtable *silenced_funcs;
33 static struct hashtable *no_inline_funcs;
34
is_skipped_function(void)35 int is_skipped_function(void)
36 {
37 char *func;
38
39 func = get_function();
40 if (!func)
41 return 0;
42 if (search_func(skipped_funcs, func))
43 return 1;
44 return 0;
45 }
46
47 /*
48 * A silenced function will still be processed and potentially appear in info
49 * output, but not regular checks.
50 */
is_silenced_function(void)51 int is_silenced_function(void)
52 {
53 char *func;
54
55 if (is_skipped_function())
56 return 1;
57
58 func = get_function();
59 if (!func)
60 return 0;
61 if (search_func(silenced_funcs, func))
62 return 1;
63 return 0;
64 }
65
is_no_inline_function(const char * function)66 int is_no_inline_function(const char *function)
67 {
68 if (search_func(no_inline_funcs, (char *)function))
69 return 1;
70 return 0;
71 }
72
register_no_return_funcs(void)73 static void register_no_return_funcs(void)
74 {
75 struct token *token;
76 const char *func;
77 char name[256];
78
79 snprintf(name, 256, "%s.no_return_funcs", option_project_str);
80
81 token = get_tokens_file(name);
82 if (!token)
83 return;
84 if (token_type(token) != TOKEN_STREAMBEGIN)
85 return;
86 token = token->next;
87 while (token_type(token) != TOKEN_STREAMEND) {
88 if (token_type(token) != TOKEN_IDENT)
89 return;
90 func = show_ident(token->ident);
91 add_function_hook(func, &__match_nullify_path_hook, NULL);
92 token = token->next;
93 }
94 clear_token_alloc();
95 }
96
register_ignored_macros(void)97 static void register_ignored_macros(void)
98 {
99 struct token *token;
100 char *macro;
101 char name[256];
102
103 if (option_project == PROJ_NONE)
104 strcpy(name, "ignored_macros");
105 else
106 snprintf(name, 256, "%s.ignored_macros", option_project_str);
107
108 token = get_tokens_file(name);
109 if (!token)
110 return;
111 if (token_type(token) != TOKEN_STREAMBEGIN)
112 return;
113 token = token->next;
114 while (token_type(token) != TOKEN_STREAMEND) {
115 if (token_type(token) != TOKEN_IDENT)
116 return;
117 macro = alloc_string(show_ident(token->ident));
118 add_ptr_list(&__ignored_macros, macro);
119 token = token->next;
120 }
121 clear_token_alloc();
122 }
123
register_skipped_functions(void)124 static void register_skipped_functions(void)
125 {
126 struct token *token;
127 char *func;
128 char name[256];
129
130 skipped_funcs = create_function_hashtable(500);
131
132 if (option_project == PROJ_NONE)
133 return;
134
135 snprintf(name, 256, "%s.skipped_functions", option_project_str);
136
137 token = get_tokens_file(name);
138 if (!token)
139 return;
140 if (token_type(token) != TOKEN_STREAMBEGIN)
141 return;
142 token = token->next;
143 while (token_type(token) != TOKEN_STREAMEND) {
144 if (token_type(token) != TOKEN_IDENT)
145 return;
146 func = alloc_string(show_ident(token->ident));
147 insert_func(skipped_funcs, func, INT_PTR(1));
148 token = token->next;
149 }
150 clear_token_alloc();
151 }
152
register_silenced_functions(void)153 static void register_silenced_functions(void)
154 {
155 struct token *token;
156 char *func;
157 char name[256];
158
159 silenced_funcs = create_function_hashtable(500);
160
161 if (option_project == PROJ_NONE)
162 return;
163
164 snprintf(name, 256, "%s.silenced_functions", option_project_str);
165
166 token = get_tokens_file(name);
167 if (!token)
168 return;
169 if (token_type(token) != TOKEN_STREAMBEGIN)
170 return;
171 token = token->next;
172 while (token_type(token) != TOKEN_STREAMEND) {
173 if (token_type(token) != TOKEN_IDENT)
174 return;
175 func = alloc_string(show_ident(token->ident));
176 insert_func(silenced_funcs, func, INT_PTR(1));
177 token = token->next;
178 }
179 clear_token_alloc();
180 }
181
register_no_inline_functions(void)182 static void register_no_inline_functions(void)
183 {
184 struct token *token;
185 char *func;
186 char name[256];
187
188 no_inline_funcs = create_function_hashtable(500);
189
190 if (option_project == PROJ_NONE)
191 return;
192
193 snprintf(name, 256, "%s.no_inline_functions", option_project_str);
194
195 token = get_tokens_file(name);
196 if (!token)
197 return;
198 if (token_type(token) != TOKEN_STREAMBEGIN)
199 return;
200 token = token->next;
201 while (token_type(token) != TOKEN_STREAMEND) {
202 if (token_type(token) != TOKEN_IDENT)
203 return;
204 func = alloc_string(show_ident(token->ident));
205 insert_func(no_inline_funcs, func, INT_PTR(1));
206 token = token->next;
207 }
208 clear_token_alloc();
209 }
210
register_project(int id)211 void register_project(int id)
212 {
213 register_no_return_funcs();
214 register_ignored_macros();
215 register_skipped_functions();
216 register_silenced_functions();
217 register_no_inline_functions();
218 }
219