> > > #ifdef UNITTESTS
> > > ...
> > > #endif
> > >
> > > I would like to be able to not do matches on this part of the code. Is
> > > their an easy way to do so ?
> >
> > No. The matching process doesn't see the ifdefs. There is a notion of
> > skipping code that is under #if 0. It could indeed be nice to generalize
> > that to other constants. Ideally, we would do partial evaluations as
> > well, ie if we know that X is undefined, then perhaps X && Y is also
> > undefined. I can look into it.
>
> That could be great. I'm sure it could help in a lot of situation for
> example changing API for a single OS on a complex project.
Attached is a patch that works for #ifdef and #ifndef. In your case, you
would give spatch the argument --undefined UNITTESTS. It should then
ignode the code under #ifdef UNITTESTS. You can also specify several
names, eg --defined FOO,BAR,XXX. The names should be separated by commas,
but not spaces.
Interpretation of #if is not supported. Actually, the arguments to #if
are not parsed, so it would be quite a bit more work. But it is probably
not impossible to handle as well.
julia
diff --git a/parsing_c/lexer_c.mll b/parsing_c/lexer_c.mll
index 1feebe0..80e609e 100644
--- a/parsing_c/lexer_c.mll
+++ b/parsing_c/lexer_c.mll
@@ -490,10 +490,20 @@ rule token = parse
(* can have some ifdef 0 hence the letter|digit even at beginning of word *)
- | "#" [' ''\t']* "ifdef" [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*
- { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
- | "#" [' ''\t']* "ifndef" [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*
- { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
+ | "#" [' ''\t']* "ifdef" [' ''\t']+
+ (((letter|digit) ((letter|digit)*)) as x) [' ''\t']*
+ { if List.mem x !Flag_parsing_c.undefined
+ then TIfdefBool (false, no_ifdef_mark(), tokinfo lexbuf)
+ else if List.mem x !Flag_parsing_c.defined
+ then TIfdefBool (true, no_ifdef_mark(), tokinfo lexbuf)
+ else TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
+ | "#" [' ''\t']* "ifndef" [' ''\t']+
+ (((letter|digit) ((letter|digit)*)) as x) [' ''\t']*
+ { if List.mem x !Flag_parsing_c.defined
+ then TIfdefBool (false, no_ifdef_mark(), tokinfo lexbuf)
+ else if List.mem x !Flag_parsing_c.undefined
+ then TIfdefBool (true, no_ifdef_mark(), tokinfo lexbuf)
+ else TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
| "#" [' ''\t']* "if" [' ' '\t']+
{ let info = tokinfo lexbuf in
TIfdef (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf))
diff --git a/parsing_c/flag_parsing_c.ml b/parsing_c/flag_parsing_c.ml
index cdb5df1..6b17c34 100644
--- a/parsing_c/flag_parsing_c.ml
+++ b/parsing_c/flag_parsing_c.ml
@@ -169,6 +169,11 @@ let disable_add_typedef = ref false
let if0_passing = ref true
let add_typedef_root = ref true
+(* defined and undefined constants *)
+let add c s = c := (Str.split (Str.regexp ",") s) @ !c
+let defined = ref ([] : string list)
+let undefined = ref ([] : string list)
+
let cmdline_flags_parsing_algos () = [
"--directive-passing", Arg.Set cpp_directive_passing,
diff --git a/main.ml b/main.ml
index 129c390..ef131eb 100644
--- a/main.ml
+++ b/main.ml
@@ -565,8 +565,10 @@ let other_options = [
"--disable-multi-pass", Arg.Set Flag_parsing_c.disable_multi_pass, " ";
- "--noif0-passing", Arg.Clear Flag_parsing_c.if0_passing,
- " ";
+ "--noif0-passing", Arg.Clear Flag_parsing_c.if0_passing, " ";
+ "--defined", Arg.String (Flag_parsing_c.add Flag_parsing_c.defined), " ";
+ "--undefined", Arg.String
+ (Flag_parsing_c.add Flag_parsing_c.undefined), " ";
"--noadd-typedef-root", Arg.Clear Flag_parsing_c.add_typedef_root, " ";
(* could use Flag_parsing_c.options_algo instead *)
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)