| "u8" | "u16" | "u32" | "u64"
| "s8" | "s16" | "s32" | "s64"
| "__u8" | "__u16" | "__u32" | "__u64"
- -> true
+ -> true
| "acpi_handle"
| "acpi_status"
| "UTS_RELEASE"
| "SIZE_STR"
| "DMA_STR"
- -> true
+ -> true
(* s when s =~ ".*STR.*" -> true *)
| _ -> false
)
(* 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: *)
let not_annot s =
not (s ==~ regexp_annot)
+let is_macro s =
+ s ==~ regexp_macro
+let not_macro s =
+ not (is_macro s)
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
| TIfdefBool (_, tag, _)
| TIfdefMisc (_, tag, _)
- | TIfdefVersion (_, tag, _)
- ->
- tag := Some cnt;
+ | TIfdefVersion (_, tag, _) ->
+ tag := Some cnt;
- | _ -> raise Impossible
+ | _ -> raise (Impossible 89)
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
* 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
)
};
(* 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;
}
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));
| NotIfdefLine _ -> ()
| Ifdef (xxs, info_ifdef_stmt) ->
(match xxs with
- | [] -> raise Impossible
+ | [] -> raise (Impossible 91)
| [first] -> ()
| first::second::rest ->
(* don't analyse big ifdef *)
| NotIfdefLine _ -> ()
| Ifdef (xxs, info_ifdef_stmt) ->
(match xxs with
- | [] -> raise Impossible
+ | [] -> raise (Impossible 92)
| [first] -> ()
| first::second::rest ->
+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 *)
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
let lookahead2 ~pass next before =
match (next, before) with
-
+
(* c++ hacks *)
(* yy xx( and in function *)
| TOPar i1::_, TIdent(s,i2)::TypedefIdent _::_
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)
| (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)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
+
msg_typedef s i1 5; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
+
msg_typedef s i1 6; LP.add_typedef_root s;
TypedefIdent (s, i1)
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;
(* ( 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)
when not_struct_enum before
&& ok_typedef s
->
+
msg_typedef s i1 11; LP.add_typedef_root s;
TypedefIdent (s, i1)
when (LP.current_context() =*= LP.InParameter)
&& ok_typedef s
->
+
msg_typedef s i1 12; LP.add_typedef_root s;
TypedefIdent (s, i1)
(Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when
pointer ptr && ok_typedef s
->
+
msg_typedef s i1 13; LP.add_typedef_root s;
TypedefIdent (s, i1)
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)
&& (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)
(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)
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)
when not_struct_enum before
&& ok_typedef s && pointer ptr
->
+
msg_typedef s i1 21; LP.add_typedef_root s;
TypedefIdent (s, i1)
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)
(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)
(TOBrace _| TPtVirg _)::_) when
ok_typedef s && pointer ptr
->
+
msg_typedef s i1 24; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* struct user_info_t sometimes *)
&& ok_typedef s && pointer ptr
->
+
msg_typedef s i1 25; LP.add_typedef_root s;
TypedefIdent (s, i1)
| (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)
&& ok_typedef s
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
->
+
msg_typedef s i1 27; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
+
msg_typedef s i1 28; LP.add_typedef_root s;
TypedefIdent (s, i1)
&& 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)
(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)
| (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)
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)
when not_struct_enum before
&& ok_typedef s
->
+
msg_typedef s i1 34; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s
->
+
msg_typedef s i1 35; LP.add_typedef_root s;
TypedefIdent (s, i1)
as x)
::_, _
->
+
(*
if not !Flag_parsing_c.ifdef_to_if
then TCommentCpp (Ast_c.CppIfDirective, ii)
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)