+let rec drop_end_comma = function
+ [] -> []
+ | [x] -> [x]
+ | ((Comma ",") as x) :: rest ->
+ let (newlines,rest2) = Common.span is_whitespace rest in
+ (match rest2 with
+ (Cocci2 _) :: _ -> x :: drop_end_comma rest
+ | _ -> drop_end_comma rest)
+ | x :: xs -> x :: drop_end_comma xs
+
+(* The following only works for the outermost function call. Stack records
+the column of all open parentheses. Space_cell contains the most recent
+comma in the outermost function call. The goal is to decide whether this
+should be followed by a space or a newline and indent. *)
+let add_newlines toks tabbing_unit =
+ let create_indent n =
+ let (tu,tlen) =
+ match tabbing_unit with
+ Some ("\t",_) -> ("\t",8)
+ | Some ("",_) -> ("\t",8) (* not sure why... *)
+ | Some (s,_) -> (s,String.length s) (* assuming only spaces *)
+ | None -> ("\t",8) in
+ let rec loop seen =
+ if seen + tlen <= n
+ then tu ^ loop (seen + tlen)
+ else String.make (n-seen) ' ' in
+ loop 0 in
+ let check_for_newline count x = function
+ Some (start,space_cell) when count > Flag_parsing_c.max_width ->
+ space_cell := "\n"^(create_indent x);
+ Some (x + (count - start))
+ | _ -> None in
+ (* the following is for strings that may contain newline *)
+ let string_length s count =
+ let l = list_of_string s in
+ List.fold_left
+ (function count ->
+ function
+ '\t' -> count + 8
+ | '\n' -> 0
+ | c -> count + 1)
+ count l in
+ let rec loop info count = function
+ [] -> []
+ | ((T2(tok,_,_)) as a)::xs ->
+ a :: loop info (string_length (TH.str_of_tok tok) count) xs
+ | ((Cocci2(s,line,lcol,rcol,hint)) as a)::xs ->
+ let (stack,space_cell) = info in
+ let rest =
+ match hint with
+ None -> loop info (count + (String.length s)) xs
+ | Some Unparse_cocci.StartBox ->
+ let count = count + (String.length s) in
+ loop (count::stack,space_cell) count xs
+ | Some Unparse_cocci.EndBox ->
+ let count = count + (String.length s) in
+ (match stack with
+ [x] ->
+ (match check_for_newline count x space_cell with
+ Some count -> loop ([],None) count xs
+ | None -> loop ([],None) count xs)
+ | _ -> loop (List.tl stack,space_cell) count xs)
+ | Some (Unparse_cocci.SpaceOrNewline sp) ->
+ let count = count + (String.length s) + 1 (*space*) in
+ (match stack with
+ [x] ->
+ (match check_for_newline count x space_cell with
+ Some count -> loop (stack,Some (x,sp)) count xs
+ | None -> loop (stack,Some (count,sp)) count xs)
+ | _ -> loop info count xs) in
+ a :: rest
+ | ((C2(s)) as a)::xs -> a :: loop info (string_length s count) xs
+ | ((Comma(s)) as a)::xs -> a :: loop info (string_length s count) xs
+ | Fake2 :: _ | Indent_cocci2 :: _
+ | Unindent_cocci2 _::_ ->
+ failwith "unexpected fake, indent, or unindent" in
+ let redo_spaces prev = function
+ Cocci2(s,line,lcol,rcol,Some (Unparse_cocci.SpaceOrNewline sp)) ->
+ C2 !sp :: Cocci2(s,line,lcol,rcol,None) :: prev
+ | t -> t::prev in
+ (match !Flag_parsing_c.spacing with
+ Flag_parsing_c.SMPL -> toks
+ | _ -> List.rev (List.fold_left redo_spaces [] (loop ([],None) 0 toks)))