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