generator: Fix documentation for 'is-file' command.
[libguestfs.git] / src / generator.ml
index cb3f773..c81eb8b 100755 (executable)
@@ -551,15 +551,13 @@ handle is closed.  We don't currently have any method to enable
 changes to be committed, although qemu can support this.
 
 This is equivalent to the qemu parameter
-C<-drive file=filename,snapshot=on,readonly=on,if=...>.
+C<-drive file=filename,snapshot=on,if=...>.
 
 C<if=...> is set at compile time by the configuration option
 C<./configure --with-drive-if=...>.  In the rare case where you
 might need to change this at run time, use C<guestfs_add_drive_with_if>
 or C<guestfs_add_drive_ro_with_if>.
 
-C<readonly=on> is only added where qemu supports this option.
-
 Note that this call checks for the existence of C<filename>.  This
 stops you from specifying other types of drive which are supported
 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
@@ -1437,9 +1435,9 @@ See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
       [["is_file"; "/known-1"]]);
     InitISOFS, Always, TestOutputFalse (
       [["is_file"; "/directory"]])],
-   "test if file exists",
+   "test if a regular file",
    "\
-This returns C<true> if and only if there is a file
+This returns C<true> if and only if there is a regular file
 with the given C<path> name.  Note that it returns false for
 other objects like directories.
 
@@ -5095,6 +5093,40 @@ type callt =
   | CallBool of bool
   | CallBuffer of string
 
