Add poc files
This commit is contained in:
parent
30da2412e3
commit
fa600b98f7
220 changed files with 45679 additions and 0 deletions
755
lang_cpp/parsing/parsing_hacks_pp.ml
Normal file
755
lang_cpp/parsing/parsing_hacks_pp.ml
Normal file
|
|
@ -0,0 +1,755 @@
|
|||
(* Yoann Padioleau
|
||||
*
|
||||
* Copyright (C) 2002-2008 Yoann Padioleau
|
||||
* Copyright (C) 2011 Facebook
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License (GPL)
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* file license.txt for more details.
|
||||
*)
|
||||
open Common
|
||||
|
||||
module Flag = Flag_parsing_cpp
|
||||
module Ast = Ast_cpp
|
||||
|
||||
module TH = Token_helpers_cpp
|
||||
module TV = Token_views_cpp
|
||||
module Parser = Parser_cpp
|
||||
module PI = Parse_info
|
||||
|
||||
open Parser_cpp
|
||||
open Token_views_cpp
|
||||
|
||||
open Parsing_hacks_lib
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Prelude *)
|
||||
(*****************************************************************************)
|
||||
(*
|
||||
* This file gathers parsing heuristics related to the C preprocessor cpp.
|
||||
*)
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Helpers *)
|
||||
(*****************************************************************************)
|
||||
|
||||
let (==~) = Common2.(==~)
|
||||
|
||||
(* the pair is the status of '()' and '{}', ex: (-1,0)
|
||||
* if too much ')' and good '{}'
|
||||
* could do for [] too ?
|
||||
* could do for ',' if encounter ',' at "toplevel", not inside () or {}
|
||||
* then if have ifdef, then certainly can lead to a problem.
|
||||
*)
|
||||
let (count_open_close_stuff_ifdef_clause: ifdef_grouped list -> (int * int)) =
|
||||
fun xs ->
|
||||
let cnt_paren, cnt_brace = ref 0, ref 0 in
|
||||
xs +> iter_token_ifdef (fun x ->
|
||||
(match x.t with
|
||||
| x when TH.is_opar x -> incr cnt_paren
|
||||
| x when TH.is_obrace x -> incr cnt_brace
|
||||
| x when TH.is_cpar x -> decr cnt_paren
|
||||
| x when TH.is_obrace x -> decr cnt_brace
|
||||
| _ -> ()
|
||||
)
|
||||
);
|
||||
!cnt_paren, !cnt_brace
|
||||
|
||||
(* look if there is a '{' just after the closing ')', and handling the
|
||||
* possibility to have nested expressions inside nested parenthesis
|
||||
*)
|
||||
(*
|
||||
let is_really_foreach xs =
|
||||
let rec is_foreach_aux = function
|
||||
| [] -> false, []
|
||||
| TCPar _::TOBrace _::xs -> true, xs
|
||||
(* the following attempts to handle the cases where there is a
|
||||
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
|
||||
| TCPar _::Tfor _::xs -> true, xs
|
||||
| TCPar _::Tswitch _::xs -> true, xs
|
||||
|
||||
| TCPar _::xs -> false, xs
|
||||
| TOPar _::xs ->
|
||||
let (_, xs') = is_foreach_aux xs in
|
||||
is_foreach_aux xs'
|
||||
| x::xs -> is_foreach_aux xs
|
||||
in
|
||||
is_foreach_aux xs +> fst
|
||||
*)
|
||||
|
||||
(* TODO: set_ifdef_parenthize_info ?? from parsing_c/ *)
|
||||
|
||||
let filter_pp_or_comment_stuff xs =
|
||||
let rec aux xs =
|
||||
match xs with
|
||||
| [] -> []
|
||||
| x::xs ->
|
||||
(match x.TV.t with
|
||||
| tok when TH.is_comment tok ->
|
||||
aux xs
|
||||
(* don't want drop the define, or if drop, have to drop
|
||||
* also its body otherwise the line heuristics may be lost
|
||||
* by not finding the TDefine in column 0 but by finding
|
||||
* a TDefineIdent in a column > 0
|
||||
*
|
||||
* todo? but define often contain some unbalanced {
|
||||
*)
|
||||
| Parser.TDefine _ ->
|
||||
x::aux xs
|
||||
| tok when TH.is_pp_instruction tok ->
|
||||
aux xs
|
||||
| _ ->
|
||||
x::aux xs
|
||||
)
|
||||
in
|
||||
aux xs
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Ifdef keeping/passing *)
|
||||
(*****************************************************************************)
|
||||
|
||||
(* #if 0, #if 1, #if LINUX_VERSION handling *)
|
||||
let rec find_ifdef_bool xs =
|
||||
xs +> List.iter (function
|
||||
| NotIfdefLine _ -> ()
|
||||
| Ifdefbool (is_ifdef_positif, xxs, info_ifdef_stmt) ->
|
||||
|
||||
if is_ifdef_positif
|
||||
then pr2_pp "commenting parts of a #if 1 or #if LINUX_VERSION"
|
||||
else pr2_pp "commenting a #if 0 or #if LINUX_VERSION or __cplusplus";
|
||||
|
||||
(match xxs with
|
||||
| [] -> raise Impossible
|
||||
| firstclause::xxs ->
|
||||
info_ifdef_stmt +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
|
||||
if is_ifdef_positif
|
||||
then xxs +> List.iter
|
||||
(iter_token_ifdef (set_as_comment Token_cpp.CppOther))
|
||||
else begin
|
||||
firstclause +> iter_token_ifdef (set_as_comment Token_cpp.CppOther);
|
||||
(match List.rev xxs with
|
||||
(* keep only last *)
|
||||
| _last::startxs ->
|
||||
startxs +> List.iter
|
||||
(iter_token_ifdef (set_as_comment Token_cpp.CppOther))
|
||||
| [] -> (* not #else *) ()
|
||||
);
|
||||
end
|
||||
);
|
||||
|
||||
| Ifdef (xxs, _info_ifdef_stmt) -> xxs +> List.iter find_ifdef_bool
|
||||
)
|
||||
|
||||
|
||||
|
||||
let thresholdIfdefSizeMid = 6
|
||||
|
||||
(* infer ifdef involving not-closed expressions/statements *)
|
||||
let rec find_ifdef_mid xs =
|
||||
xs +> List.iter (function
|
||||
| NotIfdefLine _ -> ()
|
||||
| Ifdef (xxs, info_ifdef_stmt) ->
|
||||
(match xxs with
|
||||
| [] -> raise Impossible
|
||||
| [_first] -> ()
|
||||
| _first::second::rest ->
|
||||
(* don't analyse big ifdef *)
|
||||
if xxs +> List.for_all
|
||||
(fun xs -> List.length xs <= thresholdIfdefSizeMid) &&
|
||||
(* don't want nested ifdef *)
|
||||
xxs +> List.for_all (fun xs ->
|
||||
xs +> List.for_all
|
||||
(function NotIfdefLine _ -> true | _ -> false)
|
||||
)
|
||||
|
||||
then
|
||||
let counts = xxs +> List.map count_open_close_stuff_ifdef_clause in
|
||||
let cnt1, cnt2 = List.hd counts in
|
||||
if cnt1 <> 0 || cnt2 <> 0
|
||||
(*???? && counts +> List.for_all (fun x -> x = (cnt1, cnt2)) *)
|
||||
(*
|
||||
if counts +> List.exists (fun (cnt1, cnt2) ->
|
||||
cnt1 <> 0 || cnt2 <> 0
|
||||
)
|
||||
*)
|
||||
then begin
|
||||
pr2_pp "found ifdef-mid-something";
|
||||
(* keep only first, treat the rest as comment *)
|
||||
info_ifdef_stmt +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
(second::rest) +> List.iter
|
||||
(iter_token_ifdef (set_as_comment Token_cpp.CppOther));
|
||||
end
|
||||
|
||||
);
|
||||
List.iter find_ifdef_mid xxs
|
||||
|
||||
(* no need complex analysis for ifdefbool *)
|
||||
| Ifdefbool (_, xxs, _info_ifdef_stmt) ->
|
||||
List.iter find_ifdef_mid xxs
|
||||
)
|
||||
|
||||
|
||||
let thresholdFunheaderLimit = 4
|
||||
|
||||
(* ifdef defining alternate function header, type *)
|
||||
let rec find_ifdef_funheaders = function
|
||||
| [] -> ()
|
||||
| NotIfdefLine _::xs -> find_ifdef_funheaders xs
|
||||
|
||||
(* ifdef-funheader if ifdef with 2 lines and a '{' in next line *)
|
||||
| Ifdef
|
||||
([(NotIfdefLine (({col = 0} as _xline1)::_line1))::ifdefblock1;
|
||||
(NotIfdefLine (({col = 0} as xline2)::line2))::ifdefblock2
|
||||
], info_ifdef_stmt
|
||||
)
|
||||
::NotIfdefLine (({t=TOBrace _i; col = 0})::_line3)
|
||||
::xs
|
||||
when List.length ifdefblock1 <= thresholdFunheaderLimit &&
|
||||
List.length ifdefblock2 <= thresholdFunheaderLimit
|
||||
->
|
||||
find_ifdef_funheaders xs;
|
||||
info_ifdef_stmt +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
let all_toks = [xline2] @ line2 in
|
||||
all_toks +> List.iter (set_as_comment Token_cpp.CppOther) ;
|
||||
ifdefblock2 +> iter_token_ifdef (set_as_comment Token_cpp.CppOther);
|
||||
|
||||
(* ifdef with nested ifdef *)
|
||||
| Ifdef
|
||||
([[NotIfdefLine (({col = 0} as _xline1)::_line1)];
|
||||
[Ifdef
|
||||
([[NotIfdefLine (({col = 0} as xline2)::line2)];
|
||||
[NotIfdefLine (({col = 0} as xline3)::line3)];
|
||||
], info_ifdef_stmt2
|
||||
)
|
||||
]
|
||||
], info_ifdef_stmt
|
||||
)
|
||||
::NotIfdefLine (({t=TOBrace _i; col = 0})::_line4)
|
||||
::xs
|
||||
->
|
||||
find_ifdef_funheaders xs;
|
||||
info_ifdef_stmt +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
info_ifdef_stmt2 +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
let all_toks = [xline2;xline3] @ line2 @ line3 in
|
||||
all_toks +> List.iter (set_as_comment Token_cpp.CppOther);
|
||||
|
||||
(* ifdef with elseif *)
|
||||
| Ifdef
|
||||
([[NotIfdefLine (({col = 0} as _xline1)::_line1)];
|
||||
[NotIfdefLine (({col = 0} as xline2)::line2)];
|
||||
[NotIfdefLine (({col = 0} as xline3)::line3)];
|
||||
], info_ifdef_stmt
|
||||
)
|
||||
::NotIfdefLine (({t=TOBrace _i; col = 0})::_line4)
|
||||
::xs
|
||||
->
|
||||
find_ifdef_funheaders xs;
|
||||
info_ifdef_stmt +> List.iter (set_as_comment Token_cpp.CppDirective);
|
||||
let all_toks = [xline2;xline3] @ line2 @ line3 in
|
||||
all_toks +> List.iter (set_as_comment Token_cpp.CppOther)
|
||||
|
||||
|
||||
| Ifdef (xxs,_)::xs
|
||||
| Ifdefbool (_, xxs,_)::xs ->
|
||||
List.iter find_ifdef_funheaders xxs;
|
||||
find_ifdef_funheaders xs
|
||||
|
||||
|
||||
(*
|
||||
let adjust_inifdef_include xs =
|
||||
xs +> List.iter (function
|
||||
| NotIfdefLine _ -> ()
|
||||
| Ifdef (xxs, info_ifdef_stmt) | Ifdefbool (_, xxs, info_ifdef_stmt) ->
|
||||
xxs +> List.iter (iter_token_ifdef (fun tokext ->
|
||||
match tokext.t with
|
||||
| Parser.TInclude (s1, s2, ii) ->
|
||||
(* todo: inifdef_ref := true; *)
|
||||
()
|
||||
| _ -> ()
|
||||
));
|
||||
)
|
||||
*)
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Builtin macros using standard.h or other defs *)
|
||||
(*****************************************************************************)
|
||||
(* now in pp_token.ml *)
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Stringification *)
|
||||
(*****************************************************************************)
|
||||
|
||||
let rec find_string_macro_paren xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
| Parenthised(xxs, _)::xs ->
|
||||
xxs +> List.iter (fun xs ->
|
||||
if xs +> List.exists
|
||||
(function PToken({t=TString _}) -> true | _ -> false) &&
|
||||
xs +> List.for_all
|
||||
(function PToken({t=TString _}) | PToken({t=TIdent _}) ->
|
||||
true | _ -> false)
|
||||
then
|
||||
xs +> List.iter (fun tok ->
|
||||
match tok with
|
||||
| PToken({t=TIdent (_s,_)} as id) ->
|
||||
change_tok id (TIdent_MacroString (TH.info_of_tok id.t))
|
||||
| _ -> ()
|
||||
)
|
||||
else
|
||||
find_string_macro_paren xs
|
||||
);
|
||||
find_string_macro_paren xs
|
||||
| PToken _ ::xs ->
|
||||
find_string_macro_paren xs
|
||||
|
||||
|
||||
(*****************************************************************************)
|
||||
(* Macros *)
|
||||
(*****************************************************************************)
|
||||
|
||||
(* don't forget to recurse in each case.
|
||||
* note that the code below is called after the ifdef phase simplification,
|
||||
* so if this previous phase is buggy, then it may pass some code that
|
||||
* could be matched by the following rules but will not.
|
||||
**)
|
||||
let rec find_macro_paren xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
|
||||
(* attribute *)
|
||||
| PToken ({t=Tattribute _} as id)
|
||||
::Parenthised (xxs,info_parens)
|
||||
::xs
|
||||
->
|
||||
pr2_pp ("MACRO: __attribute detected ");
|
||||
[Parenthised (xxs, info_parens)] +>
|
||||
iter_token_paren (set_as_comment Token_cpp.CppAttr);
|
||||
set_as_comment Token_cpp.CppAttr id;
|
||||
find_macro_paren xs
|
||||
|
||||
(* stringification
|
||||
*
|
||||
* the order of the matching clause is important
|
||||
*
|
||||
*)
|
||||
|
||||
(* string macro with params, before case *)
|
||||
| PToken ({t=TString _})::PToken ({t=TIdent (_s,_)} as id)
|
||||
::Parenthised (xxs, info_parens)
|
||||
::xs ->
|
||||
change_tok id (TIdent_MacroString (TH.info_of_tok id.t));
|
||||
[Parenthised (xxs, info_parens)] +>
|
||||
iter_token_paren (set_as_comment Token_cpp.CppMacro);
|
||||
find_macro_paren xs
|
||||
|
||||
(* after case *)
|
||||
| PToken ({t=TIdent (_s,_)} as id)
|
||||
::Parenthised (xxs, info_parens)
|
||||
::PToken ({t=TString _})
|
||||
::xs ->
|
||||
change_tok id (TIdent_MacroString (TH.info_of_tok id.t));
|
||||
[Parenthised (xxs, info_parens)] +>
|
||||
iter_token_paren (set_as_comment Token_cpp.CppMacro);
|
||||
find_macro_paren xs
|
||||
|
||||
|
||||
(* for the case where the string is not inside a funcall, but
|
||||
* for instance in an initializer.
|
||||
*)
|
||||
|
||||
(* string macro variable, before case *)
|
||||
| PToken ({t=TString ((str,_),_)})::PToken ({t=TIdent (_s,_)} as id)
|
||||
::xs ->
|
||||
|
||||
(* c++ext: *)
|
||||
if str <> "C" then begin
|
||||
change_tok id (TIdent_MacroString (TH.info_of_tok id.t));
|
||||
find_macro_paren xs
|
||||
end
|
||||
(* bugfix, forgot to recurse in else case too ... *)
|
||||
else
|
||||
find_macro_paren xs
|
||||
|
||||
(* after case *)
|
||||
| PToken ({t=TIdent (_s,_)} as id)::PToken ({t=TString _})
|
||||
::xs ->
|
||||
change_tok id (TIdent_MacroString (TH.info_of_tok id.t));
|
||||
find_macro_paren xs
|
||||
|
||||
(* TODO: cooperating with standard.h *)
|
||||
| PToken ({t=TIdent (s,_i1)} as id)::xs
|
||||
when s = "MACROSTATEMENT" ->
|
||||
change_tok id (TIdent_MacroStmt(TH.info_of_tok id.t));
|
||||
find_macro_paren xs
|
||||
|
||||
|
||||
|
||||
(* recurse *)
|
||||
| (PToken _x)::xs -> find_macro_paren xs
|
||||
| (Parenthised (xxs, _))::xs ->
|
||||
xxs +> List.iter find_macro_paren;
|
||||
find_macro_paren xs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(* don't forget to recurse in each case *)
|
||||
let rec find_macro_lineparen xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
|
||||
(* firefoxext: ex: NS_DECL_NSIDOMNODELIST *)
|
||||
| (Line ([PToken ({t=TIdent (s,_)} as macro);]))::xs
|
||||
when s ==~ regexp_ns_decl_like ->
|
||||
set_as_comment Token_cpp.CppMacro macro;
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
(* firefoxext: ex: NS_DECL_NSIDOMNODELIST; *)
|
||||
| (Line ([PToken ({t=TIdent (s,_)} as macro);
|
||||
PToken ({t=TPtVirg _})]))::xs
|
||||
when s ==~ regexp_ns_decl_like ->
|
||||
set_as_comment Token_cpp.CppMacro macro;
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
(* firefoxext: ex: NS_IMPL_XXX(a) *)
|
||||
| (Line ([PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (xxs,info_parens);
|
||||
]))::xs
|
||||
when s ==~ regexp_ns_decl_like ->
|
||||
|
||||
[Parenthised (xxs, info_parens)] +>
|
||||
iter_token_paren (set_as_comment Token_cpp.CppMacro);
|
||||
set_as_comment Token_cpp.CppMacro macro;
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
|
||||
(* linuxext: ex: static [const] DEVICE_ATTR(); *)
|
||||
| (Line
|
||||
(
|
||||
[PToken ({t=Tstatic _});
|
||||
PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (_xxs,_);
|
||||
PToken ({t=TPtVirg _});
|
||||
]
|
||||
))::xs
|
||||
when (s ==~ regexp_macro) ->
|
||||
let info = TH.info_of_tok macro.t in
|
||||
change_tok macro (TIdent_MacroDecl (PI.str_of_info info, info));
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
(* the static const case *)
|
||||
| (Line
|
||||
(
|
||||
[PToken ({t=Tstatic _});
|
||||
PToken ({t=Tconst _} as const);
|
||||
PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (_xxs,_info_parens);
|
||||
PToken ({t=TPtVirg _});
|
||||
]
|
||||
(*as line1*)
|
||||
|
||||
))
|
||||
::xs
|
||||
when (s ==~ regexp_macro) ->
|
||||
let info = TH.info_of_tok macro.t in
|
||||
change_tok macro (TIdent_MacroDecl (PI.str_of_info info, info));
|
||||
|
||||
(* need retag this const, otherwise ambiguity in grammar
|
||||
21: shift/reduce conflict (shift 121, reduce 137) on Tconst
|
||||
decl2 : Tstatic . TMacroDecl TOPar argument_list TCPar ...
|
||||
decl2 : Tstatic . Tconst TMacroDecl TOPar argument_list TCPar ...
|
||||
storage_class_spec : Tstatic . (137)
|
||||
*)
|
||||
change_tok const (Tconst_MacroDeclConst (TH.info_of_tok const.t));
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
|
||||
(* same but without trailing ';'
|
||||
*
|
||||
* I do not put the final ';' because it can be on a multiline and
|
||||
* because of the way mk_line is coded, we will not have access to
|
||||
* this ';' on the next line, even if next to the ')' *)
|
||||
| (Line
|
||||
([PToken ({t=Tstatic _});
|
||||
PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (_xxs,_);
|
||||
]
|
||||
))::xs
|
||||
when s ==~ regexp_macro ->
|
||||
|
||||
let info = TH.info_of_tok macro.t in
|
||||
change_tok macro (TIdent_MacroDecl (PI.str_of_info info, info));
|
||||
|
||||
find_macro_lineparen (xs)
|
||||
|
||||
|
||||
|
||||
|
||||
(* on multiple lines *)
|
||||
| (Line
|
||||
(
|
||||
(PToken ({t=Tstatic _})::[]
|
||||
)))
|
||||
::(Line
|
||||
(
|
||||
[PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (_,_);
|
||||
PToken ({t=TPtVirg _});
|
||||
]
|
||||
)
|
||||
)::xs
|
||||
when (s ==~ regexp_macro) ->
|
||||
let info = TH.info_of_tok macro.t in
|
||||
change_tok macro (TIdent_MacroDecl (PI.str_of_info info, info));
|
||||
|
||||
find_macro_lineparen xs
|
||||
|
||||
|
||||
(* linuxext: ex: DECLARE_BITMAP();
|
||||
*
|
||||
* Here I use regexp_declare and not regexp_macro because
|
||||
* Sometimes it can be a FunCallMacro such as DEBUG(foo());
|
||||
* Here we don't have the preceding 'static' so only way to
|
||||
* not have positive is to restrict to .*DECLARE.* macros.
|
||||
*
|
||||
* but there is a grammar rule for that, so don't need this case anymore
|
||||
* unless the parameter of the DECLARE_xxx are wierd and can not be mapped
|
||||
* on a argument_list
|
||||
*)
|
||||
|
||||
| (Line
|
||||
([PToken ({t=TIdent (s,_)} as macro);
|
||||
Parenthised (_,_);
|
||||
PToken ({t=TPtVirg _});
|
||||
]
|
||||
))::xs
|
||||
when (s ==~ regexp_declare) ->
|
||||
|
||||
let info = TH.info_of_tok macro.t in
|
||||
change_tok macro (TIdent_MacroDecl (PI.str_of_info info, info));
|
||||
|
||||
find_macro_lineparen xs
|
||||
|
||||
(* toplevel macros.
|
||||
* module_init(xxx)
|
||||
*
|
||||
* Could also transform the TIdent in a TMacroTop but can have false
|
||||
* positive, so easier to just change the TCPar and so just solve
|
||||
* the end-of-stream pb of ocamlyacc
|
||||
*)
|
||||
| (Line
|
||||
([PToken ({t=TIdent (_s,_ii); col = col1; where = ctx} as _macro);
|
||||
Parenthised (_,info_parens);
|
||||
] as _line1
|
||||
))
|
||||
::xs when col1 = 0
|
||||
->
|
||||
let condition =
|
||||
(* to reduce number of false positive *)
|
||||
(match xs with
|
||||
| (Line (PToken ({col = col2 } as other)::_restline2))::_ ->
|
||||
TH.is_eof other.t || (col2 = 0 &&
|
||||
(match other.t with
|
||||
| TOBrace _ -> false (* otherwise would match funcdecl *)
|
||||
| TCBrace _ when List.hd ctx <> InFunction -> false
|
||||
| TPtVirg _
|
||||
| TCol _
|
||||
-> false
|
||||
| tok when TH.is_binary_operator tok -> false
|
||||
|
||||
| _ -> true
|
||||
)
|
||||
)
|
||||
| _ -> false
|
||||
)
|
||||
in
|
||||
if condition
|
||||
then begin
|
||||
(* just to avoid the end-of-stream pb of ocamlyacc *)
|
||||
let tcpar = Common2.list_last info_parens in
|
||||
change_tok tcpar (TCPar_EOL (TH.info_of_tok tcpar.t));
|
||||
(*macro.t <- TMacroTop (s, TH.info_of_tok macro.t);*)
|
||||
end;
|
||||
find_macro_lineparen xs
|
||||
|
||||
|
||||
|
||||
(* macro with parameters
|
||||
* ex: DEBUG()
|
||||
* return x;
|
||||
*)
|
||||
| (Line
|
||||
([PToken ({t=TIdent (_s,_ii); col = col1; where = ctx} as macro);
|
||||
Parenthised (xxs,info_parens);
|
||||
] as _line1
|
||||
))
|
||||
::(Line
|
||||
(PToken ({col = col2 } as other)::_restline2
|
||||
) as line2)
|
||||
::xs
|
||||
(* when s ==~ regexp_macro *)
|
||||
->
|
||||
let condition =
|
||||
(col1 = col2 &&
|
||||
(match other.t with
|
||||
| TOBrace _ -> false (* otherwise would match funcdecl *)
|
||||
| TCBrace _ when List.hd ctx <> InFunction -> false
|
||||
| TPtVirg _
|
||||
| TCol _
|
||||
-> false
|
||||
| tok when TH.is_binary_operator tok -> false
|
||||
|
||||
| _ -> true
|
||||
)
|
||||
)
|
||||
||
|
||||
(col2 <= col1 &&
|
||||
(match other.t with
|
||||
| TCBrace _ when List.hd ctx = InFunction -> true
|
||||
| Treturn _ -> true
|
||||
| Tif _ -> true
|
||||
| Telse _ -> true
|
||||
|
||||
| _ -> false
|
||||
)
|
||||
)
|
||||
|
||||
in
|
||||
|
||||
if condition
|
||||
then
|
||||
if col1 = 0 then ()
|
||||
else begin
|
||||
change_tok macro (TIdent_MacroStmt (TH.info_of_tok macro.t));
|
||||
[Parenthised (xxs, info_parens)] +>
|
||||
iter_token_paren (set_as_comment Token_cpp.CppMacro);
|
||||
end;
|
||||
|
||||
find_macro_lineparen (line2::xs)
|
||||
|
||||
(* linuxext:? single macro
|
||||
* ex: LOCK
|
||||
* foo();
|
||||
* UNLOCK
|
||||
*)
|
||||
| (Line
|
||||
([PToken ({t=TIdent (_s,_ii); col = col1; where = ctx} as macro);
|
||||
] as _line1
|
||||
))
|
||||
::(Line
|
||||
(PToken ({col = col2 } as other)::_restline2
|
||||
) as line2)
|
||||
::xs ->
|
||||
(* when s ==~ regexp_macro *)
|
||||
|
||||
let condition =
|
||||
(col1 = col2 &&
|
||||
col1 <> 0 && (* otherwise can match typedef of fundecl*)
|
||||
(match other.t with
|
||||
| TPtVirg _ -> false
|
||||
| TOr _ -> false
|
||||
| TCBrace _ when List.hd ctx <> InFunction -> false
|
||||
| tok when TH.is_binary_operator tok -> false
|
||||
|
||||
| _ -> true
|
||||
)) ||
|
||||
(col2 <= col1 &&
|
||||
(match other.t with
|
||||
| TCBrace _ when List.hd ctx = InFunction -> true
|
||||
| Treturn _ -> true
|
||||
| Tif _ -> true
|
||||
| Telse _ -> true
|
||||
| _ -> false
|
||||
))
|
||||
in
|
||||
|
||||
if condition
|
||||
then change_tok macro (TIdent_MacroStmt (TH.info_of_tok macro.t));
|
||||
|
||||
find_macro_lineparen (line2::xs)
|
||||
|
||||
| _x::xs ->
|
||||
find_macro_lineparen xs
|
||||
|
||||
|
||||
(*****************************************************************************)
|
||||
(* #Define tobrace init *)
|
||||
(*****************************************************************************)
|
||||
|
||||
let is_init tok2 tok3 =
|
||||
match tok2.t, tok3.t with
|
||||
| TInt _, TComma _ -> true
|
||||
| TString _, TComma _ -> true
|
||||
| TIdent _, TComma _ -> true
|
||||
| _ -> false
|
||||
|
||||
let find_define_init_brace_paren xs =
|
||||
let rec aux xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
|
||||
(* mainly for firefox *)
|
||||
| (PToken {t=TDefine _})
|
||||
::(PToken {t=TIdent_Define (_s,_)})
|
||||
::(PToken ({t=TOBrace i1} as tokbrace))
|
||||
::(PToken tok2)
|
||||
::(PToken tok3)
|
||||
::xs ->
|
||||
if is_init tok2 tok3
|
||||
then change_tok tokbrace (TOBrace_DefineInit i1);
|
||||
aux xs
|
||||
|
||||
(* mainly for linux, especially in sound/ *)
|
||||
| (PToken {t=TDefine _})
|
||||
::(PToken {t=TIdent_Define (s,_); col=c})
|
||||
::(Parenthised(_, {col=c2; _}::_))
|
||||
::(PToken ({t=TOBrace i1} as tokbrace))
|
||||
::(PToken tok2)
|
||||
::(PToken tok3)
|
||||
::xs when c2 = c + String.length s ->
|
||||
if is_init tok2 tok3
|
||||
then change_tok tokbrace (TOBrace_DefineInit i1);
|
||||
|
||||
aux xs
|
||||
|
||||
(* ugly: for plan9, too general? *)
|
||||
| (PToken {t=TDefine _})
|
||||
::(PToken {t=TIdent_Define (_s,_)})
|
||||
::(Parenthised(_xxx, _))
|
||||
::(PToken ({t=TOBrace i1} as tokbrace))
|
||||
(* can be more complex expression than just an int, like (b)&... *)
|
||||
::(Parenthised(_, _))
|
||||
::(PToken {t=(TAnd _|TOr _);_})
|
||||
::xs ->
|
||||
change_tok tokbrace (TOBrace_DefineInit i1);
|
||||
aux xs
|
||||
|
||||
(* recurse *)
|
||||
| (PToken _)::xs -> aux xs
|
||||
| (Parenthised (_, _))::xs ->
|
||||
(* not need for tobrace init:
|
||||
* xxs +> List.iter aux;
|
||||
*)
|
||||
aux xs
|
||||
in
|
||||
aux xs
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue