extra: revert the mod_expr changes for modify expression hooks
[smatch.git] / smatch_project.c
blobcf7d5d87e4219cbc1ce6e6985e07ca167c3ac273
1 /*
2 * Copyright (C) 2010 Dan Carpenter.
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.
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.
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
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.
25 #include "smatch.h"
26 #include "smatch_extra.h"
27 #include "smatch_function_hashtable.h"
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 *skipped_macros;
33 static struct hashtable *silenced_funcs;
34 static struct hashtable *no_inline_funcs;
36 static unsigned long skipped;
38 void set_function_skipped(void)
40 skipped = true;
43 int is_skipped_function(void)
45 return skipped;
48 static void match_function_def(struct symbol *sym)
50 char *macro;
51 char *func;
53 func = get_function();
54 if (!func)
55 return;
56 if (skipped_funcs && search_func(skipped_funcs, func)) {
57 set_function_skipped();
58 return;
60 macro = get_macro_name(cur_func_sym->pos);
61 if (macro && skipped_macros && search_func(skipped_macros, macro)) {
62 set_function_skipped();
63 return;
68 * A silenced function will still be processed and potentially appear in info
69 * output, but not regular checks.
71 int is_silenced_function(void)
73 char *func;
75 if (is_skipped_function())
76 return 1;
78 func = get_function();
79 if (!func)
80 return 0;
81 if (search_func(silenced_funcs, func))
82 return 1;
83 return 0;
86 int is_no_inline_function(const char *function)
88 if (search_func(no_inline_funcs, (char *)function))
89 return 1;
90 return 0;
93 static void register_no_return_funcs(void)
95 struct token *token;
96 const char *func;
97 char name[256];
99 snprintf(name, 256, "%s.no_return_funcs", option_project_str);
101 token = get_tokens_file(name);
102 if (!token)
103 return;
104 if (token_type(token) != TOKEN_STREAMBEGIN)
105 return;
106 token = token->next;
107 while (token_type(token) != TOKEN_STREAMEND) {
108 if (token_type(token) != TOKEN_IDENT)
109 return;
110 func = show_ident(token->ident);
111 add_function_hook(func, &__match_nullify_path_hook, NULL);
112 token = token->next;
114 clear_token_alloc();
117 static void register_ignored_macros(void)
119 struct token *token;
120 char *macro;
121 char name[256];
123 if (option_project == PROJ_NONE)
124 strcpy(name, "ignored_macros");
125 else
126 snprintf(name, 256, "%s.ignored_macros", option_project_str);
128 token = get_tokens_file(name);
129 if (!token)
130 return;
131 if (token_type(token) != TOKEN_STREAMBEGIN)
132 return;
133 token = token->next;
134 while (token_type(token) != TOKEN_STREAMEND) {
135 if (token_type(token) != TOKEN_IDENT)
136 return;
137 macro = alloc_string(show_ident(token->ident));
138 add_ptr_list(&__ignored_macros, macro);
139 token = token->next;
141 clear_token_alloc();
144 static struct hashtable *register_skipped(const char *filename)
146 struct hashtable *table;
147 struct token *token;
148 char *func;
149 char name[256];
151 if (option_project == PROJ_NONE)
152 return NULL;
154 snprintf(name, 256, "%s.%s", option_project_str, filename);
156 token = get_tokens_file(name);
157 if (!token)
158 return NULL;
159 if (token_type(token) != TOKEN_STREAMBEGIN)
160 return NULL;
162 table = create_function_hashtable(500);
164 token = token->next;
165 while (token_type(token) != TOKEN_STREAMEND) {
166 if (token_type(token) != TOKEN_IDENT)
167 return table;
168 func = alloc_string(show_ident(token->ident));
169 insert_func(table, func, INT_PTR(1));
170 token = token->next;
172 clear_token_alloc();
174 return table;
177 static void register_silenced_functions(void)
179 struct token *token;
180 char *func;
181 char name[256];
183 silenced_funcs = create_function_hashtable(500);
185 if (option_project == PROJ_NONE)
186 return;
188 snprintf(name, 256, "%s.silenced_functions", option_project_str);
190 token = get_tokens_file(name);
191 if (!token)
192 return;
193 if (token_type(token) != TOKEN_STREAMBEGIN)
194 return;
195 token = token->next;
196 while (token_type(token) != TOKEN_STREAMEND) {
197 if (token_type(token) != TOKEN_IDENT)
198 return;
199 func = alloc_string(show_ident(token->ident));
200 insert_func(silenced_funcs, func, INT_PTR(1));
201 token = token->next;
203 clear_token_alloc();
206 static void register_no_inline_functions(void)
208 struct token *token;
209 char *func;
210 char name[256];
212 no_inline_funcs = create_function_hashtable(500);
214 if (option_project == PROJ_NONE)
215 return;
217 snprintf(name, 256, "%s.no_inline_functions", option_project_str);
219 token = get_tokens_file(name);
220 if (!token)
221 return;
222 if (token_type(token) != TOKEN_STREAMBEGIN)
223 return;
224 token = token->next;
225 while (token_type(token) != TOKEN_STREAMEND) {
226 if (token_type(token) != TOKEN_IDENT)
227 return;
228 func = alloc_string(show_ident(token->ident));
229 insert_func(no_inline_funcs, func, INT_PTR(1));
230 token = token->next;
232 clear_token_alloc();
235 void register_project(int id)
237 add_hook(&match_function_def, FUNC_DEF_HOOK);
238 add_function_data(&skipped);
239 register_no_return_funcs();
240 register_ignored_macros();
241 skipped_funcs = register_skipped("skipped_functions");
242 skipped_macros = register_skipped("skipped_macros");
243 register_silenced_functions();
244 register_no_inline_functions();