X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=generator%2Fwrappi_c_xdr.ml;fp=generator%2Fwrappi_c_xdr.ml;h=2eb4b52f17379d476684cec92cad29887108533e;hb=a6d8cf44fbc4fb4a09b3c3bb54701e35f201f997;hp=0000000000000000000000000000000000000000;hpb=00e9ee626a00324c1808ab860f00f1a07c88ade8;p=wrappi.git diff --git a/generator/wrappi_c_xdr.ml b/generator/wrappi_c_xdr.ml new file mode 100644 index 0000000..2eb4b52 --- /dev/null +++ b/generator/wrappi_c_xdr.ml @@ -0,0 +1,148 @@ +(* wrappi + * Copyright (C) 2011 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + +open Camlp4.PreCast + +open Wrappi_utils +open Wrappi_types +open Wrappi_boilerplate +open Wrappi_pr + +open Printf + +let inputs = ["wrappi_c_xdr.ml"] + +(* Traditionally 'rpcgen' is used to generate this code. However the + * glibc maintainers have shown no interest (in fact, malign influence) + * in doing a proper job maintaining this, resulting in bitrot and poor + * code being generated. In any case the code that rpcgen makes is + * relatively simple. + *) + +let pr_xdr_of_ptype n = function + | TBool -> + pr " if (!xdr_bool (xdrs, &%s)) return FALSE;\n" n + | TBuffer -> assert false (* XXX not implemented *) + | TEnum _ -> + pr " if (!xdr_int (xdrs, &%s)) return FALSE;\n" n + | TFile -> assert false (* XXX not implemented *) + | THash t -> assert false (* XXX not implemented *) + | TInt -> (* XXX not int, correct type depends on preconditions *) + pr " if (!xdr_int (xdrs, &%s)) return FALSE;\n" n + | TInt32 -> + pr " if (!xdr_int32_t (xdrs, &%s)) return FALSE;\n" n + | TInt64 -> + pr " if (!xdr_int64_t (xdrs, &%s)) return FALSE;\n" n + | TList t -> assert false (* XXX not implemented *) + | TNullable TString -> + pr " if (!xdr_pointer (xdrs, &%s, sizeof (unlimited_string), (xdrproc_t) xdr_unlimited_string)) return FALSE;\n" n + | TNullable _ -> assert false (* XXX may be implemented in future *) + | TString -> + pr " if (!xdr_unlimited_string (xdrs, (void *) &%s)) return FALSE;\n" n + | TStruct sname -> + pr " if (!xdr_struct_%s (xdrs, %s)) return FALSE;\n" sname n + | TTypedef name -> assert false (* should never happen *) + | TUInt32 -> + pr " if (!xdr_uint32_t (xdrs, &%s)) return FALSE;\n" n + | TUInt64 -> + pr " if (!xdr_uint64_t (xdrs, &%s)) return FALSE;\n" n + | TUnion uname -> + pr " if (!xdr_union_%s (xdrs, %s)) return FALSE;\n" uname n + +let generate_lib_proto_xdr_impl_c api = + generate_header inputs CStyle LGPLv2plus; + + pr "\ +#include +#include + +#include \"wrappi.h\" +#include \"internal.h\" + +/* An unlimited length string. */ +typedef char *unlimited_string; + +static bool_t +xdr_unlimited_string (XDR *xdrs, unlimited_string *objp) +{ + if (!xdr_string (xdrs, objp, ~0)) return FALSE; + return TRUE; +} +"; + + iter_structs api ( + fun sd -> + let name = sd.sd_name in + + pr "\n"; + pr "static bool_t\n"; + pr "xdr_struct_%s (XDR *xdrs, struct wrap_%s *objp)\n" name name; + pr "{\n"; + + Array.iter ( + fun (n, t) -> + pr_xdr_of_ptype (sprintf "objp->%s" n) t + ) sd.sd_fields; + + pr " return TRUE;\n"; + pr "}\n"; + ); + + iter_entry_points api ( + fun ep -> + if not ep.ep_local then ( + let name = ep.ep_name in + let ret, req, opt = ep.ep_ftype in + + pr "\n"; + pr "bool_t\n"; + pr "wrap_int_xdr_%s_args (XDR *xdrs, struct wrap_int_%s_args *args)\n" + name name; + pr "{\n"; + + List.iter ( + fun (n, t, _) -> + pr_xdr_of_ptype (sprintf "args->%s" n) t + ) req; + + if opt <> [] then assert false; (* XXX not implemented *) + + pr " return TRUE;\n"; + pr "}\n"; + + pr "\n"; + pr "bool_t\n"; + pr "wrap_int_xdr_%s_ret (XDR *xdrs, struct wrap_int_%s_ret *ret)\n" + name name; + pr "{\n"; + + (match ret with + | RVoid -> () + | RStaticString -> + assert false (* RStaticString cannot be used for remote functions. *) + | Return t -> + pr_xdr_of_ptype "ret->r" t + ); + + pr " return TRUE;\n"; + pr "}\n" + ) + ) + +let generate api = + output_to "lib/proto-xdr-impl.c" generate_lib_proto_xdr_impl_c api