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 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 */ 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 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 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 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 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 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 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 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