- Try to do better pretty printing when array elements are individually
[bpt/coccinelle.git] / parsing_c / parsing_hacks.ml
index 9d05efe..c3ac6b7 100644 (file)
@@ -62,7 +62,7 @@ let is_known_typdef =
       | "u8" | "u16" | "u32" | "u64"
       | "s8"  | "s16" | "s32" | "s64"
       | "__u8" | "__u16" | "__u32"  | "__u64"
-          -> true
+        -> true
 
       | "acpi_handle"
       | "acpi_status"
@@ -182,7 +182,7 @@ let msg_stringification s =
       | "UTS_RELEASE"
       | "SIZE_STR"
       | "DMA_STR"
-          -> true
+        -> true
       (* s when s =~ ".*STR.*" -> true  *)
       | _ -> false
       )
@@ -239,15 +239,15 @@ let msg_attribute s =
 
 (* opti: better to built then once and for all, especially regexp_foreach *)
 
-let regexp_macro =  Str.regexp
+let regexp_macro = Str.regexp
   "^[A-Z_][A-Z_0-9]*$"
 
 (* linuxext: *)
-let regexp_annot =  Str.regexp
+let regexp_annot = Str.regexp
   "^__.*$"
 
 (* linuxext: *)
-let regexp_declare =  Str.regexp
+let regexp_declare = Str.regexp
   ".*DECLARE.*"
 
 (* linuxext: *)
@@ -266,6 +266,10 @@ let ok_typedef s = not (List.mem s false_typedef)
 
 let not_annot s =
   not (s ==~ regexp_annot)
+let is_macro s =
+  s ==~ regexp_macro
+let not_macro s =
+  not (is_macro s)
 
 
 
@@ -313,7 +317,7 @@ let rec is_really_foreach xs =
         single statement in the body of the loop.  undoubtedly more
         cases are needed.
          todo: premier(statement) - suivant(funcall)
-      *)
+       *)
     | TCPar _::TIdent _::xs -> true, xs
     | TCPar _::Tif _::xs -> true, xs
     | TCPar _::Twhile _::xs -> true, xs
@@ -341,11 +345,10 @@ let set_ifdef_token_parenthize_info cnt x =
 
     | TIfdefBool (_, tag, _)
     | TIfdefMisc (_, tag, _)
-    | TIfdefVersion (_, tag, _)
-        ->
-        tag := Some cnt;
+    | TIfdefVersion (_, tag, _) ->
+       tag := Some cnt;
 
-    | _ -> raise Impossible
+    | _ -> raise (Impossible 89)
 
 
 
@@ -410,6 +413,7 @@ let mark_end_define ii =
         Common.charpos = Ast_c.pos_of_info ii + 1
       };
       cocci_tag = ref Ast_c.emptyAnnot;
+      annots_tag = Token_annot.empty;
       comments_tag = ref Ast_c.emptyComments;
     }
   in
@@ -509,23 +513,18 @@ let rec define_ident acc xs =
        * body (it would be a recursive macro, which is forbidden).
        *)
 
-      | TCommentSpace i1::t::xs ->
-
+      | TCommentSpace i1::t::xs
+       when TH.str_of_tok t ==~ Common.regexp_alpha
+       ->
           let s = TH.str_of_tok t in
           let ii = TH.info_of_tok t in
-          if s ==~ Common.regexp_alpha
-          then begin
-            pr2 (spf "remapping: %s to an ident in macro name" s);
-           let acc = (TCommentSpace i1) :: acc in
-           let acc = (TIdentDefine (s,ii)) :: acc in
-            define_ident acc xs
-          end
-          else begin
-            pr2 "WEIRD: weird #define body";
-            define_ident acc xs
-          end
-
-      | _ ->
+         pr2 (spf "remapping: %s to an ident in macro name" s);
+          let acc = (TCommentSpace i1) :: acc in
+         let acc = (TIdentDefine (s,ii)) :: acc in
+          define_ident acc xs
+          
+      | TCommentSpace _::_::xs
+      | xs ->
           pr2 "WEIRD: weird #define body";
           define_ident acc xs
       )
@@ -575,6 +574,7 @@ let new_info posadd str ii =
       };
     (* must generate a new ref each time, otherwise share *)
     cocci_tag = ref Ast_c.emptyAnnot;
