--- /dev/null
+(* Memory info command for virtual domains.
+ (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
+ http://libvirt.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+open Camlp4.PreCast
+open Syntax
+(*open Ast*)
+
+open ExtList
+open ExtString
+open Printf
+
+module PP = Pahole_parser
+module SC = Struct_classify
+
+(* We don't care about locations when generating code, so it's
+ * useful to just have a single global _loc.
+ *)
+let _loc = Loc.ghost
+
+(* Some handy camlp4 construction functions which do some
+ * things that ought to be easy/obvious but aren't.
+ *
+ * 'concat_str_items' concatenates a list of str_item together into
+ * one big str_item.
+ *
+ * 'concat_record_fields' concatenates a list of records fields into
+ * a record. The list must have at least one element.
+ *
+ * 'build_record' builds a record out of record fields.
+ *
+ * 'build_tuple_from_exprs' builds an arbitrary length tuple from
+ * a list of expressions of length >= 2.
+ *
+ * Thanks to bluestorm on #ocaml for getting these working.
+ *)
+let concat_str_items items =
+ match items with
+ | [] -> <:str_item< >>
+ | x :: xs ->
+ List.fold_left (fun xs x -> <:str_item< $xs$ $x$ >>) x xs
+
+let concat_sig_items items =
+ match items with
+ | [] -> <:sig_item< >>
+ | x :: xs ->
+ List.fold_left (fun xs x -> <:sig_item< $xs$ $x$ >>) x xs
+
+let concat_record_fields fields =
+ match fields with
+ | [] -> assert false
+ | f :: fs ->
+ List.fold_left (fun fs f -> <:ctyp< $fs$ ; $f$ >>) f fs
+
+let concat_record_bindings rbs =
+ match rbs with
+ | [] -> assert false
+ | rb :: rbs ->
+ List.fold_left (fun rbs rb -> <:rec_binding< $rbs$ ; $rb$ >>) rb rbs
+
+let build_record rbs =
+ Ast.ExRec (_loc, rbs, Ast.ExNil _loc)
+
+let build_tuple_from_exprs exprs =
+ match exprs with
+ | [] | [_] -> assert false
+ | x :: xs ->
+ Ast.ExTup (_loc,
+ List.fold_left (fun xs x -> Ast.ExCom (_loc, x, xs)) x xs)
+
+let ocaml_type_of_field_type = function
+ | PP.FInteger -> <:ctyp< int64 >>
+ | PP.FString _ -> <:ctyp< string >>
+ | PP.FStructPointer _ | PP.FVoidPointer
+ | PP.FAnonListHeadPointer | PP.FListHeadPointer _ ->
+ <:ctyp< Virt_mem_mmap.addr >>
+
+let generate_types xs =
+ let strs = List.map (
+ fun (struct_name, sflist, cflist) ->
+ let sflist = List.map (
+ fun { SC.sf_name = name; sf_fields = fields } ->
+ if fields <> [] then (
+ let fields = List.map (
+ fun { PP.field_name = name; PP.field_type = t } ->
+ let t = ocaml_type_of_field_type t in
+ <:ctyp< $lid:name$ : $t$ >>
+ ) fields in
+ let fields = concat_record_fields fields in
+
+ <:str_item<
+ type $lid:name$ = { $fields$ }
+ >>
+ ) else
+ <:str_item< type $lid:name$ = unit >>
+ ) sflist in
+ let sflist = concat_str_items sflist in
+
+ let cflist = List.map (
+ fun { SC.cf_name = name; cf_fields = fields } ->
+ if fields <> [] then (
+ let fields = List.map (
+ fun { PP.field_name = name; PP.field_type = t } ->
+ let t = ocaml_type_of_field_type t in
+ <:ctyp< $lid:name$ : $t$ >>
+ ) fields in
+ let fields = concat_record_fields fields in
+
+ <:str_item<
+ type $lid:name$ = { $fields$ }
+ >>
+ ) else
+ <:str_item< type $lid:name$ = unit >>
+ ) cflist in
+ let cflist = concat_str_items cflist in
+
+ <:str_item<
+ type ('a, 'b) $lid:struct_name$ = {
+ $lid:struct_name^"_shape"$ : 'a;
+ $lid:struct_name^"_content"$ : 'b;
+ }
+ $sflist$
+ $cflist$
+ >>
+ ) xs in
+
+ let sigs =
+ List.map (
+ fun (struct_name, _, _) ->
+ <:sig_item<
+ type ('a, 'b) $lid:struct_name$
+ >>
+ ) xs in
+
+ concat_str_items strs, concat_sig_items sigs
+
+let output_interf ~output_file types =
+ let sigs = concat_sig_items [ types ] in
+ Printers.OCaml.print_interf ~output_file sigs
+
+let output_implem ~output_file types =
+ let strs = concat_str_items [ types ] in
+ Printers.OCaml.print_implem ~output_file strs