From f4ef980b13bde6e00fa918e35fd834a9fe824d0e Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 1 Jan 2012 14:30:25 +0000 Subject: [PATCH] More implementation code. --- APIs/filesize.api | 1 + APIs/mknod.api | 1 + generator-lib/wrappi_types.ml | 1 + generator-lib/wrappi_types.mli | 1 + generator-macros/pa_wrap.ml | 13 +++++--- generator/wrappi_c_impl.ml | 68 +++++++++++++++++++++++++++++++++++++++++- lib/implementation_files.mk | 2 +- 7 files changed, 81 insertions(+), 6 deletions(-) diff --git a/APIs/filesize.api b/APIs/filesize.api index 89a4063..218a1da 100644 --- a/APIs/filesize.api +++ b/APIs/filesize.api @@ -28,6 +28,7 @@ off_t filesize (pathname path) return buf.st_size; >> +includes ["sys/types.h"; "sys/stat.h"; "unistd.h"] (* mknod_block diff --git a/APIs/mknod.api b/APIs/mknod.api index 85c6458..07d2cca 100644 --- a/APIs/mknod.api +++ b/APIs/mknod.api @@ -25,6 +25,7 @@ void mknod_char (pathname path, fileperm perm, uint64 major, uint64 minor) } return 0; >> +includes [ "sys/types.h"; "sys/stat.h"; "fcntl.h"; "unistd.h" ] (* mknod_block diff --git a/generator-lib/wrappi_types.ml b/generator-lib/wrappi_types.ml index 588ad70..f738f95 100644 --- a/generator-lib/wrappi_types.ml +++ b/generator-lib/wrappi_types.ml @@ -56,6 +56,7 @@ type entry_point = { ep_name : string; ep_ftype : ftype; ep_code : c_code option; + ep_includes : string list; } type typedef = { diff --git a/generator-lib/wrappi_types.mli b/generator-lib/wrappi_types.mli index 04283d5..94cf371 100644 --- a/generator-lib/wrappi_types.mli +++ b/generator-lib/wrappi_types.mli @@ -58,6 +58,7 @@ type entry_point = { ep_name : string; ep_ftype : ftype; ep_code : c_code option; + ep_includes : string list; } (** An API entry point. *) diff --git a/generator-macros/pa_wrap.ml b/generator-macros/pa_wrap.ml index ffd9e6b..c176fe2 100644 --- a/generator-macros/pa_wrap.ml +++ b/generator-macros/pa_wrap.ml @@ -51,7 +51,7 @@ let expr_of_loc _loc loc = $`int:stop_line$, $`int:stop_bol$, $`int:stop_off$, $`bool:ghost$) >> -let add_entry_point _loc local name parameters rtype code = +let add_entry_point _loc local name parameters rtype code includes = let loc = expr_of_loc _loc _loc in let local = @@ -64,12 +64,15 @@ let add_entry_point _loc local name parameters rtype code = let code = expr_of_option _loc code in + let includes = match includes with None -> <:expr< [] >> | Some xs -> xs in + <:str_item< let ep = { Wrappi_types.ep_loc = $loc$; ep_local = $local$; ep_name = $str:name$; ep_ftype = ($rtype$, $parameters$, []); - ep_code = $code$ } in + ep_code = $code$; + ep_includes = $includes$ } in Wrappi_accumulator.add_entry_point ep >> @@ -135,8 +138,10 @@ EXTEND Gram local = OPT "local"; rtype = rtype; name = LIDENT; "("; parameters = LIST0 parameter SEP ","; ")"; - code = OPT [ code = expr -> code ] -> - add_entry_point _loc local name parameters rtype code + code = OPT [ code = expr -> code ]; + includes = OPT [ "includes"; includes = expr -> includes ] + -> + add_entry_point _loc local name parameters rtype code includes ] | [ "typedef"; t = ptype; name = LIDENT -> add_typedef _loc name t diff --git a/generator/wrappi_c_impl.ml b/generator/wrappi_c_impl.ml index 50673fc..8742fad 100644 --- a/generator/wrappi_c_impl.ml +++ b/generator/wrappi_c_impl.ml @@ -25,6 +25,50 @@ open Wrappi_pr open Printf +let c_of_ptype ~param = function + | TBool -> "int" + | TBuffer -> assert false (* XXX not implemented *) + | TEnum name -> sprintf "enum wrap_%s" name + | TFile -> if param then "const char *" else "char *" + | THash t -> if param then "char * const *" else "char **" + | TInt -> "int" (* XXX not int, correct type depends on preconditions *) + | TInt32 -> "int32_t" + | TInt64 -> "int64_t" + | TList t -> assert false (* XXX not implemented *) + | TNullable TString -> if param then "const char *" else "char *" + | TNullable _ -> assert false (* XXX may be implemented in future *) + | TString -> if param then "const char *" else "char *" + | TStruct name -> sprintf "struct wrap_%s" name + | TTypedef name -> assert false (* should never happen *) + | TUInt32 -> "uint32_t" + | TUInt64 -> "uint64_t" + | TUnion name -> sprintf "union wrap_%s" name + +let c_of_rtype = function + | RVoid -> "void" + | Return t -> c_of_ptype ~param:false t + +let pr_decl ep = + let ret, req, opt = ep.ep_ftype in + pr "%s\n" (c_of_rtype ret); + pr "wrap_%s (wrap_h *w" ep.ep_name; + + (* Required parameters. *) + List.iter ( + fun (name, t, _) -> + let t = c_of_ptype ~param:true t in + let sep = (* "const char *" - omit space after asterisk *) + let len = String.length t in + if isalnum t.[len-1] then " " else "" in + pr ", %s%s%s" t sep name + ) req; + + (* Optional parameters. *) + if opt <> [] then + pr ", ..."; + + pr ")\n" + let generate_implementation ep = generate_header CStyle LGPLv2plus; @@ -33,18 +77,40 @@ let generate_implementation ep = #include #include +"; + List.iter (pr "#include <%s>\n") ep.ep_includes; + +pr "\ #include \"wrappi.h\" #include \"internal.h\" -" +/* Automatically generated implementation of '%s'. + * This API was defined in '%s' at line %d. + */ + +" ep.ep_name (Loc.file_name ep.ep_loc) (Loc.start_line ep.ep_loc); (* Depending on whether this is a local or remote function, include * different definitions here. *) (*if ep.ep_local then ... *) + pr_decl ep; + + pr "\ +{ +#line %d \"%s\" +" (Loc.start_line ep.ep_loc) (Loc.file_name ep.ep_loc); + + (match ep.ep_code with + | None -> () + | Some code -> pr "%s" code + ); + + pr "}\n" + (* Make a unique, reproducible filename for each entry point. *) let filename_of_ep ep = let filename = Loc.file_name ep.ep_loc in diff --git a/lib/implementation_files.mk b/lib/implementation_files.mk index 8760929..4631ce5 100644 --- a/lib/implementation_files.mk +++ b/lib/implementation_files.mk @@ -3,7 +3,7 @@ # generator/wrappi_*.ml # ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST. # -# Copyright (C) 2011 Red Hat Inc. +# Copyright (C) 2011-2012 Red Hat Inc. # # 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 -- 1.8.3.1