1 (* Memory info command for virtual domains.
2 (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 module PP = Pahole_parser
29 module SC = Struct_classify
31 (* We don't care about locations when generating code, so it's
32 * useful to just have a single global _loc.
36 (* Some handy camlp4 construction functions which do some
37 * things that ought to be easy/obvious but aren't.
39 * 'concat_str_items' concatenates a list of str_item together into
42 * 'concat_record_fields' concatenates a list of records fields into
43 * a record. The list must have at least one element.
45 * 'build_record' builds a record out of record fields.
47 * 'build_tuple_from_exprs' builds an arbitrary length tuple from
48 * a list of expressions of length >= 2.
50 * Thanks to bluestorm on #ocaml for getting these working.
52 let concat_str_items items =
54 | [] -> <:str_item< >>
56 List.fold_left (fun xs x -> <:str_item< $xs$ $x$ >>) x xs
58 let concat_sig_items items =
60 | [] -> <:sig_item< >>
62 List.fold_left (fun xs x -> <:sig_item< $xs$ $x$ >>) x xs
64 let concat_record_fields fields =
68 List.fold_left (fun fs f -> <:ctyp< $fs$ ; $f$ >>) f fs
70 let concat_record_bindings rbs =
74 List.fold_left (fun rbs rb -> <:rec_binding< $rbs$ ; $rb$ >>) rb rbs
76 let build_record rbs =
77 Ast.ExRec (_loc, rbs, Ast.ExNil _loc)
79 let build_tuple_from_exprs exprs =
81 | [] | [_] -> assert false
84 List.fold_left (fun xs x -> Ast.ExCom (_loc, x, xs)) x xs)
86 let ocaml_type_of_field_type = function
87 | PP.FInteger -> <:ctyp< int64 >>
88 | PP.FString _ -> <:ctyp< string >>
89 | PP.FStructPointer _ | PP.FVoidPointer
90 | PP.FAnonListHeadPointer | PP.FListHeadPointer _ ->
91 <:ctyp< Virt_mem_mmap.addr >>
93 let generate_types xs =
95 fun (struct_name, sflist, cflist) ->
96 let sflist = List.map (
97 fun { SC.sf_name = name; sf_fields = fields } ->
98 if fields <> [] then (
99 let fields = List.map (
100 fun { PP.field_name = name; PP.field_type = t } ->
101 let t = ocaml_type_of_field_type t in
102 <:ctyp< $lid:name$ : $t$ >>
104 let fields = concat_record_fields fields in
107 type $lid:name$ = { $fields$ }
110 <:str_item< type $lid:name$ = unit >>
112 let sflist = concat_str_items sflist in
114 let cflist = List.map (
115 fun { SC.cf_name = name; cf_fields = fields } ->
116 if fields <> [] then (
117 let fields = List.map (
118 fun { PP.field_name = name; PP.field_type = t } ->
119 let t = ocaml_type_of_field_type t in
120 <:ctyp< $lid:name$ : $t$ >>
122 let fields = concat_record_fields fields in
125 type $lid:name$ = { $fields$ }
128 <:str_item< type $lid:name$ = unit >>
130 let cflist = concat_str_items cflist in
133 type ('a, 'b) $lid:struct_name$ = {
134 $lid:struct_name^"_shape"$ : 'a;
135 $lid:struct_name^"_content"$ : 'b;
144 fun (struct_name, _, _) ->
146 type ('a, 'b) $lid:struct_name$
150 concat_str_items strs, concat_sig_items sigs
152 let output_interf ~output_file types =
153 let sigs = concat_sig_items [ types ] in
154 Printers.OCaml.print_interf ~output_file sigs
156 let output_implem ~output_file types =
157 let strs = concat_str_items [ types ] in
158 Printers.OCaml.print_implem ~output_file strs