+(* Used for the guestfish -N (prepared disk images) option.
+ * Note that the longdescs are indented by 2 spaces.
+ *)
+let prepopts = [
+  ("disk",
+   "create a blank disk",
+   [ "size", "100M", "the size of the disk image" ],
+   "  Create a blank disk, size 100MB (by default).
+
+  The default size can be changed by supplying an optional parameter.");
+
+  ("part",
+   "create a partitioned disk",
+   [ "size", "100M", "the size of the disk image";
+     "partition", "mbr", "partition table type" ],
+   "  Create a disk with a single partition.  By default the size of the disk
+  is 100MB (the available space in the partition will be a tiny bit smaller)
+  and the partition table will be MBR (old DOS-style).
+
+  These defaults can be changed by supplying optional parameters.");
+
+  ("fs",
+   "create a filesystem",
+   [ "filesystem", "ext2", "the type of filesystem to use";
+     "size", "100M", "the size of the disk image";
+     "partition", "mbr", "partition table type" ],
+   "  Create a disk with a single partition, with the partition containing
+  an empty filesystem.  This defaults to creating a 100MB disk (the available
+  space in the filesystem will be a tiny bit smaller) with an MBR (old
+  DOS-style) partition table and an ext2 filesystem.
+
+  These defaults can be changed by supplying optional parameters.");
+]
+
 (* Used to memoize the result of pod2text. *)
 let pod2text_memo_filename = "src/.pod2text.data"
 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
@@ -5581,7 +5613,7 @@ let rec generate_actions_pod () =
 The string is owned by the guest handle and must I<not> be freed.\n\n"
          | RConstOptString _ ->
              pr "This function returns a string which may be NULL.
-There is way to return an error from this function.
+There is no way to return an error from this function.
 The string is owned by the guest handle and must I<not> be freed.\n\n"
          | RString _ ->
              pr "This function returns a string, or NULL on error.
@@ -5686,7 +5718,7 @@ and generate_xdr () =
   generate_header CStyle LGPLv2plus;
 
   (* This has to be defined to get around a limitation in Sun's rpcgen. *)
-  pr "typedef string str<>;\n";
+  pr "typedef string guestfs_str<>;\n";
   pr "\n";
 
   (* Internal structures. *)
@@ -5721,8 +5753,8 @@ and generate_xdr () =
              function
              | Pathname n | Device n | Dev_or_Path n | String n ->
                  pr "  string %s<>;\n" n
-             | OptString n -> pr "  str *%s;\n" n
-             | StringList n | DeviceList n -> pr "  str %s<>;\n" n
+             | OptString n -> pr "  guestfs_str *%s;\n" n
+             | StringList n | DeviceList n -> pr "  guestfs_str %s<>;\n" n
              | Bool n -> pr "  bool %s;\n" n
              | Int n -> pr "  int %s;\n" n
              | Int64 n -> pr "  hyper %s;\n" n
@@ -5754,7 +5786,7 @@ and generate_xdr () =
            pr "};\n\n"
        | RStringList n ->
            pr "struct %s_ret {\n" name;
-           pr "  str %s<>;\n" n;
+           pr "  guestfs_str %s<>;\n" n;
            pr "};\n\n"
        | RStruct (n, typ) ->
            pr "struct %s_ret {\n" name;
@@ -5766,7 +5798,7 @@ and generate_xdr () =
            pr "};\n\n"
        | RHashtable n ->
            pr "struct %s_ret {\n" name;
-           pr "  str %s<>;\n" n;
+           pr "  guestfs_str %s<>;\n" n;
            pr "};\n\n"
        | RBufferOut n ->
            pr "struct %s_ret {\n" name;
@@ -5924,13 +5956,6 @@ and generate_client_actions () =
 #include \"guestfs-internal-actions.h\"
 #include \"guestfs_protocol.h\"
 
-#define error guestfs_error
-//#define perrorf guestfs_perrorf
-#define safe_malloc guestfs_safe_malloc
-#define safe_realloc guestfs_safe_realloc
-//#define safe_strdup guestfs_safe_strdup
-#define safe_memdup guestfs_safe_memdup
-
 /* Check the return message from a call for validity. */
 static int
 check_reply_header (guestfs_h *g,
@@ -6034,7 +6059,7 @@ check_state (guestfs_h *g, const char *caller)
                    | StringList _ | DeviceList _ -> true
                    | _ -> false) (snd style) in
     if needs_i then (
-      pr "    int i;\n";
+      pr "    size_t i;\n";
       pr "\n"
     );
 
@@ -6487,7 +6512,7 @@ and generate_daemon_actions () =
                  pr "   * and perform device name translation.\n";
                  pr "   */\n";
                  pr "  {\n";
-                 pr "    int i;\n";
+                 pr "    size_t i;\n";
                  pr "    for (i = 0; %s[i] != NULL; ++i)\n" n;
                  pr "      RESOLVE_DEVICE (%s[i], %s, goto done);\n" n
                    (if is_filein then "cancel_receive ()" else "0");
@@ -6637,7 +6662,7 @@ and generate_daemon_actions () =
         pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
         pr "{\n";
         pr "  char *tok, *p, *next;\n";
-        pr "  int i, j;\n";
+        pr "  size_t i, j;\n";
         pr "\n";
         (*
           pr "  fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
@@ -6862,7 +6887,7 @@ static void print_error (guestfs_h *g, void *data, const char *msg)
 /* FIXME: nearly identical code appears in fish.c */
 static void print_strings (char *const *argv)
 {
-  int argc;
+  size_t argc;
 
   for (argc = 0; argv[argc] != NULL; ++argc)
     printf (\"\\t%%s\\n\", argv[argc]);
@@ -6871,7 +6896,7 @@ static void print_strings (char *const *argv)
 /*
 static void print_table (char const *const *argv)
 {
-  int i;
+  size_t i;
 
   for (i = 0; argv[i] != NULL; i += 2)
     printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
@@ -7526,7 +7551,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
         | RString _ -> pr "    char *r;\n"; "NULL"
         | RStringList _ | RHashtable _ ->
             pr "    char **r;\n";
-            pr "    int i;\n";
+            pr "    size_t i;\n";
             "NULL"
         | RStruct (_, typ) ->
             pr "    struct guestfs_%s *r;\n" typ; "NULL"
@@ -7930,10 +7955,10 @@ and generate_fish_cmds () =
 
       List.iter (
         function
-        | Device name | String name
-        | OptString name | Bool name
-        | Int name | Int64 name
-        | BufferIn name -> ()
+        | Device _ | String _
+        | OptString _ | Bool _
+        | Int _ | Int64 _
+        | BufferIn _ -> ()
         | Pathname name | Dev_or_Path name | FileOut name ->
             pr "  free (%s);\n" name
         | FileIn name ->
@@ -8106,7 +8131,7 @@ static const char *const commands[] = {
 static char *
 generator (const char *text, int state)
 {
-  static int index, len;
+  static size_t index, len;
   const char *name;
 
   if (!state) {
@@ -8215,6 +8240,84 @@ and generate_fish_actions_pod () =
       | Some txt -> pr "%s\n\n" txt
   ) all_functions_sorted
 
+and generate_fish_prep_options_h () =
+  generate_header CStyle GPLv2plus;
+
+  pr "#ifndef PREPOPTS_H\n";
+  pr "\n";
+
+  pr "\
+struct prep {
+  const char *name;             /* eg. \"fs\" */
+
+  size_t nr_params;             /* optional parameters */
+  struct prep_param *params;
+
+  const char *shortdesc;        /* short description */
+  const char *longdesc;         /* long description */
+
+                                /* functions to implement it */
+  void (*prelaunch) (const char *filename, prep_data *);
+  void (*postlaunch) (const char *filename, prep_data *, const char *device);
+};
+
+struct prep_param {
+  const char *pname;            /* parameter name */
+  const char *pdefault;         /* parameter default */
+  const char *pdesc;            /* parameter description */
+};
+
+extern const struct prep preps[];
+#define NR_PREPS %d
+
+" (List.length prepopts);
+
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "\
+extern void prep_prelaunch_%s (const char *filename, prep_data *data);
+extern void prep_postlaunch_%s (const char *filename, prep_data *data, const char *device);
+
+" name name;
+  ) prepopts;
+
+  pr "\n";
+  pr "#endif /* PREPOPTS_H */\n"
+
+and generate_fish_prep_options_c () =
+  generate_header CStyle GPLv2plus;
+
+  pr "\
+#include \"fish.h\"
+#include \"prepopts.h\"
+
+";
+
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "static struct prep_param %s_args[] = {\n" name;
+      List.iter (
+        fun (n, default, desc) ->
+          pr "  { \"%s\", \"%s\", \"%s\" },\n" n default desc
+      ) args;
+      pr "};\n";
+      pr "\n";
+  ) prepopts;
+
+  pr "const struct prep preps[] = {\n";
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "  { \"%s\", %d, %s_args,
+    \"%s\",
+    \"%s\",
+    prep_prelaunch_%s, prep_postlaunch_%s },
+"
+        name (List.length args) name
+        (c_quote shortdesc) (c_quote longdesc)
+        name name;
+  ) prepopts;
+  pr "};\n"
+
 (* Generate a C function prototype. *)
 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
     ?(single_line = false) ?(newline = false) ?(in_daemon = false)
@@ -8413,7 +8516,7 @@ copy_table (char * const * argv)
 {
   CAMLparam0 ();
   CAMLlocal5 (rv, pairv, kv, vv, cons);
-  int i;
+  size_t i;
 
   rv = Val_int (0);
   for (i = 0; argv[i] != NULL; i += 2) {
@@ -8596,7 +8699,7 @@ copy_table (char * const * argv)
             pr "  const char *r;\n"; "NULL"
         | RString _ -> pr "  char *r;\n"; "NULL"
         | RStringList _ ->
-            pr "  int i;\n";
+            pr "  size_t i;\n";
             pr "  char **r;\n";
             "NULL"
         | RStruct (_, typ) ->
@@ -8604,7 +8707,7 @@ copy_table (char * const * argv)
         | RStructList (_, typ) ->
             pr "  struct guestfs_%s_list *r;\n" typ; "NULL"
         | RHashtable _ ->
-            pr "  int i;\n";
+            pr "  size_t i;\n";
             pr "  char **r;\n";
             "NULL"
         | RBufferOut _ ->
@@ -8994,7 +9097,7 @@ close (g)
        | RStringList n | RHashtable n ->
            pr "PREINIT:\n";
            pr "      char **%s;\n" n;
-           pr "      int i, n;\n";
+           pr "      size_t i, n;\n";
            pr " PPCODE:\n";
            pr "      %s = guestfs_%s " n name;
            generate_c_call_args ~handle:"g" style;
@@ -9038,7 +9141,7 @@ close (g)
 and generate_perl_struct_list_code typ cols name style n do_cleanups =
   pr "PREINIT:\n";
   pr "      struct guestfs_%s_list *%s;\n" typ n;
-  pr "      int i;\n";
+  pr "      size_t i;\n";
   pr "      HV *hv;\n";
   pr " PPCODE:\n";
   pr "      %s = guestfs_%s " n name;
@@ -9260,6 +9363,55 @@ when the final reference is cleaned up is OK).
 
 =back
 
+=head1 AVAILABILITY
+
+From time to time we add new libguestfs APIs.  Also some libguestfs
+APIs won't be available in all builds of libguestfs (the Fedora
+build is full-featured, but other builds may disable features).
+How do you test whether the APIs that your Perl program needs are
+available in the version of C<Sys::Guestfs> that you are using?
+
+To test if a particular function is available in the C<Sys::Guestfs>
+class, use the ordinary Perl UNIVERSAL method C<can(METHOD)>
+(see L<perlobj(1)>).  For example:
+
+ use Sys::Guestfs;
+ if (defined (Sys::Guestfs->can (\"set_verbose\"))) {
+   print \"\\$h->set_verbose is available\\n\";
+ }
+
+To test if particular features are supported by the current
+build, use the L</available> method like the example below.  Note
+that the appliance must be launched first.
+
+ $h->available ( [\"augeas\"] );
+
+Since the L</available> method croaks if the feature is not supported,
+you might also want to wrap this in an eval and return a boolean.
+In fact this has already been done for you: use
+L<Sys::Guestfs::Lib(3)/feature_available>.
+
+For further discussion on this topic, refer to
+L<guestfs(3)/AVAILABILITY>.
+
+=head1 STORING DATA IN THE HANDLE
+
+The handle returned from L</new> is a hash reference.  The hash
+normally contains a single element:
+
+ {
+   _g => [private data used by libguestfs]
+ }
+
+Callers can add other elements to this hash to store data for their own
+purposes.  The data lasts for the lifetime of the handle.
+
+Any fields whose names begin with an underscore are reserved
+for private use by libguestfs.  We may add more in future.
+
+It is recommended that callers prefix the name of their field(s)
+with some unique string, to avoid conflicts with other users.
+
 =head1 COPYRIGHT
 
 Copyright (C) %s Red Hat Inc.
@@ -9354,7 +9506,7 @@ put_handle (guestfs_h *g)
 static char **
 get_string_list (PyObject *obj)
 {
-  int i, len;
+  size_t i, len;
   char **r;
 
   assert (obj);
@@ -9364,7 +9516,12 @@ get_string_list (PyObject *obj)
     return NULL;
   }
 
-  len = PyList_Size (obj);
+  Py_ssize_t slen = PyList_Size (obj);
+  if (slen == -1) {
+    PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\");
+    return NULL;
+  }
+  len = (size_t) slen;
   r = malloc (sizeof (char *) * (len+1));
   if (r == NULL) {
     PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
@@ -9462,7 +9619,7 @@ py_guestfs_close (PyObject *self, PyObject *args)
     pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
     pr "{\n";
     pr "  PyObject *list;\n";
-    pr "  int i;\n";
+    pr "  size_t i;\n";
     pr "\n";
     pr "  list = PyList_New (%ss->len);\n" typ;
     pr "  for (i = 0; i < %ss->len; ++i)\n" typ;
@@ -9960,7 +10117,7 @@ static VALUE ruby_guestfs_close (VALUE gv)
             pr "  char **%s;\n" n;
             pr "  Check_Type (%sv, T_ARRAY);\n" n;
             pr "  {\n";
-            pr "    int i, len;\n";
+            pr "    size_t i, len;\n";
             pr "    len = RARRAY_LEN (%sv);\n" n;
             pr "    %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
               n;
@@ -10032,7 +10189,7 @@ static VALUE ruby_guestfs_close (VALUE gv)
            pr "  free (r);\n";
            pr "  return rv;\n";
        | RStringList _ ->
-           pr "  int i, len = 0;\n";
+           pr "  size_t i, len = 0;\n";
            pr "  for (i = 0; r[i] != NULL; ++i) len++;\n";
            pr "  VALUE rv = rb_ary_new2 (len);\n";
            pr "  for (i = 0; r[i] != NULL; ++i) {\n";
@@ -10049,7 +10206,7 @@ static VALUE ruby_guestfs_close (VALUE gv)
            generate_ruby_struct_list_code typ cols
        | RHashtable _ ->
            pr "  VALUE rv = rb_hash_new ();\n";
-           pr "  int i;\n";
+           pr "  size_t i;\n";
            pr "  for (i = 0; r[i] != NULL; i+=2) {\n";
            pr "    rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
            pr "    free (r[i]);\n";
@@ -10118,7 +10275,7 @@ and generate_ruby_struct_code typ cols =
 (* Ruby code to return a struct list. *)
 and generate_ruby_struct_list_code typ cols =
   pr "  VALUE rv = rb_ary_new2 (r->len);\n";
-  pr "  int i;\n";
+  pr "  size_t i;\n";
   pr "  for (i = 0; i < r->len; ++i) {\n";
   pr "    VALUE hv = rb_hash_new ();\n";
   List.iter (
@@ -10525,7 +10682,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
                        | DeviceList _ -> true
                        | _ -> false) (snd style) in
       if needs_i then
-        pr "  int i;\n";
+        pr "  size_t i;\n";
 
       pr "\n";
 
@@ -11177,7 +11334,7 @@ namespace Guestfs
            pr "      return r != 0 ? true : false;\n"
        | RHashtable _ ->
            pr "      Hashtable rr = new Hashtable ();\n";
-           pr "      for (int i = 0; i < r.Length; i += 2)\n";
+           pr "      for (size_t i = 0; i < r.Length; i += 2)\n";
            pr "        rr.Add (r[i], r[i+1]);\n";
            pr "      return rr;\n"
        | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
@@ -11214,7 +11371,7 @@ and generate_bindtests () =
 static void
 print_strings (char *const *argv)
 {
-  int argc;
+  size_t argc;
 
   printf (\"[\");
   for (argc = 0; argv[argc] != NULL; ++argc) {
@@ -12176,8 +12333,8 @@ Run it from the top source directory using the command
   output_to "src/guestfs-structs.h" generate_structs_h;
   output_to "src/guestfs-actions.h" generate_actions_h;
   output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
-  output_to "src/guestfs-actions.c" generate_client_actions;
-  output_to "src/guestfs-bindtests.c" generate_bindtests;
+  output_to "src/actions.c" generate_client_actions;
+  output_to "src/bindtests.c" generate_bindtests;
   output_to "src/guestfs-structs.pod" generate_structs_pod;
   output_to "src/guestfs-actions.pod" generate_actions_pod;
   output_to "src/guestfs-availability.pod" generate_availability_pod;
@@ -12192,6 +12349,8 @@ Run it from the top source directory using the command
   output_to "fish/cmds.c" generate_fish_cmds;
   output_to "fish/completion.c" generate_fish_completion;
   output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
+  output_to "fish/prepopts.c" generate_fish_prep_options_c;
+  output_to "fish/prepopts.h" generate_fish_prep_options_h;
   output_to "ocaml/guestfs.mli" generate_ocaml_mli;
   output_to "ocaml/guestfs.ml" generate_ocaml_ml;
   output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;