748
747
| rest -> adjust_before_brace rest in
750
749
let xs = List.rev (from_newline (List.rev xs)) in
751
let cleanup_ifdefs toks =
752
(* TODO: these functions are horrid, but using tokens caused circularity *)
753
let is_ifdef = function
754
T2((Parser_c.TCommentCpp
755
(Token_c.CppIfDirective Token_c.IfDef, _)),m,idx) -> true
756
| T2((Parser_c.TCommentCpp
757
(Token_c.CppIfDirective Token_c.IfDef0, _)),m,idx) -> true
759
let is_else = function
760
T2((Parser_c.TCommentCpp
761
(Token_c.CppIfDirective Token_c.Else, _)),m,idx) -> true
763
let is_endif = function
764
T2((Parser_c.TCommentCpp
765
(Token_c.CppIfDirective Token_c.Endif, _)),m,idx) -> true
768
l::rest -> (t::l)::rest
769
| _ -> failwith "not possible" in
770
let rec parse_ifdef acc_keywords acc_code stack = function
771
[] -> (None,acc_keywords,acc_code)
772
| t::rest when is_else t ->
774
[] -> parse_ifdef (t::acc_keywords) ([]::acc_code) stack rest
775
| _ -> parse_ifdef acc_keywords (add t acc_code) stack rest)
776
| t::rest when is_endif t ->
778
[] -> ((Some (t,rest)),acc_keywords,acc_code)
779
| _::stack -> parse_ifdef acc_keywords (add t acc_code) stack rest)
780
| t::rest when is_ifdef t ->
781
parse_ifdef acc_keywords (add t acc_code) (()::stack) rest
782
| t::rest -> parse_ifdef acc_keywords (add t acc_code) stack rest in
783
let unminus = function
784
T2 (t,Min adj,idx) -> T2 (t,Ctx,idx)
786
let is_minus = function
787
T2 (t,Min adj,idx) -> true
789
let rec loop = function
791
| t::rest when is_ifdef t ->
792
let (ender,acc_keywords,acc_code) =
793
parse_ifdef [t] [[]] [] rest in
794
let acc_code = List.map loop acc_code in
795
let merge = (* args reversed *)
797
(fun prev kwd code -> kwd :: (List.rev code) @ prev)
800
None -> merge (List.map unminus acc_keywords) acc_code
801
| Some(endif,rest) ->
802
let rest = loop rest in
803
if List.for_all is_minus (endif::acc_keywords)
804
then (merge acc_keywords acc_code) @ (endif :: rest)
806
(merge (List.map unminus acc_keywords) acc_code) @
807
((unminus endif) :: rest))
808
| x::xs -> x :: loop xs in
811
let xs = cleanup_ifdefs xs in
751
812
let xs = drop_minus xs in
754
let cleanup_ifdefs toks =
755
(* TODO: these functions are horrid, but using tokens caused circularity *)
756
let is_ifdef0 = function
757
T2((Parser_c.TCommentCpp
758
(Token_c.CppIfDirective Token_c.IfDef0, _)),m,idx) -> true
760
let is_ifdef = function
761
T2((Parser_c.TCommentCpp
762
(Token_c.CppIfDirective Token_c.IfDef, _)),m,idx) -> true
763
| t -> is_ifdef0 t in
764
let is_endif = function
765
T2((Parser_c.TCommentCpp
766
(Token_c.CppIfDirective Token_c.Endif, _)),m,idx) -> true
768
(* only real comments *)
769
let is_whitespace_or_comment if0 = function
772
| Parser_c.TComment _ -> false (* previous pass chooses comments *)
773
| Parser_c.TCommentSpace _ -> true (* only whitespace *)
774
| Parser_c.TCommentNewline _ (* newline plus whitespace *)
775
| Parser_c.TCommentCpp (Token_c.CppIfDirective Token_c.Else, _) -> true
776
| Parser_c.TCommentCpp (Token_c.CppPassingNormal, _) -> if0
780
let rec loop prev if0s = function
782
| t::rest when is_ifdef0 t -> loop (t::prev) (true::if0s) rest
783
| t::rest when is_ifdef t -> loop (t::prev) (false::if0s) rest
784
| t::rest when is_endif t ->
786
[] -> loop (t::prev) if0s rest
789
Common.span (is_whitespace_or_comment tgt) prev in
791
t1::prest when is_ifdef t1 -> loop prest if0s rest
792
| _ -> loop (t::prev) [] rest)) (* failed, so drop if0 info *)
793
| x::xs -> loop (x::prev) if0s xs in
794
List.rev (loop [] [] toks)
796
815
(* things that should not be followed by space - boundary between SmPL
797
816
code and C code *)
798
817
let adjust_eat_space toks =