+    annots_tag = Token_annot.empty;
     comments_tag = ref Ast_c.emptyComments;
    }
 
@@ -672,7 +672,7 @@ let rec find_ifdef_bool xs =
       msg_ifdef_bool_passing is_ifdef_positif;
 
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 90)
       | firstclause::xxs ->
           info_ifdef_stmt +>
          List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
@@ -706,7 +706,7 @@ let rec find_ifdef_mid xs =
   | NotIfdefLine _ -> ()
   | Ifdef (xxs, info_ifdef_stmt) ->
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 91)
       | [first] -> ()
       | first::second::rest ->
           (* don't analyse big ifdef *)
@@ -852,7 +852,7 @@ let rec find_ifdef_cparen_else xs =
   | NotIfdefLine _ -> ()
   | Ifdef (xxs, info_ifdef_stmt) ->
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 92)
       | [first] -> ()
       | first::second::rest ->
 
@@ -1652,6 +1652,20 @@ let fix_tokens_cpp ~macro_defs a =
 
 
 
+let can_be_on_top_level tl =
+  match tl with
+  | Tstruct _
+  | Ttypedef _
+  | TDefine _ 
+  | TIfdef _
+  | TIfdefelse _
+  | TIfdefelif _
+  | TIfdefBool _
+  | TIfdefMisc _
+  | TIfdefVersion _
+  | TEndif _ -> true
+  | _ -> false
+
 
 (*****************************************************************************)
 (* Lexing with lookahead *)
@@ -1695,12 +1709,42 @@ let ident = function
     TIdent _ -> true
   | _ -> false
 
+let is_type = function
+  | TypedefIdent _ 
+  | Tvoid _
+  | Tchar _
+  | Tfloat _
+  | Tdouble _
+      (* christia: not sure what these are? *)
+  | Tsize_t _
+  | Tssize_t _
+  | Tptrdiff_t _
+      
+  | Tint _
+  | Tlong _
+  | Tshort _ -> true
+  | _ -> false
+
+let is_cparen = function (TCPar _) -> true | _ -> false
+let is_oparen = function (TOPar _) -> true | _ -> false
+
+let rec not_has_type_before f xs =
+  match xs with
+  | [] -> raise (Impossible 666)
+  | x :: xs ->
+      if f x then
+       true
+      else if is_type x then
+       false
+      else
+       not_has_type_before f xs
+
 (* This function is inefficient, because it will look over a K&R header,
 or function prototype multiple times.  At least when we see a , and are in a
 parameter list, we know we will eventually see a close paren, and it
 should come fairly soon. *)
 let k_and_r l =
-  let l1 = drop_until (function (TCPar _) -> true | _ -> false) l in
+  let l1 = drop_until is_cparen l in
   match l1 with
     (TCPar _) :: (TOCro _) :: _ -> false
   | (TCPar _) :: _ -> true
@@ -1722,7 +1766,7 @@ let paren_before_comma l =
 
 let lookahead2 ~pass next before =
   match (next, before) with
