2 * Copyright (C) 2014 Oracle.
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 * Some helper functions for managing links.
24 #include "smatch_slist.h"
26 static struct smatch_state
*alloc_link(struct var_sym_list
*links
)
28 struct smatch_state
*state
;
29 static char buf
[256] = "";
33 state
= __alloc_smatch_state(0);
35 FOR_EACH_PTR(links
, tmp
) {
36 cnt
+= snprintf(buf
+ cnt
, sizeof(buf
) - cnt
, "%s%s",
37 cnt
? ", " : "", tmp
->var
);
38 if (cnt
>= sizeof(buf
))
40 } END_FOR_EACH_PTR(tmp
);
43 state
->name
= alloc_sname(buf
);
48 struct smatch_state
*merge_link_states(struct smatch_state
*s1
, struct smatch_state
*s2
)
50 struct var_sym_list
*new_links
;
57 if (var_sym_lists_equiv(s1
->data
, s2
->data
))
60 new_links
= clone_var_sym_list(s1
->data
);
61 merge_var_sym_list(&new_links
, s2
->data
);
63 return alloc_link(new_links
);
66 void store_link(int link_id
, const char *var
, struct symbol
*sym
, const char *link_name
, struct symbol
*link_sym
)
69 struct smatch_state
*old_state
;
70 struct var_sym_list
*links
;
75 old_state
= get_state(link_id
, var
, sym
);
77 links
= clone_var_sym_list(old_state
->data
);
81 add_var_sym(&links
, link_name
, link_sym
);
82 set_state(link_id
, var
, sym
, alloc_link(links
));
85 static void match_link_modify(struct sm_state
*sm
, struct expression
*mod_expr
)
87 struct var_sym_list
*links
;
90 links
= sm
->state
->data
;
92 FOR_EACH_PTR(links
, tmp
) {
93 set_state(sm
->owner
- 1, tmp
->var
, tmp
->sym
, &undefined
);
94 } END_FOR_EACH_PTR(tmp
);
95 set_state(sm
->owner
, sm
->name
, sm
->sym
, &undefined
);
98 void set_up_link_functions(int id
, int link_id
)
100 if (id
+ 1 != link_id
)
101 sm_fatal("FATAL ERROR: links need to be registered directly after the check");
103 set_dynamic_states(link_id
);
104 add_merge_hook(link_id
, &merge_link_states
);
105 add_modification_hook(link_id
, &match_link_modify
);
106 // free link at the end of function