79
85
print_anything bef; printer term; print_anything aft in
81
87
let print_string_befaft fn fn1 x info =
82
List.iter (function (s,_,_) -> fn1(); print_string s; force_newline())
89
(function (s,ln,col) -> fn1(); print_string s ln col; force_newline())
85
List.iter (function (s,_,_) -> force_newline(); fn1(); print_string s)
93
(function (s,ln,col) -> force_newline(); fn1(); print_string s ln col)
88
let print_meta (r,x) = print_string x in
96
let print_meta (r,x) = print_text x in
90
98
let print_pos = function
91
99
Ast.MetaPos(name,_,_,_,_) ->
92
100
let name = Ast.unwrap_mcode name in
93
print_string "@"; print_meta name
101
print_text "@"; print_meta name
96
104
(* --------------------------------------------------------------------- *)
99
match (generating,arg) with
100
(false,(s,info,_,_)) ->
106
let mcode fn (s,info,mc,pos) =
107
let line = info.Ast.line in
108
let lcol = info.Ast.column in
109
match (generating,mc) with
101
111
(* printing for transformation *)
102
112
(* Here we don't care about the annotation on s. *)
103
113
let print_comments lb comments =
105
115
(function line_before ->
106
116
function (str,line,col) ->
107
117
match line_before with
108
None -> print_string str; Some line
109
| Some lb when line =|= lb -> print_string str; Some line
110
| _ -> print_string "\n"; print_string str; Some line)
118
None -> print_string str line col; Some line
119
| Some lb when line =|= lb ->
120
print_string str line col; Some line
121
| _ -> force_newline(); print_string str line col; Some line)
112
123
let line_before = print_comments None info.Ast.strbef in
113
124
(match line_before with
115
126
| Some lb when lb =|= info.Ast.line -> ()
116
| _ -> print_string "\n");
127
| _ -> force_newline());
118
129
let _ = print_comments (Some info.Ast.line) info.Ast.straft in
120
131
(* printing for rule generation *)
121
| (true, (x, _, Ast.MINUS(_,plus_stream), pos)) ->
132
| (true, Ast.MINUS(_,_,_,plus_stream)) ->
135
fn s line lcol; print_pos pos;
124
136
print_anything plus_stream
125
| (true, (x, _, Ast.CONTEXT(_,plus_streams), pos)) ->
126
let fn x = print_string "\n "; fn x; print_pos pos in
127
print_around fn x plus_streams
128
| (true,( x, info, Ast.PLUS, pos)) ->
129
let fn x = print_string "\n+ "; fn x; print_pos pos in
130
print_string_befaft fn (function _ -> print_string "+ ") x info
137
| (true, Ast.CONTEXT(_,plus_streams)) ->
138
let fn s = force_newline(); fn s line lcol; print_pos pos in
139
print_around fn s plus_streams
142
force_newline(); print_text "+ "; fn s line lcol; print_pos pos in
143
print_string_befaft fn (function _ -> print_text "+ ") s info
134
147
(* --------------------------------------------------------------------- *)
136
149
let handle_metavar name fn =
137
match (Common.optionise (fun () -> List.assoc (term name) env)) with
150
let ((_,b) as s,info,mc,pos) = name in
151
let line = info.Ast.line in
152
let lcol = info.Ast.column in
153
match Common.optionise (fun () -> List.assoc s env) with
139
155
let name_string (_,s) = s in
141
then mcode (function _ -> pr (name_string (term name))) name
158
mcode (function _ -> print_string (name_string s)) name
144
161
(Printf.sprintf "SP line %d: Not found a value in env for: %s"
145
(Ast_cocci.get_mcode_line name) (name_string (term name)))
162
line (name_string s))
148
then mcode (function _ -> fn e) name
164
pr_barrier line lcol;
167
(* call mcode to preserve the -+ annotation *)
168
mcode (fun _ _ _ -> fn e) name
170
let rcol = if lcol = unknown then unknown else lcol + (String.length b) in
151
173
(* --------------------------------------------------------------------- *)
152
174
let dots between fn d =
207
229
let print_disj_list fn l =
208
force_newline(); print_string "("; force_newline();
211
force_newline(); print_string "|"; force_newline())
213
force_newline(); print_string ")"; force_newline() in
231
print_between (function _ -> print_text "\n|\n") fn l;
232
print_text "\n)\n" in
215
234
let rec expression e =
216
235
match Ast.unwrap e with
217
236
Ast.Ident(id) -> ident id
219
237
| Ast.Constant(const) -> mcode constant const
220
238
| Ast.FunCall(fn,lp,args,rp) ->
221
239
expression fn; mcode print_string_box lp;
222
240
dots (function _ -> ()) expression args;
223
241
close_box(); mcode print_string rp
224
242
| Ast.Assignment(left,op,right,_) ->
225
expression left; print_string " "; mcode assignOp op;
226
print_string " "; expression right
243
expression left; pr_space(); mcode assignOp op;
244
pr_space(); expression right
227
245
| Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
228
expression exp1; print_string " "; mcode print_string why;
229
print_option (function e -> print_string " "; expression e) exp2;
230
print_string " "; mcode print_string colon; expression exp3
246
expression exp1; pr_space(); mcode print_string why;
247
print_option (function e -> pr_space(); expression e) exp2;
248
pr_space(); mcode print_string colon; expression exp3
231
249
| Ast.Postfix(exp,op) -> expression exp; mcode fixOp op
232
250
| Ast.Infix(exp,op) -> mcode fixOp op; expression exp
233
251
| Ast.Unary(exp,op) -> mcode unaryOp op; expression exp
234
252
| Ast.Binary(left,op,right) ->
235
expression left; print_string " "; mcode binaryOp op; print_string " ";
253
expression left; pr_space(); mcode binaryOp op; pr_space();
237
255
| Ast.Nested(left,op,right) -> failwith "nested only in minus code"
238
256
| Ast.Paren(lp,exp,rp) ->
602
618
and rule_elem arity re =
603
619
match Ast.unwrap re with
604
620
Ast.FunHeader(_,_,fninfo,name,lp,params,rp) ->
605
print_string arity; List.iter print_fninfo fninfo;
621
pr_arity arity; List.iter print_fninfo fninfo;
606
622
ident name; mcode print_string_box lp;
607
623
parameter_list params; close_box(); mcode print_string rp;
609
| Ast.Decl(_,_,decl) -> print_string arity; declaration decl
625
| Ast.Decl(_,_,decl) -> pr_arity arity; declaration decl
611
627
| Ast.SeqStart(brace) ->
612
print_string arity; mcode print_string brace; start_block()
628
pr_arity arity; mcode print_string brace; start_block()
613
629
| Ast.SeqEnd(brace) ->
614
end_block(); print_string arity; mcode print_string brace
630
end_block(); pr_arity arity; mcode print_string brace
616
632
| Ast.ExprStatement(exp,sem) ->
617
print_string arity; expression exp; mcode print_string sem
633
pr_arity arity; expression exp; mcode print_string sem
619
635
| Ast.IfHeader(iff,lp,exp,rp) ->
621
mcode print_string iff; print_string " "; mcode print_string_box lp;
637
mcode print_string iff; pr_space(); mcode print_string_box lp;
622
638
expression exp; close_box(); mcode print_string rp
623
639
| Ast.Else(els) ->
624
print_string arity; mcode print_string els
640
pr_arity arity; mcode print_string els
626
642
| Ast.WhileHeader(whl,lp,exp,rp) ->
628
mcode print_string whl; print_string " "; mcode print_string_box lp;
644
mcode print_string whl; pr_space(); mcode print_string_box lp;
629
645
expression exp; close_box(); mcode print_string rp
630
646
| Ast.DoHeader(d) ->
631
print_string arity; mcode print_string d
647
pr_arity arity; mcode print_string d
632
648
| Ast.WhileTail(whl,lp,exp,rp,sem) ->
634
mcode print_string whl; print_string " "; mcode print_string_box lp;
650
mcode print_string whl; pr_space(); mcode print_string_box lp;
635
651
expression exp; close_box(); mcode print_string rp;
636
652
mcode print_string sem
637
653
| Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
639
655
mcode print_string fr; mcode print_string_box lp;
640
656
print_option expression e1; mcode print_string sem1;
641
657
print_option expression e2; mcode print_string sem2;
642
658
print_option expression e3; close_box();
643
659
mcode print_string rp
644
660
| Ast.IteratorHeader(nm,lp,args,rp) ->
646
ident nm; print_string " "; mcode print_string_box lp;
662
ident nm; pr_space(); mcode print_string_box lp;
647
663
dots (function _ -> ()) expression args; close_box();
648
664
mcode print_string rp
650
666
| Ast.SwitchHeader(switch,lp,exp,rp) ->
652
mcode print_string switch; print_string " "; mcode print_string_box lp;
668
mcode print_string switch; pr_space(); mcode print_string_box lp;
653
669
expression exp; close_box(); mcode print_string rp
655
671
| Ast.Break(br,sem) ->
656
print_string arity; mcode print_string br; mcode print_string sem
672
pr_arity arity; mcode print_string br; mcode print_string sem
657
673
| Ast.Continue(cont,sem) ->
658
print_string arity; mcode print_string cont; mcode print_string sem
674
pr_arity arity; mcode print_string cont; mcode print_string sem
659
675
| Ast.Label(l,dd) -> ident l; mcode print_string dd
660
676
| Ast.Goto(goto,l,sem) ->
661
677
mcode print_string goto; ident l; mcode print_string sem
662
678
| Ast.Return(ret,sem) ->
663
print_string arity; mcode print_string ret;
679
pr_arity arity; mcode print_string ret;
664
680
mcode print_string sem
665
681
| Ast.ReturnExpr(ret,exp,sem) ->
666
print_string arity; mcode print_string ret; print_string " ";
682
pr_arity arity; mcode print_string ret; pr_space();
667
683
expression exp; mcode print_string sem
669
| Ast.Exp(exp) -> print_string arity; expression exp
670
| Ast.TopExp(exp) -> print_string arity; expression exp
671
| Ast.Ty(ty) -> print_string arity; fullType ty
685
| Ast.Exp(exp) -> pr_arity arity; expression exp
686
| Ast.TopExp(exp) -> pr_arity arity; expression exp
687
| Ast.Ty(ty) -> pr_arity arity; fullType ty
672
688
| Ast.TopInit(init) -> initialiser false init
673
689
| Ast.Include(inc,s) ->
674
mcode print_string inc; print_string " "; mcode inc_file s
690
mcode print_string inc; print_text " "; mcode inc_file s
675
691
| Ast.DefineHeader(def,id,params) ->
676
mcode print_string def; print_string " "; ident id;
692
mcode print_string def; pr_space(); ident id;
677
693
print_define_parameters params
678
694
| Ast.Default(def,colon) ->
679
mcode print_string def; mcode print_string colon; print_string " "
695
mcode print_string def; mcode print_string colon; pr_space()
680
696
| Ast.Case(case,exp,colon) ->
681
mcode print_string case; print_string " "; expression exp;
682
mcode print_string colon; print_string " "
697
mcode print_string case; pr_space(); expression exp;
698
mcode print_string colon; pr_space()
683
699
| Ast.DisjRuleElem(res) ->
687
force_newline(); print_string "("; force_newline();
689
(function _ -> force_newline(); print_string "|"; force_newline())
702
(pr_arity arity; print_text "\n(\n";
703
print_between (function _ -> print_text "\n|\n") (rule_elem arity)
692
force_newline(); print_string ")")
693
706
else raise CantBeInPlus
695
708
| Ast.MetaRuleElem(name,_,_) ->
718
731
| Ast.DPComma(comma) -> mcode print_string comma
719
732
| Ast.DPdots(dots) -> mcode print_string dots
720
733
| Ast.DPcircles(circles) -> mcode print_string circles
721
| Ast.OptDParam(dp) -> print_string "?"; print_define_param dp
722
| Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp
734
| Ast.OptDParam(dp) -> print_text "?"; print_define_param dp
735
| Ast.UniqueDParam(dp) -> print_text "!"; print_define_param dp
724
737
and print_fninfo = function
725
738
Ast.FStorage(stg) -> mcode storage stg
726
739
| Ast.FType(ty) -> fullType ty
727
| Ast.FInline(inline) -> mcode print_string inline; print_string " "
728
| Ast.FAttr(attr) -> mcode print_string attr; print_string " " in
740
| Ast.FInline(inline) -> mcode print_string inline; pr_space()
741
| Ast.FAttr(attr) -> mcode print_string attr; pr_space() in
730
743
let indent_if_needed s f =
731
744
match Ast.unwrap s with
732
Ast.Seq(lbrace,decls,body,rbrace) -> pr_space(); f()
745
Ast.Seq(lbrace,body,rbrace) -> pr_space(); f()
734
747
(*no newline at the end - someone else will do that*)
735
748
start_block(); f(); unindent() in
737
750
let rec statement arity s =
738
751
match Ast.unwrap s with
739
Ast.Seq(lbrace,decls,body,rbrace) ->
752
Ast.Seq(lbrace,body,rbrace) ->
740
753
rule_elem arity lbrace;
741
dots force_newline (statement arity) decls;
742
754
dots force_newline (statement arity) body;
743
755
rule_elem arity rbrace
765
776
| Ast.Iterator(header,body,(_,_,_,aft)) ->
766
777
rule_elem arity header;
767
778
indent_if_needed body (function _ -> statement arity body);
768
mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
779
mcode (fun _ _ _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
770
781
| Ast.Switch(header,lb,cases,rb) ->
771
rule_elem arity header; print_string " "; rule_elem arity lb;
782
rule_elem arity header; pr_space(); rule_elem arity lb;
772
783
List.iter (function x -> case_line arity x; force_newline()) cases;
773
784
rule_elem arity rb
775
786
| Ast.Atomic(re) -> rule_elem arity re
777
| Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
788
| Ast.FunDecl(header,lbrace,body,rbrace) ->
778
789
rule_elem arity header; rule_elem arity lbrace;
779
dots force_newline (statement arity) decls;
780
790
dots force_newline (statement arity) body; rule_elem arity rbrace
782
792
| Ast.Define(header,body) ->
783
rule_elem arity header; print_string " ";
793
rule_elem arity header; pr_space();
784
794
dots force_newline (statement arity) body
786
796
| Ast.Disj([stmt_dots]) ->
790
800
dots force_newline (statement arity) stmt_dots)
791
801
else raise CantBeInPlus
792
802
| Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *)
796
force_newline(); print_string "("; force_newline();
798
(function _ -> force_newline();print_string "|"; force_newline())
805
(pr_arity arity; print_text "\n(\n";
806
print_between (function _ -> print_text "\n|\n")
799
807
(dots force_newline (statement arity))
801
force_newline(); print_string ")")
802
810
else raise CantBeInPlus
803
811
| Ast.Nest(stmt_dots,whn,multi,_,_) when generating ->
805
813
nest_dots multi (statement arity)
807
815
print_between force_newline
824
832
and whencode notfn alwaysfn = function
826
print_string " WHEN != "; notfn a
834
print_text " WHEN != "; notfn a
827
835
| Ast.WhenAlways a ->
828
print_string " WHEN = "; alwaysfn a
829
| Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x
836
print_text " WHEN = "; alwaysfn a
837
| Ast.WhenModifier x -> print_text " WHEN "; print_when_modif x
830
838
| Ast.WhenNotTrue a ->
831
print_string " WHEN != TRUE "; rule_elem "" a
839
print_text " WHEN != TRUE "; rule_elem "" a
832
840
| Ast.WhenNotFalse a ->
833
print_string " WHEN != FALSE "; rule_elem "" a
841
print_text " WHEN != FALSE "; rule_elem "" a
835
843
and print_when_modif = function
836
| Ast.WhenAny -> print_string "ANY"
837
| Ast.WhenStrict -> print_string "STRICT"
838
| Ast.WhenForall -> print_string "FORALL"
839
| Ast.WhenExists -> print_string "EXISTS"
844
| Ast.WhenAny -> print_text "ANY"
845
| Ast.WhenStrict -> print_text "STRICT"
846
| Ast.WhenForall -> print_text "FORALL"
847
| Ast.WhenExists -> print_text "EXISTS"
841
849
and case_line arity c =
842
850
match Ast.unwrap c with
843
851
Ast.CaseLine(header,code) ->
844
rule_elem arity header; print_string " ";
852
rule_elem arity header; pr_space();
845
853
dots force_newline (statement arity) code
846
854
| Ast.OptCase(case) -> raise CantBeInPlus in
865
873
let rec pp_any = function
866
874
(* assert: normally there is only CONTEXT NOTHING tokens in any *)
867
875
Ast.FullTypeTag(x) -> fullType x; false
868
| Ast.BaseTypeTag(x) -> baseType x; false
869
| Ast.StructUnionTag(x) -> structUnion x; false
870
| Ast.SignTag(x) -> sign x; false
876
| Ast.BaseTypeTag(x) -> baseType x unknown unknown; false
877
| Ast.StructUnionTag(x) -> structUnion x unknown unknown; false
878
| Ast.SignTag(x) -> sign x unknown unknown; false
872
880
| Ast.IdentTag(x) -> ident x; false
874
882
| Ast.ExpressionTag(x) -> expression x; false
876
| Ast.ConstantTag(x) -> constant x; false
877
| Ast.UnaryOpTag(x) -> unaryOp x; false
878
| Ast.AssignOpTag(x) -> assignOp x; false
879
| Ast.FixOpTag(x) -> fixOp x; false
880
| Ast.BinaryOpTag(x) -> binaryOp x; false
881
| Ast.ArithOpTag(x) -> arithOp x; false
882
| Ast.LogicalOpTag(x) -> logicalOp x; false
884
| Ast.ConstantTag(x) -> constant x unknown unknown; false
885
| Ast.UnaryOpTag(x) -> unaryOp x unknown unknown; false
886
| Ast.AssignOpTag(x) -> assignOp x unknown unknown; false
887
| Ast.FixOpTag(x) -> fixOp x unknown unknown; false
888
| Ast.BinaryOpTag(x) -> binaryOp x unknown unknown; false
889
| Ast.ArithOpTag(x) -> arithOp x unknown unknown; false
890
| Ast.LogicalOpTag(x) -> logicalOp x unknown unknown; false
884
892
| Ast.InitTag(x) -> initialiser false x; false
885
893
| Ast.DeclarationTag(x) -> declaration x; false
887
| Ast.StorageTag(x) -> storage x; false
888
| Ast.IncFileTag(x) -> inc_file x; false
895
| Ast.StorageTag(x) -> storage x unknown unknown; false
896
| Ast.IncFileTag(x) -> inc_file x unknown unknown; false
890
898
| Ast.Rule_elemTag(x) -> rule_elem "" x; false
891
899
| Ast.StatementTag(x) -> statement "" x; false
892
900
| Ast.CaseLineTag(x) -> case_line "" x; false
894
| Ast.ConstVolTag(x) -> const_vol x; false
895
| Ast.Pragma(xs) -> print_between force_newline print_string xs; false
896
| Ast.Token(x,None) -> print_string x; if_open_brace x
902
| Ast.ConstVolTag(x) -> const_vol x unknown unknown; false
903
| Ast.Pragma(xs) -> print_between force_newline print_text xs; false
904
| Ast.Token(x,None) -> print_text x; if_open_brace x
897
905
| Ast.Token(x,Some info) ->
909
"else" -> force_newline()
904
(* if x ==~ Common.regexp_alpha then print_string " "; *)
911
print_string x line lcol;
906
(*"return" |*) "else" -> print_string " "
908
915
(let nomcodekind = Ast.CONTEXT(Ast.DontCarePos,Ast.NOTHING) in
909
916
(x,info,nomcodekind,Ast.NoMetaPos));