From a3d742e544ffaff9fc0425cf727060be0d3a2631 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 31 Dec 2011 17:08:53 +0000 Subject: [PATCH] Test example program. --- .gitignore | 3 ++ APIs/Makefile.am | 5 ++- APIs/block_devices.api | 2 ++ APIs/error.api | 11 +++++++ APIs/filesize.api | 20 ++++++++++++ APIs/handle.api | 5 +++ APIs/mkdir.api | 2 +- APIs/mknod.api | 8 +++-- APIs/off_t.api | 2 ++ APIs/processes.api | 2 ++ Makefile.am | 3 ++ configure.ac | 1 + examples/Makefile.am | 22 +++++++++++++ examples/remote.c | 63 +++++++++++++++++++++++++++++++++++++ generator-lib/wrappi_accumulator.ml | 2 +- generator-lib/wrappi_types.ml | 8 +++-- generator-lib/wrappi_types.mli | 5 +-- generator-macros/pa_wrap.ml | 16 +++++++--- generator/wrappi_c.ml | 4 +-- 19 files changed, 166 insertions(+), 18 deletions(-) create mode 100644 APIs/error.api create mode 100644 APIs/filesize.api create mode 100644 APIs/handle.api create mode 100644 APIs/off_t.api create mode 100644 examples/Makefile.am create mode 100644 examples/remote.c diff --git a/.gitignore b/.gitignore index 0849343..c302ff2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,11 @@ +.deps *~ *.cmi *.cmo *.cmx *.cma *.cmxa +*.o Makefile Makefile.in /aclocal.m4 @@ -16,6 +18,7 @@ Makefile.in /config.status /config.sub /configure +/depcomp /generator-lib/config.ml /generator/generator /generator/stamp-generator diff --git a/APIs/Makefile.am b/APIs/Makefile.am index 74813ff..ce6d4b3 100644 --- a/APIs/Makefile.am +++ b/APIs/Makefile.am @@ -20,8 +20,7 @@ OCAMLOPTFLAGS = $(OCAMLCFLAGS) PP = -pp '$(CAMLP4O) ../generator-macros/pa_wrap.cmo -impl' -#API_FILES = $(wildcard *.api) -API_FILES = fileperm.api mkdir.api mknod.api pathname.api +API_FILES = $(wildcard *.api) OBJECTS = $(patsubst %.api,%.cmo,$(API_FILES)) @@ -30,7 +29,7 @@ noinst_SCRIPTS = apis.cma apis.cma: $(OBJECTS) ../generator-lib/generator_lib.cma $(OCAMLFIND) ocamlc -linkall -a $(OBJECTS) -o apis.cma -%.cmo: %.api ../generator-lib/generator_lib.cma +%.cmo: %.api ../generator-lib/generator_lib.cma ../generator-macros/pa_wrap.cmo $(OCAMLFIND) ocamlc $(OCAMLOPTFLAGS) $(PP) -impl $< -c -o $@ CLEANFILES = *.cmi *.cmo *.cmx *.cma *.cmxa *~ diff --git a/APIs/block_devices.api b/APIs/block_devices.api index 5b19993..7769911 100644 --- a/APIs/block_devices.api +++ b/APIs/block_devices.api @@ -1,4 +1,6 @@ +(* system_object block_device dir_list "/sys/block/[hsv]d[a-z]*" property string name << return safe_strdup ($basename); >> +*) \ No newline at end of file diff --git a/APIs/error.api b/APIs/error.api new file mode 100644 index 0000000..0ec07c2 --- /dev/null +++ b/APIs/error.api @@ -0,0 +1,11 @@ +entry_point local +bool error () +<< + return w->error_flag; +>> + +entry_point local +void clear_error () +<< + w->error_flag = 0; +>> \ No newline at end of file diff --git a/APIs/filesize.api b/APIs/filesize.api new file mode 100644 index 0000000..a8e29d8 --- /dev/null +++ b/APIs/filesize.api @@ -0,0 +1,20 @@ +entry_point +off_t filesize (pathname path) +<< + struct stat buf; + + if (stat (path, &buf) == -1) { + error_errno ("stat: %s", path); + return -1; + } + + return buf.st_size; +>> + +;; + +(* +mknod_block +mkfifo +mknod_socket +*) diff --git a/APIs/handle.api b/APIs/handle.api new file mode 100644 index 0000000..9fd4377 --- /dev/null +++ b/APIs/handle.api @@ -0,0 +1,5 @@ +entry_point local void connect () ;; + +(* XXX Should scheme be an enum? *) +entry_point local void set_scheme (string scheme) ;; +entry_point local void set_hostname (string hostname) ;; diff --git a/APIs/mkdir.api b/APIs/mkdir.api index 09e9527..bcdebab 100644 --- a/APIs/mkdir.api +++ b/APIs/mkdir.api @@ -1 +1 @@ -entry_point err mkdir (pathname path, fileperm perm) (* implicit *);; +entry_point void mkdir (pathname path, fileperm perm) (* implicit *);; diff --git a/APIs/mknod.api b/APIs/mknod.api index bc0ba02..793833b 100644 --- a/APIs/mknod.api +++ b/APIs/mknod.api @@ -1,7 +1,11 @@ entry_point -err mknod_char (pathname path, fileperm perm, uint64 major, uint64 minor) +void mknod_char (pathname path, fileperm perm, uint64 major, uint64 minor) << - return mknod (path, S_IFCHR | perm, makedev (major, minor)); + if (mknod (path, S_IFCHR | perm, makedev (major, minor)) == -1) { + error_errno ("mknod: %s", path); + return -1; + } + return 0; >> ;; diff --git a/APIs/off_t.api b/APIs/off_t.api new file mode 100644 index 0000000..1f8e7a7 --- /dev/null +++ b/APIs/off_t.api @@ -0,0 +1,2 @@ +(* XXX preconditions: >= 0 *) +typedef int off_t diff --git a/APIs/processes.api b/APIs/processes.api index 98fc527..86c5f67 100644 --- a/APIs/processes.api +++ b/APIs/processes.api @@ -1,3 +1,4 @@ +(* system_object process dir_list "/proc/[1-9]*" @@ -32,3 +33,4 @@ system_object process save_errno (); return -1; >> +*) diff --git a/Makefile.am b/Makefile.am index 6bb6eb9..941266e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,4 +26,7 @@ SUBDIRS = generator-lib generator-macros APIs generator # The C library. SUBDIRS += lib +# Build the C example programs. +SUBDIRS += examples + CLEANFILES = *~ diff --git a/configure.ac b/configure.ac index 1182568..bc8e520 100644 --- a/configure.ac +++ b/configure.ac @@ -58,6 +58,7 @@ fi AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile APIs/Makefile + examples/Makefile generator/Makefile generator-lib/config.ml generator-lib/Makefile diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..7fd04c1 --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,22 @@ +# 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. + +noinst_PROGRAMS = remote + +remote_SOURCES = remote.c +remote_CFLAGS = -I../lib +remote_LDADD = ../lib/libwrappi.la diff --git a/examples/remote.c b/examples/remote.c new file mode 100644 index 0000000..5e0d722 --- /dev/null +++ b/examples/remote.c @@ -0,0 +1,63 @@ +/* Example using wrappi to access a remote server and read a file. */ + +#include +#include +#include + +#include + +int +main (int argc, char *argv[]) +{ + wrap_h *w; + const char *hostname; + + /* We're going to use ssh to access the remote server. This is + * automatic but we need a hostname on the command line. + */ + if (argc < 2) { + fprintf (stderr, "missing parameter: give the remote hostname\n"); + exit (EXIT_FAILURE); + } + hostname = argv[1]; + + w = wrap_create (); + if (!w) { + fprintf (stderr, "could not allocate wrappi handle\n"); + exit (EXIT_FAILURE); + } + + /* Set the connection method to ssh to the remote host. If you + * simply comment out the next two lines, then wrappi will run the + * commands on the local machine. + */ + wrap_set_scheme (w, "ssh"); + wrap_set_hostname (w, hostname); + + /* Connect the handle. Because we didn't set any error handler, + * errors will be printed on stderr, so we can just exit if we get + * an error. + */ + wrap_connect (w); + if (wrap_error (w)) + exit (EXIT_FAILURE); + +#if 0 + /* Read a file from the remote machine. Most Un*x-like machines + * should have /etc/issue. + */ + printf ("--- contents of /etc/issue from %s ---\n", hostname); + wrap_download (w, "/etc/issue", "/dev/stdout"); + if (wrap_error (w)) + exit (EXIT_FAILURE); +#else + int64_t size = wrap_filesize (w, "/etc/issue"); + if (wrap_error (w)) + exit (EXIT_FAILURE); + printf ("size of /etc/issue = %" PRIi64 " bytes\n", size); +#endif + + wrap_close (w); + + exit (EXIT_SUCCESS); +} diff --git a/generator-lib/wrappi_accumulator.ml b/generator-lib/wrappi_accumulator.ml index e2af4f8..ac09b99 100644 --- a/generator-lib/wrappi_accumulator.ml +++ b/generator-lib/wrappi_accumulator.ml @@ -101,7 +101,7 @@ let rec resolve_typedefs thing name loc = function exit 1 let resolve_typedefs_in_ret thing name loc = function - | RErr as t -> t + | RVoid as t -> t | Return t -> Return (resolve_typedefs thing name loc t) let get_api () = diff --git a/generator-lib/wrappi_types.ml b/generator-lib/wrappi_types.ml index ef3a8bd..588ad70 100644 --- a/generator-lib/wrappi_types.ml +++ b/generator-lib/wrappi_types.ml @@ -44,7 +44,7 @@ type prec type parameter = string * ptype * prec option -type rtype = RErr | Return of ptype +type rtype = RVoid | Return of ptype type ftype = rtype * parameter list * parameter list @@ -52,6 +52,7 @@ type c_code = string type entry_point = { ep_loc : Camlp4.PreCast.Loc.t; + ep_local : bool; ep_name : string; ep_ftype : ftype; ep_code : c_code option; @@ -121,7 +122,7 @@ let rec string_of_ptype = function | TUInt64 -> "uint64" | TUnion name -> sprintf "union %s" name let string_of_rtype = function - | RErr -> "err" + | RVoid -> "void" | Return t -> string_of_ptype t let string_of_parameter (name, t, _) = sprintf "%s %s" (string_of_ptype t) name @@ -143,8 +144,9 @@ let string_of_struct sd = assert false let string_of_union un = assert false let string_of_entry_point ep = - sprintf "entry_point %s %s <<%s>>" + sprintf "entry_point%s %s %s <<%s>>" (*(Loc.to_string ep.ep_loc)*) + (if ep.ep_local then " local" else "") ep.ep_name (string_of_ftype ep.ep_ftype) (match ep.ep_code with diff --git a/generator-lib/wrappi_types.mli b/generator-lib/wrappi_types.mli index b836685..04283d5 100644 --- a/generator-lib/wrappi_types.mli +++ b/generator-lib/wrappi_types.mli @@ -41,9 +41,9 @@ type prec type parameter = string * ptype * prec option (** API parameter (argument name, type, optional precondition). *) -type rtype = RErr | Return of ptype +type rtype = RVoid | Return of ptype (** API return type. A superset of {!ptype} because we allow the - special value [RErr] for dealing with errno. *) + special value [RVoid] for functions that don't return any value. *) type ftype = rtype * parameter list * parameter list (** A function type. Return type, list of required parameters, list @@ -54,6 +54,7 @@ type c_code = string type entry_point = { ep_loc : Camlp4.PreCast.Loc.t; + ep_local : bool; ep_name : string; ep_ftype : ftype; ep_code : c_code option; diff --git a/generator-macros/pa_wrap.ml b/generator-macros/pa_wrap.ml index b4fea3a..ffd9e6b 100644 --- a/generator-macros/pa_wrap.ml +++ b/generator-macros/pa_wrap.ml @@ -51,9 +51,12 @@ let expr_of_loc _loc loc = $`int:stop_line$, $`int:stop_bol$, $`int:stop_off$, $`bool:ghost$) >> -let add_entry_point _loc name parameters rtype code = +let add_entry_point _loc local name parameters rtype code = let loc = expr_of_loc _loc _loc in + let local = + match local with None -> <:expr< false >> | _ -> <:expr< true >> in + let parameters = List.map ( fun (name, t) -> <:expr< ($str:name$, $t$, None) >> ) parameters in @@ -63,6 +66,7 @@ let add_entry_point _loc name parameters rtype code = <:str_item< let ep = { Wrappi_types.ep_loc = $loc$; + ep_local = $local$; ep_name = $str:name$; ep_ftype = ($rtype$, $parameters$, []); ep_code = $code$ } in @@ -99,7 +103,9 @@ EXTEND Gram (* A parameter or return type. *) ptype: [ - [ "buffer" -> <:expr< Wrappi_types.TBuffer >> ] + [ "bool" -> <:expr< Wrappi_types.TBool >> ] + | [ "buffer" -> <:expr< Wrappi_types.TBuffer >> ] + (* enum XXX *) | [ "file" -> <:expr< Wrappi_types.TFile >> ] | [ "hash"; "("; t = ptype; ")" -> <:expr< Wrappi_types.THash $t$ >> ] | [ "int" -> <:expr< Wrappi_types.TInt >> ] @@ -111,12 +117,13 @@ EXTEND Gram | [ "struct"; name = LIDENT -> <:expr< Wrappi_types.TStruct $str:name$ >> ] | [ "uint32" -> <:expr< Wrappi_types.TUInt32 >> ] | [ "uint64" -> <:expr< Wrappi_types.TUInt64 >> ] + (* union XXX *) | [ name = LIDENT -> <:expr< Wrappi_types.TTypedef $str:name$ >> ] ]; (* A return type. *) rtype: [ - [ "err" -> <:expr< Wrappi_types.RErr >> ] + [ "void" -> <:expr< Wrappi_types.RVoid >> ] | [ t = ptype -> <:expr< Wrappi_types.Return $t$ >> ] ]; @@ -125,10 +132,11 @@ EXTEND Gram str_item: LEVEL "top" [ [ "entry_point"; + local = OPT "local"; rtype = rtype; name = LIDENT; "("; parameters = LIST0 parameter SEP ","; ")"; code = OPT [ code = expr -> code ] -> - add_entry_point _loc name parameters rtype code + add_entry_point _loc local name parameters rtype code ] | [ "typedef"; t = ptype; name = LIDENT -> add_typedef _loc name t diff --git a/generator/wrappi_c.ml b/generator/wrappi_c.ml index 1a04234..16e6caf 100644 --- a/generator/wrappi_c.ml +++ b/generator/wrappi_c.ml @@ -29,7 +29,7 @@ let c_of_ptype ~param = function | 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 -> "intXXX" (* XXX depends on preconditions *) + | TInt -> "int" (* XXX not int, correct type depends on preconditions *) | TInt32 -> "int32_t" | TInt64 -> "int64_t" | TList t -> assert false (* XXX not implemented *) @@ -43,7 +43,7 @@ let c_of_ptype ~param = function | TUnion name -> sprintf "union wrap_%s" name let c_of_rtype = function - | RErr -> "int" + | RVoid -> "void" | Return t -> c_of_ptype ~param:false t let generate_lib_wrappi_h api = -- 1.8.3.1