-
+    
   (* c++ hacks *)
   (* yy xx(   and in function *)
   | TOPar i1::_,              TIdent(s,i2)::TypedefIdent _::_
@@ -1751,17 +1795,95 @@ let lookahead2 ~pass next before =
       if !Flag_parsing_c.debug_typedef
       then pr2 ("TYPEDEF: disable typedef cos special case: " ^ s);
 
-      LP.disable_typedef();
 
+      LP.disable_typedef();
       msg_typedef s i1 1; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
+       (* christia *)
+       (* xx const tt *)
+  | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::type_::_  , _) when not_struct_enum before
+      && is_type type_
+        ->
+
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* xx struct *)
+  | (TIdent (s, i1)::Tstruct _::_  , _) when not_struct_enum before
+        ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* xx tt *)
+  | (TIdent (s, i1)::type_::_  , _) when not_struct_enum before
+      && is_type type_
+        ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* tt xx yy *)
+  | (TIdent (s, i1)::TIdent (s2, i2)::_  , seen::_) when not_struct_enum before
+      && is_type seen
+        ->
+         if is_macro s2 then
+           TIdent (s, i1)
+         else
+           TCommentCpp (Token_c.CppDirective, i1)
+
+  | (TIdent (s2, i2)::_  , TIdent (s, i1)::seen::_) when not_struct_enum before
+      && is_macro s2 && is_type seen
+        ->
+         TCommentCpp (Token_c.CppDirective, i2)
+
+       (* tt xx * *)
+  | (TIdent (s, i1)::ptr::_  , seen::_) when not_struct_enum before
+      && pointer ptr && is_type seen
+        ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* tt * xx yy *)
+  | (TIdent (s, i1)::TIdent(s2, i2)::_  , ptr::_) when not_struct_enum before
+      && pointer ptr
+        ->
+         if is_macro s2 then
+           TIdent (s, i1)
+         else
+           TCommentCpp (Token_c.CppDirective, i1)
+
+       (* tt * xx yy *)
+  | (TIdent(s2, i2)::_  , TIdent (s, i1)::ptr::_) when not_struct_enum before
+      && is_macro s2 && pointer ptr
+        ->
+         TCommentCpp (Token_c.CppDirective, i2)
+
+        (* exception to next rule *)
+  | (TIdent(s2, i2)::TOPar _ :: _ , TIdent(s, i1)::seen::_) when not_struct_enum before
+      && is_macro s2 && is_type seen
+        ->
+         TIdent(s2, i2)
+       (* tt xx yy *)
+  | (TIdent(s2, i2)::_  , TIdent(s, i1)::seen::_) when not_struct_enum before
+      && is_macro s2 && is_type seen
+        ->
+         TCommentCpp (Token_c.CppDirective, i2)
+
+  (*  xx * yy      AND  in paramdecl *)
+  | (TIdent (s, i1)::ptr::TIdent (s2, i2)::_ , _)
+    when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
+      && pointer ptr && ok_typedef s
+      ->
+
+      msg_typedef s i1 14; LP.add_typedef_root s;
+      TypedefIdent (s, i1)
+
+  (* xx yy ( *)
+  | (TIdent (s, i1)::TIdent (s2, i2)::TOPar _::_  , _) when not_struct_enum before
+      && ok_typedef s && is_macro s2
+        ->
+         TIdent (s, i1)
   (* xx yy *)
   | (TIdent (s, i1)::TIdent (s2, i2)::_  , _) when not_struct_enum before
       && ok_typedef s
         ->
          (* && not_annot s2 BUT lead to false positive*)
-
       msg_typedef s i1 2; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1770,22 +1892,27 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::Tinline i2::_  , _) when not_struct_enum before
       && ok_typedef s
       ->
+
       msg_typedef s i1 3; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* [,(] xx [,)] AND param decl *)
   | (TIdent (s, i1)::(((TComma _|TCPar _)::_) as rest) ,
-     (TComma _ |TOPar _)::_ )
+     ((TComma _ |TOPar _)::_ as bef))
     when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
-      && k_and_r rest
+      && k_and_r rest 
+      && not_has_type_before is_cparen rest 
+      && not_has_type_before is_oparen bef
       ->
+
        TKRParam(s,i1)
 
   | (TIdent (s, i1)::((TComma _|TCPar _)::_) , (TComma _ |TOPar _)::_ )
     when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
       ->
+
        msg_typedef s i1 4; LP.add_typedef_root s;
        TypedefIdent (s, i1)
 
@@ -1796,6 +1923,7 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
+
       msg_typedef s i1 5; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1807,6 +1935,7 @@ let lookahead2 ~pass next before =
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
+
       msg_typedef s i1 6; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1838,6 +1967,7 @@ let lookahead2 ~pass next before =
       when pointer ptr && not_struct_enum before
       && ok_typedef s
       ->
+
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
 
       msg_typedef s i1 9; LP.add_typedef_root s;
