Release coccinelle-0.1.1
[bpt/coccinelle.git] / parsing_cocci / parse_cocci.ml
index 45938ff..b661baf 100644 (file)
@@ -194,8 +194,11 @@ let token2c (tok,_) =
   | PC.TArobArob -> "@@"
   | PC.TArob -> "@"
   | PC.TPArob -> "P@"
+  | PC.TScript -> "script"
 
   | PC.TWhen(clt) -> "WHEN"^(line_type2c clt)
+  | PC.TWhenTrue(clt) -> "WHEN TRUE"^(line_type2c clt)
+  | PC.TWhenFalse(clt) -> "WHEN FALSE"^(line_type2c clt)
   | PC.TAny(clt) -> "ANY"^(line_type2c clt)
   | PC.TStrict(clt) -> "STRICT"^(line_type2c clt)
   | PC.TEllipsis(clt) -> "..."^(line_type2c clt)
@@ -231,6 +234,7 @@ let token2c (tok,_) =
   | PC.TCBrace(clt) -> "}"^(line_type2c clt)
   | PC.TOCro(clt) -> "["^(line_type2c clt)
   | PC.TCCro(clt) -> "]"^(line_type2c clt)
+  | PC.TOInit(clt) -> "{"^(line_type2c clt)
 
   | PC.TPtrOp(clt) -> "->"^(line_type2c clt)
 
@@ -302,13 +306,15 @@ let plus_attachable (tok,_) =
   | PC.TMetaStmList(_,_,clt)  | PC.TMetaFunc(_,_,_,clt) 
   | PC.TMetaLocalFunc(_,_,_,clt)
 
-  | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  | PC.TWhen(clt) |  PC.TWhenTrue(clt) |  PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
   (* | PC.TCircles(clt) | PC.TStars(clt) *)
 
   | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) 
   | PC.TCPar(clt)
 
   | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt)
+  | PC.TOInit(clt) 
 
   | PC.TPtrOp(clt)
 
@@ -361,13 +367,15 @@ let get_clt (tok,_) =
   | PC.TMetaStmList(_,_,clt)  | PC.TMetaFunc(_,_,_,clt) 
   | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
 
-  | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) |
+    PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
   (* | PC.TCircles(clt) | PC.TStars(clt) *)
 
   | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) 
   | PC.TCPar(clt)
 
   | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt)
+  | PC.TOInit(clt)
 
   | PC.TPtrOp(clt)
 
@@ -469,6 +477,8 @@ let update_clt (tok,x) clt =
   | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x)
 
   | PC.TWhen(_) -> (PC.TWhen(clt),x)
+  | PC.TWhenTrue(_) -> (PC.TWhenTrue(clt),x)
+  | PC.TWhenFalse(_) -> (PC.TWhenFalse(clt),x)
   | PC.TAny(_) -> (PC.TAny(clt),x)
   | PC.TStrict(_) -> (PC.TStrict(clt),x)
   | PC.TEllipsis(_) -> (PC.TEllipsis(clt),x)
@@ -501,6 +511,7 @@ let update_clt (tok,x) clt =
   | PC.TCBrace(_) -> (PC.TCBrace(clt),x)
   | PC.TOCro(_) -> (PC.TOCro(clt),x)
   | PC.TCCro(_) -> (PC.TCCro(clt),x)
+  | PC.TOInit(_) -> (PC.TOInit(clt),x)
 
   | PC.TPtrOp(_) -> (PC.TPtrOp(clt),x)
 
@@ -605,11 +616,12 @@ let split_token ((tok,_) as t) =
   | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt)
   | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
   | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt
-  | PC.TMPtVirg | PC.TArob | PC.TArobArob -> ([t],[t])
+  | PC.TMPtVirg | PC.TArob | PC.TArobArob | PC.TScript -> ([t],[t])
   | PC.TPArob | PC.TMetaPos(_,_,_,_) -> ([t],[])
 
   | PC.TFunDecl(clt)
