permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_cocci / pretty_print_cocci.ml
CommitLineData
f537ebc4 1(*
17ba0788
C
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
f537ebc4
C
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
9 *
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
d6ce1786
C
13 *
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
feec80c3 27# 0 "./pretty_print_cocci.ml"
34e49164
C
28open Format
29module Ast = Ast_cocci
30
31let print_plus_flag = ref true
32let print_minus_flag = ref true
33let print_newlines_disj = ref true
34
35let start_block str =
36 force_newline(); print_string " "; open_box 0
37
38let end_block str =
39 close_box(); force_newline ()
40
41let print_string_box s = print_string s; open_box 0
42
43
44let print_option = Common.do_option
45let print_between = Common.print_between
46
47(* --------------------------------------------------------------------- *)
48(* Modified code *)
49
50(* avoid polyvariance problems *)
51let anything : (Ast.anything -> unit) ref = ref (function _ -> ())
52
53let rec print_anything str = function
54 [] -> ()
55 | stream ->
56 start_block();
57 print_between force_newline
58 (function x ->
59 print_string str; open_box 0; print_anything_list x; close_box())
60 stream;
61 end_block()
62
63and print_anything_list = function
64 [] -> ()
65 | [x] -> !anything x
66 | bef::((aft::_) as rest) ->
67 !anything bef;
68 let space =
69 (match bef with
70 Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_)
71 | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_)
72 | Ast.Token("if",_) | Ast.Token("while",_) -> true | _ -> false) or
73 (match aft with
74 Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_)
75 | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) | Ast.Token("{",_) -> true
76 | _ -> false) in
77 if space then print_string " ";
78 print_anything_list rest
79
80let print_around printer term = function
81 Ast.NOTHING -> printer term
951c7801
C
82 | Ast.BEFORE(bef,_) -> print_anything "<<< " bef; printer term
83 | Ast.AFTER(aft,_) -> printer term; print_anything ">>> " aft
84 | Ast.BEFOREAFTER(bef,aft,_) ->
34e49164
C
85 print_anything "<<< " bef; printer term; print_anything ">>> " aft
86
87let print_string_befaft fn x info =
190f1acf
C
88 let print = function
89 Ast.Noindent s | Ast.Indent s | Ast.Space s -> print_string s in
c3e37e97 90 List.iter (function (s,_,_) -> print s; force_newline()) info.Ast.strbef;
34e49164 91 fn x;
c3e37e97 92 List.iter (function (s,_,_) -> force_newline(); print s) info.Ast.straft
34e49164
C
93
94let print_meta (r,x) = print_string r; print_string ":"; print_string x
95
8f657093
C
96let print_pos l =
97 List.iter
98 (function
99 Ast.MetaPos(name,_,_,_,_) ->
100 let name = Ast.unwrap_mcode name in
101 print_string "@"; print_meta name)
102 l
34e49164
C
103
104let mcode fn = function
708f4980 105 (x, _, Ast.MINUS(_,_,adj,plus_stream), pos) ->
34e49164
C
106 if !print_minus_flag
107 then print_string (if !Flag.sgrep_mode2 then "*" else "-");
108 fn x; print_pos pos;
faf9a90c 109 if !print_plus_flag
8babbc8f
C
110 then
111 (match plus_stream with
112 Ast.NOREPLACEMENT -> ()
113 | Ast.REPLACEMENT(plus_stream,_) -> print_anything ">>> " plus_stream)
faf9a90c 114 | (x, _, Ast.CONTEXT(_,plus_streams), pos) ->
34e49164
C
115 if !print_plus_flag
116 then
117 let fn x = fn x; print_pos pos in
118 print_around fn x plus_streams
119 else (fn x; print_pos pos)
951c7801 120 | (x, info, Ast.PLUS _, pos) ->
34e49164
C
121 let fn x = fn x; print_pos pos in
122 print_string_befaft fn x info
123
faf9a90c 124let print_mcodekind = function
708f4980 125 Ast.MINUS(_,_,_,plus_stream) ->
34e49164 126 print_string "MINUS";
8babbc8f
C
127 (match plus_stream with
128 Ast.NOREPLACEMENT -> ()
129 | Ast.REPLACEMENT(plus_stream,_) -> print_anything ">>> " plus_stream)
34e49164
C
130 | Ast.CONTEXT(_,plus_streams) ->
131 print_around (function _ -> print_string "CONTEXT") () plus_streams
951c7801 132 | Ast.PLUS _ -> print_string "PLUS"
34e49164
C
133
134(* --------------------------------------------------------------------- *)
135(* --------------------------------------------------------------------- *)
136(* Dots *)
137
138let dots between fn d =
139 match Ast.unwrap d with
140 Ast.DOTS(l) -> print_between between fn l
141 | Ast.CIRCLES(l) -> print_between between fn l
142 | Ast.STARS(l) -> print_between between fn l
143
5636bb2c
C
144let nest_dots starter ender fn f d =
145 mcode print_string starter;
146 f(); start_block();
147 (match Ast.unwrap d with
148 Ast.DOTS(l) -> print_between force_newline fn l
149 | Ast.CIRCLES(l) -> print_between force_newline fn l
150 | Ast.STARS(l) -> print_between force_newline fn l);
151 end_block();
152 mcode print_string ender
34e49164 153
d3f655c6
C
154(* --------------------------------------------------------------------- *)
155(* Disjunctions *)
156
157let print_disj_list fn l =
158 if !print_newlines_disj
159 then (force_newline(); print_string "("; force_newline())
160 else print_string "(";
161 print_between
162 (function _ ->
163 if !print_newlines_disj
164 then (force_newline(); print_string "|"; force_newline())
165 else print_string " | ")
166 fn l;
167 if !print_newlines_disj
168 then (force_newline(); print_string ")"; force_newline())
169 else print_string ")"
170
34e49164
C
171(* --------------------------------------------------------------------- *)
172
173let print_type keep info = function
174 None -> ()
175 (* print_string "/* ";
176 print_string "keep:"; print_unitary keep;
177 print_string " inherited:"; print_bool inherited;
178 print_string " */"*)
179 | Some ty -> ()
180 (*;
181 print_string "/* ";
182 print_between (function _ -> print_string ", ") Type_cocci.typeC ty;(*
183 print_string "keep:"; print_unitary keep;
184 print_string " inherited:"; print_bool inherited;*)
185 print_string " */"*)
186
951c7801
C
187(* --------------------------------------------------------------------- *)
188(* Contraint on Identifier and Function *)
189(* FIXME: Not called at the moment *)
190
5636bb2c
C
191let rec idconstraint = function
192 Ast.IdNoConstraint -> print_string "/* No constraint */"
193 | Ast.IdNegIdSet (str,meta) ->
194 List.iter (function s -> print_string (" "^s)) str;
195 List.iter (function (r,n) -> print_string " "; print_meta(r,n)) meta
196 | Ast.IdRegExpConstraint re -> regconstraint re
197
198and regconstraint = function
199 Ast.IdRegExp (re,_) ->
200 print_string "~= \""; print_string re; print_string "\""
201 | Ast.IdNotRegExp (re,_) ->
202 print_string "~!= \""; print_string re; print_string "\""
951c7801 203
34e49164
C
204(* --------------------------------------------------------------------- *)
205(* Identifier *)
206
207let rec ident i =
208 match Ast.unwrap i with
d3f655c6
C
209 Ast.Id(name) -> mcode print_string name
210 | Ast.MetaId(name,_,keep,inherited) -> mcode print_meta name
211 | Ast.MetaFunc(name,_,_,_) -> mcode print_meta name
212 | Ast.MetaLocalFunc(name,_,_,_) -> mcode print_meta name
d6ce1786 213 | Ast.AsIdent(id,asid) -> ident id; print_string "@"; ident asid
d3f655c6
C
214 | Ast.DisjId(id_list) -> print_disj_list ident id_list
215 | Ast.OptIdent(id) -> print_string "?"; ident id
216 | Ast.UniqueIdent(id) -> print_string "!"; ident id
34e49164
C
217
218and print_unitary = function
219 Type_cocci.Unitary -> print_string "unitary"
220 | Type_cocci.Nonunitary -> print_string "nonunitary"
221 | Type_cocci.Saved -> print_string "saved"
222
223(* --------------------------------------------------------------------- *)
224(* Expression *)
225
34e49164
C
226let rec expression e =
227 match Ast.unwrap e with
228 Ast.Ident(id) -> ident id
229 | Ast.Constant(const) -> mcode constant const
230 | Ast.FunCall(fn,lp,args,rp) ->
231 expression fn; mcode print_string_box lp;
232 dots (function _ -> ()) expression args;
233 close_box(); mcode print_string rp
234 | Ast.Assignment(left,op,right,simple) ->
235 expression left; print_string " "; mcode assignOp op;
236 print_string " "; expression right
17ba0788
C
237 | Ast.Sequence(left,op,right) ->
238 expression left; mcode print_string op;
239 print_string " "; expression right
34e49164
C
240 | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
241 expression exp1; print_string " "; mcode print_string why;
242 print_option (function e -> print_string " "; expression e) exp2;
243 print_string " "; mcode print_string colon; expression exp3
244 | Ast.Postfix(exp,op) -> expression exp; mcode fixOp op
245 | Ast.Infix(exp,op) -> mcode fixOp op; expression exp
246 | Ast.Unary(exp,op) -> mcode unaryOp op; expression exp
247 | Ast.Binary(left,op,right) ->
248 expression left; print_string " "; mcode binaryOp op; print_string " ";
249 expression right
250 | Ast.Nested(left,op,right) ->
251 expression left; print_string " "; mcode binaryOp op; print_string " ";
252 expression right
253 | Ast.Paren(lp,exp,rp) ->
254 mcode print_string_box lp; expression exp; close_box();
255 mcode print_string rp
256 | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
257 expression exp1; mcode print_string_box lb; expression exp2; close_box();
258 mcode print_string rb
259 | Ast.RecordAccess(exp,pt,field) ->
260 expression exp; mcode print_string pt; ident field
261 | Ast.RecordPtAccess(exp,ar,field) ->
262 expression exp; mcode print_string ar; ident field
263 | Ast.Cast(lp,ty,rp,exp) ->
264 mcode print_string_box lp; fullType ty; close_box();
265 mcode print_string rp; expression exp
266 | Ast.SizeOfExpr(sizeof,exp) ->
267 mcode print_string sizeof; expression exp
268 | Ast.SizeOfType(sizeof,lp,ty,rp) ->
269 mcode print_string sizeof;
270 mcode print_string_box lp; fullType ty; close_box();
271 mcode print_string rp
272 | Ast.TypeExp(ty) -> fullType ty
7fe62b65
C
273 | Ast.Constructor(lp,ty,rp,init) ->
274 mcode print_string_box lp; fullType ty; close_box();
275 mcode print_string rp; initialiser init
34e49164
C
276
277 | Ast.MetaErr(name,_,_,_) -> mcode print_meta name
278 | Ast.MetaExpr(name,_,keep,ty,form,inherited) ->
279 mcode print_meta name; print_type keep inherited ty
280 | Ast.MetaExprList(name,_,_,_) -> mcode print_meta name
17ba0788 281 | Ast.AsExpr(exp,asexp) -> expression exp; print_string "@"; expression asexp
34e49164
C
282 | Ast.EComma(cm) -> mcode print_string cm; print_space()
283 | Ast.DisjExpr(exp_list) -> print_disj_list expression exp_list
5636bb2c
C
284 | Ast.NestExpr(starter,expr_dots,ender,Some whencode,multi) ->
285 nest_dots starter ender expression
34e49164
C
286 (function _ -> print_string " when != "; expression whencode)
287 expr_dots
5636bb2c
C
288 | Ast.NestExpr(starter,expr_dots,ender,None,multi) ->
289 nest_dots starter ender expression (function _ -> ()) expr_dots
34e49164
C
290 | Ast.Edots(dots,Some whencode)
291 | Ast.Ecircles(dots,Some whencode)
292 | Ast.Estars(dots,Some whencode) ->
293 mcode print_string dots; print_string " when != "; expression whencode
294 | Ast.Edots(dots,None)
295 | Ast.Ecircles(dots,None)
296 | Ast.Estars(dots,None) -> mcode print_string dots
297 | Ast.OptExp(exp) -> print_string "?"; expression exp
298 | Ast.UniqueExp(exp) -> print_string "!"; expression exp
299
300and unaryOp = function
301 Ast.GetRef -> print_string "&"
8babbc8f 302 | Ast.GetRefLabel -> print_string "&&"
34e49164
C
303 | Ast.DeRef -> print_string "*"
304 | Ast.UnPlus -> print_string "+"
305 | Ast.UnMinus -> print_string "-"
306 | Ast.Tilde -> print_string "~"
307 | Ast.Not -> print_string "!"
308
309and assignOp = function
310 Ast.SimpleAssign -> print_string "="
311 | Ast.OpAssign(aop) -> arithOp aop; print_string "="
312
313and fixOp = function
314 Ast.Dec -> print_string "--"
315 | Ast.Inc -> print_string "++"
316
317and binaryOp = function
318 Ast.Arith(aop) -> arithOp aop
319 | Ast.Logical(lop) -> logicalOp lop
320
321and arithOp = function
322 Ast.Plus -> print_string "+"
323 | Ast.Minus -> print_string "-"
324 | Ast.Mul -> print_string "*"
325 | Ast.Div -> print_string "/"
1b9ae606
C
326 | Ast.Max -> print_string ">?"
327 | Ast.Min -> print_string "<?"
34e49164
C
328 | Ast.Mod -> print_string "%"
329 | Ast.DecLeft -> print_string "<<"
330 | Ast.DecRight -> print_string ">>"
331 | Ast.And -> print_string "&"
332 | Ast.Or -> print_string "|"
333 | Ast.Xor -> print_string "^"
334
335and logicalOp = function
336 Ast.Inf -> print_string "<"
337 | Ast.Sup -> print_string ">"
338 | Ast.InfEq -> print_string "<="
339 | Ast.SupEq -> print_string ">="
340 | Ast.Eq -> print_string "=="
341 | Ast.NotEq -> print_string "!="
342 | Ast.AndLog -> print_string "&&"
343 | Ast.OrLog -> print_string "||"
344
345and constant = function
346 Ast.String(s) -> print_string "\""; print_string s; print_string "\""
347 | Ast.Char(s) -> print_string "'"; print_string s; print_string "'"
348 | Ast.Int(s) -> print_string s
349 | Ast.Float(s) -> print_string s
350
351(* --------------------------------------------------------------------- *)
352(* Declarations *)
353
354and storage = function
355 Ast.Static -> print_string "static "
356 | Ast.Auto -> print_string "auto "
357 | Ast.Register -> print_string "register "
358 | Ast.Extern -> print_string "extern "
359
360(* --------------------------------------------------------------------- *)
361(* Types *)
362
363and fullType ft =
364 match Ast.unwrap ft with
17ba0788 365 Ast.Type(_,cv,ty) ->
755320b0
C
366 (match Ast.unwrap ty with
367 Ast.Pointer(_,_) ->
368 typeC ty;
369 print_option (function x -> print_string " "; mcode const_vol x) cv
370 | _ ->
371 print_option (function x -> mcode const_vol x; print_string " ") cv;
372 typeC ty)
17ba0788 373 | Ast.AsType(ty,asty) -> fullType ty; print_string "@"; fullType asty
34e49164
C
374 | Ast.DisjType(decls) -> print_disj_list fullType decls
375 | Ast.OptType(ty) -> print_string "?"; fullType ty
376 | Ast.UniqueType(ty) -> print_string "!"; fullType ty
377
378and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn =
379 fullType ty; mcode print_string lp1; mcode print_string star; fn();
380 mcode print_string rp1; mcode print_string lp1;
381 parameter_list params; mcode print_string rp2
382
383and print_function_type (ty,lp1,params,rp1) fn =
384 print_option fullType ty; fn(); mcode print_string lp1;
385 parameter_list params; mcode print_string rp1
386
387and print_fninfo = function
388 Ast.FStorage(stg) -> mcode storage stg
389 | Ast.FType(ty) -> fullType ty
390 | Ast.FInline(inline) -> mcode print_string inline; print_string " "
391 | Ast.FAttr(attr) -> mcode print_string attr; print_string " "
392
393and typeC ty =
394 match Ast.unwrap ty with
faf9a90c
C
395 Ast.BaseType(ty,strings) ->
396 List.iter (function s -> mcode print_string s; print_string " ") strings
397 | Ast.SignedT(sgn,ty) -> mcode sign sgn; print_option typeC ty
34e49164
C
398 | Ast.Pointer(ty,star) -> fullType ty; mcode print_string star
399 | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
400 print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
401 (function _ -> ())
402 | Ast.FunctionType (_,ty,lp1,params,rp1) ->
403 print_function_type (ty,lp1,params,rp1) (function _ -> ())
404 | Ast.Array(ty,lb,size,rb) ->
405 fullType ty; mcode print_string lb; print_option expression size;
406 mcode print_string rb
c491d8ee
C
407 | Ast.EnumName(kind,name) ->
408 mcode print_string kind;
409 print_option (function x -> ident x; print_string " ") name
410 | Ast.EnumDef(ty,lb,ids,rb) ->
411 fullType ty; mcode print_string lb;
412 dots force_newline expression ids;
413 mcode print_string rb
34e49164
C
414 | Ast.StructUnionName(kind,name) ->
415 mcode structUnion kind;
416 print_option (function x -> ident x; print_string " ") name
417 | Ast.StructUnionDef(ty,lb,decls,rb) ->
418 fullType ty; mcode print_string lb;
419 dots force_newline declaration decls;
420 mcode print_string rb
421 | Ast.TypeName(name) -> mcode print_string name; print_string " "
422 | Ast.MetaType(name,_,_) ->
423 mcode print_meta name; print_string " "
424
425and baseType = function
426 Ast.VoidType -> print_string "void "
427 | Ast.CharType -> print_string "char "
428 | Ast.ShortType -> print_string "short "
f3c4ece6 429 | Ast.ShortIntType -> print_string "short int "
34e49164
C
430 | Ast.IntType -> print_string "int "
431 | Ast.DoubleType -> print_string "double "
f3c4ece6 432 | Ast.LongDoubleType -> print_string "long double "
34e49164
C
433 | Ast.FloatType -> print_string "float "
434 | Ast.LongType -> print_string "long "
f3c4ece6 435 | Ast.LongIntType -> print_string "long int "
faf9a90c 436 | Ast.LongLongType -> print_string "long long "
f3c4ece6 437 | Ast.LongLongIntType -> print_string "long long int "
1eddfd50
C
438 | Ast.SizeType -> print_string "size_t "
439 | Ast.SSizeType -> print_string "ssize_t "
440 | Ast.PtrDiffType -> print_string "ptrdiff_t "
34e49164
C
441
442and structUnion = function
443 Ast.Struct -> print_string "struct "
444 | Ast.Union -> print_string "union "
445
446and sign = function
447 Ast.Signed -> print_string "signed "
448 | Ast.Unsigned -> print_string "unsigned "
449
450and const_vol = function
451 Ast.Const -> print_string "const"
452 | Ast.Volatile -> print_string "volatile"
453
454(* --------------------------------------------------------------------- *)
455(* Variable declaration *)
456(* Even if the Cocci program specifies a list of declarations, they are
457 split out into multiple declarations of a single variable each. *)
458
459and print_named_type ty id =
460 match Ast.unwrap ty with
17ba0788 461 Ast.Type(_,None,ty1) ->
34e49164
C
462 (match Ast.unwrap ty1 with
463 Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
464 print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
465 (function _ -> print_string " "; ident id)
466 | Ast.FunctionType(_,ty,lp1,params,rp1) ->
467 print_function_type (ty,lp1,params,rp1)
468 (function _ -> print_string " "; ident id)
469 | Ast.Array(ty,lb,size,rb) ->
470 let rec loop ty k =
471 match Ast.unwrap ty with
472 Ast.Array(ty,lb,size,rb) ->
473 (match Ast.unwrap ty with
17ba0788
C
474 Ast.Type(_,cv,ty) ->
475 print_option
476 (function x -> mcode const_vol x; print_string " ")
477 cv;
34e49164
C
478 loop ty
479 (function _ ->
480 k ();
481 mcode print_string lb;
482 print_option expression size;
483 mcode print_string rb)
484 | _ -> failwith "complex array types not supported")
485 | _ -> typeC ty; ident id; k () in
486 loop ty1 (function _ -> ())
487 | _ -> fullType ty; ident id)
488 | _ -> fullType ty; ident id
489
490and declaration d =
491 match Ast.unwrap d with
190f1acf
C
492 Ast.MetaDecl(name,_,_) | Ast.MetaField(name,_,_)
493 | Ast.MetaFieldList(name,_,_,_) ->
494 mcode print_meta name
17ba0788
C
495 | Ast.AsDecl(decl,asdecl) -> declaration decl; print_string "@";
496 declaration asdecl
413ffc02 497 | Ast.Init(stg,ty,id,eq,ini,sem) ->
34e49164
C
498 print_option (mcode storage) stg; print_named_type ty id;
499 print_string " "; mcode print_string eq;
500 print_string " "; initialiser ini; mcode print_string sem
501 | Ast.UnInit(stg,ty,id,sem) ->
502 print_option (mcode storage) stg; print_named_type ty id;
503 mcode print_string sem
504 | Ast.MacroDecl(name,lp,args,rp,sem) ->
505 ident name; mcode print_string_box lp;
506 dots (function _ -> ()) expression args;
507 close_box(); mcode print_string rp; mcode print_string sem
17ba0788
C
508 | Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
509 ident name; mcode print_string_box lp;
510 dots (function _ -> ()) expression args;
511 close_box(); mcode print_string rp;
512 print_string " "; mcode print_string eq;
513 print_string " "; initialiser ini; mcode print_string sem
34e49164
C
514 | Ast.TyDecl(ty,sem) -> fullType ty; mcode print_string sem
515 | Ast.Typedef(stg,ty,id,sem) ->
516 mcode print_string stg; print_string " "; fullType ty; typeC id;
517 mcode print_string sem
518 | Ast.DisjDecl(decls) -> print_disj_list declaration decls
faf9a90c 519 | Ast.Ddots(dots,Some whencode) ->
34e49164
C
520 mcode print_string dots; print_string " when != "; declaration whencode
521 | Ast.Ddots(dots,None) -> mcode print_string dots
34e49164
C
522 | Ast.OptDecl(decl) -> print_string "?"; declaration decl
523 | Ast.UniqueDecl(decl) -> print_string "!"; declaration decl
524
525(* --------------------------------------------------------------------- *)
526(* Initialiser *)
527
528and initialiser i =
529 match Ast.unwrap i with
113803cf
C
530 Ast.MetaInit(name,_,_) ->
531 mcode print_meta name; print_string " "
8f657093
C
532 | Ast.MetaInitList(name,_,_,_) ->
533 mcode print_meta name; print_string " "
17ba0788
C
534 | Ast.AsInit(ini,asini) -> initialiser ini; print_string "@";
535 initialiser asini
113803cf 536 | Ast.InitExpr(exp) -> expression exp
c491d8ee
C
537 | Ast.ArInitList(lb,initlist,rb) ->
538 mcode print_string lb; open_box 0;
539 dots force_newline initialiser initlist; close_box();
540 mcode print_string rb
541 | Ast.StrInitList(allminus,lb,initlist,rb,whencode) ->
34e49164
C
542 mcode print_string lb; open_box 0;
543 if not (whencode = [])
544 then
545 (print_string " WHEN != ";
546 print_between (function _ -> print_string " v ")
547 initialiser whencode;
548 force_newline());
549 List.iter initialiser initlist; close_box();
550 mcode print_string rb
113803cf
C
551 | Ast.InitGccExt(designators,eq,ini) ->
552 List.iter designator designators; print_string " ";
34e49164
C
553 mcode print_string eq; print_string " "; initialiser ini
554 | Ast.InitGccName(name,eq,ini) ->
555 ident name; mcode print_string eq; initialiser ini
34e49164 556 | Ast.IComma(comma) -> mcode print_string comma; force_newline()
c491d8ee
C
557 | Ast.Idots(dots,Some whencode) ->
558 mcode print_string dots; print_string " when != "; initialiser whencode
559 | Ast.Idots(dots,None) -> mcode print_string dots
34e49164
C
560 | Ast.OptIni(ini) -> print_string "?"; initialiser ini
561 | Ast.UniqueIni(ini) -> print_string "!"; initialiser ini
562
113803cf
C
563and designator = function
564 Ast.DesignatorField(dot,id) -> mcode print_string dot; ident id
565 | Ast.DesignatorIndex(lb,exp,rb) ->
566 mcode print_string lb; expression exp; mcode print_string rb
567 | Ast.DesignatorRange(lb,min,dots,max,rb) ->
568 mcode print_string lb; expression min; mcode print_string dots;
569 expression max; mcode print_string rb
570
34e49164
C
571(* --------------------------------------------------------------------- *)
572(* Parameter *)
573
574and parameterTypeDef p =
575 match Ast.unwrap p with
576 Ast.VoidParam(ty) -> fullType ty
577 | Ast.Param(ty,Some id) -> print_named_type ty id
578 | Ast.Param(ty,None) -> fullType ty
579 | Ast.MetaParam(name,_,_) -> mcode print_meta name
580 | Ast.MetaParamList(name,_,_,_) -> mcode print_meta name
581 | Ast.PComma(cm) -> mcode print_string cm; print_space()
582 | Ast.Pdots(dots) -> mcode print_string dots
583 | Ast.Pcircles(dots) -> mcode print_string dots
584 | Ast.OptParam(param) -> print_string "?"; parameterTypeDef param
585 | Ast.UniqueParam(param) -> print_string "!"; parameterTypeDef param
1b9ae606
C
586 | Ast.AsParam(p,asexp) ->
587 parameterTypeDef p; print_string "@"; expression asexp
34e49164
C
588
589and parameter_list l = dots (function _ -> ()) parameterTypeDef l
590
591(* --------------------------------------------------------------------- *)
592(* Top-level code *)
593
594let rec rule_elem arity re =
595 match Ast.unwrap re with
596 Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) ->
8f657093 597 mcode (function _ -> ()) ((),Ast.no_info,bef,[]);
34e49164
C
598 print_string arity; List.iter print_fninfo fninfo;
599 ident name; mcode print_string_box lp;
600 parameter_list params; close_box(); mcode print_string rp;
601 print_string " "
602 | Ast.Decl(bef,allminus,decl) ->
8f657093 603 mcode (function _ -> ()) ((),Ast.no_info,bef,[]);
34e49164
C
604 print_string arity;
605 declaration decl
606 | Ast.SeqStart(brace) ->
607 print_string arity; mcode print_string brace;
608 if !print_newlines_disj then start_block()
609 | Ast.SeqEnd(brace) ->
610 if !print_newlines_disj then end_block();
611 print_string arity; mcode print_string brace
612 | Ast.ExprStatement(exp,sem) ->
8babbc8f 613 print_string arity; print_option expression exp; mcode print_string sem
34e49164
C
614 | Ast.IfHeader(iff,lp,exp,rp) ->
615 print_string arity;
616 mcode print_string iff; print_string " "; mcode print_string_box lp;
617 expression exp; close_box(); mcode print_string rp; print_string " "
618 | Ast.Else(els) ->
619 print_string arity; mcode print_string els; print_string " "
620 | Ast.WhileHeader(whl,lp,exp,rp) ->
621 print_string arity;
622 mcode print_string whl; print_string " "; mcode print_string_box lp;
623 expression exp; close_box(); mcode print_string rp; print_string " "
624 | Ast.DoHeader(d) ->
625 print_string arity; mcode print_string d; print_string " "
626 | Ast.WhileTail(whl,lp,exp,rp,sem) ->
627 print_string arity;
628 mcode print_string whl; print_string " "; mcode print_string_box lp;
629 expression exp; close_box(); mcode print_string rp;
630 mcode print_string sem
755320b0 631 | Ast.ForHeader(fr,lp,first,e2,sem2,e3,rp) ->
34e49164 632 print_string arity;
755320b0 633 mcode print_string fr; mcode print_string_box lp; forinfo first;
34e49164
C
634 print_option expression e2; mcode print_string sem2;
635 print_option expression e3; close_box();
636 mcode print_string rp; print_string " "
637 | Ast.IteratorHeader(nm,lp,args,rp) ->
638 print_string arity;
639 ident nm; print_string " "; mcode print_string_box lp;
640 dots (function _ -> ()) expression args; close_box();
641 mcode print_string rp; print_string " "
642 | Ast.SwitchHeader(switch,lp,exp,rp) ->
643 print_string arity;
644 mcode print_string switch; print_string " "; mcode print_string_box lp;
645 expression exp; close_box(); mcode print_string rp; print_string " "
646 | Ast.Break(br,sem) ->
647 print_string arity; mcode print_string br; mcode print_string sem
648 | Ast.Continue(cont,sem) ->
649 print_string arity; mcode print_string cont; mcode print_string sem
650 | Ast.Label(l,dd) -> ident l; mcode print_string dd
651 | Ast.Goto(goto,l,sem) ->
652 mcode print_string goto; ident l; mcode print_string sem
653 | Ast.Return(ret,sem) ->
654 print_string arity; mcode print_string ret; mcode print_string sem
655 | Ast.ReturnExpr(ret,exp,sem) ->
656 print_string arity; mcode print_string ret; print_string " ";
657 expression exp; mcode print_string sem
658 | Ast.MetaRuleElem(name,_,_) ->
659 print_string arity; mcode print_meta name
660 | Ast.MetaStmt(name,_,_,_) ->
661 print_string arity; mcode print_meta name
662 | Ast.MetaStmtList(name,_,_) ->
663 print_string arity; mcode print_meta name
664 | Ast.Exp(exp) -> print_string arity; expression exp
665 | Ast.TopExp(exp) -> print_string arity; expression exp
666 | Ast.Ty(ty) -> print_string arity; fullType ty
1be43e12 667 | Ast.TopInit(init) -> initialiser init
34e49164
C
668 | Ast.Include(inc,s) ->
669 mcode print_string inc; print_string " "; mcode inc_file s
3a314143
C
670 | Ast.Undef(def,id) ->
671 mcode print_string def; print_string " "; ident id
34e49164
C
672 | Ast.DefineHeader(def,id,params) ->
673 mcode print_string def; print_string " "; ident id;
674 print_define_parameters params
675 | Ast.Default(def,colon) ->
676 mcode print_string def; mcode print_string colon; print_string " "
677 | Ast.Case(case,exp,colon) ->
678 mcode print_string case; print_string " "; expression exp;
679 mcode print_string colon; print_string " "
680 | Ast.DisjRuleElem(res) ->
681 print_string arity;
682 force_newline(); print_string "("; force_newline();
683 print_between
684 (function _ -> force_newline();print_string "|"; force_newline())
685 (rule_elem arity)
686 res;
687 force_newline(); print_string ")"
688
755320b0
C
689and forinfo = function
690 Ast.ForExp(e1,sem1) ->
691 print_option expression e1; mcode print_string sem1
692 | Ast.ForDecl (bef,allminus,decl) ->
693 mcode (function _ -> ()) ((),Ast.no_info,bef,[]);
694 declaration decl
34e49164
C
695
696and print_define_parameters params =
697 match Ast.unwrap params with
698 Ast.NoParams -> ()
699 | Ast.DParams(lp,params,rp) ->
700 mcode print_string lp;
701 dots (function _ -> ()) print_define_param params; mcode print_string rp
702
703and print_define_param param =
704 match Ast.unwrap param with
705 Ast.DParam(id) -> ident id
706 | Ast.DPComma(comma) -> mcode print_string comma
707 | Ast.DPdots(dots) -> mcode print_string dots
708 | Ast.DPcircles(circles) -> mcode print_string circles
709 | Ast.OptDParam(dp) -> print_string "?"; print_define_param dp
710 | Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp
711
712and statement arity s =
713 match Ast.unwrap s with
708f4980 714 Ast.Seq(lbrace,body,rbrace) ->
34e49164 715 rule_elem arity lbrace;
34e49164
C
716 dots force_newline (statement arity) body;
717 rule_elem arity rbrace
718 | Ast.IfThen(header,branch,(_,_,_,aft)) ->
719 rule_elem arity header; statement arity branch;
8f657093 720 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
721 | Ast.IfThenElse(header,branch1,els,branch2,(_,_,_,aft)) ->
722 rule_elem arity header; statement arity branch1; print_string " ";
723 rule_elem arity els; statement arity branch2;
8f657093 724 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
725 | Ast.While(header,body,(_,_,_,aft)) ->
726 rule_elem arity header; statement arity body;
8f657093 727 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
728 | Ast.Do(header,body,tail) ->
729 rule_elem arity header; statement arity body;
730 rule_elem arity tail
731 | Ast.For(header,body,(_,_,_,aft)) ->
732 rule_elem arity header; statement arity body;
8f657093 733 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
734 | Ast.Iterator(header,body,(_,_,_,aft)) ->
735 rule_elem arity header; statement arity body;
8f657093 736 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
fc1ad971 737 | Ast.Switch(header,lb,decls,cases,rb) ->
34e49164 738 rule_elem arity header; rule_elem arity lb;
fc1ad971 739 dots force_newline (statement arity) decls;
34e49164
C
740 List.iter (function x -> case_line arity x; force_newline()) cases;
741 rule_elem arity rb
742 | Ast.Atomic(re) -> rule_elem arity re
708f4980 743 | Ast.FunDecl(header,lbrace,body,rbrace) ->
34e49164 744 rule_elem arity header; rule_elem arity lbrace;
34e49164
C
745 dots force_newline (statement arity) body;
746 rule_elem arity rbrace
747 | Ast.Disj([stmt_dots]) ->
748 print_string arity;
749 dots (function _ -> if !print_newlines_disj then force_newline())
750 (statement arity) stmt_dots
751 | Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *)
752 print_string arity;
753 force_newline(); print_string "("; force_newline();
754 print_between
755 (function _ -> force_newline();print_string "|"; force_newline())
756 (dots force_newline (statement arity))
757 stmt_dots_list;
758 force_newline(); print_string ")"
759 | Ast.Define(header,body) ->
760 rule_elem arity header; print_string " ";
761 dots force_newline (statement arity) body
17ba0788
C
762 | Ast.AsStmt(stm,asstm) ->
763 statement arity stm; print_string "@"; statement arity asstm
5636bb2c 764 | Ast.Nest(starter,stmt_dots,ender,whn,multi,_,_) ->
34e49164 765 print_string arity;
5636bb2c 766 nest_dots starter ender (statement arity)
34e49164
C
767 (function _ ->
768 open_box 0;
769 print_between force_newline
770 (whencode (dots force_newline (statement "")) (statement "")) whn;
771 close_box(); force_newline())
772 stmt_dots
773 | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) ->
774 print_string arity; mcode print_string d;
775 open_box 0;
776 print_between force_newline
777 (whencode (dots force_newline (statement "")) (statement "")) whn;
778 close_box(); force_newline()
779 | Ast.OptStm(s) -> statement "?" s
780 | Ast.UniqueStm(s) -> statement "!" s
781
782and print_statement_when whencode =
783 print_string " WHEN != ";
784 open_box 0;
785 print_between (function _ -> print_string " &"; force_newline())
786 (dots force_newline (statement "")) whencode;
787 close_box()
788
789
790and whencode notfn alwaysfn = function
791 Ast.WhenNot a ->
792 print_string " WHEN != "; open_box 0; notfn a; close_box()
793 | Ast.WhenAlways a ->
794 print_string " WHEN = "; open_box 0; alwaysfn a; close_box()
795 | Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x
1be43e12
C
796 | Ast.WhenNotTrue a ->
797 print_string " WHEN != TRUE "; open_box 0; rule_elem "" a; close_box()
798 | Ast.WhenNotFalse a ->
799 print_string " WHEN != FALSE "; open_box 0; rule_elem "" a; close_box()
34e49164
C
800
801and print_when_modif = function
802 | Ast.WhenAny -> print_string "ANY"
803 | Ast.WhenStrict -> print_string "STRICT"
804 | Ast.WhenForall -> print_string "FORALL"
805 | Ast.WhenExists -> print_string "EXISTS"
806
807and case_line arity c =
808 match Ast.unwrap c with
809 Ast.CaseLine(header,code) ->
810 rule_elem arity header; print_string " ";
811 dots force_newline (statement arity) code
812 | Ast.OptCase(case) -> case_line "?" case
813
814(* --------------------------------------------------------------------- *)
815(* CPP code *)
816
817and inc_file = function
818 Ast.Local(elems) ->
819 print_string "\"";
820 print_between (function _ -> print_string "/") inc_elem elems;
821 print_string "\""
822 | Ast.NonLocal(elems) ->
823 print_string "<";
824 print_between (function _ -> print_string "/") inc_elem elems;
825 print_string ">"
826
827and inc_elem = function
828 Ast.IncPath s -> print_string s
829 | Ast.IncDots -> print_string "..."
830
831(* for export only *)
832let statement_dots l = dots force_newline (statement "") l
833
834let top_level t =
835 match Ast.unwrap t with
836 Ast.FILEINFO(old_file,new_file) ->
837 print_string "--- "; mcode print_string old_file; force_newline();
838 print_string "+++ "; mcode print_string new_file
65038c61 839 | Ast.NONDECL(stmt) -> statement "" stmt
34e49164
C
840 | Ast.CODE(stmt_dots) ->
841 dots force_newline (statement "") stmt_dots
842 | Ast.ERRORWORDS(exps) ->
843 print_string "error words = [";
844 print_between (function _ -> print_string ", ") expression exps;
845 print_string "]"
846
847let rule =
848 print_between (function _ -> force_newline(); force_newline()) top_level
849
850let pp_print_anything x = !anything x
851
852let _ =
853 anything := function
854 Ast.FullTypeTag(x) -> fullType x
855 | Ast.BaseTypeTag(x) -> baseType x
856 | Ast.StructUnionTag(x) -> structUnion x
857 | Ast.SignTag(x) -> sign x
858 | Ast.IdentTag(x) -> ident x
859 | Ast.ExpressionTag(x) -> expression x
860 | Ast.ConstantTag(x) -> constant x
861 | Ast.UnaryOpTag(x) -> unaryOp x
862 | Ast.AssignOpTag(x) -> assignOp x
863 | Ast.FixOpTag(x) -> fixOp x
864 | Ast.BinaryOpTag(x) -> binaryOp x
865 | Ast.ArithOpTag(x) -> arithOp x
866 | Ast.LogicalOpTag(x) -> logicalOp x
867 | Ast.InitTag(x) -> initialiser x
868 | Ast.DeclarationTag(x) -> declaration x
869 | Ast.StorageTag(x) -> storage x
870 | Ast.IncFileTag(x) -> inc_file x
871 | Ast.Rule_elemTag(x) -> rule_elem "" x
872 | Ast.StatementTag(x) -> statement "" x
755320b0 873 | Ast.ForInfoTag(x) -> forinfo x
34e49164
C
874 | Ast.CaseLineTag(x) -> case_line "" x
875 | Ast.ConstVolTag(x) -> const_vol x
876 | Ast.Token(x,Some info) -> print_string_befaft print_string x info
877 | Ast.Token(x,None) -> print_string x
c3e37e97 878 | Ast.Pragma(xs) ->
190f1acf
C
879 let print = function
880 Ast.Noindent s | Ast.Indent s | Ast.Space s -> print_string s in
c3e37e97 881 print_between force_newline print xs
34e49164
C
882 | Ast.Code(x) -> let _ = top_level x in ()
883 | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x
884 | Ast.ParamDotsTag(x) -> parameter_list x
885 | Ast.StmtDotsTag(x) -> dots (function _ -> ()) (statement "") x
886 | Ast.DeclDotsTag(x) -> dots (function _ -> ()) declaration x
887 | Ast.TypeCTag(x) -> typeC x
888 | Ast.ParamTag(x) -> parameterTypeDef x
889 | Ast.SgrepStartTag(x) -> print_string x
890 | Ast.SgrepEndTag(x) -> print_string x
891
892let rec dep in_and = function
893 Ast.Dep(s) -> print_string s
894 | Ast.AntiDep(s) -> print_string "!"; print_string s
895 | Ast.EverDep(s) -> print_string "ever "; print_string s
896 | Ast.NeverDep(s) -> print_string "never "; print_string s
897 | Ast.AndDep(s1,s2) ->
898 let print_and _ = dep true s1; print_string " && "; dep true s2 in
899 if in_and
900 then print_and ()
901 else (print_string "("; print_and(); print_string ")")
902 | Ast.OrDep(s1,s2) ->
903 let print_or _ = dep false s1; print_string " || "; dep false s2 in
904 if not in_and
905 then print_or ()
906 else (print_string "("; print_or(); print_string ")")
7f004419
C
907 | Ast.NoDep -> print_string "no_dep"
908 | Ast.FailDep -> print_string "fail_dep"
34e49164 909
c3e37e97
C
910let script_header str lang deps code =
911 print_string "@@";
912 force_newline();
913 print_string (str ^ ":" ^ lang);
914 (match deps with
915 Ast.NoDep -> ()
916 | _ -> print_string " depends on "; dep true deps);
917 force_newline();
918 print_string "@@";
919 force_newline();
d6ce1786
C
920 let code =
921 String.concat "\n"
922 (Str.split (Str.regexp "[\n\r\011\012]#.*[\n\r\011\012]") code) in
c3e37e97
C
923 print_string code;
924 force_newline()
925
34e49164
C
926let unparse z =
927 match z with
174d1640 928 Ast.InitialScriptRule (name,lang,deps,code) ->
c3e37e97 929 script_header "initialize" lang deps code
174d1640 930 | Ast.FinalScriptRule (name,lang,deps,code) ->
c3e37e97 931 script_header "finalize" lang deps code
413ffc02 932 | Ast.ScriptRule (name,lang,deps,bindings,script_vars,code) ->
c3e37e97 933 script_header "script" lang deps code
faf9a90c 934 | Ast.CocciRule (nm, (deps, drops, exists), x, _, _) ->
b1b2de81
C
935 print_string "@@";
936 force_newline();
937 print_string nm;
938 (match deps with
939 Ast.NoDep -> ()
940 | _ -> print_string " depends on "; dep true deps);
34e49164
C
941 (*
942 print_string "line ";
943 print_int (Ast.get_line (List.hd x));
944 *)
b1b2de81
C
945 force_newline();
946 print_string "@@";
947 print_newlines_disj := true;
948 force_newline();
949 force_newline();
950 rule x;
951 force_newline()
34e49164
C
952
953let rule_elem_to_string x =
954 print_newlines_disj := true;
955 Common.format_to_string (function _ -> rule_elem "" x)
956
957let ident_to_string x =
958 print_newlines_disj := true;
959 Common.format_to_string (function _ -> ident x)
960
961let unparse_to_string x =
962 print_newlines_disj := true;
963 Common.format_to_string (function _ -> unparse x)
964
965let print_rule_elem re =
966 let nl = !print_newlines_disj in
967 print_newlines_disj := false;
968 rule_elem "" re;
969 print_newlines_disj := nl
970