@@ -1847,6 +1977,7 @@ let lookahead2 ~pass next before =
   (* ( const xx)  *)
   | (TIdent (s, i1)::TCPar _::_,  (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
       ok_typedef s ->
+
       msg_typedef s i1 10; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1857,6 +1988,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s
     ->
+
       msg_typedef s i1 11; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1865,6 +1997,7 @@ let lookahead2 ~pass next before =
       when (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
      ->
+
       msg_typedef s i1 12; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1878,6 +2011,7 @@ let lookahead2 ~pass next before =
      (Tregister _|Tstatic _  |Tvolatile _|Tconst _|Trestrict _)::_) when
       pointer ptr && ok_typedef s
         ->
+
       msg_typedef s i1 13; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1901,6 +2035,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before && pointer ptr &&
       (LP.is_top_or_struct (LP.current_context ()))
       ->
+
       msg_typedef s i1 15; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1919,6 +2054,7 @@ let lookahead2 ~pass next before =
       && (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer ptr
       ->
+
       msg_typedef s i1 17; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1929,6 +2065,7 @@ let lookahead2 ~pass next before =
       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer ptr
       ->
+
       msg_typedef s i1 18;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1937,6 +2074,7 @@ let lookahead2 ~pass next before =
     when       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s
       ->
+
       msg_typedef s i1 19;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1959,6 +2097,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s && pointer ptr
       ->
+
       msg_typedef s i1 21; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1968,6 +2107,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
       && ok_typedef s && pointer ptr
         ->
+
       msg_typedef s i1 22; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1977,6 +2117,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_)  when not_struct_enum before
       && ok_typedef s & pointer ptr
         ->
+
       msg_typedef s i1 23;  LP.add_typedef_root s;
       msg_maybe_dangereous_typedef s;
       TypedefIdent (s, i1)
@@ -1987,6 +2128,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_) when
       ok_typedef s && pointer ptr
     ->
+
       msg_typedef s i1 24; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -1997,6 +2139,7 @@ let lookahead2 ~pass next before =
         (* struct user_info_t sometimes *)
       && ok_typedef s && pointer ptr
         ->
+
       msg_typedef s i1 25; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2004,8 +2147,12 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::TMul _::TMul _::TIdent (s2, i2)::_ , _)
     when not_struct_enum before
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
-      && ok_typedef s
-      ->
+       && ok_typedef s
+       (* christia : this code catches 'a * *b' which is wrong 
+        *)
+       && true
+    ->
+
       msg_typedef s i1 26; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2015,6 +2162,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       ->
+
       msg_typedef s i1 27; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2024,6 +2172,7 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
       ->
+
       msg_typedef s i1 28; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2045,6 +2194,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
       && not (ident x) (* possible K&R declaration *)
       ->
+
       msg_typedef s i1 29; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s, i1)
@@ -2067,6 +2217,7 @@ let lookahead2 ~pass next before =
     (TOPar info)::(TEq _ |TEqEq _)::_)
     when ok_typedef s && paren_before_comma rest
         ->
+
       msg_typedef s i1 31; LP.add_typedef_root s;
       (* TOPar info *)
       TypedefIdent (s, i1)
@@ -2076,6 +2227,7 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_)
     when ok_typedef s && pointer ptr
         ->
+
       msg_typedef s i1 32; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s,i1)
@@ -2086,6 +2238,7 @@ let lookahead2 ~pass next before =
       when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x)
       && ok_typedef s
         ->
+
       msg_typedef s i1 33; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2103,6 +2256,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
+
       msg_typedef s i1 34; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2111,6 +2265,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
+
       msg_typedef s i1 35; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
@@ -2123,6 +2278,7 @@ let lookahead2 ~pass next before =
         as x)
     ::_, _
       ->
+
       (*
       if not !Flag_parsing_c.ifdef_to_if
       then TCommentCpp (Ast_c.CppIfDirective, ii)
@@ -2191,9 +2347,16 @@ let lookahead2 ~pass next before =
       end
       else TIdent (s, i1)
 
- (*-------------------------------------------------------------*)
+(*  (* christia: here insert support for macros on top level *)
+  | TIdent (s, ii) :: tl :: _, _ when
+    can_be_on_top_level tl && LP.current_context () = InTopLevel ->
+      pr2_cpp ("'" ^ s ^ "' looks like a macro, I treat it as comment");
+      TCommentCpp (Token_c.CppDirective, ii)
+*)      
+    
+(*-------------------------------------------------------------*)
  | v::xs, _ -> v
- | _ -> raise Impossible
+ | _ -> raise (Impossible 93)
 
 let lookahead ~pass a b =
   Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 ~pass a b)