2 * sparse/smatch_modification_hooks.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
13 #include "smatch_slist.h"
21 static modification_hook
**hooks
;
22 static modification_hook
**indirect_hooks
; /* parent struct modified etc */
24 void add_modification_hook(int owner
, modification_hook
*call_back
)
26 hooks
[owner
] = call_back
;
29 void add_indirect_modification_hook(int owner
, modification_hook
*call_back
)
31 indirect_hooks
[owner
] = call_back
;
34 static int matches(char *name
, struct symbol
*sym
, struct sm_state
*sm
)
42 if (strncmp(sm
->name
, name
, len
) == 0) {
43 if (sm
->name
[len
] == '\0')
45 if (sm
->name
[len
] == '-' || sm
->name
[len
] == '.')
46 return match_indirect
;
48 if (sm
->name
[0] != '*')
50 if (strncmp(sm
->name
+ 1, name
, len
) == 0) {
51 if (sm
->name
[len
+ 1] == '\0')
52 return match_indirect
;
53 if (sm
->name
[len
+ 1] == '-' || sm
->name
[len
+ 1] == '.')
54 return match_indirect
;
59 static void call_modification_hooks(struct expression
*expr
)
63 struct state_list
*slist
;
67 name
= get_variable_from_expr(expr
, &sym
);
70 slist
= __get_cur_slist();
72 FOR_EACH_PTR(slist
, sm
) {
73 if (sm
->owner
> num_checks
)
75 match
= matches(name
, sym
, sm
);
77 if (match
&& hooks
[sm
->owner
])
78 (hooks
[sm
->owner
])(sm
);
80 if (match
== match_indirect
&& indirect_hooks
[sm
->owner
])
81 (indirect_hooks
[sm
->owner
])(sm
);
82 } END_FOR_EACH_PTR(sm
);
87 static void match_assign(struct expression
*expr
)
89 call_modification_hooks(expr
->left
);
92 static void unop_expr(struct expression
*expr
)
94 if (expr
->op
!= SPECIAL_DECREMENT
&& expr
->op
!= SPECIAL_INCREMENT
)
97 expr
= strip_expr(expr
->unop
);
98 call_modification_hooks(expr
);
101 static void match_call(struct expression
*expr
)
103 struct expression
*arg
, *tmp
;
105 FOR_EACH_PTR(expr
->args
, arg
) {
106 tmp
= strip_expr(arg
);
107 if (tmp
->type
!= EXPR_PREOP
|| tmp
->op
!= '&')
109 tmp
= strip_expr(tmp
->unop
);
110 call_modification_hooks(tmp
);
111 } END_FOR_EACH_PTR(arg
);
114 void register_modification_hooks(int id
)
116 hooks
= malloc((num_checks
+ 1) * sizeof(*hooks
));
117 memset(hooks
, 0, (num_checks
+ 1) * sizeof(*hooks
));
118 indirect_hooks
= malloc((num_checks
+ 1) * sizeof(*hooks
));
119 memset(indirect_hooks
, 0, (num_checks
+ 1) * sizeof(*hooks
));
121 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
122 add_hook(&unop_expr
, OP_HOOK
);
125 void register_modification_hooks_late(int id
)
127 add_hook(&match_call
, FUNCTION_CALL_HOOK
);