Test example program.
authorRichard W.M. Jones <rjones@redhat.com>
Sat, 31 Dec 2011 17:08:53 +0000 (17:08 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Sat, 31 Dec 2011 17:08:53 +0000 (17:08 +0000)
19 files changed:
.gitignore
APIs/Makefile.am
APIs/block_devices.api
APIs/error.api [new file with mode: 0644]
APIs/filesize.api [new file with mode: 0644]
APIs/handle.api [new file with mode: 0644]
APIs/mkdir.api
APIs/mknod.api
APIs/off_t.api [new file with mode: 0644]
APIs/processes.api
Makefile.am
configure.ac
examples/Makefile.am [new file with mode: 0644]
examples/remote.c [new file with mode: 0644]
generator-lib/wrappi_accumulator.ml
generator-lib/wrappi_types.ml
generator-lib/wrappi_types.mli
generator-macros/pa_wrap.ml
generator/wrappi_c.ml

index 0849343..c302ff2 100644 (file)
@@ -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
index 74813ff..ce6d4b3 100644 (file)
@@ -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 *~
index 5b19993..7769911 100644 (file)
@@ -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 (file)
index 0000000..0ec07c2
--- /dev/null
@@ -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 (file)
index 0000000..a8e29d8
--- /dev/null
@@ -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 (file)
index 0000000..9fd4377
--- /dev/null
@@ -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) ;;
index 09e9527..bcdebab 100644 (file)
@@ -1 +1 @@
-entry_point err mkdir (pathname path, fileperm perm) (* implicit *);;
+entry_point void mkdir (pathname path, fileperm perm) (* implicit *);;
index bc0ba02..793833b 100644 (file)
@@ -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 (file)
index 0000000..1f8e7a7
--- /dev/null
@@ -0,0 +1,2 @@
+(* XXX preconditions: >= 0 *)
+typedef int off_t
index 98fc527..86c5f67 100644 (file)
@@ -1,3 +1,4 @@
+(*
 system_object process
   dir_list "/proc/[1-9]*"
 
@@ -32,3 +33,4 @@ system_object process
     save_errno ();
     return -1;
   >>
+*)
index 6bb6eb9..941266e 100644 (file)
@@ -26,4 +26,7 @@ SUBDIRS = generator-lib generator-macros APIs generator
 # The C library.
 SUBDIRS += lib
 
+# Build the C example programs.
+SUBDIRS += examples
+
 CLEANFILES = *~
index 1182568..bc8e520 100644 (file)
@@ -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 (file)
index 0000000..7fd04c1
--- /dev/null
@@ -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 (file)
index 0000000..5e0d722
--- /dev/null
@@ -0,0 +1,63 @@
+/* Example using wrappi to access a remote server and read a file. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <wrappi.h>
+
+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);
+}
index e2af4f8..ac09b99 100644 (file)
@@ -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 () =
index ef3a8bd..588ad70 100644 (file)
@@ -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
index b836685..04283d5 100644 (file)
@@ -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;
index b4fea3a..ffd9e6b 100644 (file)
@@ -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
index 1a04234..16e6caf 100644 (file)
@@ -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 =