Release coccinelle-0.1.11rc1
[bpt/coccinelle.git] / parsing_c / pretty_print_c.ml
1 (* Yoann Padioleau, Julia Lawall
2 *
3 * Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes and DIKU
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License (GPL)
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * file license.txt for more details.
13 *)
14 open Common
15
16 open Ast_c
17
18 module F = Control_flow_c
19
20 (*****************************************************************************)
21 (* Wrappers *)
22 (*****************************************************************************)
23 let pr2, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_unparsing
24
25 (*****************************************************************************)
26 (* Types *)
27 (*****************************************************************************)
28
29 type type_with_ident =
30 (string * Ast_c.info) option ->
31 (Ast_c.storage * Ast_c.il) option ->
32 Ast_c.fullType ->
33 Ast_c.attribute list -> unit
34
35 type 'a printer = 'a -> unit
36
37 type pretty_printers = {
38 expression : Ast_c.expression printer;
39 arg_list : (Ast_c.argument Ast_c.wrap2 list) printer;
40 statement : Ast_c.statement printer;
41 decl : Ast_c.declaration printer;
42 init : Ast_c.initialiser printer;
43 param : Ast_c.parameterType printer;
44 ty : Ast_c.fullType printer;
45 type_with_ident : type_with_ident;
46 toplevel : Ast_c.toplevel printer;
47 flow : Control_flow_c.node printer
48 }
49
50
51
52 (*****************************************************************************)
53
54 (* This module is used by unparse_c, but because unparse_c have also
55 * the list of tokens, pretty_print_c could be useless in the future
56 * (except that the ast_c have some fake tokens not present in the list
57 * of tokens so it's still useful). But this module is also useful to
58 * unparse C when you don't have the ordered list of tokens separately,
59 * or tokens without position information, for instance when you want
60 * to pretty print some piece of C that was generated, or some
61 * abstract-lined piece of code, etc. *)
62
63 let mk_pretty_printers
64 ~pr_elem ~pr_space
65 ~pr_nl ~pr_indent ~pr_outdent ~pr_unindent
66 =
67 let start_block () = pr_nl(); pr_indent() in
68 let end_block () = pr_unindent(); pr_nl() in
69
70 let indent_if_needed st f =
71 match Ast_c.unwrap_st st with
72 Compound _ -> pr_space(); f()
73 | _ ->
74 (*no newline at the end - someone else will do that*)
75 start_block(); f(); pr_unindent() in
76
77
78
79
80 let rec pp_expression = fun ((exp, typ), ii) ->
81 (match exp, ii with
82 | Ident (ident), [] -> pp_name ident
83 (* only a MultiString can have multiple ii *)
84 | Constant (MultiString _), is -> is +> List.iter pr_elem
85 | Constant (c), [i] -> pr_elem i
86 | FunCall (e, es), [i1;i2] ->
87 pp_expression e; pr_elem i1;
88 pp_arg_list es;
89 pr_elem i2;
90
91 | CondExpr (e1, e2, e3), [i1;i2] ->
92 pp_expression e1; pr_space(); pr_elem i1; pr_space();
93 do_option (function x -> pp_expression x; pr_space()) e2; pr_elem i2;
94 pp_expression e3
95 | Sequence (e1, e2), [i] ->
96 pp_expression e1; pr_elem i; pr_space(); pp_expression e2
97 | Assignment (e1, op, e2), [i] ->
98 pp_expression e1; pr_space(); pr_elem i; pr_space(); pp_expression e2
99
100 | Postfix (e, op), [i] -> pp_expression e; pr_elem i;
101 | Infix (e, op), [i] -> pr_elem i; pp_expression e;
102 | Unary (e, op), [i] -> pr_elem i; pp_expression e
103 | Binary (e1, op, e2), [i] ->
104 pp_expression e1; pr_space(); pr_elem i; pr_space(); pp_expression e2
105
106 | ArrayAccess (e1, e2), [i1;i2] ->
107 pp_expression e1; pr_elem i1; pp_expression e2; pr_elem i2
108 | RecordAccess (e, name), [i1] ->
109 pp_expression e; pr_elem i1; pp_name name;
110 | RecordPtAccess (e, name), [i1] ->
111 pp_expression e; pr_elem i1; pp_name name;
112
113 | SizeOfExpr (e), [i] ->
114 pr_elem i;
115 (match Ast_c.unwrap e with
116 ParenExpr (e), _ -> ()
117 | _ -> pr_space());
118 pp_expression e
119 | SizeOfType (t), [i1;i2;i3] ->
120 pr_elem i1; pr_elem i2; pp_type t; pr_elem i3
121 | Cast (t, e), [i1;i2] ->
122 pr_elem i1; pp_type t; pr_elem i2; pp_expression e
123
124 | StatementExpr (statxs, [ii1;ii2]), [i1;i2] ->
125 pr_elem i1;
126 pr_elem ii1;
127 statxs +> List.iter pp_statement_seq;
128 pr_elem ii2;
129 pr_elem i2;
130 | Constructor (t, xs), lp::rp::i1::i2::iicommaopt ->
131 pr_elem lp;
132 pp_type t;
133 pr_elem rp;
134 pr_elem i1;
135 xs +> List.iter (fun (x, ii) ->
136 assert (List.length ii <= 1);
137 ii +> List.iter (function x -> pr_elem x; pr_space());
138 pp_init x
139 );
140 iicommaopt +> List.iter pr_elem;
141 pr_elem i2;
142
143 | ParenExpr (e), [i1;i2] -> pr_elem i1; pp_expression e; pr_elem i2;
144
145 | (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_)
146 | Sequence (_,_)
147 | Assignment (_,_,_)
148 | Postfix (_,_) | Infix (_,_) | Unary (_,_) | Binary (_,_,_)
149 | ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_)
150 | SizeOfExpr (_) | SizeOfType (_) | Cast (_,_)
151 | StatementExpr (_) | Constructor _
152 | ParenExpr (_)),_ -> raise Impossible
153 );
154
155 if !Flag_parsing_c.pretty_print_type_info
156 then begin
157 pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "/*");
158 !typ +>
159 (fun (ty,_test) -> ty +>
160 Common.do_option
161 (fun (x,l) -> pp_type x;
162 let s = match l with
163 Ast_c.LocalVar _ -> ", local"
164 | _ -> "" in
165 pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str s)));
166 pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "*/");
167 end
168
169 and pp_arg_list es =
170 es +> List.iter (fun (e, opt) ->
171 assert (List.length opt <= 1); (* opt must be a comma? *)
172 opt +> List.iter (function x -> pr_elem x; pr_space());
173 pp_argument e)
174
175 and pp_argument argument =
176 let rec pp_action (ActMisc ii) = ii +> List.iter pr_elem in
177 match argument with
178 | Left e -> pp_expression e
179 | Right weird ->
180 (match weird with
181 | ArgType param -> pp_param param
182 | ArgAction action -> pp_action action)
183
184 (* ---------------------- *)
185 and pp_name = function
186 | RegularName (s, ii) ->
187 let (i1) = Common.tuple_of_list1 ii in
188 pr_elem i1
189 | CppConcatenatedName xs ->
190 xs +> List.iter (fun ((x,ii1), ii2) ->
191 ii2 +> List.iter pr_elem;
192 ii1 +> List.iter pr_elem;
193 )
194 | CppVariadicName (s, ii) ->
195 ii +> List.iter pr_elem
196 | CppIdentBuilder ((s,iis), xs) ->
197 let (iis, iop, icp) = Common.tuple_of_list3 iis in
198 pr_elem iis;
199 pr_elem iop;
200 xs +> List.iter (fun ((x,iix), iicomma) ->
201 iicomma +> List.iter pr_elem;
202 iix +> List.iter pr_elem;
203 );
204 pr_elem icp
205
206 (* ---------------------- *)
207 and pp_statement = fun st ->
208 match Ast_c.get_st_and_ii st with
209 | Labeled (Label (name, st)), ii ->
210 let (i2) = Common.tuple_of_list1 ii in
211 pr_outdent(); pp_name name; pr_elem i2; pr_nl(); pp_statement st
212 | Labeled (Case (e, st)), [i1;i2] ->
213 pr_unindent();
214 pr_elem i1; pp_expression e; pr_elem i2; pr_nl(); pr_indent();
215 pp_statement st
216 | Labeled (CaseRange (e, e2, st)), [i1;i2;i3] ->
217 pr_unindent();
218 pr_elem i1; pp_expression e; pr_elem i2; pp_expression e2; pr_elem i3;
219 pr_nl(); pr_indent();
220 pp_statement st
221 | Labeled (Default st), [i1;i2] ->
222 pr_unindent(); pr_elem i1; pr_elem i2; pr_nl(); pr_indent();
223 pp_statement st
224 | Compound statxs, [i1;i2] ->
225 pr_elem i1; start_block();
226 statxs +> Common.print_between pr_nl pp_statement_seq;
227 end_block(); pr_elem i2;
228
229 | ExprStatement (None), [i] -> pr_elem i;
230 | ExprStatement (None), [] -> ()
231 | ExprStatement (Some e), [i] -> pp_expression e; pr_elem i
232 (* the last ExprStatement of a for does not have a trailing
233 ';' hence the [] for ii *)
234 | ExprStatement (Some e), [] -> pp_expression e;
235 | Selection (If (e, st1, st2)), i1::i2::i3::is ->
236 pr_elem i1; pr_space(); pr_elem i2; pp_expression e; pr_elem i3;
237 indent_if_needed st1 (function _ -> pp_statement st1);
238 (match (Ast_c.get_st_and_ii st2, is) with
239 | ((ExprStatement None, []), []) -> ()
240 | ((ExprStatement None, []), [iifakend]) -> pr_elem iifakend
241 | _st2, [i4;iifakend] -> pr_elem i4;
242 indent_if_needed st2 (function _ -> pp_statement st2);
243 pr_elem iifakend
244 | x -> raise Impossible
245 )
246 | Selection (Switch (e, st)), [i1;i2;i3;iifakend] ->
247 pr_elem i1; pr_space(); pr_elem i2; pp_expression e; pr_elem i3;
248 indent_if_needed st (function _-> pp_statement st); pr_elem iifakend
249 | Iteration (While (e, st)), [i1;i2;i3;iifakend] ->
250 pr_elem i1; pr_space(); pr_elem i2; pp_expression e; pr_elem i3;
251 indent_if_needed st (function _-> pp_statement st); pr_elem iifakend
252 | Iteration (DoWhile (st, e)), [i1;i2;i3;i4;i5;iifakend] ->
253 pr_elem i1;
254 indent_if_needed st (function _ -> pp_statement st);
255 pr_elem i2; pr_elem i3; pp_expression e;
256 pr_elem i4; pr_elem i5;
257 pr_elem iifakend
258
259
260 | Iteration (For ((e1opt,il1),(e2opt,il2),(e3opt, il3),st)),
261 [i1;i2;i3;iifakend] ->
262
263 pr_elem i1; pr_space();
264 pr_elem i2;
265 pp_statement (Ast_c.mk_st (ExprStatement e1opt) il1);
266 pp_statement (Ast_c.mk_st (ExprStatement e2opt) il2);
267 assert (null il3);
268 pp_statement (Ast_c.mk_st (ExprStatement e3opt) il3);
269 pr_elem i3;
270 indent_if_needed st (function _ -> pp_statement st);
271 pr_elem iifakend
272
273 | Iteration (MacroIteration (s,es,st)), [i1;i2;i3;iifakend] ->
274 pr_elem i1; pr_space();
275 pr_elem i2;
276
277 es +> List.iter (fun (e, opt) ->
278 assert (List.length opt <= 1);
279 opt +> List.iter pr_elem;
280 pp_argument e;
281 );
282
283 pr_elem i3;
284 indent_if_needed st (function _ -> pp_statement st);
285 pr_elem iifakend
286
287 | Jump (Goto name), ii ->
288 let (i1, i3) = Common.tuple_of_list2 ii in
289 pr_elem i1; pr_space(); pp_name name; pr_elem i3;
290 | Jump ((Continue|Break|Return)), [i1;i2] -> pr_elem i1; pr_elem i2;
291 | Jump (ReturnExpr e), [i1;i2] ->
292 pr_elem i1; pr_space(); pp_expression e; pr_elem i2
293 | Jump (GotoComputed e), [i1;i2;i3] ->
294 pr_elem i1; pr_elem i2; pp_expression e; pr_elem i3
295
296 | Decl decl, [] -> pp_decl decl
297 | Asm asmbody, ii ->
298 (match ii with
299 | [iasm;iopar;icpar;iptvirg] ->
300 pr_elem iasm; pr_elem iopar;
301 pp_asmbody asmbody;
302 pr_elem icpar; pr_elem iptvirg
303 | [iasm;ivolatile;iopar;icpar;iptvirg] ->
304 pr_elem iasm; pr_elem ivolatile; pr_elem iopar;
305 pp_asmbody asmbody;
306 pr_elem icpar; pr_elem iptvirg
307 | _ -> raise Impossible
308 )
309
310 | NestedFunc def, ii ->
311 assert (null ii);
312 pp_def def
313 | MacroStmt, ii ->
314 ii +> List.iter pr_elem ;
315
316 | (Labeled (Case (_,_))
317 | Labeled (CaseRange (_,_,_)) | Labeled (Default _)
318 | Compound _ | ExprStatement _
319 | Selection (If (_, _, _)) | Selection (Switch (_, _))
320 | Iteration (While (_, _)) | Iteration (DoWhile (_, _))
321 | Iteration (For ((_,_), (_,_), (_, _), _))
322 | Iteration (MacroIteration (_,_,_))
323 | Jump ((Continue|Break|Return)) | Jump (ReturnExpr _)
324 | Jump (GotoComputed _)
325 | Decl _
326 ), _ -> raise Impossible
327
328 and pp_statement_seq = function
329 | StmtElem st -> pp_statement st
330 | IfdefStmt ifdef -> pp_ifdef ifdef
331 | CppDirectiveStmt cpp -> pp_directive cpp
332 | IfdefStmt2 (ifdef, xxs) -> pp_ifdef_tree_sequence ifdef xxs
333
334 (* ifdef XXX elsif YYY elsif ZZZ endif *)
335 and pp_ifdef_tree_sequence ifdef xxs =
336 match ifdef with
337 | if1::ifxs ->
338 pp_ifdef if1;
339 pp_ifdef_tree_sequence_aux ifxs xxs
340 | _ -> raise Impossible
341
342 (* XXX elsif YYY elsif ZZZ endif *)
343 and pp_ifdef_tree_sequence_aux ifdefs xxs =
344 Common.zip ifdefs xxs +> List.iter (fun (ifdef, xs) ->
345 xs +> List.iter pp_statement_seq;
346 pp_ifdef ifdef
347 )
348
349
350
351
352
353 (* ---------------------- *)
354 and pp_asmbody (string_list, colon_list) =
355 string_list +> List.iter pr_elem ;
356 colon_list +> List.iter (fun (Colon xs, ii) ->
357 ii +> List.iter pr_elem;
358 xs +> List.iter (fun (x,iicomma) ->
359 assert ((List.length iicomma) <= 1);
360 iicomma +> List.iter (function x -> pr_elem x; pr_space());
361 (match x with
362 | ColonMisc, ii -> ii +> List.iter pr_elem;
363 | ColonExpr e, [istring;iopar;icpar] ->
364 pr_elem istring;
365 pr_elem iopar;
366 pp_expression e;
367 pr_elem icpar
368 | (ColonExpr _), _ -> raise Impossible)
369 ))
370
371
372 (* ---------------------- *)
373
374 (*
375 pp_type_with_ident
376 pp_base_type
377 pp_type_with_ident_rest
378 pp_type_left
379 pp_type_right
380 pp_type
381
382 pp_decl
383 *)
384 and (pp_type_with_ident:
385 (string * info) option -> (storage * il) option ->
386 fullType -> attribute list ->
387 unit) =
388 fun ident sto ft attrs ->
389 pp_base_type ft sto;
390 (match (ident, Ast_c.unwrap_typeC ft) with
391 (Some _,_) | (_,Pointer _) -> pr_space()
392 | _ -> ());
393 pp_type_with_ident_rest ident ft attrs
394
395
396 and (pp_base_type: fullType -> (storage * il) option -> unit) =
397 fun (qu, (ty, iity)) sto ->
398 let get_sto sto =
399 match sto with
400 | None -> [] | Some (s, iis) -> (*assert (List.length iis = 1);*) iis
401 in
402 let print_sto_qu (sto, (qu, iiqu)) =
403 let all_ii = get_sto sto ++ iiqu in
404 all_ii
405 +> List.sort Ast_c.compare_pos
406 +> Common.print_between pr_space pr_elem
407
408 in
409 let print_sto_qu_ty (sto, (qu, iiqu), iity) =
410 let all_ii = get_sto sto ++ iiqu ++ iity in
411 let all_ii2 = all_ii +> List.sort Ast_c.compare_pos in
412
413 if all_ii <> all_ii2
414 then begin
415 (* TODO in fact for pointer, the qualifier is after the type
416 * cf -test strangeorder
417 *)
418 pr2 "STRANGEORDER";
419 all_ii2 +> Common.print_between pr_space pr_elem
420 end
421 else all_ii2 +> Common.print_between pr_space pr_elem
422 in
423
424 match ty, iity with
425 | (Pointer t, [i]) -> pp_base_type t sto
426 | (ParenType t, _) -> pp_base_type t sto
427 | (Array (eopt, t), [i1;i2]) -> pp_base_type t sto
428 | (FunctionType (returnt, paramst), [i1;i2]) ->
429 pp_base_type returnt sto
430
431
432 | (StructUnion (su, sopt, fields),iis) ->
433 print_sto_qu (sto, qu);
434
435 (match sopt,iis with
436 | Some s , [i1;i2;i3;i4] ->
437 pr_elem i1; pr_elem i2; pr_elem i3;
438 | None, [i1;i2;i3] ->
439 pr_elem i1; pr_elem i2;
440 | x -> raise Impossible
441 );
442
443 fields +> List.iter
444 (fun (field) ->
445
446 match field with
447 | DeclarationField(FieldDeclList(onefield_multivars,iiptvirg))->
448 (match onefield_multivars with
449 | x::xs ->
450 (* handling the first var. Special case, with the
451 first var, we print the whole type *)
452
453 (match x with
454 | (Simple (nameopt, typ)), iivirg ->
455 (* first var cant have a preceding ',' *)
456 assert (List.length iivirg =|= 0);
457 let identinfo =
458 match nameopt with
459 | None -> None
460 | Some name -> Some (get_s_and_info_of_name name)
461 in
462 pp_type_with_ident identinfo None typ Ast_c.noattr;
463
464 | (BitField (nameopt, typ, iidot, expr)), iivirg ->
465 (* first var cant have a preceding ',' *)
466 assert (List.length iivirg =|= 0);
467 (match nameopt with
468 | None ->
469 pp_type typ;
470 | Some name ->
471 let (s, is) = get_s_and_info_of_name name in
472 pp_type_with_ident
473 (Some (s, is)) None typ Ast_c.noattr;
474 );
475 pr_elem iidot;
476 pp_expression expr
477
478 ); (* match x, first onefield_multivars *)
479
480 (* for other vars *)
481 xs +> List.iter (function
482 | (Simple (nameopt, typ)), iivirg ->
483 iivirg +> List.iter pr_elem;
484 let identinfo =
485 match nameopt with
486 | None -> None
487 | Some name -> Some (get_s_and_info_of_name name)
488 in
489 pp_type_with_ident_rest identinfo typ Ast_c.noattr
490
491 | (BitField (nameopt, typ, iidot, expr)), iivirg ->
492 iivirg +> List.iter pr_elem;
493 (match nameopt with
494 | Some name ->
495 let (s,is) = get_s_and_info_of_name name in
496 pp_type_with_ident_rest
497 (Some (s, is)) typ Ast_c.noattr;
498 pr_elem iidot;
499 pp_expression expr
500 | x -> raise Impossible
501 )); (* iter other vars *)
502
503 | [] -> raise Impossible
504 ); (* onefield_multivars *)
505 assert (List.length iiptvirg =|= 1);
506 iiptvirg +> List.iter pr_elem;
507
508
509 | MacroDeclField ((s, es), ii) ->
510 let (iis, lp, rp, iiend, ifakestart) =
511 Common.tuple_of_list5 ii in
512 (* iis::lp::rp::iiend::ifakestart::iisto
513 iisto +> List.iter pr_elem; (* static and const *)
514 *)
515 pr_elem ifakestart;
516 pr_elem iis;
517 pr_elem lp;
518 es +> List.iter (fun (e, opt) ->
519 assert (List.length opt <= 1);
520 opt +> List.iter pr_elem;
521 pp_argument e;
522 );
523
524 pr_elem rp;
525 pr_elem iiend;
526
527
528
529 | EmptyField iipttvirg_when_emptyfield ->
530 pr_elem iipttvirg_when_emptyfield
531
532 | CppDirectiveStruct cpp -> pp_directive cpp
533 | IfdefStruct ifdef -> pp_ifdef ifdef
534 );
535
536 (match sopt,iis with
537 | Some s , [i1;i2;i3;i4] -> pr_elem i4
538 | None, [i1;i2;i3] -> pr_elem i3;
539 | x -> raise Impossible
540 );
541
542
543
544 | (Enum (sopt, enumt), iis) ->
545 print_sto_qu (sto, qu);
546
547 (match sopt, iis with
548 | (Some s, ([i1;i2;i3;i4]|[i1;i2;i3;i4;_])) ->
549 pr_elem i1; pr_elem i2; pr_elem i3;
550 | (None, ([i1;i2;i3]|[i1;i2;i3;_])) ->
551 pr_elem i1; pr_elem i2
552 | x -> raise Impossible
553 );
554
555 enumt +> List.iter (fun ((name, eopt), iicomma) ->
556 assert (List.length iicomma <= 1);
557 iicomma +> List.iter (function x -> pr_elem x; pr_space());
558 pp_name name;
559 eopt +> Common.do_option (fun (ieq, e) ->
560 pr_elem ieq;
561 pp_expression e;
562 ));
563
564 (match sopt, iis with
565 | (Some s, [i1;i2;i3;i4]) -> pr_elem i4
566 | (Some s, [i1;i2;i3;i4;i5]) ->
567 pr_elem i5; pr_elem i4 (* trailing comma *)
568 | (None, [i1;i2;i3]) -> pr_elem i3
569 | (None, [i1;i2;i3;i4]) ->
570 pr_elem i4; pr_elem i3 (* trailing comma *)
571
572
573 | x -> raise Impossible
574 );
575
576
577 | (BaseType _, iis) ->
578 print_sto_qu_ty (sto, qu, iis);
579
580 | (StructUnionName (s, structunion), iis) ->
581 assert (List.length iis =|= 2);
582 print_sto_qu_ty (sto, qu, iis);
583
584 | (EnumName s, iis) ->
585 assert (List.length iis =|= 2);
586 print_sto_qu_ty (sto, qu, iis);
587
588 | (TypeName (name,typ), noii) ->
589 assert (null noii);
590 let (_s, iis) = get_s_and_info_of_name name in
591 print_sto_qu_ty (sto, qu, [iis]);
592
593 if !Flag_parsing_c.pretty_print_typedef_value
594 then begin
595 pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "{*");
596 typ +> Common.do_option (fun typ ->
597 pp_type typ;
598 );
599 pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "*}");
600 end;
601
602 | (TypeOfExpr (e), iis) ->
603 print_sto_qu (sto, qu);
604 (match iis with
605 | [itypeof;iopar;icpar] ->
606 pr_elem itypeof; pr_elem iopar;
607 pp_expression e;
608 pr_elem icpar;
609 | _ -> raise Impossible
610 )
611
612 | (TypeOfType (t), iis) ->
613 print_sto_qu (sto, qu);
614 (match iis with
615 | [itypeof;iopar;icpar] ->
616 pr_elem itypeof; pr_elem iopar;
617 pp_type t;
618 pr_elem icpar;
619 | _ -> raise Impossible
620 )
621
622 | (Pointer _ | (*ParenType _ |*) Array _ | FunctionType _
623 (* | StructUnion _ | Enum _ | BaseType _ *)
624 (* | StructUnionName _ | EnumName _ | TypeName _ *)
625 (* | TypeOfExpr _ | TypeOfType _ *)
626 ), _ -> raise Impossible
627
628
629
630 (* used because of DeclList, in int i,*j[23]; we dont print anymore the
631 int before *j *)
632 and (pp_type_with_ident_rest: (string * info) option ->
633 fullType -> attribute list -> unit) =
634
635 fun ident (((qu, iiqu), (ty, iity)) as fullt) attrs ->
636
637 let print_ident ident = Common.do_option (fun (s, iis) ->
638 (* XXX attrs +> pp_attributes pr_elem pr_space; *)
639 pr_elem iis
640 ) ident
641 in
642
643 match ty, iity with
644 (* the work is to do in base_type !! *)
645 | (BaseType _, iis) -> print_ident ident
646 | (Enum (sopt, enumt), iis) -> print_ident ident
647 | (StructUnion (_, sopt, fields),iis) -> print_ident ident
648 | (StructUnionName (s, structunion), iis) -> print_ident ident
649 | (EnumName s, iis) -> print_ident ident
650 | (TypeName (_name,_typ), iis) -> print_ident ident
651 | (TypeOfExpr (e), iis) -> print_ident ident
652 | (TypeOfType (e), iis) -> print_ident ident
653
654
655
656 | (Pointer t, [i]) ->
657 (* subtil: void ( *done)(int i) is a Pointer
658 (FunctionType (return=void, params=int i) *)
659 (*WRONG I THINK, use left & right function *)
660 (* bug: pp_type_with_ident_rest None t; print_ident ident *)
661 pr_elem i;
662 iiqu +> List.iter pr_elem; (* le const est forcement apres le '*' *)
663 pp_type_with_ident_rest ident t attrs;
664
665 (* ugly special case ... todo? maybe sufficient in practice *)
666 | (ParenType ttop, [i1;i2]) ->
667 (match Ast_c.get_ty_and_ii ttop with
668 | (_q1, (Pointer t2, [ipointer])) ->
669 (match Ast_c.get_ty_and_ii t2 with
670 | (q2, (FunctionType t, ii3)) ->
671
672 pp_type_left (q2, mk_tybis (FunctionType t) ii3);
673 pr_elem i1;
674 pr_elem ipointer;
675 print_ident ident;
676 pr_elem i2;
677 pp_type_right (q2, mk_tybis (FunctionType t) ii3);
678 | _ ->
679 pr2 "PB PARENTYPE ZARB, I forget about the ()";
680 pp_type_with_ident_rest ident ttop attrs;
681 )
682 (* another ugly special case *)
683 | _q1, (Array (eopt,t2 ), [iarray1;iarray2]) ->
684 (match Ast_c.get_ty_and_ii t2 with
685 | (_q2, (Pointer t3, [ipointer])) ->
686 (match Ast_c.get_ty_and_ii t3 with
687 | (q3, (FunctionType t, iifunc)) ->
688
689 pp_type_left (q3, mk_tybis (FunctionType t) iifunc);
690 pr_elem i1;
691 pr_elem ipointer;
692 print_ident ident;
693 pr_elem iarray1;
694 do_option pp_expression eopt;
695 pr_elem iarray2;
696 pr_elem i2;
697 pp_type_right (q3, mk_tybis (FunctionType t) iifunc)
698 | _ ->
699 pr2 "PB PARENTYPE ZARB, I forget about the ()";
700 pp_type_with_ident_rest ident ttop attrs;
701 )
702 | _ ->
703 pr2 "PB PARENTYPE ZARB, I forget about the ()";
704 pp_type_with_ident_rest ident ttop attrs;
705 )
706 | _t ->
707
708 pr2 "PB PARENTYPE ZARB, I forget about the ()";
709 pp_type_with_ident_rest ident ttop attrs;
710 )
711
712
713 | (Array (eopt, t), [i1;i2]) ->
714 pp_type_left fullt;
715
716 iiqu +> List.iter pr_elem;
717 print_ident ident;
718
719 pp_type_right fullt;
720
721
722 | (FunctionType (returnt, paramst), [i1;i2]) ->
723 pp_type_left fullt;
724
725 iiqu +> List.iter pr_elem;
726 print_ident ident;
727
728 pp_type_right fullt;
729
730
731 | (FunctionType _ | Array _ | ParenType _ | Pointer _), _ ->
732 raise Impossible
733
734
735 and (pp_type_left: fullType -> unit) =
736 fun ((qu, iiqu), (ty, iity)) ->
737 match ty, iity with
738 | (Pointer t, [i]) ->
739 pr_elem i;
740 iiqu +> List.iter pr_elem; (* le const est forcement apres le '*' *)
741 pp_type_left t
742
743 | (Array (eopt, t), [i1;i2]) -> pp_type_left t
744 | (FunctionType (returnt, paramst), [i1;i2]) -> pp_type_left returnt
745
746 | (ParenType t, _) -> failwith "parenType"
747
748
749 | (BaseType _, iis) -> ()
750 | (Enum (sopt, enumt), iis) -> ()
751 | (StructUnion (_, sopt, fields),iis) -> ()
752 | (StructUnionName (s, structunion), iis) -> ()
753 | (EnumName s, iis) -> ()
754 | (TypeName (_name,_typ), iis) -> ()
755
756 | TypeOfType _, _ -> ()
757 | TypeOfExpr _, _ -> ()
758
759 | (FunctionType _ | Array _ | Pointer _), _ -> raise Impossible
760
761
762 and pp_param param =
763 let {p_namei = nameopt;
764 p_register = (b,iib);
765 p_type=t;} = param in
766
767 iib +> List.iter pr_elem;
768
769 match nameopt with
770 | None ->
771 pp_type t
772 | Some name ->
773 let (s,i1) = get_s_and_info_of_name name in
774 pp_type_with_ident
775 (Some (s, i1)) None t Ast_c.noattr
776
777
778
779
780 and pp_type_right (((qu, iiqu), (ty, iity)) : fullType) =
781 match ty, iity with
782 | (Pointer t, [i]) -> pp_type_right t
783
784 | (Array (eopt, t), [i1;i2]) ->
785 pr_elem i1;
786 eopt +> do_option pp_expression;
787 pr_elem i2;
788 pp_type_right t
789
790 | (ParenType t, _) -> failwith "parenType"
791 | (FunctionType (returnt, paramst), [i1;i2]) ->
792 pr_elem i1;
793 (match paramst with
794 | (ts, (b, iib)) ->
795 ts +> List.iter (fun (param,iicomma) ->
796 assert ((List.length iicomma) <= 1);
797 iicomma +> List.iter (function x -> pr_elem x; pr_space());
798
799 pp_param param;
800 );
801 iib +> List.iter pr_elem;
802 );
803 pr_elem i2
804
805 | (BaseType _, iis) -> ()
806 | (Enum (sopt, enumt), iis) -> ()
807 | (StructUnion (_, sopt, fields),iis)-> ()
808 | (StructUnionName (s, structunion), iis) -> ()
809 | (EnumName s, iis) -> ()
810 | (TypeName (name,_typ), iis) -> ()
811
812 | TypeOfType _, _ -> ()
813 | TypeOfExpr _, _ -> ()
814
815 | (FunctionType _ | Array _ | Pointer _), _ -> raise Impossible
816
817 and pp_type t =
818 pp_type_with_ident None None t Ast_c.noattr
819
820 (* ---------------------- *)
821 and pp_decl = function
822 | DeclList ((({v_namei = var;
823 v_type = returnType;
824 v_storage = storage;
825 v_attr = attrs;
826 },[])::xs),
827 iivirg::ifakestart::iisto) ->
828
829 pr_elem ifakestart;
830
831 (* old: iisto +> List.iter pr_elem; *)
832
833
834 (* handling the first var. Special case, we print the whole type *)
835 (match var with
836 | Some (name, iniopt) ->
837 let (s,iis) = get_s_and_info_of_name name in
838 pp_type_with_ident
839 (Some (s, iis)) (Some (storage, iisto))
840 returnType attrs;
841 iniopt +> do_option (fun (iini, init) ->
842 pr_elem iini;
843 pp_init init);
844 | None -> pp_type returnType
845 );
846
847 (* for other vars, we just call pp_type_with_ident_rest. *)
848 xs +> List.iter (function
849 | ({v_namei = Some (name, iniopt);
850 v_type = returnType;
851 v_storage = storage2;
852 v_attr = attrs;
853 }, iivirg) ->
854
855 let (s,iis) = get_s_and_info_of_name name in
856 assert (storage2 =*= storage);
857 iivirg +> List.iter pr_elem;
858 pp_type_with_ident_rest
859 (Some (s, iis)) returnType attrs;
860 iniopt +> do_option (fun (iini, init) ->
861 pr_elem iini; pp_init init
862 );
863
864
865 | x -> raise Impossible
866 );
867
868 pr_elem iivirg;
869
870 | MacroDecl ((s, es), iis::lp::rp::iiend::ifakestart::iisto) ->
871 pr_elem ifakestart;
872 iisto +> List.iter pr_elem; (* static and const *)
873 pr_elem iis;
874 pr_elem lp;
875 es +> List.iter (fun (e, opt) ->
876 assert (List.length opt <= 1);
877 opt +> List.iter pr_elem;
878 pp_argument e;
879 );
880
881 pr_elem rp;
882 pr_elem iiend;
883
884 | (DeclList (_, _) | (MacroDecl _)) -> raise Impossible
885
886
887 (* ---------------------- *)
888 and pp_init (init, iinit) =
889 match init, iinit with
890 | InitExpr e, [] -> pp_expression e;
891 | InitList xs, i1::i2::iicommaopt ->
892 pr_elem i1; start_block();
893 xs +> List.iter (fun (x, ii) ->
894 assert (List.length ii <= 1);
895 ii +> List.iter (function e -> pr_elem e; pr_nl());
896 pp_init x
897 );
898 iicommaopt +> List.iter pr_elem;
899 end_block();
900 pr_elem i2;
901
902 | InitDesignators (xs, initialiser), [i1] -> (* : *)
903 xs +> List.iter pp_designator;
904 pr_elem i1;
905 pp_init initialiser
906
907 (* no use of '=' in the "Old" style *)
908 | InitFieldOld (string, initialiser), [i1;i2] -> (* label: in oldgcc *)
909 pr_elem i1; pr_elem i2; pp_init initialiser
910 | InitIndexOld (expression, initialiser), [i1;i2] -> (* [1] in oldgcc *)
911 pr_elem i1; pp_expression expression; pr_elem i2;
912 pp_init initialiser
913
914 | (InitIndexOld _ | InitFieldOld _ | InitDesignators _
915 | InitList _ | InitExpr _
916 ), _ -> raise Impossible
917
918
919
920 and pp_designator = function
921 | DesignatorField (s), [i1; i2] ->
922 pr_elem i1; pr_elem i2;
923 | DesignatorIndex (expression), [i1;i2] ->
924 pr_elem i1; pp_expression expression; pr_elem i2;
925
926 | DesignatorRange (e1, e2), [iocro;iellipsis;iccro] ->
927 pr_elem iocro; pp_expression e1; pr_elem iellipsis;
928 pp_expression e2; pr_elem iccro;
929
930 | (DesignatorField _ | DesignatorIndex _ | DesignatorRange _
931 ), _ -> raise Impossible
932
933
934 (* ---------------------- *)
935 and pp_attributes pr_elem pr_space attrs =
936 attrs +> List.iter (fun (attr, ii) ->
937 ii +> List.iter pr_elem;
938 );
939
940 (* ---------------------- *)
941 and pp_def def =
942 let defbis, ii = def in
943 match ii with
944 | iifunc1::iifunc2::i1::i2::ifakestart::isto ->
945 let {f_name = name;
946 f_type = (returnt, (paramst, (b, iib)));
947 f_storage = sto;
948 f_body = statxs;
949 f_attr = attrs;
950 } = defbis
951 in
952 pr_elem ifakestart;
953
954 pp_type_with_ident None (Some (sto, isto))
955 returnt Ast_c.noattr;
956
957 pp_attributes pr_elem pr_space attrs;
958 pp_name name;
959
960 pr_elem iifunc1;
961
962 (* not anymore, cf tests/optional_name_parameter and
963 macro_parameter_shortcut.c
964 (match paramst with
965 | [(((bool, None, t), ii_b_s), iicomma)] ->
966 assert
967 (match t with
968 | qu, (BaseType Void, ii) -> true
969 | _ -> true
970 );
971 assert (null iicomma);
972 assert (null ii_b_s);
973 pp_type_with_ident None None t
974
975 | paramst ->
976 paramst +> List.iter (fun (((bool, s, t), ii_b_s), iicomma) ->
977 iicomma +> List.iter pr_elem;
978
979 (match b, s, ii_b_s with
980 | false, Some s, [i1] ->
981 pp_type_with_ident (Some (s, i1)) None t;
982 | true, Some s, [i1;i2] ->
983 pr_elem i1;
984 pp_type_with_ident (Some (s, i2)) None t;
985
986 (* in definition we have name for params, except when f(void) *)
987 | _, None, _ -> raise Impossible
988 | false, None, [] ->
989
990 | _ -> raise Impossible
991 )));
992
993 (* normally ii represent the ",..." but it is also abused
994 with the f(void) case *)
995 (* assert (List.length iib <= 2);*)
996 iib +> List.iter pr_elem;
997
998 *)
999 paramst +> List.iter (fun (param,iicomma) ->
1000 assert ((List.length iicomma) <= 1);
1001 iicomma +> List.iter (function x -> pr_elem x; pr_space());
1002
1003 pp_param param;
1004 );
1005 iib +> List.iter pr_elem;
1006
1007
1008 pr_elem iifunc2;
1009 pr_elem i1;
1010 statxs +> List.iter pp_statement_seq;
1011 pr_elem i2;
1012 | _ -> raise Impossible
1013
1014
1015
1016 (* ---------------------- *)
1017
1018 and pp_ifdef ifdef =
1019 match ifdef with
1020 | IfdefDirective (ifdef, ii) ->
1021 List.iter pr_elem ii
1022
1023
1024 and pp_directive = function
1025 | Include {i_include = (s, ii);} ->
1026 let (i1,i2) = Common.tuple_of_list2 ii in
1027 pr_elem i1; pr_elem i2
1028 | Define ((s,ii), (defkind, defval)) ->
1029 let (idefine,iident,ieol) = Common.tuple_of_list3 ii in
1030 pr_elem idefine;
1031 pr_elem iident;
1032
1033 let define_val = function
1034 | DefineExpr e -> pp_expression e
1035 | DefineStmt st -> pp_statement st
1036 | DefineDoWhileZero ((st,e), ii) ->
1037 (match ii with
1038 | [ido;iwhile;iopar;icpar] ->
1039 pr_elem ido;
1040 pp_statement st;
1041 pr_elem iwhile; pr_elem iopar;
1042 pp_expression e;
1043 pr_elem icpar
1044 | _ -> raise Impossible
1045 )
1046 | DefineFunction def -> pp_def def
1047
1048 | DefineType ty -> pp_type ty
1049 | DefineText (s, ii) -> List.iter pr_elem ii
1050 | DefineEmpty -> ()
1051 | DefineInit ini -> pp_init ini
1052
1053 | DefineTodo -> pr2 "DefineTodo"
1054 in
1055 (match defkind with
1056 | DefineVar -> ()
1057 | DefineFunc (params, ii) ->
1058 let (i1,i2) = tuple_of_list2 ii in
1059 pr_elem i1;
1060 params +> List.iter (fun ((s,iis), iicomma) ->
1061 assert (List.length iicomma <= 1);
1062 iicomma +> List.iter pr_elem;
1063 iis +> List.iter pr_elem;
1064 );
1065 pr_elem i2;
1066 );
1067 define_val defval;
1068 pr_elem ieol
1069
1070 | Undef (s, ii) ->
1071 List.iter pr_elem ii
1072 | PragmaAndCo (ii) ->
1073 List.iter pr_elem ii in
1074
1075
1076
1077
1078 let pp_toplevel = function
1079 | Declaration decl -> pp_decl decl
1080 | Definition def -> pp_def def
1081
1082 | CppTop directive -> pp_directive directive
1083
1084
1085 | MacroTop (s, es, [i1;i2;i3;i4]) ->
1086 pr_elem i1;
1087 pr_elem i2;
1088 es +> List.iter (fun (e, opt) ->
1089 assert (List.length opt <= 1);
1090 opt +> List.iter pr_elem;
1091 pp_argument e;
1092 );
1093 pr_elem i3;
1094 pr_elem i4;
1095
1096
1097 | EmptyDef ii -> ii +> List.iter pr_elem
1098 | NotParsedCorrectly ii ->
1099 assert (List.length ii >= 1);
1100 ii +> List.iter pr_elem
1101 | FinalDef info -> pr_elem (Ast_c.rewrap_str "" info)
1102
1103 | IfdefTop ifdefdir -> pp_ifdef ifdefdir
1104
1105 | (MacroTop _) -> raise Impossible in
1106
1107
1108
1109
1110 let pp_flow n =
1111 match F.unwrap n with
1112 | F.FunHeader ({f_name =idb;
1113 f_type = (rett, (paramst,(isvaargs,iidotsb)));
1114 f_storage = stob;
1115 f_body = body;
1116 f_attr = attrs},ii) ->
1117
1118 assert(null body);
1119 (*
1120 iif ii;
1121 iif iidotsb;
1122 attrs +> List.iter (vk_attribute bigf);
1123 vk_type bigf rett;
1124 paramst +> List.iter (fun (param, iicomma) ->
1125 vk_param bigf param;
1126 iif iicomma;
1127 );
1128 *)
1129 pr2 "Def";
1130
1131
1132 | F.Decl decl ->
1133 (* vk_decl bigf decl *)
1134 pr2 "Decl"
1135
1136 | F.ExprStatement (st, (eopt, ii)) ->
1137 pp_statement (Ast_c.mk_st (ExprStatement eopt) ii)
1138
1139 | F.IfHeader (_, (e,ii))
1140 | F.SwitchHeader (_, (e,ii))
1141 | F.WhileHeader (_, (e,ii))
1142 | F.DoWhileTail (e,ii) ->
1143 (*
1144 iif ii;
1145 vk_expr bigf e
1146 *)
1147 pr2 "XXX";
1148
1149
1150 | F.ForHeader (_st, (((e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) ->
1151 (*
1152 iif i1; iif i2; iif i3;
1153 iif ii;
1154 e1opt +> do_option (vk_expr bigf);
1155 e2opt +> do_option (vk_expr bigf);
1156 e3opt +> do_option (vk_expr bigf);
1157 *)
1158 pr2 "XXX"
1159
1160 | F.MacroIterHeader (_s, ((s,es), ii)) ->
1161 (*
1162 iif ii;
1163 vk_argument_list bigf es;
1164 *)
1165 pr2 "XXX"
1166
1167
1168 | F.ReturnExpr (_st, (e,ii)) ->
1169 (* iif ii; vk_expr bigf e*)
1170 pr2 "XXX"
1171
1172
1173 | F.Case (_st, (e,ii)) ->
1174 (* iif ii; vk_expr bigf e *)
1175 pr2 "XXX"
1176
1177 | F.CaseRange (_st, ((e1, e2),ii)) ->
1178 (* iif ii; vk_expr bigf e1; vk_expr bigf e2 *)
1179 pr2 "XXX"
1180
1181
1182
1183 | F.CaseNode i -> ()
1184
1185 | F.DefineExpr e ->
1186 (* vk_expr bigf e *)
1187 pr2 "XXX"
1188
1189 | F.DefineType ft ->
1190 (* vk_type bigf ft *)
1191 pr2 "XXX"
1192
1193 | F.DefineHeader ((s,ii), (defkind)) ->
1194 (*
1195 iif ii;
1196 vk_define_kind bigf defkind;
1197 *)
1198 pr2 "XXX"
1199
1200
1201 | F.DefineDoWhileZeroHeader (((),ii)) ->
1202 (* iif ii *)
1203 pr2 "XXX"
1204
1205
1206 | F.Include {i_include = (s, ii);} ->
1207 (* iif ii; *)
1208 pr2 "XXX"
1209
1210
1211 | F.MacroTop (s, args, ii) ->
1212 (* iif ii;
1213 vk_argument_list bigf args *)
1214 pr2 "XXX"
1215
1216
1217 | F.Break (st,((),ii)) ->
1218 (* iif ii *)
1219 pr2 "XXX"
1220 | F.Continue (st,((),ii)) ->
1221 (* iif ii *)
1222 pr2 "XXX"
1223 | F.Default (st,((),ii)) ->
1224 (* iif ii *)
1225 pr2 "XXX"
1226 | F.Return (st,((),ii)) ->
1227 (* iif ii *)
1228 pr2 "XXX"
1229 | F.Goto (st, name, ((),ii)) ->
1230 (* iif ii *)
1231 pr2 "XXX"
1232 | F.Label (st, name, ((),ii)) ->
1233 (* iif ii *)
1234 pr2 "XXX"
1235 | F.EndStatement iopt ->
1236 (* do_option infof iopt *)
1237 pr2 "XXX"
1238 | F.DoHeader (st, info) ->
1239 (* infof info *)
1240 pr2 "XXX"
1241 | F.Else info ->
1242 (* infof info *)
1243 pr2 "XXX"
1244 | F.SeqEnd (i, info) ->
1245 (* infof info *)
1246 pr2 "XXX"
1247 | F.SeqStart (st, i, info) ->
1248 (* infof info *)
1249 pr2 "XXX"
1250
1251 | F.MacroStmt (st, ((),ii)) ->
1252 (* iif ii *)
1253 pr2 "XXX"
1254 | F.Asm (st, (asmbody,ii)) ->
1255 (*
1256 iif ii;
1257 vk_asmbody bigf asmbody
1258 *)
1259 pr2 "XXX"
1260
1261
1262 | F.IfdefHeader (info) ->
1263 pp_ifdef info
1264 | F.IfdefElse (info) ->
1265 pp_ifdef info
1266 | F.IfdefEndif (info) ->
1267 pp_ifdef info
1268
1269 | F.DefineTodo ->
1270 pr2 "XXX"
1271
1272
1273 | (F.TopNode|F.EndNode|
1274 F.ErrorExit|F.Exit|F.Enter|F.LoopFallThroughNode|F.FallThroughNode|
1275 F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
1276 F.Fake) ->
1277 pr2 "YYY" in
1278
1279
1280 { expression = pp_expression;
1281 arg_list = pp_arg_list;
1282 statement = pp_statement;
1283 decl = pp_decl;
1284 init = pp_init;
1285 param = pp_param;
1286 ty = pp_type;
1287 type_with_ident = pp_type_with_ident;
1288 toplevel = pp_toplevel;
1289 flow = pp_flow;
1290 }
1291
1292 (*****************************************************************************)
1293
1294 (* Here we do not use (mcode, env). It is a simple C pretty printer. *)
1295 let pr_elem info =
1296 let s = Ast_c.str_of_info info in
1297 if !Flag_parsing_c.pretty_print_comment_info then begin
1298 let before = !(info.comments_tag).mbefore in
1299 if not (null before) then begin
1300 pp "-->";
1301 before +> List.iter (fun (comment_like, pinfo) ->
1302 let s = pinfo.Common.str in
1303 pp s
1304 );
1305 pp "<--";
1306 end;
1307 end;
1308 pp s
1309
1310 let pr_space _ = Format.print_space()
1311
1312 let pr_nl _ = ()
1313 let pr_indent _ = ()
1314 let pr_outdent _ = ()
1315 let pr_unindent _ = ()
1316
1317
1318 let ppc =
1319 mk_pretty_printers
1320 ~pr_elem ~pr_space ~pr_nl ~pr_outdent ~pr_indent ~pr_unindent
1321
1322 let pp_expression_simple = ppc.expression
1323 let pp_statement_simple = ppc.statement
1324 let pp_type_simple = ppc.ty
1325 let pp_init_simple = ppc.init
1326 let pp_toplevel_simple = ppc.toplevel
1327 let pp_flow_simple = ppc.flow
1328
1329
1330 let pp_elem_sp ~pr_elem ~pr_space =
1331 mk_pretty_printers
1332 ~pr_elem ~pr_space
1333 ~pr_nl ~pr_outdent ~pr_indent ~pr_unindent
1334
1335 let pp_expression_gen ~pr_elem ~pr_space =
1336 (pp_elem_sp pr_elem pr_space).expression
1337
1338 let pp_arg_list_gen pr_elem pr_space =
1339 (pp_elem_sp pr_elem pr_space).arg_list
1340
1341 let pp_statement_gen ~pr_elem ~pr_space =
1342 (pp_elem_sp pr_elem pr_space).statement
1343
1344 let pp_decl_gen pr_elem pr_space =
1345 (pp_elem_sp pr_elem pr_space).decl
1346
1347 let pp_init_gen ~pr_elem ~pr_space =
1348 (pp_elem_sp pr_elem pr_space).init
1349
1350 let pp_param_gen ~pr_elem ~pr_space =
1351 (pp_elem_sp pr_elem pr_space).param
1352
1353 let pp_type_gen ~pr_elem ~pr_space =
1354 (pp_elem_sp pr_elem pr_space).ty
1355
1356 let pp_type_with_ident_gen pr_elem pr_space =
1357 (pp_elem_sp pr_elem pr_space).type_with_ident
1358
1359 let pp_program_gen ~pr_elem ~pr_space =
1360 (pp_elem_sp pr_elem pr_space).toplevel
1361
1362
1363 let string_of_expression e =
1364 Common.format_to_string (fun () ->
1365 pp_expression_simple e
1366 )
1367
1368 let string_of_toplevel top =
1369 Common.format_to_string (fun () ->
1370 pp_toplevel_simple top
1371 )
1372
1373 let (debug_info_of_node:
1374 Ograph_extended.nodei -> Control_flow_c.cflow -> string) =
1375 fun nodei flow ->
1376 let node = flow#nodes#assoc nodei in
1377 let s = Common.format_to_string (fun () ->
1378 pp_flow_simple node
1379 ) in
1380 let pos = Lib_parsing_c.min_pinfo_of_node node in
1381 (spf "%s(n%d)--> %s" (Common.string_of_parse_info_bis pos) nodei s)
1382