For what it is worth, here is a semantic patch that creates the debug 
wrappers of functions like you described.  It could be adapted to insert 
other kinds of asserts.  I just decided to assert that all pointer-typed 
parameters are not NULL.

Semantic patch:

@r@
identifier f;
fresh identifier ff = "_called_function_";
parameter list pl;
type T;
@@

  T 
- f
+ ff
  (pl) { ... }
+ T f(pl) { return ff(); }

@script:ocaml s@
(_,pl) << r.pl;
ff << r.ff;
newargs;
@@

newargs := String.concat ", "
  (List.map
   (function pt ->
     match (Ast_c.unwrap pt).Ast_c.p_namei with
       None -> failwith "bad param"
     | Some nm -> Ast_c.str_of_name nm)
    pl)

@@
identifier s.newargs;
identifier r.ff;
@@

  ff(
+ newargs
  )

@t@
identifier r.ff;
identifier x;
type T;
@@

ff(..., T *x, ...) { ... }

@@
identifier r.f, r.ff, t.x;
@@

f(...) {
++ assert(x != NULL);
   ...
   return ff(...);  // be sure this is the right function
} 

Note that this semantic patch code uses the access to the abstract syntax 
tree like Nicolas described.  This is because there is no good way to 
convert a list of parameters to a list of just the declared variable 
names.  It could also have been done in a more ad hoc manner by parsing 
the string representing the parameter list in the ocaml (or python, in 
this case) code.

The test program is then as follows:

#ifdef FIRST
int main (int a, struct foo *b, struct bar *c) {
  a = b->x;
  return c->d;
}
#else
int main (int a, struct foo *xyz) {
  a = xyz->x;
  return xyz->d;
}
#endif

And the resulting program is:

#ifdef FIRST
int _called_function_0 (int a, struct foo *b, struct bar *c) {
  a = b->x;
  return c->d;
}

int main(int a, struct foo *b, struct bar *c) {
  assert(c != NULL);
  assert(b != NULL);
  return _called_function_0(a, b, c);
}
#else
int _called_function_1 (int a, struct foo *xyz) {
  a = xyz->x;
  return xyz->d;
}

int main(int a, struct foo *xyz) {
  assert(xyz != NULL);
  return _called_function_1(a, xyz);
}
#endif

This, however, changes the line numbers.  It could be possible to find the 
last function in the file and put all of the new wrapper functions after 
that one.

julia
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to