Coccinelle release 1.0.0-rc12
[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.
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
213 | Ast.DisjId(id_list) -> print_disj_list ident id_list
214 | Ast.OptIdent(id) -> print_string "?"; ident id
215 | Ast.UniqueIdent(id) -> print_string "!"; ident id
34e49164
C
216
217and print_unitary = function
218 Type_cocci.Unitary -> print_string "unitary"
219 | Type_cocci.Nonunitary -> print_string "nonunitary"
220 | Type_cocci.Saved -> print_string "saved"
221
222(* --------------------------------------------------------------------- *)
223(* Expression *)
224
34e49164
C
225let rec expression e =
226 match Ast.unwrap e with
227 Ast.Ident(id) -> ident id
228 | Ast.Constant(const) -> mcode constant const
229 | Ast.FunCall(fn,lp,args,rp) ->
230 expression fn; mcode print_string_box lp;
231 dots (function _ -> ()) expression args;
232 close_box(); mcode print_string rp
233 | Ast.Assignment(left,op,right,simple) ->
234 expression left; print_string " "; mcode assignOp op;
235 print_string " "; expression right
17ba0788
C
236 | Ast.Sequence(left,op,right) ->
237 expression left; mcode print_string op;
238 print_string " "; expression right
34e49164
C
239 | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
240 expression exp1; print_string " "; mcode print_string why;
241 print_option (function e -> print_string " "; expression e) exp2;
242 print_string " "; mcode print_string colon; expression exp3
243 | Ast.Postfix(exp,op) -> expression exp; mcode fixOp op
244 | Ast.Infix(exp,op) -> mcode fixOp op; expression exp
245 | Ast.Unary(exp,op) -> mcode unaryOp op; expression exp
246 | Ast.Binary(left,op,right) ->
247 expression left; print_string " "; mcode binaryOp op; print_string " ";
248 expression right
249 | Ast.Nested(left,op,right) ->
250 expression left; print_string " "; mcode binaryOp op; print_string " ";
251 expression right
252 | Ast.Paren(lp,exp,rp) ->
253 mcode print_string_box lp; expression exp; close_box();
254 mcode print_string rp
255 | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
256 expression exp1; mcode print_string_box lb; expression exp2; close_box();
257 mcode print_string rb
258 | Ast.RecordAccess(exp,pt,field) ->
259 expression exp; mcode print_string pt; ident field
260 | Ast.RecordPtAccess(exp,ar,field) ->
261 expression exp; mcode print_string ar; ident field
262 | Ast.Cast(lp,ty,rp,exp) ->
263 mcode print_string_box lp; fullType ty; close_box();
264 mcode print_string rp; expression exp
265 | Ast.SizeOfExpr(sizeof,exp) ->
266 mcode print_string sizeof; expression exp
267 | Ast.SizeOfType(sizeof,lp,ty,rp) ->
268 mcode print_string sizeof;
269 mcode print_string_box lp; fullType ty; close_box();
270 mcode print_string rp
271 | Ast.TypeExp(ty) -> fullType ty
7fe62b65
C
272 | Ast.Constructor(lp,ty,rp,init) ->
273 mcode print_string_box lp; fullType ty; close_box();
274 mcode print_string rp; initialiser init
34e49164
C
275
276 | Ast.MetaErr(name,_,_,_) -> mcode print_meta name
277 | Ast.MetaExpr(name,_,keep,ty,form,inherited) ->
278 mcode print_meta name; print_type keep inherited ty
279 | Ast.MetaExprList(name,_,_,_) -> mcode print_meta name
17ba0788 280 | Ast.AsExpr(exp,asexp) -> expression exp; print_string "@"; expression asexp
34e49164
C
281 | Ast.EComma(cm) -> mcode print_string cm; print_space()
282 | Ast.DisjExpr(exp_list) -> print_disj_list expression exp_list
5636bb2c
C
283 | Ast.NestExpr(starter,expr_dots,ender,Some whencode,multi) ->
284 nest_dots starter ender expression
34e49164
C
285 (function _ -> print_string " when != "; expression whencode)
286 expr_dots
5636bb2c
C
287 | Ast.NestExpr(starter,expr_dots,ender,None,multi) ->
288 nest_dots starter ender expression (function _ -> ()) expr_dots
34e49164
C
289 | Ast.Edots(dots,Some whencode)
290 | Ast.Ecircles(dots,Some whencode)
291 | Ast.Estars(dots,Some whencode) ->
292 mcode print_string dots; print_string " when != "; expression whencode
293 | Ast.Edots(dots,None)
294 | Ast.Ecircles(dots,None)
295 | Ast.Estars(dots,None) -> mcode print_string dots
296 | Ast.OptExp(exp) -> print_string "?"; expression exp
297 | Ast.UniqueExp(exp) -> print_string "!"; expression exp
298
299and unaryOp = function
300 Ast.GetRef -> print_string "&"
8babbc8f 301 | Ast.GetRefLabel -> print_string "&&"
34e49164
C
302 | Ast.DeRef -> print_string "*"
303 | Ast.UnPlus -> print_string "+"
304 | Ast.UnMinus -> print_string "-"
305 | Ast.Tilde -> print_string "~"
306 | Ast.Not -> print_string "!"
307
308and assignOp = function
309 Ast.SimpleAssign -> print_string "="
310 | Ast.OpAssign(aop) -> arithOp aop; print_string "="
311
312and fixOp = function
313 Ast.Dec -> print_string "--"
314 | Ast.Inc -> print_string "++"
315
316and binaryOp = function
317 Ast.Arith(aop) -> arithOp aop
318 | Ast.Logical(lop) -> logicalOp lop
319
320and arithOp = function
321 Ast.Plus -> print_string "+"
322 | Ast.Minus -> print_string "-"
323 | Ast.Mul -> print_string "*"
324 | Ast.Div -> print_string "/"
325 | Ast.Mod -> print_string "%"
326 | Ast.DecLeft -> print_string "<<"
327 | Ast.DecRight -> print_string ">>"
328 | Ast.And -> print_string "&"
329 | Ast.Or -> print_string "|"
330 | Ast.Xor -> print_string "^"
331
332and logicalOp = function
333 Ast.Inf -> print_string "<"
334 | Ast.Sup -> print_string ">"
335 | Ast.InfEq -> print_string "<="
336 | Ast.SupEq -> print_string ">="
337 | Ast.Eq -> print_string "=="
338 | Ast.NotEq -> print_string "!="
339 | Ast.AndLog -> print_string "&&"
340 | Ast.OrLog -> print_string "||"
341
342and constant = function
343 Ast.String(s) -> print_string "\""; print_string s; print_string "\""
344 | Ast.Char(s) -> print_string "'"; print_string s; print_string "'"
345 | Ast.Int(s) -> print_string s
346 | Ast.Float(s) -> print_string s
347
348(* --------------------------------------------------------------------- *)
349(* Declarations *)
350
351and storage = function
352 Ast.Static -> print_string "static "
353 | Ast.Auto -> print_string "auto "
354 | Ast.Register -> print_string "register "
355 | Ast.Extern -> print_string "extern "
356
357(* --------------------------------------------------------------------- *)
358(* Types *)
359
360and fullType ft =
361 match Ast.unwrap ft with
17ba0788 362 Ast.Type(_,cv,ty) ->
34e49164
C
363 print_option (function x -> mcode const_vol x; print_string " ") cv;
364 typeC ty
17ba0788 365 | Ast.AsType(ty,asty) -> fullType ty; print_string "@"; fullType asty
34e49164
C
366 | Ast.DisjType(decls) -> print_disj_list fullType decls
367 | Ast.OptType(ty) -> print_string "?"; fullType ty
368 | Ast.UniqueType(ty) -> print_string "!"; fullType ty
369
370and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn =
371 fullType ty; mcode print_string lp1; mcode print_string star; fn();
372 mcode print_string rp1; mcode print_string lp1;
373 parameter_list params; mcode print_string rp2
374
375and print_function_type (ty,lp1,params,rp1) fn =
376 print_option fullType ty; fn(); mcode print_string lp1;
377 parameter_list params; mcode print_string rp1
378
379and print_fninfo = function
380 Ast.FStorage(stg) -> mcode storage stg
381 | Ast.FType(ty) -> fullType ty
382 | Ast.FInline(inline) -> mcode print_string inline; print_string " "
383 | Ast.FAttr(attr) -> mcode print_string attr; print_string " "
384
385and typeC ty =
386 match Ast.unwrap ty with
faf9a90c
C
387 Ast.BaseType(ty,strings) ->
388 List.iter (function s -> mcode print_string s; print_string " ") strings
389 | Ast.SignedT(sgn,ty) -> mcode sign sgn; print_option typeC ty
34e49164
C
390 | Ast.Pointer(ty,star) -> fullType ty; mcode print_string star
391 | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
392 print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
393 (function _ -> ())
394 | Ast.FunctionType (_,ty,lp1,params,rp1) ->
395 print_function_type (ty,lp1,params,rp1) (function _ -> ())
396 | Ast.Array(ty,lb,size,rb) ->
397 fullType ty; mcode print_string lb; print_option expression size;
398 mcode print_string rb
c491d8ee
C
399 | Ast.EnumName(kind,name) ->
400 mcode print_string kind;
401 print_option (function x -> ident x; print_string " ") name
402 | Ast.EnumDef(ty,lb,ids,rb) ->
403 fullType ty; mcode print_string lb;
404 dots force_newline expression ids;
405 mcode print_string rb
34e49164
C
406 | Ast.StructUnionName(kind,name) ->
407 mcode structUnion kind;
408 print_option (function x -> ident x; print_string " ") name
409 | Ast.StructUnionDef(ty,lb,decls,rb) ->
410 fullType ty; mcode print_string lb;
411 dots force_newline declaration decls;
412 mcode print_string rb
413 | Ast.TypeName(name) -> mcode print_string name; print_string " "
414 | Ast.MetaType(name,_,_) ->
415 mcode print_meta name; print_string " "
416
417and baseType = function
418 Ast.VoidType -> print_string "void "
419 | Ast.CharType -> print_string "char "
420 | Ast.ShortType -> print_string "short "
f3c4ece6 421 | Ast.ShortIntType -> print_string "short int "
34e49164
C
422 | Ast.IntType -> print_string "int "
423 | Ast.DoubleType -> print_string "double "
f3c4ece6 424 | Ast.LongDoubleType -> print_string "long double "
34e49164
C
425 | Ast.FloatType -> print_string "float "
426 | Ast.LongType -> print_string "long "
f3c4ece6 427 | Ast.LongIntType -> print_string "long int "
faf9a90c 428 | Ast.LongLongType -> print_string "long long "
f3c4ece6 429 | Ast.LongLongIntType -> print_string "long long int "
1eddfd50
C
430 | Ast.SizeType -> print_string "size_t "
431 | Ast.SSizeType -> print_string "ssize_t "
432 | Ast.PtrDiffType -> print_string "ptrdiff_t "
34e49164
C
433
434and structUnion = function
435 Ast.Struct -> print_string "struct "
436 | Ast.Union -> print_string "union "
437
438and sign = function
439 Ast.Signed -> print_string "signed "
440 | Ast.Unsigned -> print_string "unsigned "
441
442and const_vol = function
443 Ast.Const -> print_string "const"
444 | Ast.Volatile -> print_string "volatile"
445
446(* --------------------------------------------------------------------- *)
447(* Variable declaration *)
448(* Even if the Cocci program specifies a list of declarations, they are
449 split out into multiple declarations of a single variable each. *)
450
451and print_named_type ty id =
452 match Ast.unwrap ty with
17ba0788 453 Ast.Type(_,None,ty1) ->
34e49164
C
454 (match Ast.unwrap ty1 with
455 Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
456 print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
457 (function _ -> print_string " "; ident id)
458 | Ast.FunctionType(_,ty,lp1,params,rp1) ->
459 print_function_type (ty,lp1,params,rp1)
460 (function _ -> print_string " "; ident id)
461 | Ast.Array(ty,lb,size,rb) ->
462 let rec loop ty k =
463 match Ast.unwrap ty with
464 Ast.Array(ty,lb,size,rb) ->
465 (match Ast.unwrap ty with
17ba0788
C
466 Ast.Type(_,cv,ty) ->
467 print_option
468 (function x -> mcode const_vol x; print_string " ")
469 cv;
34e49164
C
470 loop ty
471 (function _ ->
472 k ();
473 mcode print_string lb;
474 print_option expression size;
475 mcode print_string rb)
476 | _ -> failwith "complex array types not supported")
477 | _ -> typeC ty; ident id; k () in
478 loop ty1 (function _ -> ())
479 | _ -> fullType ty; ident id)
480 | _ -> fullType ty; ident id
481
482and declaration d =
483 match Ast.unwrap d with
190f1acf
C
484 Ast.MetaDecl(name,_,_) | Ast.MetaField(name,_,_)
485 | Ast.MetaFieldList(name,_,_,_) ->
486 mcode print_meta name
17ba0788
C
487 | Ast.AsDecl(decl,asdecl) -> declaration decl; print_string "@";
488 declaration asdecl
413ffc02 489 | Ast.Init(stg,ty,id,eq,ini,sem) ->
34e49164
C
490 print_option (mcode storage) stg; print_named_type ty id;
491 print_string " "; mcode print_string eq;
492 print_string " "; initialiser ini; mcode print_string sem
493 | Ast.UnInit(stg,ty,id,sem) ->
494 print_option (mcode storage) stg; print_named_type ty id;
495 mcode print_string sem
496 | Ast.MacroDecl(name,lp,args,rp,sem) ->
497 ident name; mcode print_string_box lp;
498 dots (function _ -> ()) expression args;
499 close_box(); mcode print_string rp; mcode print_string sem
17ba0788
C
500 | Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
501 ident name; mcode print_string_box lp;
502 dots (function _ -> ()) expression args;
503 close_box(); mcode print_string rp;
504 print_string " "; mcode print_string eq;
505 print_string " "; initialiser ini; mcode print_string sem
34e49164
C
506 | Ast.TyDecl(ty,sem) -> fullType ty; mcode print_string sem
507 | Ast.Typedef(stg,ty,id,sem) ->
508 mcode print_string stg; print_string " "; fullType ty; typeC id;
509 mcode print_string sem
510 | Ast.DisjDecl(decls) -> print_disj_list declaration decls
faf9a90c 511 | Ast.Ddots(dots,Some whencode) ->
34e49164
C
512 mcode print_string dots; print_string " when != "; declaration whencode
513 | Ast.Ddots(dots,None) -> mcode print_string dots
34e49164
C
514 | Ast.OptDecl(decl) -> print_string "?"; declaration decl
515 | Ast.UniqueDecl(decl) -> print_string "!"; declaration decl
516
517(* --------------------------------------------------------------------- *)
518(* Initialiser *)
519
520and initialiser i =
521 match Ast.unwrap i with
113803cf
C
522 Ast.MetaInit(name,_,_) ->
523 mcode print_meta name; print_string " "
8f657093
C
524 | Ast.MetaInitList(name,_,_,_) ->
525 mcode print_meta name; print_string " "
17ba0788
C
526 | Ast.AsInit(ini,asini) -> initialiser ini; print_string "@";
527 initialiser asini
113803cf 528 | Ast.InitExpr(exp) -> expression exp
c491d8ee
C
529 | Ast.ArInitList(lb,initlist,rb) ->
530 mcode print_string lb; open_box 0;
531 dots force_newline initialiser initlist; close_box();
532 mcode print_string rb
533 | Ast.StrInitList(allminus,lb,initlist,rb,whencode) ->
34e49164
C
534 mcode print_string lb; open_box 0;
535 if not (whencode = [])
536 then
537 (print_string " WHEN != ";
538 print_between (function _ -> print_string " v ")
539 initialiser whencode;
540 force_newline());
541 List.iter initialiser initlist; close_box();
542 mcode print_string rb
113803cf
C
543 | Ast.InitGccExt(designators,eq,ini) ->
544 List.iter designator designators; print_string " ";
34e49164
C
545 mcode print_string eq; print_string " "; initialiser ini
546 | Ast.InitGccName(name,eq,ini) ->
547 ident name; mcode print_string eq; initialiser ini
34e49164 548 | Ast.IComma(comma) -> mcode print_string comma; force_newline()
c491d8ee
C
549 | Ast.Idots(dots,Some whencode) ->
550 mcode print_string dots; print_string " when != "; initialiser whencode
551 | Ast.Idots(dots,None) -> mcode print_string dots
34e49164
C
552 | Ast.OptIni(ini) -> print_string "?"; initialiser ini
553 | Ast.UniqueIni(ini) -> print_string "!"; initialiser ini
554
113803cf
C
555and designator = function
556 Ast.DesignatorField(dot,id) -> mcode print_string dot; ident id
557 | Ast.DesignatorIndex(lb,exp,rb) ->
558 mcode print_string lb; expression exp; mcode print_string rb
559 | Ast.DesignatorRange(lb,min,dots,max,rb) ->
560 mcode print_string lb; expression min; mcode print_string dots;
561 expression max; mcode print_string rb
562
34e49164
C
563(* --------------------------------------------------------------------- *)
564(* Parameter *)
565
566and parameterTypeDef p =
567 match Ast.unwrap p with
568 Ast.VoidParam(ty) -> fullType ty
569 | Ast.Param(ty,Some id) -> print_named_type ty id
570 | Ast.Param(ty,None) -> fullType ty
571 | Ast.MetaParam(name,_,_) -> mcode print_meta name
572 | Ast.MetaParamList(name,_,_,_) -> mcode print_meta name
573 | Ast.PComma(cm) -> mcode print_string cm; print_space()
574 | Ast.Pdots(dots) -> mcode print_string dots
575 | Ast.Pcircles(dots) -> mcode print_string dots
576 | Ast.OptParam(param) -> print_string "?"; parameterTypeDef param
577 | Ast.UniqueParam(param) -> print_string "!"; parameterTypeDef param
578
579and parameter_list l = dots (function _ -> ()) parameterTypeDef l
580
581(* --------------------------------------------------------------------- *)
582(* Top-level code *)
583
584let rec rule_elem arity re =
585 match Ast.unwrap re with
586 Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) ->
8f657093 587 mcode (function _ -> ()) ((),Ast.no_info,bef,[]);
34e49164
C
588 print_string arity; List.iter print_fninfo fninfo;
589 ident name; mcode print_string_box lp;
590 parameter_list params; close_box(); mcode print_string rp;
591 print_string " "
592 | Ast.Decl(bef,allminus,decl) ->
8f657093 593 mcode (function _ -> ()) ((),Ast.no_info,bef,[]);
34e49164
C
594 print_string arity;
595 declaration decl
596 | Ast.SeqStart(brace) ->
597 print_string arity; mcode print_string brace;
598 if !print_newlines_disj then start_block()
599 | Ast.SeqEnd(brace) ->
600 if !print_newlines_disj then end_block();
601 print_string arity; mcode print_string brace
602 | Ast.ExprStatement(exp,sem) ->
8babbc8f 603 print_string arity; print_option expression exp; mcode print_string sem
34e49164
C
604 | Ast.IfHeader(iff,lp,exp,rp) ->
605 print_string arity;
606 mcode print_string iff; print_string " "; mcode print_string_box lp;
607 expression exp; close_box(); mcode print_string rp; print_string " "
608 | Ast.Else(els) ->
609 print_string arity; mcode print_string els; print_string " "
610 | Ast.WhileHeader(whl,lp,exp,rp) ->
611 print_string arity;
612 mcode print_string whl; print_string " "; mcode print_string_box lp;
613 expression exp; close_box(); mcode print_string rp; print_string " "
614 | Ast.DoHeader(d) ->
615 print_string arity; mcode print_string d; print_string " "
616 | Ast.WhileTail(whl,lp,exp,rp,sem) ->
617 print_string arity;
618 mcode print_string whl; print_string " "; mcode print_string_box lp;
619 expression exp; close_box(); mcode print_string rp;
620 mcode print_string sem
621 | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
622 print_string arity;
623 mcode print_string fr; mcode print_string_box lp;
624 print_option expression e1; mcode print_string sem1;
625 print_option expression e2; mcode print_string sem2;
626 print_option expression e3; close_box();
627 mcode print_string rp; print_string " "
628 | Ast.IteratorHeader(nm,lp,args,rp) ->
629 print_string arity;
630 ident nm; print_string " "; mcode print_string_box lp;
631 dots (function _ -> ()) expression args; close_box();
632 mcode print_string rp; print_string " "
633 | Ast.SwitchHeader(switch,lp,exp,rp) ->
634 print_string arity;
635 mcode print_string switch; print_string " "; mcode print_string_box lp;
636 expression exp; close_box(); mcode print_string rp; print_string " "
637 | Ast.Break(br,sem) ->
638 print_string arity; mcode print_string br; mcode print_string sem
639 | Ast.Continue(cont,sem) ->
640 print_string arity; mcode print_string cont; mcode print_string sem
641 | Ast.Label(l,dd) -> ident l; mcode print_string dd
642 | Ast.Goto(goto,l,sem) ->
643 mcode print_string goto; ident l; mcode print_string sem
644 | Ast.Return(ret,sem) ->
645 print_string arity; mcode print_string ret; mcode print_string sem
646 | Ast.ReturnExpr(ret,exp,sem) ->
647 print_string arity; mcode print_string ret; print_string " ";
648 expression exp; mcode print_string sem
649 | Ast.MetaRuleElem(name,_,_) ->
650 print_string arity; mcode print_meta name
651 | Ast.MetaStmt(name,_,_,_) ->
652 print_string arity; mcode print_meta name
653 | Ast.MetaStmtList(name,_,_) ->
654 print_string arity; mcode print_meta name
655 | Ast.Exp(exp) -> print_string arity; expression exp
656 | Ast.TopExp(exp) -> print_string arity; expression exp
657 | Ast.Ty(ty) -> print_string arity; fullType ty
1be43e12 658 | Ast.TopInit(init) -> initialiser init
34e49164
C
659 | Ast.Include(inc,s) ->
660 mcode print_string inc; print_string " "; mcode inc_file s
3a314143
C
661 | Ast.Undef(def,id) ->
662 mcode print_string def; print_string " "; ident id
34e49164
C
663 | Ast.DefineHeader(def,id,params) ->
664 mcode print_string def; print_string " "; ident id;
665 print_define_parameters params
666 | Ast.Default(def,colon) ->
667 mcode print_string def; mcode print_string colon; print_string " "
668 | Ast.Case(case,exp,colon) ->
669 mcode print_string case; print_string " "; expression exp;
670 mcode print_string colon; print_string " "
671 | Ast.DisjRuleElem(res) ->
672 print_string arity;
673 force_newline(); print_string "("; force_newline();
674 print_between
675 (function _ -> force_newline();print_string "|"; force_newline())
676 (rule_elem arity)
677 res;
678 force_newline(); print_string ")"
679
680
681and print_define_parameters params =
682 match Ast.unwrap params with
683 Ast.NoParams -> ()
684 | Ast.DParams(lp,params,rp) ->
685 mcode print_string lp;
686 dots (function _ -> ()) print_define_param params; mcode print_string rp
687
688and print_define_param param =
689 match Ast.unwrap param with
690 Ast.DParam(id) -> ident id
691 | Ast.DPComma(comma) -> mcode print_string comma
692 | Ast.DPdots(dots) -> mcode print_string dots
693 | Ast.DPcircles(circles) -> mcode print_string circles
694 | Ast.OptDParam(dp) -> print_string "?"; print_define_param dp
695 | Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp
696
697and statement arity s =
698 match Ast.unwrap s with
708f4980 699 Ast.Seq(lbrace,body,rbrace) ->
34e49164 700 rule_elem arity lbrace;
34e49164
C
701 dots force_newline (statement arity) body;
702 rule_elem arity rbrace
703 | Ast.IfThen(header,branch,(_,_,_,aft)) ->
704 rule_elem arity header; statement arity branch;
8f657093 705 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
706 | Ast.IfThenElse(header,branch1,els,branch2,(_,_,_,aft)) ->
707 rule_elem arity header; statement arity branch1; print_string " ";
708 rule_elem arity els; statement arity branch2;
8f657093 709 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
710 | Ast.While(header,body,(_,_,_,aft)) ->
711 rule_elem arity header; statement arity body;
8f657093 712 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
713 | Ast.Do(header,body,tail) ->
714 rule_elem arity header; statement arity body;
715 rule_elem arity tail
716 | Ast.For(header,body,(_,_,_,aft)) ->
717 rule_elem arity header; statement arity body;
8f657093 718 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
34e49164
C
719 | Ast.Iterator(header,body,(_,_,_,aft)) ->
720 rule_elem arity header; statement arity body;
8f657093 721 mcode (function _ -> ()) ((),Ast.no_info,aft,[])
fc1ad971 722 | Ast.Switch(header,lb,decls,cases,rb) ->
34e49164 723 rule_elem arity header; rule_elem arity lb;
fc1ad971 724 dots force_newline (statement arity) decls;
34e49164
C
725 List.iter (function x -> case_line arity x; force_newline()) cases;
726 rule_elem arity rb
727 | Ast.Atomic(re) -> rule_elem arity re
708f4980 728 | Ast.FunDecl(header,lbrace,body,rbrace) ->
34e49164 729 rule_elem arity header; rule_elem arity lbrace;
34e49164
C
730 dots force_newline (statement arity) body;
731 rule_elem arity rbrace
732 | Ast.Disj([stmt_dots]) ->
733 print_string arity;
734 dots (function _ -> if !print_newlines_disj then force_newline())
735 (statement arity) stmt_dots
736 | Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *)
737 print_string arity;
738 force_newline(); print_string "("; force_newline();
739 print_between
740 (function _ -> force_newline();print_string "|"; force_newline())
741 (dots force_newline (statement arity))
742 stmt_dots_list;
743 force_newline(); print_string ")"
744 | Ast.Define(header,body) ->
745 rule_elem arity header; print_string " ";
746 dots force_newline (statement arity) body
17ba0788
C
747 | Ast.AsStmt(stm,asstm) ->
748 statement arity stm; print_string "@"; statement arity asstm
5636bb2c 749 | Ast.Nest(starter,stmt_dots,ender,whn,multi,_,_) ->
34e49164 750 print_string arity;
5636bb2c 751 nest_dots starter ender (statement arity)
34e49164
C
752 (function _ ->
753 open_box 0;
754 print_between force_newline
755 (whencode (dots force_newline (statement "")) (statement "")) whn;
756 close_box(); force_newline())
757 stmt_dots
758 | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) ->
759 print_string arity; mcode print_string d;
760 open_box 0;
761 print_between force_newline
762 (whencode (dots force_newline (statement "")) (statement "")) whn;
763 close_box(); force_newline()
764 | Ast.OptStm(s) -> statement "?" s
765 | Ast.UniqueStm(s) -> statement "!" s
766
767and print_statement_when whencode =
768 print_string " WHEN != ";
769 open_box 0;
770 print_between (function _ -> print_string " &"; force_newline())
771 (dots force_newline (statement "")) whencode;
772 close_box()
773
774
775and whencode notfn alwaysfn = function
776 Ast.WhenNot a ->
777 print_string " WHEN != "; open_box 0; notfn a; close_box()
778 | Ast.WhenAlways a ->
779 print_string " WHEN = "; open_box 0; alwaysfn a; close_box()
780 | Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x
1be43e12
C
781 | Ast.WhenNotTrue a ->
782 print_string " WHEN != TRUE "; open_box 0; rule_elem "" a; close_box()
783 | Ast.WhenNotFalse a ->
784 print_string " WHEN != FALSE "; open_box 0; rule_elem "" a; close_box()
34e49164
C
785
786and print_when_modif = function
787 | Ast.WhenAny -> print_string "ANY"
788 | Ast.WhenStrict -> print_string "STRICT"
789 | Ast.WhenForall -> print_string "FORALL"
790 | Ast.WhenExists -> print_string "EXISTS"
791
792and case_line arity c =
793 match Ast.unwrap c with
794 Ast.CaseLine(header,code) ->
795 rule_elem arity header; print_string " ";
796 dots force_newline (statement arity) code
797 | Ast.OptCase(case) -> case_line "?" case
798
799(* --------------------------------------------------------------------- *)
800(* CPP code *)
801
802and inc_file = function
803 Ast.Local(elems) ->
804 print_string "\"";
805 print_between (function _ -> print_string "/") inc_elem elems;
806 print_string "\""
807 | Ast.NonLocal(elems) ->
808 print_string "<";
809 print_between (function _ -> print_string "/") inc_elem elems;
810 print_string ">"
811
812and inc_elem = function
813 Ast.IncPath s -> print_string s
814 | Ast.IncDots -> print_string "..."
815
816(* for export only *)
817let statement_dots l = dots force_newline (statement "") l
818
819let top_level t =
820 match Ast.unwrap t with
821 Ast.FILEINFO(old_file,new_file) ->
822 print_string "--- "; mcode print_string old_file; force_newline();
823 print_string "+++ "; mcode print_string new_file
65038c61 824 | Ast.NONDECL(stmt) -> statement "" stmt
34e49164
C
825 | Ast.CODE(stmt_dots) ->
826 dots force_newline (statement "") stmt_dots
827 | Ast.ERRORWORDS(exps) ->
828 print_string "error words = [";
829 print_between (function _ -> print_string ", ") expression exps;
830 print_string "]"
831
832let rule =
833 print_between (function _ -> force_newline(); force_newline()) top_level
834
835let pp_print_anything x = !anything x
836
837let _ =
838 anything := function
839 Ast.FullTypeTag(x) -> fullType x
840 | Ast.BaseTypeTag(x) -> baseType x
841 | Ast.StructUnionTag(x) -> structUnion x
842 | Ast.SignTag(x) -> sign x
843 | Ast.IdentTag(x) -> ident x
844 | Ast.ExpressionTag(x) -> expression x
845 | Ast.ConstantTag(x) -> constant x
846 | Ast.UnaryOpTag(x) -> unaryOp x
847 | Ast.AssignOpTag(x) -> assignOp x
848 | Ast.FixOpTag(x) -> fixOp x
849 | Ast.BinaryOpTag(x) -> binaryOp x
850 | Ast.ArithOpTag(x) -> arithOp x
851 | Ast.LogicalOpTag(x) -> logicalOp x
852 | Ast.InitTag(x) -> initialiser x
853 | Ast.DeclarationTag(x) -> declaration x
854 | Ast.StorageTag(x) -> storage x
855 | Ast.IncFileTag(x) -> inc_file x
856 | Ast.Rule_elemTag(x) -> rule_elem "" x
857 | Ast.StatementTag(x) -> statement "" x
858 | Ast.CaseLineTag(x) -> case_line "" x
859 | Ast.ConstVolTag(x) -> const_vol x
860 | Ast.Token(x,Some info) -> print_string_befaft print_string x info
861 | Ast.Token(x,None) -> print_string x
c3e37e97 862 | Ast.Pragma(xs) ->
190f1acf
C
863 let print = function
864 Ast.Noindent s | Ast.Indent s | Ast.Space s -> print_string s in
c3e37e97 865 print_between force_newline print xs
34e49164
C
866 | Ast.Code(x) -> let _ = top_level x in ()
867 | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x
868 | Ast.ParamDotsTag(x) -> parameter_list x
869 | Ast.StmtDotsTag(x) -> dots (function _ -> ()) (statement "") x
870 | Ast.DeclDotsTag(x) -> dots (function _ -> ()) declaration x
871 | Ast.TypeCTag(x) -> typeC x
872 | Ast.ParamTag(x) -> parameterTypeDef x
873 | Ast.SgrepStartTag(x) -> print_string x
874 | Ast.SgrepEndTag(x) -> print_string x
875
876let rec dep in_and = function
877 Ast.Dep(s) -> print_string s
878 | Ast.AntiDep(s) -> print_string "!"; print_string s
879 | Ast.EverDep(s) -> print_string "ever "; print_string s
880 | Ast.NeverDep(s) -> print_string "never "; print_string s
881 | Ast.AndDep(s1,s2) ->
882 let print_and _ = dep true s1; print_string " && "; dep true s2 in
883 if in_and
884 then print_and ()
885 else (print_string "("; print_and(); print_string ")")
886 | Ast.OrDep(s1,s2) ->
887 let print_or _ = dep false s1; print_string " || "; dep false s2 in
888 if not in_and
889 then print_or ()
890 else (print_string "("; print_or(); print_string ")")
7f004419
C
891 | Ast.NoDep -> print_string "no_dep"
892 | Ast.FailDep -> print_string "fail_dep"
34e49164 893
c3e37e97
C
894let script_header str lang deps code =
895 print_string "@@";
896 force_newline();
897 print_string (str ^ ":" ^ lang);
898 (match deps with
899 Ast.NoDep -> ()
900 | _ -> print_string " depends on "; dep true deps);
901 force_newline();
902 print_string "@@";
903 force_newline();
904 print_string code;
905 force_newline()
906
34e49164
C
907let unparse z =
908 match z with
174d1640 909 Ast.InitialScriptRule (name,lang,deps,code) ->
c3e37e97 910 script_header "initialize" lang deps code
174d1640 911 | Ast.FinalScriptRule (name,lang,deps,code) ->
c3e37e97 912 script_header "finalize" lang deps code
413ffc02 913 | Ast.ScriptRule (name,lang,deps,bindings,script_vars,code) ->
c3e37e97 914 script_header "script" lang deps code
faf9a90c 915 | Ast.CocciRule (nm, (deps, drops, exists), x, _, _) ->
b1b2de81
C
916 print_string "@@";
917 force_newline();
918 print_string nm;
919 (match deps with
920 Ast.NoDep -> ()
921 | _ -> print_string " depends on "; dep true deps);
34e49164
C
922 (*
923 print_string "line ";
924 print_int (Ast.get_line (List.hd x));
925 *)
b1b2de81
C
926 force_newline();
927 print_string "@@";
928 print_newlines_disj := true;
929 force_newline();
930 force_newline();
931 rule x;
932 force_newline()
34e49164
C
933
934let rule_elem_to_string x =
935 print_newlines_disj := true;
936 Common.format_to_string (function _ -> rule_elem "" x)
937
938let ident_to_string x =
939 print_newlines_disj := true;
940 Common.format_to_string (function _ -> ident x)
941
942let unparse_to_string x =
943 print_newlines_disj := true;
944 Common.format_to_string (function _ -> unparse x)
945
946let print_rule_elem re =
947 let nl = !print_newlines_disj in
948 print_newlines_disj := false;
949 rule_elem "" re;
950 print_newlines_disj := nl
951