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