math: handle foo = !2;
[smatch.git] / smatch_project.c
blob5bda3e9bb68ba7c4951995b195eb820c2bb0d43e
1 /*
2 * sparse/smatch_project.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * This file is only for very generic stuff, that is reusable
12 * between projects. If you need something special create a
13 * check_your_project.c.
17 #include "smatch.h"
18 #include "smatch_extra.h"
20 static void register_no_return_funcs(void)
22 struct token *token;
23 const char *func;
24 char name[256];
26 if (option_project == PROJ_NONE)
27 strcpy(name, "no_return_funcs");
28 else
29 snprintf(name, 256, "%s.no_return_funcs", option_project_str);
31 token = get_tokens_file(name);
32 if (!token)
33 return;
34 if (token_type(token) != TOKEN_STREAMBEGIN)
35 return;
36 token = token->next;
37 while (token_type(token) != TOKEN_STREAMEND) {
38 if (token_type(token) != TOKEN_IDENT)
39 return;
40 func = show_ident(token->ident);
41 add_function_hook(func, &__match_nullify_path_hook, NULL);
42 token = token->next;
44 clear_token_alloc();
47 static void register_ignored_macros(void)
49 struct token *token;
50 char *macro;
51 char name[256];
53 if (option_project == PROJ_NONE)
54 strcpy(name, "ignored_macros");
55 else
56 snprintf(name, 256, "%s.ignored_macros", option_project_str);
58 token = get_tokens_file(name);
59 if (!token)
60 return;
61 if (token_type(token) != TOKEN_STREAMBEGIN)
62 return;
63 token = token->next;
64 while (token_type(token) != TOKEN_STREAMEND) {
65 if (token_type(token) != TOKEN_IDENT)
66 return;
67 macro = alloc_string(show_ident(token->ident));
68 add_ptr_list(&__ignored_macros, macro);
69 token = token->next;
71 clear_token_alloc();
74 struct param_implication {
75 int param;
76 struct range_list *rl;
79 static void match_param_implication(const char *fn, struct expression *call_expr,
80 struct expression *assign_expr, void *_imp)
82 struct param_implication *imp = _imp;
83 struct expression *arg;
85 arg = get_argument_from_call_expr(call_expr->args, imp->param);
86 set_extra_expr_nomod(arg, alloc_estate_range_list(clone_range_list(imp->rl)));
89 static void add_param_implication(const char *func, int param, char *range, char *ret_range)
91 struct range_list *ret_rl = NULL;
92 struct range_list *rl = NULL;
93 struct param_implication *imp;
95 get_value_ranges(ret_range, &ret_rl);
97 get_value_ranges(range, &rl);
98 rl = clone_permanent(rl);
100 imp = malloc(sizeof(*imp));
101 imp->param = param;
102 imp->rl = rl;
104 return_implies_state(func, rl_min(ret_rl), rl_max(ret_rl), &match_param_implication, imp);
107 static void register_parameter_implications(void)
109 char name[256];
110 struct token *token;
111 const char *func;
112 int param;
113 char *range;
114 char *ret_range;
116 snprintf(name, 256, "%s.parameter_implications", option_project_str);
117 name[255] = '\0';
118 token = get_tokens_file(name);
119 if (!token)
120 return;
121 if (token_type(token) != TOKEN_STREAMBEGIN)
122 return;
123 token = token->next;
124 while (token_type(token) != TOKEN_STREAMEND) {
125 if (token_type(token) != TOKEN_IDENT)
126 return;
127 func = show_ident(token->ident);
129 token = token->next;
130 if (token_type(token) != TOKEN_STRING)
131 return;
132 ret_range = token->string->data;
134 token = token->next;
135 if (token_type(token) != TOKEN_NUMBER)
136 return;
137 param = atoi(token->number);
139 token = token->next;
140 if (token_type(token) != TOKEN_STRING)
141 return;
142 range = token->string->data;
144 add_param_implication(func, param, range, ret_range);
146 token = token->next;
148 clear_token_alloc();
151 void register_project(int id)
153 register_no_return_funcs();
154 register_ignored_macros();
155 register_parameter_implications();