-  | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt)
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt)
   | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) -> split t clt
 
   | PC.TOEllipsis(_) | PC.TCEllipsis(_) (* clt must be context *)
@@ -635,7 +647,7 @@ let split_token ((tok,_) as t) =
   | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
   | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt
 
-  | PC.TOBrace(clt) | PC.TCBrace(clt) -> split t clt
+  | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOInit(clt) -> split t clt
   | PC.TOCro(clt) | PC.TCCro(clt) -> split t clt
 
   | PC.TPtrOp(clt) -> split t clt
@@ -728,7 +740,8 @@ let detect_types in_meta_decls l =
       (PC.TOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *)
     | (PC.TPOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *)
     | (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *)
-    | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TCBrace(_),_)
+    | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TOInit(_),_)
+    | (PC.TCBrace(_),_)
     | (PC.TPure,_) | (PC.TContext,_)
     | (PC.Tstatic(_),_) | (PC.Textern(_),_)
     | (PC.Tinline(_),_) | (PC.Ttypedef(_),_) | (PC.Tattr(_),_) -> true
@@ -841,7 +854,8 @@ let token2line (tok,_) =
   | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
 
   | PC.TFunDecl(clt)
-  | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
   (* | PC.TCircles(clt) | PC.TStars(clt) *)
 
   | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) 
@@ -853,6 +867,7 @@ let token2line (tok,_) =
   | PC.TCPar0(clt) 
 
   | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) 
+  | PC.TOInit(clt)
 
   | PC.TPtrOp(clt) 
 
@@ -897,6 +912,43 @@ and find_line_end inwhen line clt q = function
   | x::xs when token2line x = line -> x :: (find_line_end inwhen line clt q xs)
   | xs -> (PC.TLineEnd(clt),q)::(insert_line_end xs)
 
+let rec translate_when_true_false = function
+    [] -> []
+  | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("true",_),_)::xs ->
+      (PC.TWhenTrue(clt),q)::x::xs
+  | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("false",_),_)::xs ->
+      (PC.TWhenFalse(clt),q)::x::xs
+  | x::xs -> x :: (translate_when_true_false xs)
+
+(* ----------------------------------------------------------------------- *)
+(* top level initializers: a sequence of braces followed by a dot *)
+
+let find_top_init tokens =
+  match tokens with
+    (PC.TOBrace(clt),q) :: rest ->
+      let rec dot_start acc = function
+         ((PC.TOBrace(_),_) as x) :: rest ->
+           dot_start (x::acc) rest
+       | ((PC.TDot(_),_) :: rest) as x ->
+           Some ((PC.TOInit(clt),q) :: (List.rev acc) @ x)
+       | l -> None in
+      let rec comma_end acc = function
+         ((PC.TCBrace(_),_) as x) :: rest ->
+           comma_end (x::acc) rest
+       | ((PC.TComma(_),_) :: rest) as x ->
+           Some ((PC.TOInit(clt),q) :: (List.rev x) @ acc)
+       | l -> None in
+      (match dot_start [] rest with
+       Some x -> x
+      |        None ->
+         (match List.rev rest with
+           ((PC.EOF,_) as x)::rest ->
+             (match comma_end [x] rest with
+               Some x -> x
+             | None -> tokens)
+         | _ -> failwith "unexpected empty token list"))
+  | _ -> tokens
+
 (* ----------------------------------------------------------------------- *)
 (* process pragmas: they can only be used in + code, and adjacent to
 another + token.  They are concatenated to the string representation of
@@ -1068,8 +1120,10 @@ let parse_one str parsefn file toks =
   | e -> raise e
 
 let prepare_tokens tokens =
-  insert_line_end
-    (detect_types false (find_function_names (detect_attr tokens)))
+  find_top_init
+    (translate_when_true_false (* after insert_line_end *)
+       (insert_line_end
+         (detect_types false (find_function_names (detect_attr tokens)))))
 
 let rec consume_minus_positions = function
     [] -> []