[Libguestfs] [PATCH 1/2] generator: Simplify the handling of string parameters.

Richard W.M. Jones rjones at redhat.com
Fri Apr 21 14:06:47 UTC 2017


Previously we had lots of types like String, Device, StringList,
DeviceList, etc. where Device was just a String with magical
properties (but only inside the daemon), and DeviceList was just a
list of Device strings.

Replace these with some simple top-level types:

  String
  StringList

and move the magic into a subtype.

The change is mechanical, for example:

    old                     --->    new
  FileIn "filename"               String (FileIn, "filename")
  DeviceList "devices"            StringList (Device, "devices")

Handling BufferIn is sufficiently different from a plain String
throughout all the bindings that it still uses a top-level type.
(Compare with FileIn/FileOut where the only difference is in the
protocol, but the bindings can uniformly treat it as a plain String.)

There is no semantic change, and the generated files are identical
except for a minor change in the (deprecated) Perl
%guestfs_introspection table.
---
 generator/GObject.ml                       |  36 +-
 generator/OCaml.ml                         |  25 +-
 generator/XDR.ml                           |  12 +-
 generator/actions_augeas.ml                |  24 +-
 generator/actions_core.ml                  | 720 ++++++++++++++---------------
 generator/actions_core_deprecated.ml       | 100 ++--
 generator/actions_debug.ml                 |   4 +-
 generator/actions_hivex.ml                 |  10 +-
 generator/actions_inspection.ml            |  46 +-
 generator/actions_inspection_deprecated.ml |   2 +-
 generator/actions_internal_tests.ml        |  12 +-
 generator/actions_properties.ml            |  16 +-
 generator/actions_properties_deprecated.ml |   2 +-
 generator/actions_tsk.ml                   |  12 +-
 generator/bindtests.ml                     |  16 +-
 generator/c.ml                             |  87 ++--
 generator/csharp.ml                        |  20 +-
 generator/daemon.ml                        |  56 ++-
 generator/erlang.ml                        |  10 +-
 generator/fish.ml                          |  64 ++-
 generator/golang.ml                        |  44 +-
 generator/haskell.ml                       |  73 ++-
 generator/java.ml                          |  57 +--
 generator/lua.ml                           |  21 +-
 generator/perl.ml                          |  56 +--
 generator/php.ml                           |  49 +-
 generator/python.ml                        |  43 +-
 generator/ruby.ml                          |  14 +-
 generator/tests_c_api.ml                   |  38 +-
 generator/types.ml                         |  88 ++--
 generator/utils.ml                         |  13 +-
 31 files changed, 793 insertions(+), 977 deletions(-)

diff --git a/generator/GObject.ml b/generator/GObject.ml
index cb96eb9cb..bb95b170c 100644
--- a/generator/GObject.ml
+++ b/generator/GObject.ml
@@ -77,19 +77,10 @@ let generate_gobject_proto name ?(single_line = true)
         pr "gint32 %s" n
       | Int64 n->
         pr "gint64 %s" n
-      | String n
-      | Device n | Mountable n
-      | Pathname n
-      | Dev_or_Path n | Mountable_or_Path n
-      | OptString n
-      | Key n
-      | FileIn n
-      | FileOut n
-      | GUID n ->
+      | String (_, n)
+      | OptString n ->
         pr "const gchar *%s" n
-      | StringList n
-      | DeviceList n
-      | FilenameList n ->
+      | StringList (_, n) ->
         pr "gchar *const *%s" n
       | BufferIn n ->
         pr "const guint8 *%s, gsize %s_size" n n
@@ -1047,17 +1038,17 @@ guestfs_session_close (GuestfsSession *session, GError **err)
             pr " (type gint32):"
           | Int64 _ ->
             pr " (type gint64):"
-          | String _ | Key _ | GUID _ ->
+          | String ((PlainString|Key|GUID), _) ->
             pr " (transfer none) (type utf8):"
           | OptString _ ->
             pr " (transfer none) (type utf8) (allow-none):"
-          | Device _ | Mountable _ | Pathname _
-          | Dev_or_Path _ | Mountable_or_Path _
-          | FileIn _ | FileOut _ ->
+          | String ((Device|Mountable|Pathname|Filename
+                     |Dev_or_Path|Mountable_or_Path|FileIn|FileOut), _) ->
             pr " (transfer none) (type filename):"
-          | StringList _ ->
+          | StringList ((PlainString|Key|GUID), _) ->
             pr " (transfer none) (array zero-terminated=1) (element-type utf8): an array of strings"
-          | DeviceList _ | FilenameList _ ->
+          | StringList ((Device|Mountable|Pathname|Filename
+                         |Dev_or_Path|Mountable_or_Path|FileIn|FileOut), _) ->
             pr " (transfer none) (array zero-terminated=1) (element-type filename): an array of strings"
           | BufferIn n ->
             pr " (transfer none) (array length=%s_size) (element-type guint8): an array of binary data\n" n;
@@ -1222,11 +1213,10 @@ guestfs_session_close (GuestfsSession *session, GError **err)
           match argt with
           | BufferIn n ->
             pr "(const char *) %s, %s_size" n n
-          | Bool n | Int n | Int64 n | String n | Device n | Mountable n
-          | Pathname n | Dev_or_Path n | Mountable_or_Path n
-          | OptString n | StringList n
-          | DeviceList n | Key n | FileIn n | FileOut n
-          | GUID n | FilenameList n ->
+          | Bool n | Int n | Int64 n
+          | String (_, n)
+          | OptString n
+          | StringList (_, n) ->
             pr "%s" n
           | Pointer (_, n) ->
             pr "%s" n
diff --git a/generator/OCaml.ml b/generator/OCaml.ml
index f0af3ae67..955da6f09 100644
--- a/generator/OCaml.ml
+++ b/generator/OCaml.ml
@@ -602,13 +602,7 @@ copy_table (char * const * argv)
 
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n ->
+        | String (_, n) ->
             (* Copy strings in case the GC moves them: RHBZ#604691 *)
             pr "  char *%s;\n" n;
             pr "  %s = strdup (String_val (%sv));\n" n n;
@@ -627,7 +621,7 @@ copy_table (char * const * argv)
             pr "  %s = malloc (%s_size);\n" n n;
             pr "  if (%s == NULL) caml_raise_out_of_memory ();\n" n;
             pr "  memcpy (%s, String_val (%sv), %s_size);\n" n n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  char **%s = guestfs_int_ocaml_strings_val (g, %sv);\n" n n
         | Bool n ->
             pr "  int %s = Bool_val (%sv);\n" n n
@@ -701,12 +695,10 @@ copy_table (char * const * argv)
       (* Free strings if we copied them above. *)
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n
-        | OptString n | FileIn n | FileOut n | BufferIn n
-        | Key n | GUID n ->
+        | String (_, n)
+        | OptString n | BufferIn n ->
             pr "  free (%s);\n" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  guestfs_int_free_string_list (%s);\n" n;
         | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
       ) args;
@@ -874,12 +866,9 @@ and generate_ocaml_function_type ?(extra_unit = false) (ret, args, optargs) =
   ) optargs;
   List.iter (
     function
-    | Pathname _ | Device _ | Mountable _
-    | Dev_or_Path _ | Mountable_or_Path _ | String _
-    | FileIn _ | FileOut _ | BufferIn _ | Key _
-    | GUID _ -> pr "string -> "
+    | String _ | BufferIn _ -> pr "string -> "
     | OptString _ -> pr "string option -> "
-    | StringList _ | DeviceList _ | FilenameList _ ->
+    | StringList _ ->
         pr "string array -> "
     | Bool _ -> pr "bool -> "
     | Int _ -> pr "int -> "
diff --git a/generator/XDR.ml b/generator/XDR.ml
index 634a4f336..b0ca26558 100644
--- a/generator/XDR.ml
+++ b/generator/XDR.ml
@@ -90,27 +90,25 @@ let generate_xdr () =
        *)
       let args_passed_to_daemon = args @ args_of_optargs optargs in
       let args_passed_to_daemon =
-        List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
-          args_passed_to_daemon in
+        List.filter (function String ((FileIn|FileOut), _) -> false | _ -> true)
+                    args_passed_to_daemon in
       (match args_passed_to_daemon with
       | [] -> ()
       | args ->
         pr "struct %s_args {\n" name;
         List.iter (
           function
-          | Pathname n | Device n | Mountable n | Dev_or_Path n
-          | Mountable_or_Path n | String n
-          | Key n | GUID n ->
+          | String (_, n) ->
             pr "  string %s<>;\n" n
           | OptString n -> pr "  guestfs_str *%s;\n" n
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
             pr "  guestfs_str %s<>;\n" n
           | Bool n -> pr "  bool %s;\n" n
           | Int n -> pr "  int %s;\n" n
           | Int64 n -> pr "  int64_t %s;\n" n
           | BufferIn n ->
             pr "  opaque %s<>;\n" n
-          | FileIn _ | FileOut _ | Pointer _ -> assert false
+          | Pointer _ -> assert false
         ) args;
         pr "};\n\n"
       );
diff --git a/generator/actions_augeas.ml b/generator/actions_augeas.ml
index 5e905b2e6..83cdcc38c 100644
--- a/generator/actions_augeas.ml
+++ b/generator/actions_augeas.ml
@@ -25,7 +25,7 @@ open Types
 let daemon_functions = [
   { defaults with
     name = "aug_init"; added = (0, 0, 7);
-    style = RErr, [Pathname "root"; Int "flags"], [];
+    style = RErr, [String (Pathname, "root"); Int "flags"], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["mkdir"; "/etc"];
@@ -99,7 +99,7 @@ Augeas functions." };
 
   { defaults with
     name = "aug_defvar"; added = (0, 0, 7);
-    style = RInt "nrnodes", [String "name"; OptString "expr"], [];
+    style = RInt "nrnodes", [String (PlainString, "name"); OptString "expr"], [];
     shortdesc = "define an Augeas variable";
     longdesc = "\
 Defines an Augeas variable C<name> whose value is the result
@@ -111,7 +111,7 @@ C<0> if C<expr> evaluates to something which is not a nodeset." };
 
   { defaults with
     name = "aug_defnode"; added = (0, 0, 7);
-    style = RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"], [];
+    style = RStruct ("nrnodescreated", "int_bool"), [String (PlainString, "name"); String (PlainString, "expr"); String (PlainString, "val")], [];
     shortdesc = "define an Augeas node";
     longdesc = "\
 Defines a variable C<name> whose value is the result of
@@ -127,7 +127,7 @@ if a node was created." };
 
   { defaults with
     name = "aug_get"; added = (0, 0, 7);
-    style = RString "val", [String "augpath"], [];
+    style = RString "val", [String (PlainString, "augpath")], [];
     shortdesc = "look up the value of an Augeas path";
     longdesc = "\
 Look up the value associated with C<path>.  If C<path>
@@ -135,7 +135,7 @@ matches exactly one node, the C<value> is returned." };
 
   { defaults with
     name = "aug_set"; added = (0, 0, 7);
-    style = RErr, [String "augpath"; String "val"], [];
+    style = RErr, [String (PlainString, "augpath"); String (PlainString, "val")], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["mkdir"; "/etc"];
@@ -155,7 +155,7 @@ C<guestfs_aug_clear> call." };
 
   { defaults with
     name = "aug_insert"; added = (0, 0, 7);
-    style = RErr, [String "augpath"; String "label"; Bool "before"], [];
+    style = RErr, [String (PlainString, "augpath"); String (PlainString, "label"); Bool "before"], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["mkdir"; "/etc"];
@@ -181,7 +181,7 @@ with a bracketed index C<[N]>." };
 
   { defaults with
     name = "aug_rm"; added = (0, 0, 7);
-    style = RInt "nrnodes", [String "augpath"], [];
+    style = RInt "nrnodes", [String (PlainString, "augpath")], [];
     shortdesc = "remove an Augeas path";
     longdesc = "\
 Remove C<path> and all of its children.
@@ -190,7 +190,7 @@ On success this returns the number of entries which were removed." };
 
   { defaults with
     name = "aug_mv"; added = (0, 0, 7);
-    style = RErr, [String "src"; String "dest"], [];
+    style = RErr, [String (PlainString, "src"); String (PlainString, "dest")], [];
     shortdesc = "move Augeas node";
     longdesc = "\
 Move the node C<src> to C<dest>.  C<src> must match exactly
@@ -198,7 +198,7 @@ one node.  C<dest> is overwritten if it exists." };
 
   { defaults with
     name = "aug_match"; added = (0, 0, 7);
-    style = RStringList "matches", [String "augpath"], [];
+    style = RStringList "matches", [String (PlainString, "augpath")], [];
     shortdesc = "return Augeas nodes which match augpath";
     longdesc = "\
 Returns a list of paths which match the path expression C<path>.
@@ -227,7 +227,7 @@ details." };
 
   { defaults with
     name = "aug_ls"; added = (0, 0, 8);
-    style = RStringList "matches", [String "augpath"], [];
+    style = RStringList "matches", [String (PlainString, "augpath")], [];
     tests = [
       InitBasicFS, Always, TestResult (
         [["mkdir"; "/etc"];
@@ -243,7 +243,7 @@ C<path/*> and sorting the resulting nodes into alphabetical order." };
 
   { defaults with
     name = "aug_clear"; added = (1, 3, 4);
-    style = RErr, [String "augpath"], [];
+    style = RErr, [String (PlainString, "augpath")], [];
     shortdesc = "clear Augeas path";
     longdesc = "\
 Set the value associated with C<path> to C<NULL>.  This
@@ -251,7 +251,7 @@ is the same as the L<augtool(1)> C<clear> command." };
 
   { defaults with
     name = "aug_transform"; added = (1, 35, 2);
-    style = RErr, [String "lens"; String "file"], [ OBool "remove"];
+    style = RErr, [String (PlainString, "lens"); String (PlainString, "file")], [ OBool "remove"];
     shortdesc = "add/remove an Augeas lens transformation";
     longdesc = "\
 Add an Augeas transformation for the specified C<lens> so it can
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 0dee25a9d..1860e9766 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -40,7 +40,7 @@ very cheap to create, so create a new one for each launch." };
 
   { defaults with
     name = "add_drive_ro"; added = (1, 0, 38);
-    style = RErr, [String "filename"], [];
+    style = RErr, [String (PlainString, "filename")], [];
     fish_alias = ["add-ro"]; config_only = true;
     blocking = false;
     shortdesc = "add a drive in snapshot mode (read-only)";
@@ -52,7 +52,7 @@ automatically." };
 
   { defaults with
     name = "config"; added = (0, 0, 3);
-    style = RErr, [String "hvparam"; OptString "hvvalue"], [];
+    style = RErr, [String (PlainString, "hvparam"); OptString "hvvalue"], [];
     config_only = true;
     blocking = false;
     shortdesc = "add hypervisor parameters";
@@ -184,7 +184,7 @@ Use C<guestfs_available> or C<guestfs_feature_available> instead." };
 
   { defaults with
     name = "file_architecture"; added = (1, 5, 3);
-    style = RString "arch", [Pathname "filename"], [];
+    style = RString "arch", [String (Pathname, "filename")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["file_architecture"; "/bin-aarch64-dynamic"]], "aarch64"), [];
@@ -372,7 +372,7 @@ initrd or kernel module(s) instead.
 
   { defaults with
     name = "mountable_device"; added = (1, 33, 15);
-    style = RString "device", [Mountable "mountable"], [];
+    style = RString "device", [String (Mountable, "mountable")], [];
     shortdesc = "extract the device part of a mountable";
     longdesc = "\
 Returns the device name of a mountable. In quite a lot of
@@ -385,7 +385,7 @@ extract the subvolume path of the mountable if any)." };
 
   { defaults with
     name = "mountable_subvolume"; added = (1, 33, 15);
-    style = RString "subvolume", [Mountable "mountable"], [];
+    style = RString "subvolume", [String (Mountable, "mountable")], [];
     shortdesc = "extract the subvolume part of a mountable";
     longdesc = "\
 Returns the subvolume path of a mountable. Btrfs subvolumes
@@ -435,7 +435,7 @@ not all belong to a single logical operating system
 
   { defaults with
     name = "add_drive"; added = (0, 0, 3);
-    style = RErr, [String "filename"], [OBool "readonly"; OString "format"; OString "iface"; OString "name"; OString "label"; OString "protocol"; OStringList "server"; OString "username"; OString "secret"; OString "cachemode"; OString "discard"; OBool "copyonread"];
+    style = RErr, [String (PlainString, "filename")], [OBool "readonly"; OString "format"; OString "iface"; OString "name"; OString "label"; OString "protocol"; OStringList "server"; OString "username"; OString "secret"; OString "cachemode"; OString "discard"; OBool "copyonread"];
     once_had_no_optargs = true;
     blocking = false;
     fish_alias = ["add"];
@@ -698,7 +698,7 @@ The default is false.
 
   { defaults with
     name = "add_domain"; added = (1, 7, 4);
-    style = RInt "nrdisks", [String "dom"], [OString "libvirturi"; OBool "readonly"; OString "iface"; OBool "live"; OBool "allowuuid"; OString "readonlydisk"; OString "cachemode"; OString "discard"; OBool "copyonread"];
+    style = RInt "nrdisks", [String (PlainString, "dom")], [OString "libvirturi"; OBool "readonly"; OString "iface"; OBool "live"; OBool "allowuuid"; OString "readonlydisk"; OString "cachemode"; OString "discard"; OBool "copyonread"];
     fish_alias = ["domain"]; config_only = true;
     shortdesc = "add the disk(s) from a named libvirt domain";
     longdesc = "\
@@ -827,7 +827,7 @@ C<guestfs_add_drive_opts>." };
 
   { defaults with
     name = "mount_local"; added = (1, 17, 22);
-    style = RErr, [String "localmountpoint"], [OBool "readonly"; OString "options"; OInt "cachetimeout"; OBool "debugcalls"];
+    style = RErr, [String (PlainString, "localmountpoint")], [OBool "readonly"; OString "options"; OInt "cachetimeout"; OBool "debugcalls"];
     shortdesc = "mount on the local filesystem";
     longdesc = "\
 This call exports the libguestfs-accessible filesystem to
@@ -905,7 +905,7 @@ information on this topic." };
 
   { defaults with
     name = "canonical_device_name"; added = (1, 19, 7);
-    style = RString "canonical", [String "device"], [];
+    style = RString "canonical", [String (PlainString, "device")], [];
     tests = [
       InitNone, Always, TestResultString (
         [["canonical_device_name"; "/dev/hda"]], "/dev/sda"), [];
@@ -969,7 +969,7 @@ but note that any errors are ignored in that case." };
 
   { defaults with
     name = "cat"; added = (0, 0, 4);
-    style = RString "content", [Pathname "path"], [];
+    style = RString "content", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["cat"; "/known-2"]], "abcdef\n"), []
@@ -985,7 +985,7 @@ or C<guestfs_download> functions." };
 
   { defaults with
     name = "find"; added = (1, 0, 27);
-    style = RStringList "names", [Pathname "directory"], [];
+    style = RStringList "names", [String (Pathname, "directory")], [];
     tests = [
       InitBasicFS, Always, TestResult (
         [["find"; "/"]],
@@ -1031,7 +1031,7 @@ The returned list is sorted." };
 
   { defaults with
     name = "read_file"; added = (1, 0, 63);
-    style = RBufferOut "content", [Pathname "path"], [];
+    style = RBufferOut "content", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["read_file"; "/known-4"]],
@@ -1047,7 +1047,7 @@ handle files that contain embedded ASCII NUL characters." };
 
   { defaults with
     name = "read_lines"; added = (0, 0, 7);
-    style = RStringList "lines", [Pathname "path"], [];
+    style = RStringList "lines", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["read_lines"; "/known-4"]],
@@ -1102,7 +1102,7 @@ function and split the buffer into lines yourself." };
 
   { defaults with
     name = "write"; added = (1, 3, 14);
-    style = RErr, [Pathname "path"; BufferIn "content"], [];
+    style = RErr, [String (Pathname, "path"); BufferIn "content"], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["write"; "/write"; "new file contents"];
@@ -1132,7 +1132,7 @@ See also C<guestfs_write_append>." };
 
   { defaults with
     name = "write_append"; added = (1, 11, 18);
-    style = RErr, [Pathname "path"; BufferIn "content"], [];
+    style = RErr, [String (Pathname, "path"); BufferIn "content"], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["write"; "/write_append"; "line1\n"];
@@ -1150,7 +1150,7 @@ See also C<guestfs_write>." };
 
   { defaults with
     name = "lstatnslist"; added = (1, 27, 53);
-    style = RStructList ("statbufs", "statns"), [Pathname "path"; FilenameList "names"], [];
+    style = RStructList ("statbufs", "statns"), [String (Pathname, "path"); StringList (Filename, "names")], [];
     shortdesc = "lstat on multiple files";
     longdesc = "\
 This call allows you to perform the C<guestfs_lstatns> operation
@@ -1169,7 +1169,7 @@ for getting extended attributes." };
 
   { defaults with
     name = "lxattrlist"; added = (1, 0, 77);
-    style = RStructList ("xattrs", "xattr"), [Pathname "path"; FilenameList "names"], [];
+    style = RStructList ("xattrs", "xattr"), [String (Pathname, "path"); StringList (Filename, "names")], [];
     optional = Some "linuxxattrs";
     shortdesc = "lgetxattr on multiple files";
     longdesc = "\
@@ -1194,7 +1194,7 @@ for getting standard stats." };
 
   { defaults with
     name = "readlinklist"; added = (1, 0, 77);
-    style = RStringList "links", [Pathname "path"; FilenameList "names"], [];
+    style = RStringList "links", [String (Pathname, "path"); StringList (Filename, "names")], [];
     shortdesc = "readlink on multiple files";
     longdesc = "\
 This call allows you to do a C<readlink> operation
@@ -1217,7 +1217,7 @@ list a directory contents without making many round-trips." };
 
   { defaults with
     name = "ls"; added = (0, 0, 4);
-    style = RStringList "listing", [Pathname "directory"], [];
+    style = RStringList "listing", [String (Pathname, "directory")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["mkdir"; "/ls"];
@@ -1235,7 +1235,7 @@ hidden files are shown." };
 
   { defaults with
     name = "disk_format"; added = (1, 19, 38);
-    style = RString "format", [String "filename"], [];
+    style = RString "format", [String (PlainString, "filename")], [];
     tests = [
       InitEmpty, Always, TestResultString (
         [["disk_format"; "../../test-data/blank-disks/blank-disk-1s.raw"]], "raw"), [];
@@ -1265,7 +1265,7 @@ See also: L<guestfs(3)/DISK IMAGE FORMATS>" };
 
   { defaults with
     name = "disk_virtual_size"; added = (1, 19, 39);
-    style = RInt64 "size", [String "filename"], [];
+    style = RInt64 "size", [String (PlainString, "filename")], [];
     tests = [
       InitEmpty, Always, TestResult (
         [["disk_virtual_size"; "../../test-data/blank-disks/blank-disk-1s.raw"]], "ret == 512"), [];
@@ -1292,7 +1292,7 @@ circumstances.  See L<guestfs(3)/CVE-2010-3851>." };
 
   { defaults with
     name = "disk_has_backing_file"; added = (1, 19, 39);
-    style = RBool "backingfile", [String "filename"], [];
+    style = RBool "backingfile", [String (PlainString, "filename")], [];
     tests = [
       InitEmpty, Always, TestResultFalse (
         [["disk_has_backing_file"; "../../test-data/blank-disks/blank-disk-1s.raw"]]), [];
@@ -1319,7 +1319,7 @@ circumstances.  See L<guestfs(3)/CVE-2010-3851>." };
 
   { defaults with
     name = "remove_drive"; added = (1, 19, 49);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     blocking = false;
     shortdesc = "remove a disk image";
     longdesc = "\
@@ -1338,7 +1338,7 @@ disk is in use and stop you from doing this." };
 
   { defaults with
     name = "set_libvirt_supported_credentials"; added = (1, 19, 52);
-    style = RErr, [StringList "creds"], [];
+    style = RErr, [StringList (PlainString, "creds")], [];
     blocking = false;
     shortdesc = "set libvirt credentials supported by calling program";
     longdesc = "\
@@ -1457,7 +1457,7 @@ C<guestfs_parse_environment_list>." };
 
   { defaults with
     name = "parse_environment_list"; added = (1, 19, 53);
-    style = RErr, [StringList "environment"], [];
+    style = RErr, [StringList (PlainString, "environment")], [];
     blocking = false;
     shortdesc = "parse the environment and set handle flags accordingly";
     longdesc = "\
@@ -1543,7 +1543,7 @@ the libguestfs protocol." };
 
   { defaults with
     name = "disk_create"; added = (1, 25, 31);
-    style = RErr, [String "filename"; String "format"; Int64 "size"], [OString "backingfile"; OString "backingformat"; OString "preallocation"; OString "compat"; OInt "clustersize"];
+    style = RErr, [String (PlainString, "filename"); String (PlainString, "format"); Int64 "size"], [OString "backingfile"; OString "backingformat"; OString "preallocation"; OString "compat"; OInt "clustersize"];
     test_excuse = "tests in tests/create subdirectory";
     shortdesc = "create a blank disk image";
     longdesc = "\
@@ -1610,7 +1610,7 @@ to allow other libraries to interwork with libguestfs." };
 
   { defaults with
     name = "copy_in"; added = (1, 29, 24);
-    style = RErr, [String "localpath"; Pathname "remotedir"], [];
+    style = RErr, [String (PlainString, "localpath"); String (Pathname, "remotedir")], [];
     visibility = VPublicNoFish;
     shortdesc = "copy local files or directories into an image";
     longdesc = "\
@@ -1622,7 +1622,7 @@ Wildcards cannot be used." };
 
   { defaults with
     name = "copy_out"; added = (1, 29, 24);
-    style = RErr, [Pathname "remotepath"; String "localdir"], [];
+    style = RErr, [String (Pathname, "remotepath"); String (PlainString, "localdir")], [];
     visibility = VPublicNoFish;
     shortdesc = "copy remote files or directories out of an image";
     longdesc = "\
@@ -1638,7 +1638,7 @@ Wildcards cannot be used." };
 
   { defaults with
     name = "available"; added = (1, 0, 80);
-    style = RErr, [StringList "groups"], [];
+    style = RErr, [StringList (PlainString, "groups")], [];
     tests = [
       InitNone, Always, TestRun [["available"; ""]], []
     ];
@@ -1711,7 +1711,7 @@ See also C<guestfs_filesystem_available>." };
 
   { defaults with
     name = "feature_available"; added = (1, 21, 26);
-    style = RBool "isavailable", [StringList "groups"], [];
+    style = RBool "isavailable", [StringList (PlainString, "groups")], [];
     tests = [
       InitNone, Always, TestResultTrue [["feature_available"; ""]], []
     ];
@@ -1738,7 +1738,7 @@ not normally be used by other libguestfs users." };
 let daemon_functions = [
   { defaults with
     name = "mount"; added = (0, 0, 3);
-    style = RErr, [Mountable "mountable"; String "mountpoint"], [];
+    style = RErr, [String (Mountable, "mountable"); String (PlainString, "mountpoint")], [];
     tests = [
       InitEmpty, Always, TestResultString (
         [["part_disk"; "/dev/sda"; "mbr"];
@@ -1787,7 +1787,7 @@ closing the handle." };
 
   { defaults with
     name = "touch"; added = (0, 0, 3);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResultTrue (
         [["touch"; "/touch"];
@@ -1804,7 +1804,7 @@ file types such as directories, symbolic links, block special etc." };
 
   { defaults with
     name = "ll"; added = (0, 0, 4);
-    style = RString "listing", [Pathname "directory"], [];
+    style = RString "listing", [String (Pathname, "directory")], [];
     test_excuse = "tricky to test because it depends on the exact format of the 'ls -l' command, which changed between Fedora 10 and Fedora 11";
     shortdesc = "list the files in a directory (long format)";
     longdesc = "\
@@ -1977,7 +1977,7 @@ of the L<lvs(8)> command.  The \"full\" version includes all fields." };
 
   { defaults with
     name = "rm"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestRun
         [["mkdir"; "/rm"];
@@ -1995,7 +1995,7 @@ Remove the single file C<path>." };
 
   { defaults with
     name = "rmdir"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestRun
         [["mkdir"; "/rmdir"];
@@ -2013,7 +2013,7 @@ Remove the single directory C<path>." };
 
   { defaults with
     name = "rm_rf"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResultFalse
         [["mkdir"; "/rm_rf"];
@@ -2030,7 +2030,7 @@ command." };
 
   { defaults with
     name = "mkdir"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResultTrue
         [["mkdir"; "/mkdir"];
@@ -2044,7 +2044,7 @@ Create a directory named C<path>." };
 
   { defaults with
     name = "mkdir_p"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResultTrue
         [["mkdir_p"; "/mkdir_p/foo/bar"];
@@ -2070,7 +2070,7 @@ as necessary.  This is like the C<mkdir -p> shell command." };
 
   { defaults with
     name = "chmod"; added = (0, 0, 8);
-    style = RErr, [Int "mode"; Pathname "path"], [];
+    style = RErr, [Int "mode"; String (Pathname, "path")], [];
     shortdesc = "change file mode";
     longdesc = "\
 Change the mode (permissions) of C<path> to C<mode>.  Only
@@ -2084,7 +2084,7 @@ The mode actually set is affected by the umask." };
 
   { defaults with
     name = "chown"; added = (0, 0, 8);
-    style = RErr, [Int "owner"; Int "group"; Pathname "path"], [];
+    style = RErr, [Int "owner"; Int "group"; String (Pathname, "path")], [];
     shortdesc = "change file owner and group";
     longdesc = "\
 Change the file owner to C<owner> and group to C<group>.
@@ -2095,7 +2095,7 @@ yourself (Augeas support makes this relatively easy)." };
 
   { defaults with
     name = "exists"; added = (0, 0, 8);
-    style = RBool "existsflag", [Pathname "path"], [];
+    style = RBool "existsflag", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultTrue (
         [["exists"; "/empty"]]), [];
@@ -2111,7 +2111,7 @@ See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>." };
 
   { defaults with
     name = "is_file"; added = (0, 0, 8);
-    style = RBool "fileflag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "fileflag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultTrue (
@@ -2135,7 +2135,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_dir"; added = (0, 0, 8);
-    style = RBool "dirflag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "dirflag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
@@ -2157,7 +2157,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "pvcreate"; added = (0, 0, 8);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -2179,7 +2179,7 @@ as F</dev/sda1>." };
 
   { defaults with
     name = "vgcreate"; added = (0, 0, 8);
-    style = RErr, [String "volgroup"; DeviceList "physvols"], [];
+    style = RErr, [String (PlainString, "volgroup"); StringList (Device, "physvols")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -2211,7 +2211,7 @@ from the non-empty list of physical volumes C<physvols>." };
 
   { defaults with
     name = "lvcreate"; added = (0, 0, 8);
-    style = RErr, [String "logvol"; String "volgroup"; Int "mbytes"], [];
+    style = RErr, [String (PlainString, "logvol"); String (PlainString, "volgroup"); Int "mbytes"], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -2239,7 +2239,7 @@ on the volume group C<volgroup>, with C<size> megabytes." };
 
   { defaults with
     name = "umount"; added = (0, 0, 8);
-    style = RErr, [Dev_or_Path "pathordevice"], [OBool "force"; OBool "lazyunmount"];
+    style = RErr, [String (Dev_or_Path, "pathordevice")], [OBool "force"; OBool "lazyunmount"];
     fish_alias = ["unmount"];
     once_had_no_optargs = true;
     tests = [
@@ -2320,7 +2320,7 @@ and physical volumes." };
 
   { defaults with
     name = "file"; added = (1, 9, 1);
-    style = RString "description", [Dev_or_Path "path"], [];
+    style = RString "description", [String (Dev_or_Path, "path")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["file"; "/empty"]], "empty"), [];
@@ -2354,7 +2354,7 @@ C<guestfs_is_file>, C<guestfs_is_blockdev> (etc), C<guestfs_is_zero>." };
 
   { defaults with
     name = "command"; added = (1, 9, 1);
-    style = RString "output", [StringList "arguments"], [];
+    style = RString "output", [StringList (PlainString, "arguments")], [];
     protocol_limit_warning = true;
     tests = [
       InitScratchFS, IfNotCrossAppliance, TestResultString (
@@ -2457,7 +2457,7 @@ locations." };
 
   { defaults with
     name = "command_lines"; added = (1, 9, 1);
-    style = RStringList "lines", [StringList "arguments"], [];
+    style = RStringList "lines", [StringList (PlainString, "arguments")], [];
     protocol_limit_warning = true;
     tests = [
       InitScratchFS, IfNotCrossAppliance, TestResult (
@@ -2536,7 +2536,7 @@ See also: C<guestfs_sh_lines>" };
 
   { defaults with
     name = "statvfs"; added = (1, 9, 2);
-    style = RStruct ("statbuf", "statvfs"), [Pathname "path"], [];
+    style = RStruct ("statbuf", "statvfs"), [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["statvfs"; "/"]], "ret->namemax == 255"), []
@@ -2551,7 +2551,7 @@ This is the same as the L<statvfs(2)> system call." };
 
   { defaults with
     name = "tune2fs_l"; added = (1, 9, 2);
-    style = RHashtable "superblock", [Device "device"], [];
+    style = RHashtable "superblock", [String (Device, "device")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["tune2fs_l"; "/dev/sdb1"]],
@@ -2570,7 +2570,7 @@ that libguestfs was built against, and the filesystem itself." };
 
   { defaults with
     name = "blockdev_setro"; added = (1, 9, 3);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResultTrue (
         [["blockdev_setro"; "/dev/sda"];
@@ -2584,7 +2584,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_setrw"; added = (1, 9, 3);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResultFalse (
         [["blockdev_setrw"; "/dev/sda"];
@@ -2598,7 +2598,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_getro"; added = (1, 9, 3);
-    style = RBool "ro", [Device "device"], [];
+    style = RBool "ro", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResultTrue (
         [["blockdev_setro"; "/dev/sda"];
@@ -2613,7 +2613,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_getss"; added = (1, 9, 3);
-    style = RInt "sectorsize", [Device "device"], [];
+    style = RInt "sectorsize", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResult (
         [["blockdev_getss"; "/dev/sda"]], "ret == 512"), []
@@ -2630,7 +2630,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_getbsz"; added = (1, 9, 3);
-    style = RInt "blocksize", [Device "device"], [];
+    style = RInt "blocksize", [String (Device, "device")], [];
     test_excuse = "cannot be tested because output differs depending on page size";
     shortdesc = "get blocksize of block device";
     longdesc = "\
@@ -2646,7 +2646,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_getsz"; added = (1, 9, 3);
-    style = RInt64 "sizeinsectors", [Device "device"], [];
+    style = RInt64 "sizeinsectors", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResult (
         [["blockdev_getsz"; "/dev/sda"]],
@@ -2665,7 +2665,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_getsize64"; added = (1, 9, 3);
-    style = RInt64 "sizeinbytes", [Device "device"], [];
+    style = RInt64 "sizeinbytes", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResult (
         [["blockdev_getsize64"; "/dev/sda"]],
@@ -2681,7 +2681,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_flushbufs"; added = (1, 9, 3);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestRun
         [["blockdev_flushbufs"; "/dev/sda"]], []
@@ -2695,7 +2695,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "blockdev_rereadpt"; added = (1, 9, 3);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestRun
         [["blockdev_rereadpt"; "/dev/sda"]], []
@@ -2708,7 +2708,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "upload"; added = (1, 0, 2);
-    style = RErr, [FileIn "filename"; Dev_or_Path "remotefilename"], [];
+    style = RErr, [String (FileIn, "filename"); String (Dev_or_Path, "remotefilename")], [];
     progress = true; cancellable = true;
     tests = [
       InitScratchFS, Always, TestResultString (
@@ -2729,7 +2729,7 @@ See also C<guestfs_download>." };
 
   { defaults with
     name = "download"; added = (1, 0, 2);
-    style = RErr, [Dev_or_Path "remotefilename"; FileOut "filename"], [];
+    style = RErr, [String (Dev_or_Path, "remotefilename"); String (FileOut, "filename")], [];
     progress = true; cancellable = true;
     tests = [
       InitScratchFS, Always, TestResultString (
@@ -2752,7 +2752,7 @@ See also C<guestfs_upload>, C<guestfs_cat>." };
 
   { defaults with
     name = "checksum"; added = (1, 0, 2);
-    style = RString "checksum", [String "csumtype"; Pathname "path"], [];
+    style = RString "checksum", [String (PlainString, "csumtype"); String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["checksum"; "crc"; "/known-3"]], "2891671662"), [];
@@ -2823,7 +2823,7 @@ To get the checksums for many files, use C<guestfs_checksums_out>." };
 
   { defaults with
     name = "tar_in"; added = (1, 0, 3);
-    style = RErr, [FileIn "tarfile"; Pathname "directory"], [OString "compress"; OBool "xattrs"; OBool "selinux"; OBool "acls"];
+    style = RErr, [String (FileIn, "tarfile"); String (Pathname, "directory")], [OString "compress"; OBool "xattrs"; OBool "selinux"; OBool "acls"];
     once_had_no_optargs = true;
     cancellable = true;
     tests = [
@@ -2871,7 +2871,7 @@ If set to true, POSIX ACLs are restored from the tar file.
 
   { defaults with
     name = "tar_out"; added = (1, 0, 3);
-    style = RErr, [String "directory"; FileOut "tarfile"], [OString "compress"; OBool "numericowner"; OStringList "excludes"; OBool "xattrs"; OBool "selinux"; OBool "acls"];
+    style = RErr, [String (PlainString, "directory"); String (FileOut, "tarfile")], [OString "compress"; OBool "numericowner"; OStringList "excludes"; OBool "xattrs"; OBool "selinux"; OBool "acls"];
     once_had_no_optargs = true;
     cancellable = true;
     shortdesc = "pack directory into tarfile";
@@ -2916,7 +2916,7 @@ If set to true, POSIX ACLs are saved in the output tar.
 
   { defaults with
     name = "mount_ro"; added = (1, 0, 10);
-    style = RErr, [Mountable "mountable"; String "mountpoint"], [];
+    style = RErr, [String (Mountable, "mountable"); String (PlainString, "mountpoint")], [];
     tests = [
       InitBasicFS, Always, TestLastFail (
         [["umount"; "/"; "false"; "false"];
@@ -2935,7 +2935,7 @@ mounts the filesystem with the read-only (I<-o ro>) flag." };
 
   { defaults with
     name = "mount_options"; added = (1, 0, 10);
-    style = RErr, [String "options"; Mountable "mountable"; String "mountpoint"], [];
+    style = RErr, [String (PlainString, "options"); String (Mountable, "mountable"); String (PlainString, "mountpoint")], [];
     shortdesc = "mount a guest disk with mount options";
     longdesc = "\
 This is the same as the C<guestfs_mount> command, but it
@@ -2948,7 +2948,7 @@ the filesystem uses)." };
 
   { defaults with
     name = "mount_vfs"; added = (1, 0, 10);
-    style = RErr, [String "options"; String "vfstype"; Mountable "mountable"; String "mountpoint"], [];
+    style = RErr, [String (PlainString, "options"); String (PlainString, "vfstype"); String (Mountable, "mountable"); String (PlainString, "mountpoint")], [];
     shortdesc = "mount a guest disk with mount options and vfstype";
     longdesc = "\
 This is the same as the C<guestfs_mount> command, but it
@@ -2957,7 +2957,7 @@ as for the L<mount(8)> I<-o> and I<-t> flags." };
 
   { defaults with
     name = "lvremove"; added = (1, 0, 13);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -2998,7 +2998,7 @@ the VG name, F</dev/VG>." };
 
   { defaults with
     name = "vgremove"; added = (1, 0, 13);
-    style = RErr, [String "vgname"], [];
+    style = RErr, [String (PlainString, "vgname")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -3029,7 +3029,7 @@ group (if any)." };
 
   { defaults with
     name = "pvremove"; added = (1, 0, 13);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -3074,7 +3074,7 @@ to remove those first." };
 
   { defaults with
     name = "fsck"; added = (1, 0, 16);
-    style = RInt "status", [String "fstype"; Device "device"], [];
+    style = RInt "status", [String (PlainString, "fstype"); String (Device, "device")], [];
     fish_output = Some FishOutputHexadecimal;
     tests = [
       InitBasicFS, Always, TestResult (
@@ -3117,7 +3117,7 @@ This command is entirely equivalent to running C<fsck -a -t fstype device>." };
 
   { defaults with
     name = "zero"; added = (1, 0, 16);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     progress = true;
     tests = [
       InitBasicFS, Always, TestRun (
@@ -3141,7 +3141,7 @@ C<guestfs_is_zero_device>" };
 
   { defaults with
     name = "grub_install"; added = (1, 0, 17);
-    style = RErr, [Pathname "root"; Device "device"], [];
+    style = RErr, [String (Pathname, "root"); String (Device, "device")], [];
     optional = Some "grub";
     (* See:
      * https://bugzilla.redhat.com/show_bug.cgi?id=484986
@@ -3194,7 +3194,7 @@ replacing F</dev/vda> with the name of the installation device.
 
   { defaults with
     name = "cp"; added = (1, 0, 18);
-    style = RErr, [Pathname "src"; Pathname "dest"], [];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["mkdir"; "/cp"];
@@ -3220,7 +3220,7 @@ either a destination filename or destination directory." };
 
   { defaults with
     name = "cp_a"; added = (1, 0, 18);
-    style = RErr, [Pathname "src"; Pathname "dest"], [];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["mkdir"; "/cp_a1"];
@@ -3236,7 +3236,7 @@ recursively using the C<cp -a> command." };
 
   { defaults with
     name = "mv"; added = (1, 0, 18);
-    style = RErr, [Pathname "src"; Pathname "dest"], [];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["mkdir"; "/mv"];
@@ -3309,7 +3309,7 @@ or attached block device(s) in any other way." };
 
   { defaults with
     name = "equal"; added = (1, 0, 18);
-    style = RBool "equality", [Pathname "file1"; Pathname "file2"], [];
+    style = RBool "equality", [String (Pathname, "file1"); String (Pathname, "file2")], [];
     tests = [
       InitScratchFS, Always, TestResultTrue (
         [["mkdir"; "/equal"];
@@ -3334,7 +3334,7 @@ The external L<cmp(1)> program is used for the comparison." };
 
   { defaults with
     name = "strings"; added = (1, 0, 22);
-    style = RStringList "stringsout", [Pathname "path"], [];
+    style = RStringList "stringsout", [String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3358,7 +3358,7 @@ version of libguestfs, but see L<guestfs(3)/CVE-2014-8484>." };
 
   { defaults with
     name = "strings_e"; added = (1, 0, 22);
-    style = RStringList "stringsout", [String "encoding"; Pathname "path"], [];
+    style = RStringList "stringsout", [String (PlainString, "encoding"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3416,7 +3416,7 @@ version of libguestfs, but see L<guestfs(3)/CVE-2014-8484>." };
 
   { defaults with
     name = "hexdump"; added = (1, 0, 22);
-    style = RString "dump", [Pathname "path"], [];
+    style = RString "dump", [String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResultString (
@@ -3437,7 +3437,7 @@ the human-readable, canonical hex dump of the file." };
 
   { defaults with
     name = "zerofree"; added = (1, 0, 26);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "zerofree";
     tests = [
       InitNone, Always, TestResultString (
@@ -3465,7 +3465,7 @@ or data on the filesystem." };
 
   { defaults with
     name = "pvresize"; added = (1, 0, 26);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "lvm2";
     shortdesc = "resize an LVM physical volume";
     longdesc = "\
@@ -3474,7 +3474,7 @@ volume to match the new size of the underlying device." };
 
   { defaults with
     name = "sfdisk_kernel_geometry"; added = (1, 0, 26);
-    style = RString "partitions", [Device "device"], [];
+    style = RString "partitions", [String (Device, "device")], [];
     shortdesc = "display the kernel geometry";
     longdesc = "\
 This displays the kernel’s idea of the geometry of C<device>.
@@ -3484,7 +3484,7 @@ be parsed." };
 
   { defaults with
     name = "sfdisk_disk_geometry"; added = (1, 0, 26);
-    style = RString "partitions", [Device "device"], [];
+    style = RString "partitions", [String (Device, "device")], [];
     shortdesc = "display the disk geometry from the partition table";
     longdesc = "\
 This displays the disk geometry of C<device> read from the
@@ -3508,7 +3508,7 @@ This command is the same as running C<vgchange -a y|n>" };
 
   { defaults with
     name = "vg_activate"; added = (1, 0, 26);
-    style = RErr, [Bool "activate"; StringList "volgroups"], [];
+    style = RErr, [Bool "activate"; StringList (PlainString, "volgroups")], [];
     optional = Some "lvm2";
     shortdesc = "activate or deactivate some volume groups";
     longdesc = "\
@@ -3522,7 +3522,7 @@ are activated or deactivated." };
 
   { defaults with
     name = "lvresize"; added = (1, 0, 27);
-    style = RErr, [Device "device"; Int "mbytes"], [];
+    style = RErr, [String (Device, "device"); Int "mbytes"], [];
     optional = Some "lvm2";
     tests = [
       InitNone, Always, TestResultString (
@@ -3557,7 +3557,7 @@ is lost." };
 
   { defaults with
     name = "resize2fs"; added = (1, 0, 27);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     shortdesc = "resize an ext2, ext3 or ext4 filesystem";
     longdesc = "\
 This resizes an ext2, ext3 or ext4 filesystem to match the size of
@@ -3578,7 +3578,7 @@ Sleep for C<secs> seconds." };
 
   { defaults with
     name = "ntfs_3g_probe"; added = (1, 0, 43);
-    style = RInt "status", [Bool "rw"; Device "device"], [];
+    style = RInt "status", [Bool "rw"; String (Device, "device")], [];
     optional = Some "ntfs3g";
     tests = [
       InitNone, Always, TestResult (
@@ -3606,7 +3606,7 @@ L<ntfs-3g.probe(8)> manual page." };
 
   { defaults with
     name = "sh"; added = (1, 0, 50);
-    style = RString "output", [String "command"], [];
+    style = RString "output", [String (PlainString, "command")], [];
     shortdesc = "run a command via the shell";
     longdesc = "\
 This call runs a command from the guest filesystem via the
@@ -3624,7 +3624,7 @@ All the provisos about C<guestfs_command> apply to this call." };
 
   { defaults with
     name = "sh_lines"; added = (1, 0, 50);
-    style = RStringList "lines", [String "command"], [];
+    style = RStringList "lines", [String (PlainString, "command")], [];
     shortdesc = "run a command via the shell returning lines";
     longdesc = "\
 This is the same as C<guestfs_sh>, but splits the result
@@ -3639,7 +3639,7 @@ See also: C<guestfs_command_lines>" };
      * start with "/".  There is no concept of "cwd" in libguestfs,
      * hence no "."-relative names.
      *)
-    style = RStringList "paths", [Pathname "pattern"], [OBool "directoryslash"];
+    style = RStringList "paths", [String (Pathname, "pattern")], [OBool "directoryslash"];
     once_had_no_optargs = true;
     tests = [
       InitScratchFS, Always, TestResult (
@@ -3690,7 +3690,7 @@ C<guestfs_list_partitions> etc functions instead." };
 
   { defaults with
     name = "scrub_device"; added = (1, 0, 52);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "scrub";
     tests = [
       InitNone, Always, TestRun (	(* use /dev/sdc because it's smaller *)
@@ -3706,7 +3706,7 @@ manual page for more details." };
 
   { defaults with
     name = "scrub_file"; added = (1, 0, 52);
-    style = RErr, [Pathname "file"], [];
+    style = RErr, [String (Pathname, "file")], [];
     optional = Some "scrub";
     tests = [
       InitScratchFS, Always, TestRun (
@@ -3736,7 +3736,7 @@ manual page for more details." };
 
   { defaults with
     name = "scrub_freespace"; added = (1, 0, 52);
-    style = RErr, [Pathname "dir"], [];
+    style = RErr, [String (Pathname, "dir")], [];
     optional = Some "scrub";
     tests = [] (* XXX needs testing *);
     shortdesc = "scrub (securely wipe) free space";
@@ -3752,7 +3752,7 @@ manual page for more details." };
 
   { defaults with
     name = "mkdtemp"; added = (1, 0, 54);
-    style = RString "dir", [Pathname "tmpl"], [];
+    style = RString "dir", [String (Pathname, "tmpl")], [];
     tests = [
       InitScratchFS, Always, TestRun (
         [["mkdir"; "/mkdtemp"];
@@ -3781,7 +3781,7 @@ See also: L<mkdtemp(3)>" };
 
   { defaults with
     name = "wc_l"; added = (1, 0, 54);
-    style = RInt "lines", [Pathname "path"], [];
+    style = RInt "lines", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["wc_l"; "/10klines"]], "ret == 10000"), [];
@@ -3796,7 +3796,7 @@ C<wc -l> external command." };
 
   { defaults with
     name = "wc_w"; added = (1, 0, 54);
-    style = RInt "words", [Pathname "path"], [];
+    style = RInt "words", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["wc_w"; "/10klines"]], "ret == 10000"), []
@@ -3808,7 +3808,7 @@ C<wc -w> external command." };
 
   { defaults with
     name = "wc_c"; added = (1, 0, 54);
-    style = RInt "chars", [Pathname "path"], [];
+    style = RInt "chars", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["wc_c"; "/100kallspaces"]], "ret == 102400"), []
@@ -3820,7 +3820,7 @@ C<wc -c> external command." };
 
   { defaults with
     name = "head"; added = (1, 0, 54);
-    style = RStringList "lines", [Pathname "path"], [];
+    style = RStringList "lines", [String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3838,7 +3838,7 @@ a list of strings." };
 
   { defaults with
     name = "head_n"; added = (1, 0, 54);
-    style = RStringList "lines", [Int "nrlines"; Pathname "path"], [];
+    style = RStringList "lines", [Int "nrlines"; String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3863,7 +3863,7 @@ If the parameter C<nrlines> is zero, this returns an empty list." };
 
   { defaults with
     name = "tail"; added = (1, 0, 54);
-    style = RStringList "lines", [Pathname "path"], [];
+    style = RStringList "lines", [String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3877,7 +3877,7 @@ a list of strings." };
 
   { defaults with
     name = "tail_n"; added = (1, 0, 54);
-    style = RStringList "lines", [Int "nrlines"; Pathname "path"], [];
+    style = RStringList "lines", [Int "nrlines"; String (Pathname, "path")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3927,7 +3927,7 @@ Use C<guestfs_statvfs> from programs." };
 
   { defaults with
     name = "du"; added = (1, 0, 54);
-    style = RInt64 "sizekb", [Pathname "path"], [];
+    style = RInt64 "sizekb", [String (Pathname, "path")], [];
     progress = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -3947,7 +3947,7 @@ The result is the estimated size in I<kilobytes>
 
   { defaults with
     name = "initrd_list"; added = (1, 0, 54);
-    style = RStringList "filenames", [Pathname "path"], [];
+    style = RStringList "filenames", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["initrd_list"; "/initrd"]],
@@ -3967,7 +3967,7 @@ format (compressed cpio files)." };
 
   { defaults with
     name = "mount_loop"; added = (1, 0, 54);
-    style = RErr, [Pathname "file"; Pathname "mountpoint"], [];
+    style = RErr, [String (Pathname, "file"); String (Pathname, "mountpoint")], [];
     shortdesc = "mount a file using the loop device";
     longdesc = "\
 This command lets you mount F<file> (a filesystem image
@@ -3976,7 +3976,7 @@ the command C<mount -o loop file mountpoint>." };
 
   { defaults with
     name = "mkswap"; added = (1, 0, 55);
-    style = RErr, [Device "device"], [OString "label"; OString "uuid"];
+    style = RErr, [String (Device, "device")], [OString "label"; OString "uuid"];
     once_had_no_optargs = true;
     tests = [
       InitEmpty, Always, TestRun (
@@ -4003,7 +4003,7 @@ label and/or UUID of the new swap partition." };
 
   { defaults with
     name = "mknod"; added = (1, 0, 55);
-    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"], [];
+    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String (Pathname, "path")], [];
     optional = Some "mknod";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4038,7 +4038,7 @@ The mode actually set is affected by the umask." };
 
   { defaults with
     name = "mkfifo"; added = (1, 0, 55);
-    style = RErr, [Int "mode"; Pathname "path"], [];
+    style = RErr, [Int "mode"; String (Pathname, "path")], [];
     optional = Some "mknod";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4061,7 +4061,7 @@ The mode actually set is affected by the umask." };
 
   { defaults with
     name = "mknod_b"; added = (1, 0, 55);
-    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"], [];
+    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String (Pathname, "path")], [];
     optional = Some "mknod";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4084,7 +4084,7 @@ The mode actually set is affected by the umask." };
 
   { defaults with
     name = "mknod_c"; added = (1, 0, 55);
-    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"], [];
+    style = RErr, [Int "mode"; Int "devmajor"; Int "devminor"; String (Pathname, "path")], [];
     optional = Some "mknod";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4134,7 +4134,7 @@ This call returns the previous umask." };
 
   { defaults with
     name = "readdir"; added = (1, 0, 55);
-    style = RStructList ("entries", "dirent"), [Pathname "dir"], [];
+    style = RStructList ("entries", "dirent"), [String (Pathname, "dir")], [];
     protocol_limit_warning = true;
     shortdesc = "read directories entries";
     longdesc = "\
@@ -4194,7 +4194,7 @@ directory for human consumption, use C<guestfs_ll>." };
 
   { defaults with
     name = "getxattrs"; added = (1, 0, 59);
-    style = RStructList ("xattrs", "xattr"), [Pathname "path"], [];
+    style = RStructList ("xattrs", "xattr"), [String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "list extended attributes of a file or directory";
     longdesc = "\
@@ -4208,7 +4208,7 @@ See also: C<guestfs_lgetxattrs>, L<attr(5)>." };
 
   { defaults with
     name = "lgetxattrs"; added = (1, 0, 59);
-    style = RStructList ("xattrs", "xattr"), [Pathname "path"], [];
+    style = RStructList ("xattrs", "xattr"), [String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "list extended attributes of a file or directory";
     longdesc = "\
@@ -4218,9 +4218,9 @@ of the link itself." };
 
   { defaults with
     name = "setxattr"; added = (1, 0, 59);
-    style = RErr, [String "xattr";
-                   String "val"; Int "vallen"; (* will be BufferIn *)
-                   Pathname "path"], [];
+    style = RErr, [String (PlainString, "xattr");
+                   String (PlainString, "val"); Int "vallen"; (* will be BufferIn *)
+                   String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "set extended attribute of a file or directory";
     longdesc = "\
@@ -4232,9 +4232,9 @@ See also: C<guestfs_lsetxattr>, L<attr(5)>." };
 
   { defaults with
     name = "lsetxattr"; added = (1, 0, 59);
-    style = RErr, [String "xattr";
-                   String "val"; Int "vallen"; (* will be BufferIn *)
-                   Pathname "path"], [];
+    style = RErr, [String (PlainString, "xattr");
+                   String (PlainString, "val"); Int "vallen"; (* will be BufferIn *)
+                   String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "set extended attribute of a file or directory";
     longdesc = "\
@@ -4244,7 +4244,7 @@ of the link itself." };
 
   { defaults with
     name = "removexattr"; added = (1, 0, 59);
-    style = RErr, [String "xattr"; Pathname "path"], [];
+    style = RErr, [String (PlainString, "xattr"); String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "remove extended attribute of a file or directory";
     longdesc = "\
@@ -4255,7 +4255,7 @@ See also: C<guestfs_lremovexattr>, L<attr(5)>." };
 
   { defaults with
     name = "lremovexattr"; added = (1, 0, 59);
-    style = RErr, [String "xattr"; Pathname "path"], [];
+    style = RErr, [String (PlainString, "xattr"); String (Pathname, "path")], [];
     optional = Some "linuxxattrs";
     shortdesc = "remove extended attribute of a file or directory";
     longdesc = "\
@@ -4279,7 +4279,7 @@ device name to directory where the device is mounted." };
      * NEED_ROOT in the generated calling code in stubs.c, and
      * this function cannot use NEED_ROOT.
      *)
-    style = RErr, [String "exemptpath"], [];
+    style = RErr, [String (PlainString, "exemptpath")], [];
     shortdesc = "create a mountpoint";
     longdesc = "\
 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
@@ -4323,7 +4323,7 @@ is closed which can also trigger these issues." };
 
   { defaults with
     name = "rmmountpoint"; added = (1, 0, 62);
-    style = RErr, [String "exemptpath"], [];
+    style = RErr, [String (PlainString, "exemptpath")], [];
     shortdesc = "remove a mountpoint";
     longdesc = "\
 This calls removes a mountpoint that was previously created
@@ -4332,7 +4332,7 @@ for full details." };
 
   { defaults with
     name = "grep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [OBool "extended"; OBool "fixed"; OBool "insensitive"; OBool "compressed"];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [OBool "extended"; OBool "fixed"; OBool "insensitive"; OBool "compressed"];
     protocol_limit_warning = true; once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -4411,7 +4411,7 @@ compress- or gzip-compressed.
 
   { defaults with
     name = "realpath"; added = (1, 0, 66);
-    style = RString "rpath", [Pathname "path"], [];
+    style = RString "rpath", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["realpath"; "/../directory"]], "/directory"), []
@@ -4423,7 +4423,7 @@ returned path has no C<.>, C<..> or symbolic link path elements." };
 
   { defaults with
     name = "ln"; added = (1, 0, 66);
-    style = RErr, [String "target"; Pathname "linkname"], [];
+    style = RErr, [String (PlainString, "target"); String (Pathname, "linkname")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["mkdir"; "/ln"];
@@ -4437,7 +4437,7 @@ This command creates a hard link using the C<ln> command." };
 
   { defaults with
     name = "ln_f"; added = (1, 0, 66);
-    style = RErr, [String "target"; Pathname "linkname"], [];
+    style = RErr, [String (PlainString, "target"); String (Pathname, "linkname")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["mkdir"; "/ln_f"];
@@ -4453,7 +4453,7 @@ The I<-f> option removes the link (C<linkname>) if it exists already." };
 
   { defaults with
     name = "ln_s"; added = (1, 0, 66);
-    style = RErr, [String "target"; Pathname "linkname"], [];
+    style = RErr, [String (PlainString, "target"); String (Pathname, "linkname")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["mkdir"; "/ln_s"];
@@ -4468,7 +4468,7 @@ This command creates a symbolic link using the C<ln -s> command." };
 
   { defaults with
     name = "ln_sf"; added = (1, 0, 66);
-    style = RErr, [String "target"; Pathname "linkname"], [];
+    style = RErr, [String (PlainString, "target"); String (Pathname, "linkname")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["mkdir_p"; "/ln_sf/b"];
@@ -4483,14 +4483,14 @@ The I<-f> option removes the link (C<linkname>) if it exists already." };
 
   { defaults with
     name = "readlink"; added = (1, 0, 66);
-    style = RString "link", [Pathname "path"], [];
+    style = RString "link", [String (Pathname, "path")], [];
     shortdesc = "read the target of a symbolic link";
     longdesc = "\
 This command reads the target of a symbolic link." };
 
   { defaults with
     name = "swapon_device"; added = (1, 0, 66);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
       InitPartition, Always, TestRun (
         [["mkswap"; "/dev/sda1"; "NOARG"; "NOARG"];
@@ -4513,7 +4513,7 @@ attach a new host device to the guest and swap on that." };
 
   { defaults with
     name = "swapoff_device"; added = (1, 0, 66);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     shortdesc = "disable swap on device";
     longdesc = "\
 This command disables the libguestfs appliance swap
@@ -4522,7 +4522,7 @@ See C<guestfs_swapon_device>." };
 
   { defaults with
     name = "swapon_file"; added = (1, 0, 66);
-    style = RErr, [Pathname "file"], [];
+    style = RErr, [String (Pathname, "file")], [];
     tests = [
       InitScratchFS, Always, TestRun (
         [["fallocate"; "/swapon_file"; "8388608"];
@@ -4538,14 +4538,14 @@ See C<guestfs_swapon_device> for other notes." };
 
   { defaults with
     name = "swapoff_file"; added = (1, 0, 66);
-    style = RErr, [Pathname "file"], [];
+    style = RErr, [String (Pathname, "file")], [];
     shortdesc = "disable swap on file";
     longdesc = "\
 This command disables the libguestfs appliance swap on file." };
 
   { defaults with
     name = "swapon_label"; added = (1, 0, 66);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_disk"; "/dev/sda"; "mbr"];
@@ -4562,7 +4562,7 @@ See C<guestfs_swapon_device> for other notes." };
 
   { defaults with
     name = "swapoff_label"; added = (1, 0, 66);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     shortdesc = "disable swap on labeled swap partition";
     longdesc = "\
 This command disables the libguestfs appliance swap on
@@ -4570,7 +4570,7 @@ labeled swap partition." };
 
   { defaults with
     name = "swapon_uuid"; added = (1, 0, 66);
-    style = RErr, [String "uuid"], [];
+    style = RErr, [String (PlainString, "uuid")], [];
     optional = Some "linuxfsuuid";
     tests = [
         InitEmpty, Always, TestRun (
@@ -4585,7 +4585,7 @@ See C<guestfs_swapon_device> for other notes." };
 
   { defaults with
     name = "swapoff_uuid"; added = (1, 0, 66);
-    style = RErr, [String "uuid"], [];
+    style = RErr, [String (PlainString, "uuid")], [];
     optional = Some "linuxfsuuid";
     shortdesc = "disable swap on swap partition by UUID";
     longdesc = "\
@@ -4594,7 +4594,7 @@ with the given UUID." };
 
   { defaults with
     name = "mkswap_file"; added = (1, 0, 66);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestRun (
         [["fallocate"; "/mkswap_file"; "8388608"];
@@ -4654,7 +4654,7 @@ per libguestfs instance." };
 
   { defaults with
     name = "inotify_add_watch"; added = (1, 0, 66);
-    style = RInt64 "wd", [Pathname "path"; Int "mask"], [];
+    style = RInt64 "wd", [String (Pathname, "path"); Int "mask"], [];
     optional = Some "inotify";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4726,7 +4726,7 @@ away any pending events, and deallocates all resources." };
 
   { defaults with
     name = "modprobe"; added = (1, 0, 68);
-    style = RErr, [String "modulename"], [];
+    style = RErr, [String (PlainString, "modulename")], [];
     optional = Some "linuxmodules";
     tests = [
       InitNone, Always, TestRun [["modprobe"; "fat"]], []
@@ -4737,7 +4737,7 @@ This loads a kernel module in the appliance." };
 
   { defaults with
     name = "echo_daemon"; added = (1, 0, 69);
-    style = RString "output", [StringList "words"], [];
+    style = RString "output", [StringList (PlainString, "words")], [];
     tests = [
       InitNone, Always, TestResultString (
         [["echo_daemon"; "This is a test"]], "This is a test"), [];
@@ -4755,7 +4755,7 @@ See also C<guestfs_ping_daemon>." };
 
   { defaults with
     name = "find0"; added = (1, 0, 74);
-    style = RErr, [Pathname "directory"; FileOut "files"], [];
+    style = RErr, [String (Pathname, "directory"); String (FileOut, "files")], [];
     cancellable = true;
     test_excuse = "there is a regression test for this";
     shortdesc = "find all files and directories, returning NUL-separated list";
@@ -4786,7 +4786,7 @@ The result list is not sorted.
 
   { defaults with
     name = "case_sensitive_path"; added = (1, 0, 75);
-    style = RString "rpath", [Pathname "path"], [];
+    style = RString "rpath", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultString (
         [["case_sensitive_path"; "/DIRECTORY"]], "/directory"), [];
@@ -4870,7 +4870,7 @@ See also C<guestfs_realpath>." };
 
   { defaults with
     name = "vfs_type"; added = (1, 0, 75);
-    style = RString "fstype", [Mountable "mountable"], [];
+    style = RString "fstype", [String (Mountable, "mountable")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["vfs_type"; "/dev/sdb1"]], "ext2"), []
@@ -4887,7 +4887,7 @@ For example a string such as C<ext3> or C<ntfs>." };
 
   { defaults with
     name = "truncate"; added = (1, 0, 77);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["write"; "/truncate"; "some stuff so size is not zero"];
@@ -4901,7 +4901,7 @@ file must exist already." };
 
   { defaults with
     name = "truncate_size"; added = (1, 0, 77);
-    style = RErr, [Pathname "path"; Int64 "size"], [];
+    style = RErr, [String (Pathname, "path"); Int64 "size"], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["touch"; "/truncate_size"];
@@ -4921,7 +4921,7 @@ file of zeroes, use C<guestfs_fallocate64> instead." };
 
   { defaults with
     name = "utimens"; added = (1, 0, 77);
-    style = RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"], [];
+    style = RErr, [String (Pathname, "path"); Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"], [];
     (* Test directories, named pipes etc (RHBZ#761451, RHBZ#761460) *)
     tests = [
       InitScratchFS, Always, TestResult (
@@ -4970,7 +4970,7 @@ C<*secs> field is ignored in this case)." };
 
   { defaults with
     name = "mkdir_mode"; added = (1, 0, 77);
-    style = RErr, [Pathname "path"; Int "mode"], [];
+    style = RErr, [String (Pathname, "path"); Int "mode"], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["mkdir_mode"; "/mkdir_mode"; "0o111"];
@@ -4990,7 +4990,7 @@ See also C<guestfs_mkdir>, C<guestfs_umask>" };
 
   { defaults with
     name = "lchown"; added = (1, 0, 77);
-    style = RErr, [Int "owner"; Int "group"; Pathname "path"], [];
+    style = RErr, [Int "owner"; Int "group"; String (Pathname, "path")], [];
     shortdesc = "change file owner and group";
     longdesc = "\
 Change the file owner to C<owner> and group to C<group>.
@@ -5003,7 +5003,7 @@ yourself (Augeas support makes this relatively easy)." };
 
   { defaults with
     name = "internal_lxattrlist"; added = (1, 19, 32);
-    style = RStructList ("xattrs", "xattr"), [Pathname "path"; FilenameList "names"], [];
+    style = RStructList ("xattrs", "xattr"), [String (Pathname, "path"); StringList (Filename, "names")], [];
     visibility = VInternal;
     optional = Some "linuxxattrs";
     shortdesc = "lgetxattr on multiple files";
@@ -5032,7 +5032,7 @@ into smaller groups of names." };
 
   { defaults with
     name = "internal_readlinklist"; added = (1, 19, 32);
-    style = RStringList "links", [Pathname "path"; FilenameList "names"], [];
+    style = RStringList "links", [String (Pathname, "path"); StringList (Filename, "names")], [];
     visibility = VInternal;
     shortdesc = "readlink on multiple files";
     longdesc = "\
@@ -5060,7 +5060,7 @@ into smaller groups of names." };
 
   { defaults with
     name = "pread"; added = (1, 0, 77);
-    style = RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"], [];
+    style = RBufferOut "content", [String (Pathname, "path"); Int "count"; Int64 "offset"], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -5082,7 +5082,7 @@ See also C<guestfs_pwrite>, C<guestfs_pread_device>." };
 
   { defaults with
     name = "part_init"; added = (1, 0, 78);
-    style = RErr, [Device "device"; String "parttype"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "parttype")], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_init"; "/dev/sda"; "gpt"]]), []
@@ -5164,7 +5164,7 @@ Sun disk labels.
 
   { defaults with
     name = "part_add"; added = (1, 0, 78);
-    style = RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "prlogex"); Int64 "startsect"; Int64 "endsect"], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_init"; "/dev/sda"; "mbr"];
@@ -5199,7 +5199,7 @@ Use C<guestfs_part_disk> to do that." };
 
   { defaults with
     name = "part_disk"; added = (1, 0, 78);
-    style = RErr, [Device "device"; String "parttype"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "parttype")], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_disk"; "/dev/sda"; "mbr"]]), [];
@@ -5217,7 +5217,7 @@ but other possible values are described in C<guestfs_part_init>." };
 
   { defaults with
     name = "part_set_bootable"; added = (1, 0, 78);
-    style = RErr, [Device "device"; Int "partnum"; Bool "bootable"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"; Bool "bootable"], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_disk"; "/dev/sda"; "mbr"];
@@ -5234,7 +5234,7 @@ no means universally recognized." };
 
   { defaults with
     name = "part_set_name"; added = (1, 0, 78);
-    style = RErr, [Device "device"; Int "partnum"; String "name"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"; String (PlainString, "name")], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_disk"; "/dev/sda"; "gpt"];
@@ -5250,7 +5250,7 @@ table.  This works on C<gpt> but not on C<mbr> partitions." };
 
   { defaults with
     name = "part_list"; added = (1, 0, 78);
-    style = RStructList ("partitions", "partition"), [Device "device"], [];
+    style = RStructList ("partitions", "partition"), [String (Device, "device")], [];
     tests = [] (* XXX Add a regression test for this. *);
     shortdesc = "list partitions on a device";
     longdesc = "\
@@ -5282,7 +5282,7 @@ Size of the partition in bytes.
 
   { defaults with
     name = "part_get_parttype"; added = (1, 0, 78);
-    style = RString "parttype", [Device "device"], [];
+    style = RString "parttype", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResultString (
         [["part_disk"; "/dev/sda"; "gpt"];
@@ -5300,7 +5300,7 @@ for a full list." };
 
   { defaults with
     name = "fill"; added = (1, 0, 79);
-    style = RErr, [Int "c"; Int "len"; Pathname "path"], [];
+    style = RErr, [Int "c"; Int "len"; String (Pathname, "path")], [];
     progress = true;
     tests = [
       InitScratchFS, Always, TestResult (
@@ -5321,7 +5321,7 @@ use C<guestfs_fill_pattern>." };
 
   { defaults with
     name = "filesize"; added = (1, 0, 82);
-    style = RInt64 "size", [Pathname "file"], [];
+    style = RInt64 "size", [String (Pathname, "file")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["write"; "/filesize"; "hello, world"];
@@ -5337,7 +5337,7 @@ To get the size of block devices, use C<guestfs_blockdev_getsize64>." };
 
   { defaults with
     name = "lvrename"; added = (1, 0, 83);
-    style = RErr, [String "logvol"; String "newlogvol"], [];
+    style = RErr, [String (PlainString, "logvol"); String (PlainString, "newlogvol")], [];
     tests = [
       InitBasicFSonLVM, Always, TestResult (
         [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
@@ -5350,7 +5350,7 @@ Rename a logical volume C<logvol> with the new name C<newlogvol>." };
 
   { defaults with
     name = "vgrename"; added = (1, 0, 83);
-    style = RErr, [String "volgroup"; String "newvolgroup"], [];
+    style = RErr, [String (PlainString, "volgroup"); String (PlainString, "newvolgroup")], [];
     tests = [
       InitBasicFSonLVM, Always, TestResult (
         [["umount"; "/"; "false"; "false"];
@@ -5367,7 +5367,7 @@ Rename a volume group C<volgroup> with the new name C<newvolgroup>." };
 
   { defaults with
     name = "initrd_cat"; added = (1, 0, 84);
-    style = RBufferOut "content", [Pathname "initrdpath"; String "filename"], [];
+    style = RBufferOut "content", [String (Pathname, "initrdpath"); String (PlainString, "filename")], [];
     protocol_limit_warning = true;
     tests = [
       InitISOFS, Always, TestResult (
@@ -5390,28 +5390,28 @@ See also C<guestfs_initrd_list>." };
 
   { defaults with
     name = "pvuuid"; added = (1, 0, 87);
-    style = RString "uuid", [Device "device"], [];
+    style = RString "uuid", [String (Device, "device")], [];
     shortdesc = "get the UUID of a physical volume";
     longdesc = "\
 This command returns the UUID of the LVM PV C<device>." };
 
   { defaults with
     name = "vguuid"; added = (1, 0, 87);
-    style = RString "uuid", [String "vgname"], [];
+    style = RString "uuid", [String (PlainString, "vgname")], [];
     shortdesc = "get the UUID of a volume group";
     longdesc = "\
 This command returns the UUID of the LVM VG named C<vgname>." };
 
   { defaults with
     name = "lvuuid"; added = (1, 0, 87);
-    style = RString "uuid", [Device "device"], [];
+    style = RString "uuid", [String (Device, "device")], [];
     shortdesc = "get the UUID of a logical volume";
     longdesc = "\
 This command returns the UUID of the LVM LV C<device>." };
 
   { defaults with
     name = "vgpvuuids"; added = (1, 0, 87);
-    style = RStringList "uuids", [String "vgname"], [];
+    style = RStringList "uuids", [String (PlainString, "vgname")], [];
     shortdesc = "get the PV UUIDs containing the volume group";
     longdesc = "\
 Given a VG called C<vgname>, this returns the UUIDs of all
@@ -5424,7 +5424,7 @@ See also C<guestfs_vglvuuids>." };
 
   { defaults with
     name = "vglvuuids"; added = (1, 0, 87);
-    style = RStringList "uuids", [String "vgname"], [];
+    style = RStringList "uuids", [String (PlainString, "vgname")], [];
     shortdesc = "get the LV UUIDs of all LVs in the volume group";
     longdesc = "\
 Given a VG called C<vgname>, this returns the UUIDs of all
@@ -5437,7 +5437,7 @@ See also C<guestfs_vgpvuuids>." };
 
   { defaults with
     name = "zero_device"; added = (1, 3, 1);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     progress = true;
     tests = [
       InitBasicFSonLVM, Always, TestRun (
@@ -5467,7 +5467,7 @@ physical volumes, volume groups and logical volumes." };
 
   { defaults with
     name = "part_del"; added = (1, 3, 2);
-    style = RErr, [Device "device"; Int "partnum"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["part_init"; "/dev/sda"; "mbr"];
@@ -5484,7 +5484,7 @@ it contains." };
 
   { defaults with
     name = "part_get_bootable"; added = (1, 3, 2);
-    style = RBool "bootable", [Device "device"; Int "partnum"], [];
+    style = RBool "bootable", [String (Device, "device"); Int "partnum"], [];
     tests = [
       InitEmpty, Always, TestResultTrue (
         [["part_init"; "/dev/sda"; "mbr"];
@@ -5501,7 +5501,7 @@ See also C<guestfs_part_set_bootable>." };
 
   { defaults with
     name = "part_get_mbr_id"; added = (1, 3, 2);
-    style = RInt "idbyte", [Device "device"; Int "partnum"], [];
+    style = RInt "idbyte", [String (Device, "device"); Int "partnum"], [];
     fish_output = Some FishOutputHexadecimal;
     tests = [
       InitEmpty, Always, TestResult (
@@ -5521,7 +5521,7 @@ types (see C<guestfs_part_get_parttype>)." };
 
   { defaults with
     name = "part_set_mbr_id"; added = (1, 3, 2);
-    style = RErr, [Device "device"; Int "partnum"; Int "idbyte"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"; Int "idbyte"], [];
     shortdesc = "set the MBR type byte (ID byte) of a partition";
     longdesc = "\
 Sets the MBR type byte (also known as the ID byte) of
@@ -5536,7 +5536,7 @@ types (see C<guestfs_part_get_parttype>)." };
 
   { defaults with
     name = "checksum_device"; added = (1, 3, 2);
-    style = RString "checksum", [String "csumtype"; Device "device"], [];
+    style = RString "checksum", [String (PlainString, "csumtype"); String (Device, "device")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["checksum_device"; "md5"; "/dev/sdd"]],
@@ -5550,7 +5550,7 @@ checksums supported see the C<guestfs_checksum> command." };
 
   { defaults with
     name = "lvresize_free"; added = (1, 3, 3);
-    style = RErr, [Device "lv"; Int "percent"], [];
+    style = RErr, [String (Device, "lv"); Int "percent"], [];
     optional = Some "lvm2";
     tests = [
       InitNone, Always, TestRun (
@@ -5583,7 +5583,7 @@ unless it has been set by calling C<guestfs_umask>." };
 
   { defaults with
     name = "base64_in"; added = (1, 3, 5);
-    style = RErr, [FileIn "base64file"; Pathname "filename"], [];
+    style = RErr, [String (FileIn, "base64file"); String (Pathname, "filename")], [];
     cancellable = true;
     tests = [
       InitScratchFS, Always, TestResultString (
@@ -5597,7 +5597,7 @@ to F<filename>." };
 
   { defaults with
     name = "base64_out"; added = (1, 3, 5);
-    style = RErr, [Pathname "filename"; FileOut "base64file"], [];
+    style = RErr, [String (Pathname, "filename"); String (FileOut, "base64file")], [];
     cancellable = true;
     shortdesc = "download file and encode as base64";
     longdesc = "\
@@ -5606,7 +5606,7 @@ it out to local file C<base64file> encoded as base64." };
 
   { defaults with
     name = "checksums_out"; added = (1, 3, 7);
-    style = RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"], [];
+    style = RErr, [String (PlainString, "csumtype"); String (Pathname, "directory"); String (FileOut, "sumsfile")], [];
     cancellable = true;
     shortdesc = "compute MD5, SHAx or CRC checksum of files in a directory";
     longdesc = "\
@@ -5624,7 +5624,7 @@ coreutils info file." };
 
   { defaults with
     name = "fill_pattern"; added = (1, 3, 12);
-    style = RErr, [String "pattern"; Int "len"; Pathname "path"], [];
+    style = RErr, [String (PlainString, "pattern"); Int "len"; String (Pathname, "path")], [];
     progress = true;
     tests = [
       InitScratchFS, Always, TestResult (
@@ -5641,7 +5641,7 @@ to ensure the length of the file is exactly C<len> bytes." };
 
   { defaults with
     name = "internal_write"; added = (1, 19, 32);
-    style = RErr, [Pathname "path"; BufferIn "content"], [];
+    style = RErr, [String (Pathname, "path"); BufferIn "content"], [];
     visibility = VInternal;
     protocol_limit_warning = true;
     tests = [
@@ -5673,7 +5673,7 @@ See also C<guestfs_write_append>." };
 
   { defaults with
     name = "pwrite"; added = (1, 3, 14);
-    style = RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"], [];
+    style = RInt "nbytes", [String (Pathname, "path"); BufferIn "content"; Int64 "offset"], [];
     protocol_limit_warning = true;
     tests = [
       InitScratchFS, Always, TestResultString (
@@ -5704,7 +5704,7 @@ See also C<guestfs_pread>, C<guestfs_pwrite_device>." };
 
   { defaults with
     name = "resize2fs_size"; added = (1, 3, 14);
-    style = RErr, [Device "device"; Int64 "size"], [];
+    style = RErr, [String (Device, "device"); Int64 "size"], [];
     shortdesc = "resize an ext2, ext3 or ext4 filesystem (with size)";
     longdesc = "\
 This command is the same as C<guestfs_resize2fs> except that it
@@ -5714,7 +5714,7 @@ See also L<guestfs(3)/RESIZE2FS ERRORS>." };
 
   { defaults with
     name = "pvresize_size"; added = (1, 3, 14);
-    style = RErr, [Device "device"; Int64 "size"], [];
+    style = RErr, [String (Device, "device"); Int64 "size"], [];
     optional = Some "lvm2";
     shortdesc = "resize an LVM physical volume (with size)";
     longdesc = "\
@@ -5740,7 +5740,7 @@ and L<guestfs(3)/AVAILABILITY>." };
 
   { defaults with
     name = "fallocate64"; added = (1, 3, 17);
-    style = RErr, [Pathname "path"; Int64 "len"], [];
+    style = RErr, [String (Pathname, "path"); Int64 "len"], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["fallocate64"; "/fallocate64"; "1000000"];
@@ -5766,7 +5766,7 @@ a file in the host and attach it as a device." };
 
   { defaults with
     name = "vfs_label"; added = (1, 3, 18);
-    style = RString "label", [Mountable "mountable"], [];
+    style = RString "label", [String (Mountable, "mountable")], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["set_label"; "/dev/sda1"; "LTEST"];
@@ -5791,7 +5791,7 @@ To find a filesystem from the label, use C<guestfs_findfs_label>." };
 
   { defaults with
     name = "vfs_uuid"; added = (1, 3, 18);
-    style = RString "uuid", [Mountable "mountable"], [];
+    style = RString "uuid", [String (Mountable, "mountable")], [];
     fish_alias = ["get-uuid"];
     tests = [
         InitBasicFS, Always, TestResultString (
@@ -5808,7 +5808,7 @@ To find a filesystem from the UUID, use C<guestfs_findfs_uuid>." };
 
   { defaults with
     name = "lvm_set_filter"; added = (1, 5, 1);
-    style = RErr, [DeviceList "devices"], [];
+    style = RErr, [StringList (Device, "devices")], [];
     optional = Some "lvm2";
     test_excuse = "cannot be tested with the current framework because the VG is being used by the mounted filesystem, so the 'vgchange -an' command we do first will fail";
     shortdesc = "set LVM device filter";
@@ -5850,7 +5850,7 @@ group scan." };
 
   { defaults with
     name = "luks_open"; added = (1, 5, 1);
-    style = RErr, [Device "device"; Key "key"; String "mapname"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); String (PlainString, "mapname")], [];
     optional = Some "luks";
     shortdesc = "open a LUKS-encrypted block device";
     longdesc = "\
@@ -5875,7 +5875,7 @@ devices." };
 
   { defaults with
     name = "luks_open_ro"; added = (1, 5, 1);
-    style = RErr, [Device "device"; Key "key"; String "mapname"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); String (PlainString, "mapname")], [];
     optional = Some "luks";
     shortdesc = "open a LUKS-encrypted block device read-only";
     longdesc = "\
@@ -5884,7 +5884,7 @@ mapping is created." };
 
   { defaults with
     name = "luks_close"; added = (1, 5, 1);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "luks";
     shortdesc = "close a LUKS device";
     longdesc = "\
@@ -5896,7 +5896,7 @@ of the underlying block device." };
 
   { defaults with
     name = "luks_format"; added = (1, 5, 2);
-    style = RErr, [Device "device"; Key "key"; Int "keyslot"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"], [];
     optional = Some "luks";
     shortdesc = "format a block device as a LUKS encrypted device";
     longdesc = "\
@@ -5907,7 +5907,7 @@ supports 8 key slots, numbered 0-7)." };
 
   { defaults with
     name = "luks_format_cipher"; added = (1, 5, 2);
-    style = RErr, [Device "device"; Key "key"; Int "keyslot"; String "cipher"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"; String (PlainString, "cipher")], [];
     optional = Some "luks";
     shortdesc = "format a block device as a LUKS encrypted device";
     longdesc = "\
@@ -5916,7 +5916,7 @@ it also allows you to set the C<cipher> used." };
 
   { defaults with
     name = "luks_add_key"; added = (1, 5, 2);
-    style = RErr, [Device "device"; Key "key"; Key "newkey"; Int "keyslot"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); String (Key, "newkey"); Int "keyslot"], [];
     optional = Some "luks";
     shortdesc = "add a key on a LUKS encrypted device";
     longdesc = "\
@@ -5931,7 +5931,7 @@ first to remove that key." };
 
   { defaults with
     name = "luks_kill_slot"; added = (1, 5, 2);
-    style = RErr, [Device "device"; Key "key"; Int "keyslot"], [];
+    style = RErr, [String (Device, "device"); String (Key, "key"); Int "keyslot"], [];
     optional = Some "luks";
     shortdesc = "remove a key from a LUKS encrypted device";
     longdesc = "\
@@ -5941,7 +5941,7 @@ I<other> keys." };
 
   { defaults with
     name = "is_lv"; added = (1, 5, 3);
-    style = RBool "lvflag", [Mountable "mountable"], [];
+    style = RBool "lvflag", [String (Mountable, "mountable")], [];
     tests = [
       InitBasicFSonLVM, Always, TestResultTrue (
         [["is_lv"; "/dev/VG/LV"]]), [];
@@ -5955,7 +5955,7 @@ returns true iff this is the case." };
 
   { defaults with
     name = "findfs_uuid"; added = (1, 5, 3);
-    style = RString "device", [String "uuid"], [];
+    style = RString "device", [String (PlainString, "uuid")], [];
     shortdesc = "find a filesystem by UUID";
     longdesc = "\
 This command searches the filesystems and returns the one
@@ -5966,7 +5966,7 @@ To find the UUID of a filesystem, use C<guestfs_vfs_uuid>." };
 
   { defaults with
     name = "findfs_label"; added = (1, 5, 3);
-    style = RString "device", [String "label"], [];
+    style = RString "device", [String (PlainString, "label")], [];
     shortdesc = "find a filesystem by label";
     longdesc = "\
 This command searches the filesystems and returns the one
@@ -5977,7 +5977,7 @@ To find the label of a filesystem, use C<guestfs_vfs_label>." };
 
   { defaults with
     name = "is_chardev"; added = (1, 5, 10);
-    style = RBool "flag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "flag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
@@ -5999,7 +5999,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_blockdev"; added = (1, 5, 10);
-    style = RBool "flag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "flag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
@@ -6025,7 +6025,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_fifo"; added = (1, 5, 10);
-    style = RBool "flag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "flag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     tests = [
       InitISOFS, Always, TestResultFalse (
@@ -6047,7 +6047,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_symlink"; added = (1, 5, 10);
-    style = RBool "flag", [Pathname "path"], [];
+    style = RBool "flag", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultFalse (
         [["is_symlink"; "/directory"]]), [];
@@ -6063,7 +6063,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "is_socket"; added = (1, 5, 10);
-    style = RBool "flag", [Pathname "path"], [OBool "followsymlinks"];
+    style = RBool "flag", [String (Pathname, "path")], [OBool "followsymlinks"];
     once_had_no_optargs = true;
     (* XXX Need a positive test for sockets. *)
     tests = [
@@ -6083,7 +6083,7 @@ See also C<guestfs_stat>." };
 
   { defaults with
     name = "part_to_dev"; added = (1, 5, 15);
-    style = RString "device", [Device "partition"], [];
+    style = RString "device", [String (Device, "partition")], [];
     tests = [
       InitPartition, Always, TestResultDevice (
         [["part_to_dev"; "/dev/sda1"]], "/dev/sda"), [];
@@ -6103,7 +6103,7 @@ See also C<guestfs_part_to_partnum>, C<guestfs_device_index>." };
 
   { defaults with
     name = "upload_offset"; added = (1, 5, 17);
-    style = RErr, [FileIn "filename"; Dev_or_Path "remotefilename"; Int64 "offset"], [];
+    style = RErr, [String (FileIn, "filename"); String (Dev_or_Path, "remotefilename"); Int64 "offset"], [];
     progress = true; cancellable = true;
     tests =
       (let md5 = Digest.to_hex (Digest.file "COPYING.LIB") in [
@@ -6132,7 +6132,7 @@ See also C<guestfs_upload>, C<guestfs_pwrite>." };
 
   { defaults with
     name = "download_offset"; added = (1, 5, 17);
-    style = RErr, [Dev_or_Path "remotefilename"; FileOut "filename"; Int64 "offset"; Int64 "size"], [];
+    style = RErr, [String (Dev_or_Path, "remotefilename"); String (FileOut, "filename"); Int64 "offset"; Int64 "size"], [];
     progress = true; cancellable = true;
     tests =
       (let md5 = Digest.to_hex (Digest.file "COPYING.LIB") in
@@ -6164,7 +6164,7 @@ See also C<guestfs_download>, C<guestfs_pread>." };
 
   { defaults with
     name = "pwrite_device"; added = (1, 5, 20);
-    style = RInt "nbytes", [Device "device"; BufferIn "content"; Int64 "offset"], [];
+    style = RInt "nbytes", [String (Device, "device"); BufferIn "content"; Int64 "offset"], [];
     protocol_limit_warning = true;
     tests = [
       InitPartition, Always, TestResult (
@@ -6187,7 +6187,7 @@ See also C<guestfs_pwrite>." };
 
   { defaults with
     name = "pread_device"; added = (1, 5, 21);
-    style = RBufferOut "content", [Device "device"; Int "count"; Int64 "offset"], [];
+    style = RBufferOut "content", [String (Device, "device"); Int "count"; Int64 "offset"], [];
     protocol_limit_warning = true;
     tests = [
       InitEmpty, Always, TestResult (
@@ -6206,7 +6206,7 @@ See also C<guestfs_pread>." };
 
   { defaults with
     name = "lvm_canonical_lv_name"; added = (1, 5, 24);
-    style = RString "lv", [Device "lvname"], [];
+    style = RString "lv", [String (Device, "lvname")], [];
     tests = [
       InitBasicFSonLVM, IfAvailable "lvm2", TestResultString (
         [["lvm_canonical_lv_name"; "/dev/mapper/VG-LV"]], "/dev/VG/LV"), [];
@@ -6226,7 +6226,7 @@ See also C<guestfs_is_lv>, C<guestfs_canonical_device_name>." };
 
   { defaults with
     name = "mkfs"; added = (0, 0, 8);
-    style = RErr, [String "fstype"; Device "device"], [OInt "blocksize"; OString "features"; OInt "inode"; OInt "sectorsize"; OString "label"];
+    style = RErr, [String (PlainString, "fstype"); String (Device, "device")], [OInt "blocksize"; OString "features"; OInt "inode"; OInt "sectorsize"; OString "label"];
     once_had_no_optargs = true;
     tests = [
       InitEmpty, Always, TestResultString (
@@ -6281,7 +6281,7 @@ which sets sector size for ufs filesystem.
 
   { defaults with
     name = "getxattr"; added = (1, 7, 24);
-    style = RBufferOut "xattr", [Pathname "path"; String "name"], [];
+    style = RBufferOut "xattr", [String (Pathname, "path"); String (PlainString, "name")], [];
     optional = Some "linuxxattrs";
     shortdesc = "get a single extended attribute";
     longdesc = "\
@@ -6303,7 +6303,7 @@ See also: C<guestfs_getxattrs>, C<guestfs_lgetxattr>, L<attr(5)>." };
 
   { defaults with
     name = "lgetxattr"; added = (1, 7, 24);
-    style = RBufferOut "xattr", [Pathname "path"; String "name"], [];
+    style = RBufferOut "xattr", [String (Pathname, "path"); String (PlainString, "name")], [];
     optional = Some "linuxxattrs";
     shortdesc = "get a single extended attribute";
     longdesc = "\
@@ -6325,7 +6325,7 @@ See also: C<guestfs_lgetxattrs>, C<guestfs_getxattr>, L<attr(5)>." };
 
   { defaults with
     name = "resize2fs_M"; added = (1, 9, 4);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     shortdesc = "resize an ext2, ext3 or ext4 filesystem to the minimum size";
     longdesc = "\
 This command is the same as C<guestfs_resize2fs>, but the filesystem
@@ -6353,7 +6353,7 @@ handle is closed." };
 
   { defaults with
     name = "is_zero"; added = (1, 11, 8);
-    style = RBool "zeroflag", [Pathname "path"], [];
+    style = RBool "zeroflag", [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResultTrue (
         [["is_zero"; "/100kallzeroes"]]), [];
@@ -6367,7 +6367,7 @@ it contains all zero bytes." };
 
   { defaults with
     name = "is_zero_device"; added = (1, 11, 8);
-    style = RBool "zeroflag", [Device "device"], [];
+    style = RBool "zeroflag", [String (Device, "device")], [];
     tests = [
       InitBasicFS, Always, TestResultTrue (
         [["umount"; "/dev/sda1"; "false"; "false"];
@@ -6392,7 +6392,7 @@ mount tags is returned." };
 
   { defaults with
     name = "mount_9p"; added = (1, 11, 12);
-    style = RErr, [String "mounttag"; String "mountpoint"], [OString "options"];
+    style = RErr, [String (PlainString, "mounttag"); String (PlainString, "mountpoint")], [OString "options"];
     camel_name = "Mount9P";
     shortdesc = "mount 9p filesystem";
     longdesc = "\
@@ -6419,7 +6419,7 @@ volumes." };
 
   { defaults with
     name = "ntfsresize"; added = (1, 3, 2);
-    style = RErr, [Device "device"], [OInt64 "size"; OBool "force"];
+    style = RErr, [String (Device, "device")], [OInt64 "size"; OBool "force"];
     once_had_no_optargs = true;
     optional = Some "ntfsprogs"; camel_name = "NTFSResizeOpts";
     shortdesc = "resize an NTFS filesystem";
@@ -6454,7 +6454,7 @@ See also L<ntfsresize(8)>." };
 
   { defaults with
     name = "btrfs_filesystem_resize"; added = (1, 11, 17);
-    style = RErr, [Pathname "mountpoint"], [OInt64 "size"];
+    style = RErr, [String (Pathname, "mountpoint")], [OInt64 "size"];
     optional = Some "btrfs"; camel_name = "BTRFSFilesystemResize";
     shortdesc = "resize a btrfs filesystem";
     longdesc = "\
@@ -6479,7 +6479,7 @@ See also L<btrfs(8)>." };
 
   { defaults with
     name = "internal_write_append"; added = (1, 19, 32);
-    style = RErr, [Pathname "path"; BufferIn "content"], [];
+    style = RErr, [String (Pathname, "path"); BufferIn "content"], [];
     visibility = VInternal;
     protocol_limit_warning = true;
     tests = [
@@ -6499,7 +6499,7 @@ See also C<guestfs_write>." };
 
   { defaults with
     name = "compress_out"; added = (1, 13, 15);
-    style = RErr, [String "ctype"; Pathname "file"; FileOut "zfile"], [OInt "level"];
+    style = RErr, [String (PlainString, "ctype"); String (Pathname, "file"); String (FileOut, "zfile")], [OInt "level"];
     cancellable = true;
     shortdesc = "output compressed file";
     longdesc = "\
@@ -6518,7 +6518,7 @@ program being used." };
 
   { defaults with
     name = "compress_device_out"; added = (1, 13, 15);
-    style = RErr, [String "ctype"; Device "device"; FileOut "zdevice"], [OInt "level"];
+    style = RErr, [String (PlainString, "ctype"); String (Device, "device"); String (FileOut, "zdevice")], [OInt "level"];
     cancellable = true;
     shortdesc = "output compressed device";
     longdesc = "\
@@ -6530,7 +6530,7 @@ as in C<guestfs_compress_out>." };
 
   { defaults with
     name = "part_to_partnum"; added = (1, 13, 25);
-    style = RInt "partnum", [Device "partition"], [];
+    style = RInt "partnum", [String (Device, "partition")], [];
     tests = [
       InitPartition, Always, TestResult (
         [["part_to_partnum"; "/dev/sda1"]], "ret == 1"), [];
@@ -6549,7 +6549,7 @@ See also C<guestfs_part_to_dev>." };
 
   { defaults with
     name = "copy_device_to_device"; added = (1, 13, 25);
-    style = RErr, [Device "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
+    style = RErr, [String (Device, "src"); String (Device, "dest")], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
     progress = true;
     shortdesc = "copy from source device to destination device";
     longdesc = "\
@@ -6585,7 +6585,7 @@ in incorrect copying." };
 
   { defaults with
     name = "copy_device_to_file"; added = (1, 13, 25);
-    style = RErr, [Device "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
+    style = RErr, [String (Device, "src"); String (Pathname, "dest")], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
     progress = true;
     shortdesc = "copy from source device to destination file";
     longdesc = "\
@@ -6594,7 +6594,7 @@ of this call." };
 
   { defaults with
     name = "copy_file_to_device"; added = (1, 13, 25);
-    style = RErr, [Pathname "src"; Device "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
+    style = RErr, [String (Pathname, "src"); String (Device, "dest")], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
     progress = true;
     shortdesc = "copy from source file to destination device";
     longdesc = "\
@@ -6603,7 +6603,7 @@ of this call." };
 
   { defaults with
     name = "copy_file_to_file"; added = (1, 13, 25);
-    style = RErr, [Pathname "src"; Pathname "dest"], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [OInt64 "srcoffset"; OInt64 "destoffset"; OInt64 "size"; OBool "sparse"; OBool "append"];
     progress = true;
     tests = [
       InitScratchFS, Always, TestResult (
@@ -6641,7 +6641,7 @@ moving functions." };
 
   { defaults with
     name = "tune2fs"; added = (1, 15, 4);
-    style = RErr, [Device "device"], [OBool "force"; OInt "maxmountcount"; OInt "mountcount"; OString "errorbehavior"; OInt64 "group"; OInt "intervalbetweenchecks"; OInt "reservedblockspercentage"; OString "lastmounteddirectory"; OInt64 "reservedblockscount"; OInt64 "user"];
+    style = RErr, [String (Device, "device")], [OBool "force"; OInt "maxmountcount"; OInt "mountcount"; OString "errorbehavior"; OInt64 "group"; OInt "intervalbetweenchecks"; OInt "reservedblockspercentage"; OString "lastmounteddirectory"; OInt64 "reservedblockscount"; OInt64 "user"];
     camel_name = "Tune2FS";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -6742,7 +6742,7 @@ works, see the L<tune2fs(8)> man page." };
 
   { defaults with
     name = "md_create"; added = (1, 15, 6);
-    style = RErr, [String "name"; DeviceList "devices"], [OInt64 "missingbitmap"; OInt "nrdevices"; OInt "spare"; OInt64 "chunk"; OString "level"];
+    style = RErr, [String (PlainString, "name"); StringList (Device, "devices")], [OInt64 "missingbitmap"; OInt "nrdevices"; OInt "spare"; OInt64 "chunk"; OString "level"];
     optional = Some "mdadm"; camel_name = "MDCreate";
     shortdesc = "create a Linux md (RAID) device";
     longdesc = "\
@@ -6809,7 +6809,7 @@ List all Linux md devices." };
 
   { defaults with
     name = "md_detail"; added = (1, 15, 6);
-    style = RHashtable "info", [Device "md"], [];
+    style = RHashtable "info", [String (Device, "md")], [];
     optional = Some "mdadm";
     shortdesc = "obtain metadata for an MD device";
     longdesc = "\
@@ -6843,7 +6843,7 @@ The name of the MD device.
 
   { defaults with
     name = "md_stop"; added = (1, 15, 6);
-    style = RErr, [Device "md"], [];
+    style = RErr, [String (Device, "md")], [];
     optional = Some "mdadm";
     shortdesc = "stop a Linux md (RAID) device";
     longdesc = "\
@@ -6852,7 +6852,7 @@ device is stopped, but it is not destroyed or zeroed." };
 
   { defaults with
     name = "blkid"; added = (1, 15, 9);
-    style = RHashtable "info", [Device "device"], [];
+    style = RHashtable "info", [String (Device, "device")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["blkid"; "/dev/sdb1"]],
@@ -6894,7 +6894,7 @@ The usage of this device, for example C<filesystem> or C<raid>.
 
   { defaults with
     name = "e2fsck"; added = (1, 15, 17);
-    style = RErr, [Device "device"], [OBool "correct"; OBool "forceall"];
+    style = RErr, [String (Device, "device")], [OBool "correct"; OBool "forceall"];
     shortdesc = "check an ext2/ext3 filesystem";
     longdesc = "\
 This runs the ext2/ext3 filesystem checker on C<device>.
@@ -6921,7 +6921,7 @@ This option may not be specified at the same time as the C<correct> option.
 
   { defaults with
     name = "wipefs"; added = (1, 17, 6);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "wipefs";
     tests = [
       InitBasicFSonLVM, Always, TestRun (
@@ -6941,7 +6941,7 @@ device." };
 
   { defaults with
     name = "ntfsfix"; added = (1, 17, 9);
-    style = RErr, [Device "device"], [OBool "clearbadsectors"];
+    style = RErr, [String (Device, "device")], [OBool "clearbadsectors"];
     optional = Some "ntfs3g";
     tests = [
       InitPartition, Always, TestRun (
@@ -6962,7 +6962,7 @@ This is useful after cloning a disk with bad sectors to a new disk." };
 
   { defaults with
     name = "ntfsclone_out"; added = (1, 17, 9);
-    style = RErr, [Device "device"; FileOut "backupfile"], [OBool "metadataonly"; OBool "rescue"; OBool "ignorefscheck"; OBool "preservetimestamps"; OBool "force"];
+    style = RErr, [String (Device, "device"); String (FileOut, "backupfile")], [OBool "metadataonly"; OBool "rescue"; OBool "ignorefscheck"; OBool "preservetimestamps"; OBool "force"];
     optional = Some "ntfs3g"; cancellable = true;
     test_excuse = "tested in tests/ntfsclone";
     shortdesc = "save NTFS to backup file";
@@ -6984,7 +6984,7 @@ libguestfs device." };
 
   { defaults with
     name = "ntfsclone_in"; added = (1, 17, 9);
-    style = RErr, [FileIn "backupfile"; Device "device"], [];
+    style = RErr, [String (FileIn, "backupfile"); String (Device, "device")], [];
     optional = Some "ntfs3g"; cancellable = true;
     test_excuse = "tested in tests/ntfsclone";
     shortdesc = "restore NTFS from backup file";
@@ -6995,7 +6995,7 @@ any existing contents of this device." };
 
   { defaults with
     name = "set_label"; added = (1, 17, 9);
-    style = RErr, [Mountable "mountable"; String "label"], [];
+    style = RErr, [String (Mountable, "mountable"); String (PlainString, "label")], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["set_label"; "/dev/sda1"; "testlabel"];
@@ -7055,7 +7055,7 @@ To read the label on a filesystem, call C<guestfs_vfs_label>." };
 
   { defaults with
     name = "zero_free_space"; added = (1, 17, 18);
-    style = RErr, [Pathname "directory"], [];
+    style = RErr, [String (Pathname, "directory")], [];
     progress = true;
     tests = [
       InitScratchFS, Always, TestRun (
@@ -7075,7 +7075,7 @@ or after calling this, depending on your requirements." };
 
   { defaults with
     name = "lvcreate_free"; added = (1, 17, 18);
-    style = RErr, [String "logvol"; String "volgroup"; Int "percent"], [];
+    style = RErr, [String (PlainString, "logvol"); String (PlainString, "volgroup"); Int "percent"], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestResult (
@@ -7098,7 +7098,7 @@ this will create the largest possible LV." };
 
   { defaults with
     name = "isoinfo_device"; added = (1, 17, 19);
-    style = RStruct ("isodata", "isoinfo"), [Device "device"], [];
+    style = RStruct ("isodata", "isoinfo"), [String (Device, "device")], [];
     tests = [
       InitNone, Always, TestResult (
         [["isoinfo_device"; "/dev/sdd"]],
@@ -7124,7 +7124,7 @@ L<http://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor>" };
 
   { defaults with
     name = "isoinfo"; added = (1, 17, 19);
-    style = RStruct ("isodata", "isoinfo"), [Pathname "isofile"], [];
+    style = RStruct ("isodata", "isoinfo"), [String (Pathname, "isofile")], [];
     shortdesc = "get ISO information from primary volume descriptor of ISO file";
     longdesc = "\
 This is the same as C<guestfs_isoinfo_device> except that it
@@ -7135,7 +7135,7 @@ you would call C<guestfs_isoinfo_device>." };
 
   { defaults with
     name = "vgmeta"; added = (1, 17, 20);
-    style = RBufferOut "metadata", [String "vgname"], [];
+    style = RBufferOut "metadata", [String (PlainString, "vgname")], [];
     optional = Some "lvm2";
     shortdesc = "get volume group metadata";
     longdesc = "\
@@ -7147,7 +7147,7 @@ subject to change at any time, and is provided for information only." };
 
   { defaults with
     name = "md_stat"; added = (1, 17, 21);
-    style = RStructList ("devices", "mdstat"), [Device "md"], [];
+    style = RStructList ("devices", "mdstat"), [String (Device, "md")], [];
     optional = Some "mdadm";
     shortdesc = "get underlying devices from an MD device";
     longdesc = "\
@@ -7198,7 +7198,7 @@ replacement
 
   { defaults with
     name = "mkfs_btrfs"; added = (1, 17, 25);
-    style = RErr, [DeviceList "devices"], [OInt64 "allocstart"; OInt64 "bytecount"; OString "datatype"; OInt "leafsize"; OString "label"; OString "metadata"; OInt "nodesize"; OInt "sectorsize"];
+    style = RErr, [StringList (Device, "devices")], [OInt64 "allocstart"; OInt64 "bytecount"; OString "datatype"; OInt "leafsize"; OString "label"; OString "metadata"; OInt "nodesize"; OInt "sectorsize"];
     optional = Some "btrfs";
     tests = [
       InitEmpty, Always, TestRun (
@@ -7217,7 +7217,7 @@ To create general filesystems, use C<guestfs_mkfs>." };
 
   { defaults with
     name = "get_e2attrs"; added = (1, 17, 31);
-    style = RString "attrs", [Pathname "file"], [];
+    style = RString "attrs", [String (Pathname, "file")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["touch"; "/e2attrs1"];
@@ -7365,7 +7365,7 @@ Don't confuse these attributes with extended attributes
 
   { defaults with
     name = "set_e2attrs"; added = (1, 17, 31);
-    style = RErr, [Pathname "file"; String "attrs"], [OBool "clear"];
+    style = RErr, [String (Pathname, "file"); String (PlainString, "attrs")], [OBool "clear"];
     shortdesc = "set ext2 file attributes of a file";
     longdesc = "\
 This sets or clears the file attributes C<attrs>
@@ -7390,7 +7390,7 @@ types will result in an error." };
 
   { defaults with
     name = "get_e2generation"; added = (1, 17, 31);
-    style = RInt64 "generation", [Pathname "file"], [];
+    style = RInt64 "generation", [String (Pathname, "file")], [];
     tests = [
       InitScratchFS, Always, TestResult (
         [["touch"; "/e2generation"];
@@ -7411,7 +7411,7 @@ See C<guestfs_set_e2generation>." };
 
   { defaults with
     name = "set_e2generation"; added = (1, 17, 31);
-    style = RErr, [Pathname "file"; Int64 "generation"], [];
+    style = RErr, [String (Pathname, "file"); Int64 "generation"], [];
     shortdesc = "set ext2 file generation of a file";
     longdesc = "\
 This sets the ext2 file generation of a file.
@@ -7420,7 +7420,7 @@ See C<guestfs_get_e2generation>." };
 
   { defaults with
     name = "btrfs_subvolume_snapshot"; added = (1, 17, 35);
-    style = RErr, [Pathname "source"; Pathname "dest"], [OBool "ro"; OString "qgroupid"];
+    style = RErr, [String (Pathname, "source"); String (Pathname, "dest")], [OBool "ro"; OString "qgroupid"];
     once_had_no_optargs = true;
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeSnapshot";
     tests = [
@@ -7446,7 +7446,7 @@ newly created snapshot will be added to." };
 
   { defaults with
     name = "btrfs_subvolume_delete"; added = (1, 17, 35);
-    style = RErr, [Pathname "subvolume"], [];
+    style = RErr, [String (Pathname, "subvolume")], [];
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeDelete";
     tests = [
       InitPartition, Always, TestRun (
@@ -7461,7 +7461,7 @@ Delete the named btrfs subvolume or snapshot." };
 
   { defaults with
     name = "btrfs_subvolume_create"; added = (1, 17, 35);
-    style = RErr, [Pathname "dest"], [OString "qgroupid"];
+    style = RErr, [String (Pathname, "dest")], [OString "qgroupid"];
     once_had_no_optargs = true;
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeCreate";
     shortdesc = "create a btrfs subvolume";
@@ -7473,7 +7473,7 @@ created subvolume will be added to." };
 
   { defaults with
     name = "btrfs_subvolume_list"; added = (1, 17, 35);
-    style = RStructList ("subvolumes", "btrfssubvolume"), [Mountable_or_Path "fs"], [];
+    style = RStructList ("subvolumes", "btrfssubvolume"), [String (Mountable_or_Path, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeList";
     test_excuse = "tested in tests/btrfs";
     shortdesc = "list btrfs snapshots and subvolumes";
@@ -7483,7 +7483,7 @@ which is mounted at C<fs>." };
 
   { defaults with
     name = "btrfs_subvolume_set_default"; added = (1, 17, 35);
-    style = RErr, [Int64 "id"; Pathname "fs"], [];
+    style = RErr, [Int64 "id"; String (Pathname, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeSetDefault";
     test_excuse = "tested in tests/btrfs";
     shortdesc = "set default btrfs subvolume";
@@ -7494,7 +7494,7 @@ get a list of subvolumes." };
 
   { defaults with
     name = "btrfs_filesystem_sync"; added = (1, 17, 35);
-    style = RErr, [Pathname "fs"], [];
+    style = RErr, [String (Pathname, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSFilesystemSync";
     tests = [
       InitPartition, Always, TestRun (
@@ -7510,7 +7510,7 @@ Force sync on the btrfs filesystem mounted at C<fs>." };
 
   { defaults with
     name = "btrfs_filesystem_balance"; added = (1, 17, 35);
-    style = RErr, [Pathname "fs"], [];
+    style = RErr, [String (Pathname, "fs")], [];
     fish_alias = ["btrfs-balance"];
     optional = Some "btrfs"; camel_name = "BTRFSFilesystemBalance";
     shortdesc = "balance a btrfs filesystem";
@@ -7520,7 +7520,7 @@ across the underlying devices." };
 
   { defaults with
     name = "btrfs_device_add"; added = (1, 17, 35);
-    style = RErr, [DeviceList "devices"; Pathname "fs"], [];
+    style = RErr, [StringList (Device, "devices"); String (Pathname, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSDeviceAdd";
     test_excuse = "test disk isn't large enough to test this thoroughly, so there is an external test in 'tests/btrfs' directory";
     shortdesc = "add devices to a btrfs filesystem";
@@ -7530,7 +7530,7 @@ mounted at C<fs>.  If C<devices> is an empty list, this does nothing." };
 
   { defaults with
     name = "btrfs_device_delete"; added = (1, 17, 35);
-    style = RErr, [DeviceList "devices"; Pathname "fs"], [];
+    style = RErr, [StringList (Device, "devices"); String (Pathname, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSDeviceDelete";
     test_excuse = "test disk isn't large enough to test this thoroughly, so there is an external test in 'tests/btrfs' directory.";
     shortdesc = "remove devices from a btrfs filesystem";
@@ -7540,7 +7540,7 @@ If C<devices> is an empty list, this does nothing." };
 
   { defaults with
     name = "btrfs_set_seeding"; added = (1, 17, 43);
-    style = RErr, [Device "device"; Bool "seeding"], [];
+    style = RErr, [String (Device, "device"); Bool "seeding"], [];
     optional = Some "btrfs";
     tests = [
       InitPartition, Always, TestRun (
@@ -7555,7 +7555,7 @@ a btrfs filesystem." };
 
   { defaults with
     name = "btrfs_fsck"; added = (1, 17, 43);
-    style = RErr, [Device "device"], [OInt64 "superblock"; OBool "repair"];
+    style = RErr, [String (Device, "device")], [OInt64 "superblock"; OBool "repair"];
     optional = Some "btrfs";
     tests = [
       InitPartition, Always, TestRun (
@@ -7569,7 +7569,7 @@ filesystem is stored." };
 
   { defaults with
     name = "filesystem_available"; added = (1, 19, 5);
-    style = RBool "fsavail", [String "filesystem"], [];
+    style = RBool "fsavail", [String (PlainString, "filesystem")], [];
     shortdesc = "check if filesystem is available";
     longdesc = "\
 Check whether libguestfs supports the named filesystem.
@@ -7590,7 +7590,7 @@ L<guestfs(3)/AVAILABILITY>." };
 
   { defaults with
     name = "fstrim"; added = (1, 19, 6);
-    style = RErr, [Pathname "mountpoint"], [OInt64 "offset"; OInt64 "length"; OInt64 "minimumfreeextent"];
+    style = RErr, [String (Pathname, "mountpoint")], [OInt64 "offset"; OInt64 "length"; OInt64 "minimumfreeextent"];
     optional = Some "fstrim";
     shortdesc = "trim free space in a filesystem";
     longdesc = "\
@@ -7618,7 +7618,7 @@ instead of, or after calling C<guestfs_zero_free_space>." };
 
   { defaults with
     name = "device_index"; added = (1, 19, 7);
-    style = RInt "index", [Device "device"], [];
+    style = RInt "index", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResult (
         [["device_index"; "/dev/sda"]], "ret == 0"), []
@@ -7651,7 +7651,7 @@ call C<guestfs_max_disks>." };
 
   { defaults with
     name = "xfs_info"; added = (1, 19, 21);
-    style = RStruct ("info", "xfsinfo"), [Dev_or_Path "pathordevice"], [];
+    style = RStruct ("info", "xfsinfo"), [String (Dev_or_Path, "pathordevice")], [];
     optional = Some "xfs";
     tests = [
       InitEmpty, Always, TestResult (
@@ -7671,7 +7671,7 @@ string." };
 
   { defaults with
     name = "pvchange_uuid"; added = (1, 19, 26);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestRun (
@@ -7699,7 +7699,7 @@ Generate new random UUIDs for all physical volumes." };
 
   { defaults with
     name = "vgchange_uuid"; added = (1, 19, 26);
-    style = RErr, [String "vg"], [];
+    style = RErr, [String (PlainString, "vg")], [];
     optional = Some "lvm2";
     tests = [
       InitEmpty, Always, TestRun (
@@ -7742,7 +7742,7 @@ in the returned structure is defined by the API." };
 
   { defaults with
     name = "xfs_growfs"; added = (1, 19, 28);
-    style = RErr, [Pathname "path"], [OBool "datasec"; OBool "logsec"; OBool "rtsec"; OInt64 "datasize"; OInt64 "logsize"; OInt64 "rtsize"; OInt64 "rtextsize"; OInt "maxpct"];
+    style = RErr, [String (Pathname, "path")], [OBool "datasec"; OBool "logsec"; OBool "rtsec"; OInt64 "datasize"; OInt64 "logsize"; OInt64 "rtsize"; OInt64 "rtextsize"; OInt "maxpct"];
     optional = Some "xfs";
     tests = [
       InitEmpty, Always, TestResult (
@@ -7766,7 +7766,7 @@ string." };
 
   { defaults with
     name = "rsync"; added = (1, 19, 29);
-    style = RErr, [Pathname "src"; Pathname "dest"], [OBool "archive"; OBool "deletedest"];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [OBool "archive"; OBool "deletedest"];
     optional = Some "rsync";
     test_excuse = "tests are in tests/rsync";
     shortdesc = "synchronize the contents of two directories";
@@ -7796,7 +7796,7 @@ Delete files at the destination that do not exist at the source.
 
   { defaults with
     name = "rsync_in"; added = (1, 19, 29);
-    style = RErr, [String "remote"; Pathname "dest"], [OBool "archive"; OBool "deletedest"];
+    style = RErr, [String (PlainString, "remote"); String (Pathname, "dest")], [OBool "archive"; OBool "deletedest"];
     optional = Some "rsync";
     test_excuse = "tests are in tests/rsync";
     shortdesc = "synchronize host or remote filesystem with filesystem";
@@ -7821,7 +7821,7 @@ The optional arguments are the same as those of C<guestfs_rsync>." };
 
   { defaults with
     name = "rsync_out"; added = (1, 19, 29);
-    style = RErr, [Pathname "src"; String "remote"], [OBool "archive"; OBool "deletedest"];
+    style = RErr, [String (Pathname, "src"); String (PlainString, "remote")], [OBool "archive"; OBool "deletedest"];
     optional = Some "rsync";
     test_excuse = "tests are in tests/rsync";
     shortdesc = "synchronize filesystem with host or remote filesystem";
@@ -7853,7 +7853,7 @@ command (see L<guestfish(1)/glob>), for example:
 
   { defaults with
     name = "ls0"; added = (1, 19, 32);
-    style = RErr, [Pathname "dir"; FileOut "filenames"], [];
+    style = RErr, [String (Pathname, "dir"); String (FileOut, "filenames")], [];
     shortdesc = "get list of files in a directory";
     longdesc = "\
 This specialized command is used to get a listing of
@@ -7866,7 +7866,7 @@ C<.> and C<..> are not returned.  The filenames are not sorted." };
 
   { defaults with
     name = "fill_dir"; added = (1, 19, 32);
-    style = RErr, [Pathname "dir"; Int "nr"], [];
+    style = RErr, [String (Pathname, "dir"); Int "nr"], [];
     shortdesc = "fill a directory with empty files";
     longdesc = "\
 This function, useful for testing filesystems, creates C<nr>
@@ -7876,7 +7876,7 @@ with zeroes)." };
 
   { defaults with
     name = "xfs_admin"; added = (1, 19, 33);
-    style = RErr, [Device "device"], [OBool "extunwritten"; OBool "imgfile"; OBool "v2log"; OBool "projid32bit"; OBool "lazycounter"; OString "label"; OString "uuid"];
+    style = RErr, [String (Device, "device")], [OBool "extunwritten"; OBool "imgfile"; OBool "v2log"; OBool "projid32bit"; OBool "lazycounter"; OString "label"; OString "uuid"];
     optional = Some "xfs";
     tests = [
         InitEmpty, Always, TestResult (
@@ -7910,7 +7910,7 @@ C<guestfs_xfs_growfs> calls." };
 
   { defaults with
     name = "xfs_repair"; added = (1, 19, 36);
-    style = RInt "status", [Dev_or_Path "device"], [OBool "forcelogzero"; OBool "nomodify"; OBool "noprefetch"; OBool "forcegeometry"; OInt64 "maxmem"; OInt64 "ihashsize"; OInt64 "bhashsize"; OInt64 "agstride"; OString "logdev"; OString "rtdev"];
+    style = RInt "status", [String (Dev_or_Path, "device")], [OBool "forcelogzero"; OBool "nomodify"; OBool "noprefetch"; OBool "forcegeometry"; OInt64 "maxmem"; OInt64 "ihashsize"; OInt64 "bhashsize"; OInt64 "agstride"; OString "logdev"; OString "rtdev"];
     optional = Some "xfs";
     tests = [
       InitEmpty, Always, TestRun (
@@ -7937,7 +7937,7 @@ detected (returns C<1>) or was not detected (returns C<0>)." };
 
   { defaults with
     name = "rm_f"; added = (1, 19, 42);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     tests = [
       InitScratchFS, Always, TestResultFalse
         [["mkdir"; "/rm_f"];
@@ -7963,7 +7963,7 @@ or C<guestfs_rm_rf> to remove directories recursively." };
 
   { defaults with
     name = "mke2fs"; added = (1, 19, 44);
-    style = RErr, [Device "device"], [OInt64 "blockscount"; OInt64 "blocksize"; OInt64 "fragsize"; OInt64 "blockspergroup"; OInt64 "numberofgroups"; OInt64 "bytesperinode"; OInt64 "inodesize"; OInt64 "journalsize"; OInt64 "numberofinodes"; OInt64 "stridesize"; OInt64 "stripewidth"; OInt64 "maxonlineresize"; OInt "reservedblockspercentage"; OInt "mmpupdateinterval"; OString "journaldevice"; OString "label"; OString "lastmounteddir"; OString "creatoros"; OString "fstype"; OString "usagetype"; OString "uuid"; OBool "forcecreate"; OBool "writesbandgrouponly"; OBool "lazyitableinit"; OBool "lazyjournalinit"; OBool "testfs"; OBool "discard"; OBool "quotatype";  OBool "extent"; OBool "filetype"; OBool "flexbg"; OBool "hasjournal"; OBool "journaldev"; OBool "largefile"; OBool "quota"; OBool "resizeinode"; OBool "sparsesuper"; OBool "uninitbg"];
+    style = RErr, [String (Device, "device")], [OInt64 "blockscount"; OInt64 "blocksize"; OInt64 "fragsize"; OInt64 "blockspergroup"; OInt64 "numberofgroups"; OInt64 "bytesperinode"; OInt64 "inodesize"; OInt64 "journalsize"; OInt64 "numberofinodes"; OInt64 "stridesize"; OInt64 "stripewidth"; OInt64 "maxonlineresize"; OInt "reservedblockspercentage"; OInt "mmpupdateinterval"; OString "journaldevice"; OString "label"; OString "lastmounteddir"; OString "creatoros"; OString "fstype"; OString "usagetype"; OString "uuid"; OBool "forcecreate"; OBool "writesbandgrouponly"; OBool "lazyitableinit"; OBool "lazyjournalinit"; OBool "testfs"; OBool "discard"; OBool "quotatype";  OBool "extent"; OBool "filetype"; OBool "flexbg"; OBool "hasjournal"; OBool "journaldev"; OBool "largefile"; OBool "quota"; OBool "resizeinode"; OBool "sparsesuper"; OBool "uninitbg"];
     tests = [
          InitEmpty, Always, TestResultString (
            [["part_init"; "/dev/sda"; "mbr"];
@@ -8075,7 +8075,7 @@ are the full raw block device and partition names
 
   { defaults with
     name = "internal_hot_add_drive"; added = (1, 19, 49);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     visibility = VInternal;
     shortdesc = "internal hotplugging operation";
     longdesc = "\
@@ -8083,7 +8083,7 @@ This function is used internally when hotplugging drives." };
 
   { defaults with
     name = "internal_hot_remove_drive_precheck"; added = (1, 19, 49);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     visibility = VInternal;
     shortdesc = "internal hotplugging operation";
     longdesc = "\
@@ -8091,7 +8091,7 @@ This function is used internally when hotplugging drives." };
 
   { defaults with
     name = "internal_hot_remove_drive"; added = (1, 19, 49);
-    style = RErr, [String "label"], [];
+    style = RErr, [String (PlainString, "label")], [];
     visibility = VInternal;
     shortdesc = "internal hotplugging operation";
     longdesc = "\
@@ -8099,7 +8099,7 @@ This function is used internally when hotplugging drives." };
 
   { defaults with
     name = "mktemp"; added = (1, 19, 53);
-    style = RString "path", [Pathname "tmpl"], [OString "suffix"];
+    style = RString "path", [String (Pathname, "tmpl")], [OString "suffix"];
     tests = [
       InitScratchFS, Always, TestRun (
         [["mkdir"; "/mktemp"];
@@ -8132,7 +8132,7 @@ See also: C<guestfs_mkdtemp>." };
 
   { defaults with
     name = "mklost_and_found"; added = (1, 19, 56);
-    style = RErr, [Pathname "mountpoint"], [];
+    style = RErr, [String (Pathname, "mountpoint")], [];
     tests = [
       InitBasicFS, Always, TestRun (
         [["rm_rf"; "/lost+found"];
@@ -8146,7 +8146,7 @@ which we try to create the C<lost+found> directory." };
 
   { defaults with
     name = "acl_get_file"; added = (1, 19, 63);
-    style = RString "acl", [Pathname "path"; String "acltype"], [];
+    style = RString "acl", [String (Pathname, "path"); String (PlainString, "acltype")], [];
     optional = Some "acl";
     shortdesc = "get the POSIX ACL attached to a file";
     longdesc = "\
@@ -8171,7 +8171,7 @@ C<path> is a directory.
 
   { defaults with
     name = "acl_set_file"; added = (1, 19, 63);
-    style = RErr, [Pathname "path"; String "acltype"; String "acl"], [];
+    style = RErr, [String (Pathname, "path"); String (PlainString, "acltype"); String (PlainString, "acl")], [];
     optional = Some "acl";
     tests = [
       InitScratchFS, Always, TestRun (
@@ -8237,7 +8237,7 @@ guest, use the Augeas functions (see C<guestfs_aug_init>)." };
 
   { defaults with
     name = "acl_delete_def_file"; added = (1, 19, 63);
-    style = RErr, [Pathname "dir"], [];
+    style = RErr, [String (Pathname, "dir")], [];
     optional = Some "acl";
     tests = [
       (* Documentation for libacl says this should fail, but it doesn't.
@@ -8258,7 +8258,7 @@ attached to directory C<dir>." };
 
   { defaults with
     name = "cap_get_file"; added = (1, 19, 63);
-    style = RString "cap", [Pathname "path"], [];
+    style = RString "cap", [String (Pathname, "path")], [];
     optional = Some "linuxcaps";
     shortdesc = "get the Linux capabilities attached to a file";
     longdesc = "\
@@ -8269,7 +8269,7 @@ If no capabilities are attached to a file, an empty string is returned." };
 
   { defaults with
     name = "cap_set_file"; added = (1, 19, 63);
-    style = RErr, [Pathname "path"; String "cap"], [];
+    style = RErr, [String (Pathname, "path"); String (PlainString, "cap")], [];
     optional = Some "linuxcaps";
     tests = [
       InitScratchFS, Always, TestResultString (
@@ -8346,7 +8346,7 @@ block devices, call C<guestfs_ldmtool_scan_devices> instead." };
 
   { defaults with
     name = "ldmtool_scan_devices"; added = (1, 20, 0);
-    style = RStringList "guids", [DeviceList "devices"], [];
+    style = RStringList "guids", [StringList (Device, "devices")], [];
     optional = Some "ldm";
     shortdesc = "scan for Windows dynamic disks";
     longdesc = "\
@@ -8359,7 +8359,7 @@ scanned.  If this list is empty, all block devices are scanned." };
 
   { defaults with
     name = "ldmtool_diskgroup_name"; added = (1, 20, 0);
-    style = RString "name", [String "diskgroup"], [];
+    style = RString "name", [String (PlainString, "diskgroup")], [];
     optional = Some "ldm";
     shortdesc = "return the name of a Windows dynamic disk group";
     longdesc = "\
@@ -8369,7 +8369,7 @@ the list returned by C<guestfs_ldmtool_scan>." };
 
   { defaults with
     name = "ldmtool_diskgroup_volumes"; added = (1, 20, 0);
-    style = RStringList "volumes", [String "diskgroup"], [];
+    style = RStringList "volumes", [String (PlainString, "diskgroup")], [];
     optional = Some "ldm";
     shortdesc = "return the volumes in a Windows dynamic disk group";
     longdesc = "\
@@ -8379,7 +8379,7 @@ the list returned by C<guestfs_ldmtool_scan>." };
 
   { defaults with
     name = "ldmtool_diskgroup_disks"; added = (1, 20, 0);
-    style = RStringList "disks", [String "diskgroup"], [];
+    style = RStringList "disks", [String (PlainString, "diskgroup")], [];
     optional = Some "ldm";
     shortdesc = "return the disks in a Windows dynamic disk group";
     longdesc = "\
@@ -8389,7 +8389,7 @@ the list returned by C<guestfs_ldmtool_scan>." };
 
   { defaults with
     name = "ldmtool_volume_type"; added = (1, 20, 0);
-    style = RString "voltype", [String "diskgroup"; String "volume"], [];
+    style = RString "voltype", [String (PlainString, "diskgroup"); String (PlainString, "volume")], [];
     optional = Some "ldm";
     shortdesc = "return the type of a Windows dynamic disk volume";
     longdesc = "\
@@ -8402,7 +8402,7 @@ Other types may also be returned." };
 
   { defaults with
     name = "ldmtool_volume_hint"; added = (1, 20, 0);
-    style = RString "hint", [String "diskgroup"; String "volume"], [];
+    style = RString "hint", [String (PlainString, "diskgroup"); String (PlainString, "volume")], [];
     optional = Some "ldm";
     shortdesc = "return the hint field of a Windows dynamic disk volume";
     longdesc = "\
@@ -8413,7 +8413,7 @@ not always, the name of a Windows drive, eg. C<E:>." };
 
   { defaults with
     name = "ldmtool_volume_partitions"; added = (1, 20, 0);
-    style = RStringList "partitions", [String "diskgroup"; String "volume"], [];
+    style = RStringList "partitions", [String (PlainString, "diskgroup"); String (PlainString, "volume")], [];
     optional = Some "ldm";
     shortdesc = "return the partitions in a Windows dynamic disk volume";
     longdesc = "\
@@ -8422,7 +8422,7 @@ group with GUID C<diskgroup>." };
 
   { defaults with
     name = "part_set_gpt_type"; added = (1, 21, 1);
-    style = RErr, [Device "device"; Int "partnum"; GUID "guid"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"; String (GUID, "guid")], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestLastFail (
@@ -8444,7 +8444,7 @@ for a useful list of type GUIDs." };
 
   { defaults with
     name = "part_get_gpt_type"; added = (1, 21, 1);
-    style = RString "guid", [Device "device"; Int "partnum"], [];
+    style = RString "guid", [String (Device, "device"); Int "partnum"], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestResultString (
@@ -8461,7 +8461,7 @@ for other partition types." };
 
   { defaults with
     name = "rename"; added = (1, 21, 5);
-    style = RErr, [Pathname "oldpath"; Pathname "newpath"], [];
+    style = RErr, [String (Pathname, "oldpath"); String (Pathname, "newpath")], [];
     tests = [
       InitScratchFS, Always, TestResultFalse (
         [["mkdir"; "/rename"];
@@ -8477,7 +8477,7 @@ you are better to use C<guestfs_mv> instead." };
 
   { defaults with
     name = "is_whole_device"; added = (1, 21, 9);
-    style = RBool "flag", [Device "device"], [];
+    style = RBool "flag", [String (Device, "device")], [];
     tests = [
       InitEmpty, Always, TestResultTrue (
         [["is_whole_device"; "/dev/sda"]]), [];
@@ -8493,7 +8493,7 @@ device. That is, not a partition or a logical device." };
 
   { defaults with
     name = "internal_parse_mountable"; added = (1, 21, 11);
-    style = RStruct ("mountable", "internal_mountable"), [Mountable "mountable"], [];
+    style = RStruct ("mountable", "internal_mountable"), [String (Mountable, "mountable")], [];
     visibility = VInternal;
     shortdesc = "parse a mountable string";
     longdesc = "\
@@ -8501,7 +8501,7 @@ Parse a mountable string." };
 
   { defaults with
     name = "internal_rhbz914931"; added = (1, 21, 14);
-    style = RErr, [FileIn "filename"; Int "count"], [];
+    style = RErr, [String (FileIn, "filename"); Int "count"], [];
     visibility = VInternal;
     cancellable = true;
     shortdesc = "used only to test rhbz914931 (internal use only)";
@@ -8511,7 +8511,7 @@ deliberately crashes guestfsd." };
 
   { defaults with
     name = "syslinux"; added = (1, 21, 27);
-    style = RErr, [Device "device"], [OString "directory"];
+    style = RErr, [String (Device, "device")], [OString "directory"];
     optional = Some "syslinux";
     shortdesc = "install the SYSLINUX bootloader";
     longdesc = "\
@@ -8547,7 +8547,7 @@ See also C<guestfs_extlinux>." };
 
   { defaults with
     name = "extlinux"; added = (1, 21, 27);
-    style = RErr, [Pathname "directory"], [];
+    style = RErr, [String (Pathname, "directory")], [];
     optional = Some "extlinux";
     shortdesc = "install the SYSLINUX bootloader on an ext2/3/4 or btrfs filesystem";
     longdesc = "\
@@ -8574,7 +8574,7 @@ See also C<guestfs_syslinux>." };
 
   { defaults with
     name = "cp_r"; added = (1, 21, 38);
-    style = RErr, [Pathname "src"; Pathname "dest"], [];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [];
     tests = [
       InitScratchFS, Always, TestResultString (
         [["mkdir"; "/cp_r1"];
@@ -8595,7 +8595,7 @@ writing to DOS FAT filesystems)." };
 
   { defaults with
     name = "remount"; added = (1, 23, 2);
-    style = RErr, [Pathname "mountpoint"], [OBool "rw"];
+    style = RErr, [String (Pathname, "mountpoint")], [OBool "rw"];
     tests = [
       InitScratchFS, Always, TestLastFail (
         [["remount"; "/"; "false"];
@@ -8616,7 +8616,7 @@ parameter.  In future we may allow other flags to be adjusted." };
 
   { defaults with
     name = "set_uuid"; added = (1, 23, 10);
-    style = RErr, [Device "device"; String "uuid"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "uuid")], [];
     tests = [
         InitBasicFS, Always, TestResultString (
           [["set_uuid"; "/dev/sda1"; stable_uuid];
@@ -8635,7 +8635,7 @@ To read the UUID on a filesystem, call C<guestfs_vfs_uuid>." };
 
   { defaults with
     name = "journal_open"; added = (1, 23, 11);
-    style = RErr, [Pathname "directory"], [];
+    style = RErr, [String (Pathname, "directory")], [];
     optional = Some "journal";
     test_excuse = "tests in tests/journal subdirectory";
     shortdesc = "open the systemd journal";
@@ -8691,7 +8691,7 @@ the start of the journal." };
 
   { defaults with
     name = "internal_journal_get"; added = (1, 23, 11);
-    style = RErr, [FileOut "filename"], [];
+    style = RErr, [String (FileOut, "filename")], [];
     visibility = VInternal;
     optional = Some "journal";
     test_excuse = "tests in tests/journal subdirectory";
@@ -8729,7 +8729,7 @@ See also C<guestfs_journal_get_data_threshold>." };
 
   { defaults with
     name = "aug_setm"; added = (1, 23, 14);
-    style = RInt "nodes", [String "base"; OptString "sub"; String "val"], [];
+    style = RInt "nodes", [String (PlainString, "base"); OptString "sub"; String (PlainString, "val")], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["mkdir"; "/etc"];
@@ -8751,7 +8751,7 @@ This returns the number of nodes modified." };
 
   { defaults with
     name = "aug_label"; added = (1, 23, 14);
-    style = RString "label", [String "augpath"], [];
+    style = RString "label", [String (PlainString, "augpath")], [];
     tests = [
       InitBasicFS, Always, TestResultString (
         [["mkdir"; "/etc"];
@@ -8767,7 +8767,7 @@ this function returns an error." };
 
   { defaults with
     name = "internal_upload"; added = (1, 23, 30);
-    style = RErr, [FileIn "filename"; String "tmpname"; Int "mode"], [];
+    style = RErr, [String (FileIn, "filename"); String (PlainString, "tmpname"); Int "mode"], [];
     visibility = VInternal;
     cancellable = true;
     shortdesc = "upload a file to the appliance (internal use only)";
@@ -8786,7 +8786,7 @@ This function is used internally when testing the appliance." };
 
   { defaults with
     name = "copy_attributes"; added = (1, 25, 21);
-    style = RErr, [Pathname "src"; Pathname "dest"], [OBool "all"; OBool "mode"; OBool "xattributes"; OBool "ownership"];
+    style = RErr, [String (Pathname, "src"); String (Pathname, "dest")], [OBool "all"; OBool "mode"; OBool "xattributes"; OBool "ownership"];
     shortdesc = "copy the attributes of a path (file/directory) to another";
     longdesc = "\
 Copy the attributes of a path (which can be a file or a directory)
@@ -8823,7 +8823,7 @@ enables all the other flags, if they are not specified already.
 
   { defaults with
     name = "part_get_name"; added = (1, 25, 33);
-    style = RString "name", [Device "device"; Int "partnum"], [];
+    style = RString "name", [String (Device, "device"); Int "partnum"], [];
     shortdesc = "get partition name";
     longdesc = "\
 This gets the partition name on partition numbered C<partnum> on
@@ -8834,7 +8834,7 @@ table.  This works on C<gpt> but not on C<mbr> partitions." };
 
   { defaults with
     name = "blkdiscard"; added = (1, 25, 44);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "blkdiscard";
     shortdesc = "discard all blocks on a device";
     longdesc = "\
@@ -8849,7 +8849,7 @@ C<guestfs_add_drive_opts>)." };
 
   { defaults with
     name = "blkdiscardzeroes"; added = (1, 25, 44);
-    style = RBool "zeroes", [Device "device"], [];
+    style = RBool "zeroes", [String (Device, "device")], [];
     optional = Some "blkdiscardzeroes";
     shortdesc = "return true if discarded blocks are read as zeroes";
     longdesc = "\
@@ -8862,7 +8862,7 @@ read as stale or random data." };
 
   { defaults with
     name = "cpio_out"; added = (1, 27, 9);
-    style = RErr, [String "directory"; FileOut "cpiofile"], [OString "format"];
+    style = RErr, [String (PlainString, "directory"); String (FileOut, "cpiofile")], [OString "format"];
     cancellable = true;
     shortdesc = "pack directory into cpio file";
     longdesc = "\
@@ -8898,7 +8898,7 @@ Get the realtime (wallclock) timestamp of the current journal entry." };
 
   { defaults with
     name = "statns"; added = (1, 27, 53);
-    style = RStruct ("statbuf", "statns"), [Pathname "path"], [];
+    style = RStruct ("statbuf", "statns"), [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["statns"; "/empty"]], "ret->st_size == 0"), []
@@ -8911,7 +8911,7 @@ This is the same as the L<stat(2)> system call." };
 
   { defaults with
     name = "lstatns"; added = (1, 27, 53);
-    style = RStruct ("statbuf", "statns"), [Pathname "path"], [];
+    style = RStruct ("statbuf", "statns"), [String (Pathname, "path")], [];
     tests = [
       InitISOFS, Always, TestResult (
         [["lstatns"; "/empty"]], "ret->st_size == 0"), []
@@ -8928,7 +8928,7 @@ This is the same as the L<lstat(2)> system call." };
 
   { defaults with
     name = "internal_lstatnslist"; added = (1, 27, 53);
-    style = RStructList ("statbufs", "statns"), [Pathname "path"; FilenameList "names"], [];
+    style = RStructList ("statbufs", "statns"), [String (Pathname, "path"); StringList (Filename, "names")], [];
     visibility = VInternal;
     shortdesc = "lstat on multiple files";
     longdesc = "\
@@ -8936,7 +8936,7 @@ This is the internal call which implements C<guestfs_lstatnslist>." };
 
   { defaults with
     name = "blockdev_setra"; added = (1, 29, 10);
-    style = RErr, [Device "device"; Int "sectors"], [];
+    style = RErr, [String (Device, "device"); Int "sectors"], [];
     tests = [
       InitEmpty, Always, TestRun (
         [["blockdev_setra"; "/dev/sda"; "1024" ]]), []
@@ -8949,7 +8949,7 @@ This uses the L<blockdev(8)> command." };
 
   { defaults with
     name = "btrfs_subvolume_get_default"; added = (1, 29, 17);
-    style = RInt64 "id", [Mountable_or_Path "fs"], [];
+    style = RInt64 "id", [String (Mountable_or_Path, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeGetDefault";
     tests = [
       InitPartition, Always, TestResult (
@@ -8966,7 +8966,7 @@ Get the default subvolume or snapshot of a filesystem mounted at C<mountpoint>."
 
   { defaults with
     name = "btrfs_subvolume_show"; added = (1, 29, 17);
-    style = RHashtable "btrfssubvolumeinfo", [Pathname "subvolume"], [];
+    style = RHashtable "btrfssubvolumeinfo", [String (Pathname, "subvolume")], [];
     optional = Some "btrfs"; camel_name = "BTRFSSubvolumeShow";
     tests = [
       InitPartition, Always, TestRun (
@@ -8986,7 +8986,7 @@ Return detailed information of the subvolume." };
 
   { defaults with
     name = "btrfs_quota_enable"; added = (1, 29, 17);
-    style = RErr, [Mountable_or_Path "fs"; Bool "enable"], [];
+    style = RErr, [String (Mountable_or_Path, "fs"); Bool "enable"], [];
     optional = Some "btrfs"; camel_name = "BTRFSQuotaEnable";
     tests = [
       InitPartition, Always, TestRun (
@@ -9010,7 +9010,7 @@ Enable or disable subvolume quota support for filesystem which contains C<path>.
 
   { defaults with
     name = "btrfs_quota_rescan"; added = (1, 29, 17);
-    style = RErr, [Mountable_or_Path "fs"], [];
+    style = RErr, [String (Mountable_or_Path, "fs")], [];
     optional = Some "btrfs"; camel_name = "BTRFSQuotaRescan";
     tests = [
       InitPartition, Always, TestRun (
@@ -9030,7 +9030,7 @@ Trash all qgroup numbers and scan the metadata again with the current config." }
 
   { defaults with
     name = "btrfs_qgroup_limit"; added = (1, 29, 17);
-    style = RErr, [Pathname "subvolume"; Int64 "size"], [];
+    style = RErr, [String (Pathname, "subvolume"); Int64 "size"], [];
     optional = Some "btrfs"; camel_name = "BTRFSQgroupLimit";
     tests = [
       InitPartition, Always, TestRun (
@@ -9050,7 +9050,7 @@ Limit the size of the subvolume with path C<subvolume>." };
 
   { defaults with
     name = "btrfs_qgroup_create"; added = (1, 29, 17);
-    style = RErr, [String "qgroupid"; Pathname "subvolume"], [];
+    style = RErr, [String (PlainString, "qgroupid"); String (Pathname, "subvolume")], [];
     optional = Some "btrfs"; camel_name = "BTRFSQgroupCreate";
     tests = [
       InitPartition, Always, TestRun (
@@ -9066,7 +9066,7 @@ Create a quota group (qgroup) for subvolume at C<subvolume>." };
 
   { defaults with
     name = "btrfs_qgroup_destroy"; added = (1, 29, 17);
-    style = RErr, [String "qgroupid"; Pathname "subvolume"], [];
+    style = RErr, [String (PlainString, "qgroupid"); String (Pathname, "subvolume")], [];
     optional = Some "btrfs"; camel_name = "BTRFSQgroupDestroy";
     tests = [
       InitPartition, Always, TestRun (
@@ -9083,7 +9083,7 @@ Destroy a quota group." };
 
   { defaults with
     name = "btrfs_qgroup_show"; added = (1, 29, 17);
-    style = RStructList ("qgroups", "btrfsqgroup"), [Pathname "path"], [];
+    style = RStructList ("qgroups", "btrfsqgroup"), [String (Pathname, "path")], [];
     tests = [
       InitPartition, Always, TestRun (
         [["mkfs_btrfs"; "/dev/sda1"; ""; ""; "NOARG"; ""; "NOARG"; "NOARG"; ""; ""];
@@ -9101,7 +9101,7 @@ usages." };
 
   { defaults with
     name = "btrfs_qgroup_assign"; added = (1, 29, 17);
-    style = RErr, [String "src"; String "dst"; Pathname "path"], [];
+    style = RErr, [String (PlainString, "src"); String (PlainString, "dst"); String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSQgroupAssign";
     tests = [
       InitPartition, Always, TestRun (
@@ -9119,7 +9119,7 @@ several qgroups into a parent qgroup to share common limit." };
 
   { defaults with
     name = "btrfs_qgroup_remove"; added = (1, 29, 17);
-    style = RErr, [String "src"; String "dst"; Pathname "path"], [];
+    style = RErr, [String (PlainString, "src"); String (PlainString, "dst"); String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSQgroupRemove";
     tests = [
       InitPartition, Always, TestRun (
@@ -9137,7 +9137,7 @@ Remove qgroup C<src> from the parent qgroup C<dst>." };
 
   { defaults with
     name = "btrfs_scrub_start"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSScrubStart";
     tests = [
       InitPartition, Always, TestRun (
@@ -9153,7 +9153,7 @@ corrupt data." };
 
   { defaults with
     name = "btrfs_scrub_cancel"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSScrubCancel";
     test_excuse = "test disk isn't large enough that btrfs_scrub_start completes before we can cancel it";
     shortdesc = "cancel a running scrub";
@@ -9162,7 +9162,7 @@ Cancel a running scrub on a btrfs filesystem." };
 
   { defaults with
     name = "btrfs_scrub_resume"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSScrubResume";
     test_excuse = "test disk isn't large enough that btrfs_scrub_start completes before we can cancel and resume it";
     shortdesc = "resume a previously canceled or interrupted scrub";
@@ -9171,7 +9171,7 @@ Resume a previously canceled or interrupted scrub on a btrfs filesystem." };
 
 { defaults with
     name = "btrfs_balance_pause"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSBalancePause";
     test_excuse = "test disk isn't large enough to test this thoroughly";
     shortdesc = "pause a running balance";
@@ -9180,7 +9180,7 @@ Pause a running balance on a btrfs filesystem." };
 
 { defaults with
     name = "btrfs_balance_cancel"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSBalanceCancel";
     test_excuse = "test disk isn't large enough that btrfs_balance completes before we can cancel it";
     shortdesc = "cancel a running or paused balance";
@@ -9189,7 +9189,7 @@ Cancel a running balance on a btrfs filesystem." };
 
 { defaults with
     name = "btrfs_balance_resume"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [];
+    style = RErr, [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSBalanceResume";
     test_excuse = "test disk isn't large enough that btrfs_balance completes before we can pause and resume it";
     shortdesc = "resume a paused balance";
@@ -9198,7 +9198,7 @@ Resume a paused balance on a btrfs filesystem." };
 
   { defaults with
     name = "btrfs_filesystem_defragment"; added = (1, 29, 22);
-    style = RErr, [Pathname "path"], [OBool "flush"; OString "compress"];
+    style = RErr, [String (Pathname, "path")], [OBool "flush"; OString "compress"];
     optional = Some "btrfs"; camel_name = "BTRFSFilesystemDefragment";
     tests = [
       InitPartition, Always, TestRun (
@@ -9217,7 +9217,7 @@ Defragment a file or directory on a btrfs filesystem. compress is one of zlib or
 
   { defaults with
     name = "btrfs_rescue_chunk_recover"; added = (1, 29, 22);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "btrfs"; camel_name = "BTRFSRescueChunkRecover";
     tests = [
       InitPartition, Always, TestRun (
@@ -9230,7 +9230,7 @@ Recover the chunk tree of btrfs filesystem by scanning the devices one by one."
 
   { defaults with
     name = "btrfs_rescue_super_recover"; added = (1, 29, 22);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "btrfs"; camel_name = "BTRFSRescueSuperRecover";
     tests = [
       InitPartition, Always, TestRun (
@@ -9243,7 +9243,7 @@ Recover bad superblocks from good copies." };
 
   { defaults with
     name = "part_set_gpt_guid"; added = (1, 29, 25);
-    style = RErr, [Device "device"; Int "partnum"; GUID "guid"], [];
+    style = RErr, [String (Device, "device"); Int "partnum"; String (GUID, "guid")], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestLastFail (
@@ -9262,7 +9262,7 @@ valid GUID." };
 
   { defaults with
     name = "part_get_gpt_guid"; added = (1, 29, 25);
-    style = RString "guid", [Device "device"; Int "partnum"], [];
+    style = RString "guid", [String (Device, "device"); Int "partnum"], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestResultString (
@@ -9277,7 +9277,7 @@ Return the GUID of numbered GPT partition C<partnum>." };
 
 { defaults with
     name = "btrfs_balance_status"; added = (1, 29, 26);
-    style = RStruct ("status", "btrfsbalance"), [Pathname "path"], [];
+    style = RStruct ("status", "btrfsbalance"), [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSBalanceStatus";
     test_excuse = "test disk isn't large enough that btrfs_balance completes before we can get its status";
     shortdesc = "show the status of a running or paused balance";
@@ -9286,7 +9286,7 @@ Show the status of a running or paused balance on a btrfs filesystem." };
 
   { defaults with
     name = "btrfs_scrub_status"; added = (1, 29, 26);
-    style = RStruct ("status", "btrfsscrub"), [Pathname "path"], [];
+    style = RStruct ("status", "btrfsscrub"), [String (Pathname, "path")], [];
     optional = Some "btrfs"; camel_name = "BTRFSScrubStatus";
     tests = [
       InitPartition, Always, TestRun (
@@ -9301,7 +9301,7 @@ Show status of running or finished scrub on a btrfs filesystem." };
 
   { defaults with
     name = "btrfstune_seeding"; added = (1, 29, 29);
-    style = RErr, [Device "device"; Bool "seeding"], [];
+    style = RErr, [String (Device, "device"); Bool "seeding"], [];
     optional = Some "btrfs"; camel_name = "BTRFSTuneSeeding";
     tests = [
       InitPartition, Always, TestRun (
@@ -9317,7 +9317,7 @@ so that you can use it to build other filesystems." };
 
   { defaults with
     name = "btrfstune_enable_extended_inode_refs"; added = (1, 29, 29);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "btrfs"; camel_name = "BTRFSTuneEnableExtendedInodeRefs";
     tests = [
       InitPartition, Always, TestRun (
@@ -9331,7 +9331,7 @@ This will Enable extended inode refs." };
 
   { defaults with
     name = "btrfstune_enable_skinny_metadata_extent_refs"; added = (1, 29, 29);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "btrfs"; camel_name = "BTRFSTuneEnableSkinnyMetadataExtentRefs";
     tests = [
       InitPartition, Always, TestRun (
@@ -9345,7 +9345,7 @@ This enable skinny metadata extent refs." };
 
   { defaults with
     name = "btrfs_image"; added = (1, 29, 32);
-    style = RErr, [DeviceList "source"; Pathname "image"], [OInt "compresslevel"];
+    style = RErr, [StringList (Device, "source"); String (Pathname, "image")], [OInt "compresslevel"];
     optional = Some "btrfs"; camel_name = "BTRFSImage";
     tests = [
       InitEmpty, Always, TestRun (
@@ -9366,7 +9366,7 @@ All data will be zeroed, but metadata and the like is preserved." };
 
   { defaults with
     name = "part_get_mbr_part_type"; added = (1, 29, 32);
-    style = RString "partitiontype", [Device "device"; Int "partnum"], [];
+    style = RString "partitiontype", [String (Device, "device"); Int "partnum"], [];
     tests = [
       InitEmpty, Always, TestResultString (
         [["part_init"; "/dev/sda"; "mbr"];
@@ -9391,7 +9391,7 @@ It returns C<primary>, C<logical>, or C<extended>." };
 
   { defaults with
     name = "btrfs_replace"; added = (1, 29, 48);
-    style = RErr, [Device "srcdev"; Device "targetdev"; Pathname "mntpoint"], [];
+    style = RErr, [String (Device, "srcdev"); String (Device, "targetdev"); String (Pathname, "mntpoint")], [];
     optional = Some "btrfs"; camel_name = "BTRFSReplace";
     test_excuse = "put the test in 'tests/btrfs' directory";
     shortdesc = "replace a btrfs managed device with another device";
@@ -9406,7 +9406,7 @@ which are currently mounted are never allowed to be used as the C<targetdev>." }
 
   { defaults with
     name = "set_uuid_random"; added = (1, 29, 50);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     tests = [
         InitBasicFS, Always, TestRun (
             [["set_uuid_random"; "/dev/sda1"]]), [];
@@ -9424,7 +9424,7 @@ To read the UUID on a filesystem, call C<guestfs_vfs_uuid>." };
 
   { defaults with
     name = "vfs_minimum_size"; added = (1, 31, 18);
-    style = RInt64 "sizeinbytes", [Mountable "mountable"], [];
+    style = RInt64 "sizeinbytes", [String (Mountable, "mountable")], [];
     tests = [
       InitBasicFS, Always, TestRun (
         [["vfs_minimum_size"; "/dev/sda1"]]), [];
@@ -9452,7 +9452,7 @@ See also L<ntfsresize(8)>, L<resize2fs(8)>, L<btrfs(8)>, L<xfs_info(8)>." };
 
   { defaults with
     name = "internal_feature_available"; added = (1, 31, 25);
-    style = RInt "result", [String "group"], [];
+    style = RInt "result", [String (PlainString, "group")], [];
     visibility = VInternal;
     shortdesc = "test availability of some parts of the API";
     longdesc = "\
@@ -9460,7 +9460,7 @@ This is the internal call which implements C<guestfs_feature_available>." };
 
   { defaults with
     name = "part_set_disk_guid"; added = (1, 33, 2);
-    style = RErr, [Device "device"; GUID "guid"], [];
+    style = RErr, [String (Device, "device"); String (GUID, "guid")], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestLastFail (
@@ -9479,7 +9479,7 @@ or if C<guid> is not a valid GUID." };
 
   { defaults with
     name = "part_get_disk_guid"; added = (1, 33, 2);
-    style = RString "guid", [Device "device"], [];
+    style = RString "guid", [String (Device, "device")], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestResultString (
@@ -9495,7 +9495,7 @@ Behaviour is undefined for other partition types." };
 
   { defaults with
     name = "part_set_disk_guid_random"; added = (1, 33, 2);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "gdisk";
     tests = [
       InitGPT, Always, TestRun (
@@ -9509,7 +9509,7 @@ Return an error if the partition table of C<device> isn't GPT." };
 
   { defaults with
     name = "part_expand_gpt"; added = (1, 33, 2);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     optional = Some "gdisk";
     shortdesc = "move backup GPT header to the end of the disk";
     longdesc = "\
@@ -9522,7 +9522,7 @@ See also L<sgdisk(8)>." };
 
   { defaults with
     name = "ntfscat_i"; added = (1, 33, 14);
-    style = RErr, [Mountable "device"; Int64 "inode"; FileOut "filename"], [];
+    style = RErr, [String (Mountable, "device"); Int64 "inode"; String (FileOut, "filename")], [];
     progress = true; cancellable = true;
     shortdesc = "download a file to the local machine given its inode";
     longdesc = "\
@@ -9537,7 +9537,7 @@ otherwise the call will fail." };
 
   { defaults with
     name = "btrfs_filesystem_show"; added = (1, 33, 29);
-    style = RStringList "devices", [Device "device"], [];
+    style = RStringList "devices", [String (Device, "device")], [];
     optional = Some "btrfs"; camel_name = "BTRFSFilesystemsShow";
     tests = [
       InitScratchFS, Always, TestLastFail (
@@ -9563,7 +9563,7 @@ fails and the C<errno> is set to C<ENODEV>." };
 
   { defaults with
     name = "selinux_relabel"; added = (1, 33, 43);
-    style = RErr, [String "specfile"; Pathname "path"], [OBool "force"];
+    style = RErr, [String (PlainString, "specfile"); String (Pathname, "path")], [OBool "force"];
     optional = Some "selinuxrelabel";
     test_excuse = "tests are in the tests/relabel directory";
     shortdesc = "relabel parts of the filesystem";
@@ -9585,7 +9585,7 @@ user, role and range parts of the file context is changed." };
 
   { defaults with
     name = "mksquashfs"; added = (1, 35, 25);
-    style = RErr, [Pathname "path"; FileOut "filename"], [OString "compress"; OStringList "excludes"];
+    style = RErr, [String (Pathname, "path"); String (FileOut, "filename")], [OString "compress"; OStringList "excludes"];
     optional = Some "squashfs";
     cancellable = true;
     shortdesc = "create a squashfs filesystem";
diff --git a/generator/actions_core_deprecated.ml b/generator/actions_core_deprecated.ml
index 045b08643..66bd89409 100644
--- a/generator/actions_core_deprecated.ml
+++ b/generator/actions_core_deprecated.ml
@@ -55,7 +55,7 @@ Do not call this.  See: C<guestfs_shutdown> instead." };
 
   { defaults with
     name = "add_cdrom"; added = (0, 0, 3);
-    style = RErr, [String "filename"], [];
+    style = RErr, [String (PlainString, "filename")], [];
     deprecated_by = Replaced_by "add_drive_ro"; config_only = true;
     blocking = false;
     shortdesc = "add a CD-ROM disk image to examine";
@@ -67,7 +67,7 @@ of C<guestfs_add_drive_ro>." };
 
   { defaults with
     name = "add_drive_with_if"; added = (1, 0, 84);
-    style = RErr, [String "filename"; String "iface"], [];
+    style = RErr, [String (PlainString, "filename"); String (PlainString, "iface")], [];
     deprecated_by = Replaced_by "add_drive"; config_only = true;
     blocking = false;
     shortdesc = "add a drive specifying the QEMU block emulation to use";
@@ -77,7 +77,7 @@ to specify the QEMU interface emulation to use at run time." };
 
   { defaults with
     name = "add_drive_ro_with_if"; added = (1, 0, 84);
-    style = RErr, [String "filename"; String "iface"], [];
+    style = RErr, [String (PlainString, "filename"); String (PlainString, "iface")], [];
     blocking = false;
     deprecated_by = Replaced_by "add_drive"; config_only = true;
     shortdesc = "add a drive read-only specifying the QEMU block emulation to use";
@@ -87,7 +87,7 @@ to specify the QEMU interface emulation to use at run time." };
 
   { defaults with
     name = "lstatlist"; added = (1, 0, 77);
-    style = RStructList ("statbufs", "stat"), [Pathname "path"; FilenameList "names"], [];
+    style = RStructList ("statbufs", "stat"), [String (Pathname, "path"); StringList (Filename, "names")], [];
     deprecated_by = Replaced_by "lstatnslist";
     shortdesc = "lstat on multiple files";
     longdesc = "\
@@ -107,7 +107,7 @@ for getting extended attributes." };
 
   { defaults with
     name = "stat"; added = (1, 9, 2);
-    style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
+    style = RStruct ("statbuf", "stat"), [String (Pathname, "path")], [];
     deprecated_by = Replaced_by "statns";
     tests = [
       InitISOFS, Always, TestResult (
@@ -121,7 +121,7 @@ This is the same as the L<stat(2)> system call." };
 
   { defaults with
     name = "lstat"; added = (1, 9, 2);
-    style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
+    style = RStruct ("statbuf", "stat"), [String (Pathname, "path")], [];
     deprecated_by = Replaced_by "lstatns";
     tests = [
       InitISOFS, Always, TestResult (
@@ -142,9 +142,9 @@ This is the same as the L<lstat(2)> system call." };
 let daemon_functions = [
   { defaults with
     name = "sfdisk"; added = (0, 0, 8);
-    style = RErr, [Device "device";
+    style = RErr, [String (Device, "device");
                    Int "cyls"; Int "heads"; Int "sectors";
-                   StringList "lines"], [];
+                   StringList (PlainString, "lines")], [];
     deprecated_by = Replaced_by "part_add";
     shortdesc = "create partitions on a block device";
     longdesc = "\
@@ -173,7 +173,7 @@ C<guestfs_part_init>" };
 
   { defaults with
     name = "blockdev_setbsz"; added = (1, 9, 3);
-    style = RErr, [Device "device"; Int "blocksize"], [];
+    style = RErr, [String (Device, "device"); Int "blocksize"], [];
     deprecated_by = Deprecated_no_replacement;
     shortdesc = "set blocksize of block device";
     longdesc = "\
@@ -185,7 +185,7 @@ C<blocksize> option of C<guestfs_mkfs>." };
 
   { defaults with
     name = "tgz_in"; added = (1, 0, 3);
-    style = RErr, [FileIn "tarball"; Pathname "directory"], [];
+    style = RErr, [String (FileIn, "tarball"); String (Pathname, "directory")], [];
     deprecated_by = Replaced_by "tar_in";
     cancellable = true;
     tests = [
@@ -201,7 +201,7 @@ I<gzip compressed> tar file) into F<directory>." };
 
   { defaults with
     name = "tgz_out"; added = (1, 0, 3);
-    style = RErr, [Pathname "directory"; FileOut "tarball"], [];
+    style = RErr, [String (Pathname, "directory"); String (FileOut, "tarball")], [];
     deprecated_by = Replaced_by "tar_out";
     cancellable = true;
     shortdesc = "pack directory into compressed tarball";
@@ -211,7 +211,7 @@ it to local file C<tarball>." };
 
   { defaults with
     name = "set_e2label"; added = (1, 0, 15);
-    style = RErr, [Device "device"; String "label"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "label")], [];
     deprecated_by = Replaced_by "set_label";
     tests = [
       InitBasicFS, Always, TestResultString (
@@ -229,7 +229,7 @@ to return the existing label on a filesystem." };
 
   { defaults with
     name = "get_e2label"; added = (1, 0, 15);
-    style = RString "label", [Device "device"], [];
+    style = RString "label", [String (Device, "device")], [];
     deprecated_by = Replaced_by "vfs_label";
     shortdesc = "get the ext2/3/4 filesystem label";
     longdesc = "\
@@ -238,7 +238,7 @@ C<device>." };
 
   { defaults with
     name = "set_e2uuid"; added = (1, 0, 15);
-    style = RErr, [Device "device"; String "uuid"], [];
+    style = RErr, [String (Device, "device"); String (PlainString, "uuid")], [];
     deprecated_by = Replaced_by "set_uuid";
     tests = [
         InitBasicFS, Always, TestResultString (
@@ -266,7 +266,7 @@ of a filesystem." };
 
   { defaults with
     name = "get_e2uuid"; added = (1, 0, 15);
-    style = RString "uuid", [Device "device"], [];
+    style = RString "uuid", [String (Device, "device")], [];
     deprecated_by = Replaced_by "vfs_uuid";
     tests = [
       (* We can't predict what UUID will be, so just check
@@ -282,9 +282,9 @@ C<device>." };
 
   { defaults with
     name = "sfdisk_N"; added = (1, 0, 26);
-    style = RErr, [Device "device"; Int "partnum";
+    style = RErr, [String (Device, "device"); Int "partnum";
                    Int "cyls"; Int "heads"; Int "sectors";
-                   String "line"], [];
+                   String (PlainString, "line")], [];
     deprecated_by = Replaced_by "part_add";
     shortdesc = "modify a single partition on a block device";
     longdesc = "\
@@ -298,7 +298,7 @@ See also: C<guestfs_part_add>" };
 
   { defaults with
     name = "sfdisk_l"; added = (1, 0, 26);
-    style = RString "partitions", [Device "device"], [];
+    style = RString "partitions", [String (Device, "device")], [];
     deprecated_by = Replaced_by "part_list";
     shortdesc = "display the partition table";
     longdesc = "\
@@ -310,7 +310,7 @@ See also: C<guestfs_part_list>" };
 
   { defaults with
     name = "e2fsck_f"; added = (1, 0, 29);
-    style = RErr, [Device "device"], [];
+    style = RErr, [String (Device, "device")], [];
     deprecated_by = Replaced_by "e2fsck";
     shortdesc = "check an ext2/ext3 filesystem";
     longdesc = "\
@@ -320,7 +320,7 @@ even if the filesystem appears to be clean (I<-f>)." };
 
   { defaults with
     name = "mkswap_L"; added = (1, 0, 55);
-    style = RErr, [String "label"; Device "device"], [];
+    style = RErr, [String (PlainString, "label"); String (Device, "device")], [];
     deprecated_by = Replaced_by "mkswap";
     tests = [
       InitEmpty, Always, TestRun (
@@ -337,7 +337,7 @@ a limitation of the kernel or swap tools." };
 
   { defaults with
     name = "mkswap_U"; added = (1, 0, 55);
-    style = RErr, [String "uuid"; Device "device"], [];
+    style = RErr, [String (PlainString, "uuid"); String (Device, "device")], [];
     deprecated_by = Replaced_by "mkswap";
     optional = Some "linuxfsuuid";
     tests = [
@@ -351,7 +351,7 @@ Create a swap partition on C<device> with UUID C<uuid>." };
 
   { defaults with
     name = "sfdiskM"; added = (1, 0, 55);
-    style = RErr, [Device "device"; StringList "lines"], [];
+    style = RErr, [String (Device, "device"); StringList (PlainString, "lines")], [];
     deprecated_by = Replaced_by "part_add";
     shortdesc = "create partitions on a block device";
     longdesc = "\
@@ -366,7 +366,7 @@ and C<guestfs_part_disk>" };
 
   { defaults with
     name = "zfile"; added = (1, 0, 59);
-    style = RString "description", [String "meth"; Pathname "path"], [];
+    style = RString "description", [String (PlainString, "meth"); String (Pathname, "path")], [];
     deprecated_by = Replaced_by "file";
     shortdesc = "determine file type inside a compressed file";
     longdesc = "\
@@ -380,7 +380,7 @@ process compressed files." };
 
   { defaults with
     name = "egrep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -395,7 +395,7 @@ matching lines." };
 
   { defaults with
     name = "fgrep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "pattern"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "pattern"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -410,7 +410,7 @@ matching lines." };
 
   { defaults with
     name = "grepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -425,7 +425,7 @@ matching lines." };
 
   { defaults with
     name = "egrepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -440,7 +440,7 @@ matching lines." };
 
   { defaults with
     name = "fgrepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "pattern"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "pattern"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -455,7 +455,7 @@ matching lines." };
 
   { defaults with
     name = "zgrep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -470,7 +470,7 @@ matching lines." };
 
   { defaults with
     name = "zegrep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -485,7 +485,7 @@ matching lines." };
 
   { defaults with
     name = "zfgrep"; added = (1, 0, 66);
-    style = RStringList "lines", [String "pattern"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "pattern"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -500,7 +500,7 @@ matching lines." };
 
   { defaults with
     name = "zgrepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
 
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
@@ -516,7 +516,7 @@ matching lines." };
 
   { defaults with
     name = "zegrepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "regex"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "regex"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -531,7 +531,7 @@ matching lines." };
 
   { defaults with
     name = "zfgrepi"; added = (1, 0, 66);
-    style = RStringList "lines", [String "pattern"; Pathname "path"], [];
+    style = RStringList "lines", [String (PlainString, "pattern"); String (Pathname, "path")], [];
     protocol_limit_warning = true;
     deprecated_by = Replaced_by "grep";
     tests = [
@@ -546,7 +546,7 @@ matching lines." };
 
   { defaults with
     name = "fallocate"; added = (1, 0, 66);
-    style = RErr, [Pathname "path"; Int "len"], [];
+    style = RErr, [String (Pathname, "path"); Int "len"], [];
     deprecated_by = Replaced_by "fallocate64";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -565,7 +565,7 @@ attaches it as a device." };
 
   { defaults with
     name = "setcon"; added = (1, 0, 67);
-    style = RErr, [String "context"], [];
+    style = RErr, [String (PlainString, "context")], [];
     optional = Some "selinux";
     deprecated_by = Replaced_by "selinux_relabel";
     shortdesc = "set SELinux security context";
@@ -589,7 +589,7 @@ and C<guestfs_setcon>" };
 
   { defaults with
     name = "mkfs_b"; added = (1, 0, 68);
-    style = RErr, [String "fstype"; Int "blocksize"; Device "device"], [];
+    style = RErr, [String (PlainString, "fstype"); Int "blocksize"; String (Device, "device")], [];
     deprecated_by = Replaced_by "mkfs";
     tests = [
       InitEmpty, Always, TestResultString (
@@ -626,7 +626,7 @@ the requested cluster size." };
 
   { defaults with
     name = "mke2journal"; added = (1, 0, 68);
-    style = RErr, [Int "blocksize"; Device "device"], [];
+    style = RErr, [Int "blocksize"; String (Device, "device")], [];
     deprecated_by = Replaced_by "mke2fs";
     tests = [
       InitEmpty, Always, TestResultString (
@@ -648,7 +648,7 @@ to the command:
 
   { defaults with
     name = "mke2journal_L"; added = (1, 0, 68);
-    style = RErr, [Int "blocksize"; String "label"; Device "device"], [];
+    style = RErr, [Int "blocksize"; String (PlainString, "label"); String (Device, "device")], [];
     deprecated_by = Replaced_by "mke2fs";
     tests = [
       InitEmpty, Always, TestResultString (
@@ -667,7 +667,7 @@ This creates an ext2 external journal on C<device> with label C<label>." };
 
   { defaults with
     name = "mke2journal_U"; added = (1, 0, 68);
-    style = RErr, [Int "blocksize"; String "uuid"; Device "device"], [];
+    style = RErr, [Int "blocksize"; String (PlainString, "uuid"); String (Device, "device")], [];
     deprecated_by = Replaced_by "mke2fs";
     optional = Some "linuxfsuuid";
     tests = [
@@ -687,7 +687,7 @@ This creates an ext2 external journal on C<device> with UUID C<uuid>." };
 
   { defaults with
     name = "mke2fs_J"; added = (1, 0, 68);
-    style = RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"], [];
+    style = RErr, [String (PlainString, "fstype"); Int "blocksize"; String (Device, "device"); String (Device, "journal")], [];
     deprecated_by = Replaced_by "mke2fs";
     shortdesc = "make ext2/3/4 filesystem with external journal";
     longdesc = "\
@@ -701,7 +701,7 @@ See also C<guestfs_mke2journal>." };
 
   { defaults with
     name = "mke2fs_JL"; added = (1, 0, 68);
-    style = RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"], [];
+    style = RErr, [String (PlainString, "fstype"); Int "blocksize"; String (Device, "device"); String (PlainString, "label")], [];
     deprecated_by = Replaced_by "mke2fs";
     shortdesc = "make ext2/3/4 filesystem with external journal";
     longdesc = "\
@@ -712,7 +712,7 @@ See also C<guestfs_mke2journal_L>." };
 
   { defaults with
     name = "mke2fs_JU"; added = (1, 0, 68);
-    style = RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"], [];
+    style = RErr, [String (PlainString, "fstype"); Int "blocksize"; String (Device, "device"); String (PlainString, "uuid")], [];
     deprecated_by = Replaced_by "mke2fs";
     optional = Some "linuxfsuuid";
     shortdesc = "make ext2/3/4 filesystem with external journal";
@@ -724,7 +724,7 @@ See also C<guestfs_mke2journal_U>." };
 
   { defaults with
     name = "dd"; added = (1, 0, 80);
-    style = RErr, [Dev_or_Path "src"; Dev_or_Path "dest"], [];
+    style = RErr, [String (Dev_or_Path, "src"); String (Dev_or_Path, "dest")], [];
     deprecated_by = Replaced_by "copy_device_to_device";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -748,7 +748,7 @@ This command cannot do partial copies
 
   { defaults with
     name = "txz_in"; added = (1, 3, 2);
-    style = RErr, [FileIn "tarball"; Pathname "directory"], [];
+    style = RErr, [String (FileIn, "tarball"); String (Pathname, "directory")], [];
     deprecated_by = Replaced_by "tar_in";
     optional = Some "xz"; cancellable = true;
     tests = [
@@ -764,7 +764,7 @@ I<xz compressed> tar file) into F<directory>." };
 
   { defaults with
     name = "txz_out"; added = (1, 3, 2);
-    style = RErr, [Pathname "directory"; FileOut "tarball"], [];
+    style = RErr, [String (Pathname, "directory"); String (FileOut, "tarball")], [];
     deprecated_by = Replaced_by "tar_out";
     optional = Some "xz"; cancellable = true;
     shortdesc = "pack directory into compressed tarball";
@@ -774,7 +774,7 @@ it to local file C<tarball> (as an xz compressed tar archive)." };
 
   { defaults with
     name = "llz"; added = (1, 17, 6);
-    style = RString "listing", [Pathname "directory"], [];
+    style = RString "listing", [String (Pathname, "directory")], [];
     deprecated_by = Replaced_by "lgetxattrs";
     shortdesc = "list the files in a directory (long format with SELinux contexts)";
     longdesc = "\
@@ -785,7 +785,7 @@ is I<not> intended that you try to parse the output string." };
 
   { defaults with
     name = "write_file"; added = (0, 0, 8);
-    style = RErr, [Pathname "path"; String "content"; Int "size"], [];
+    style = RErr, [String (Pathname, "path"); String (PlainString, "content"); Int "size"], [];
     protocol_limit_warning = true; deprecated_by = Replaced_by "write";
     (* Regression test for RHBZ#597135. *)
     tests = [
@@ -807,7 +807,7 @@ characters does I<not> work, even if the length is specified." };
 
   { defaults with
     name = "copy_size"; added = (1, 0, 87);
-    style = RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"], [];
+    style = RErr, [String (Dev_or_Path, "src"); String (Dev_or_Path, "dest"); Int64 "size"], [];
     progress = true; deprecated_by = Replaced_by "copy_device_to_device";
     tests = [
       InitScratchFS, Always, TestResult (
@@ -827,7 +827,7 @@ is not large enough." };
 
   { defaults with
     name = "ntfsresize_size"; added = (1, 3, 14);
-    style = RErr, [Device "device"; Int64 "size"], [];
+    style = RErr, [String (Device, "device"); Int64 "size"], [];
     optional = Some "ntfsprogs"; deprecated_by = Replaced_by "ntfsresize";
     shortdesc = "resize an NTFS filesystem (with size)";
     longdesc = "\
diff --git a/generator/actions_debug.ml b/generator/actions_debug.ml
index 959a9415f..68fc4ef79 100644
--- a/generator/actions_debug.ml
+++ b/generator/actions_debug.ml
@@ -38,7 +38,7 @@ not part of the formal API and can be removed or changed at any time." };
 let daemon_functions = [
   { defaults with
     name = "debug"; added = (1, 0, 11);
-    style = RString "result", [String "subcmd"; StringList "extraargs"], [];
+    style = RString "result", [String (PlainString, "subcmd"); StringList (PlainString, "extraargs")], [];
     visibility = VDebug;
     shortdesc = "debugging and internals";
     longdesc = "\
@@ -52,7 +52,7 @@ to find out what you can do." };
 
   { defaults with
     name = "debug_upload"; added = (1, 3, 5);
-    style = RErr, [FileIn "filename"; String "tmpname"; Int "mode"], [];
+    style = RErr, [String (FileIn, "filename"); String (PlainString, "tmpname"); Int "mode"], [];
     visibility = VDebug;
     cancellable = true;
     shortdesc = "upload a file to the appliance (internal use only)";
diff --git a/generator/actions_hivex.ml b/generator/actions_hivex.ml
index 9f14e2ebc..5369a292d 100644
--- a/generator/actions_hivex.ml
+++ b/generator/actions_hivex.ml
@@ -44,7 +44,7 @@ data." };
 let daemon_functions = [
   { defaults with
     name = "hivex_open"; added = (1, 19, 35);
-    style = RErr, [Pathname "filename"], [OBool "verbose"; OBool "debug"; OBool "write"; OBool "unsafe"];
+    style = RErr, [String (Pathname, "filename")], [OBool "verbose"; OBool "debug"; OBool "write"; OBool "unsafe"];
     optional = Some "hivex";
     tests = [
       InitScratchFS, Always, TestRun (
@@ -105,7 +105,7 @@ This is a wrapper around the L<hivex(3)> call of the same name." };
 
   { defaults with
     name = "hivex_node_get_child"; added = (1, 19, 35);
-    style = RInt64 "child", [Int64 "nodeh"; String "name"], [];
+    style = RInt64 "child", [Int64 "nodeh"; String (PlainString, "name")], [];
     optional = Some "hivex";
     shortdesc = "return the named child of node";
     longdesc = "\
@@ -136,7 +136,7 @@ This is a wrapper around the L<hivex(3)> call of the same name." };
 
   { defaults with
     name = "hivex_node_get_value"; added = (1, 19, 35);
-    style = RInt64 "valueh", [Int64 "nodeh"; String "key"], [];
+    style = RInt64 "valueh", [Int64 "nodeh"; String (PlainString, "key")], [];
     optional = Some "hivex";
     shortdesc = "return the named value";
     longdesc = "\
@@ -206,7 +206,7 @@ This is a wrapper around the L<hivex(3)> call of the same name." };
 
   { defaults with
     name = "hivex_node_add_child"; added = (1, 19, 35);
-    style = RInt64 "nodeh", [Int64 "parent"; String "name"], [];
+    style = RInt64 "nodeh", [Int64 "parent"; String (PlainString, "name")], [];
     optional = Some "hivex";
     shortdesc = "add a child node";
     longdesc = "\
@@ -226,7 +226,7 @@ This is a wrapper around the L<hivex(3)> call of the same name." };
 
   { defaults with
     name = "hivex_node_set_value"; added = (1, 19, 35);
-    style = RErr, [Int64 "nodeh"; String "key"; Int64 "t"; BufferIn "val"], [];
+    style = RErr, [Int64 "nodeh"; String (PlainString, "key"); Int64 "t"; BufferIn "val"], [];
     optional = Some "hivex";
     shortdesc = "set or replace a single value in a node";
     longdesc = "\
diff --git a/generator/actions_inspection.ml b/generator/actions_inspection.ml
index 9c0c19c28..0312fbd8b 100644
--- a/generator/actions_inspection.ml
+++ b/generator/actions_inspection.ml
@@ -62,7 +62,7 @@ See also C<guestfs_list_filesystems>." };
 
   { defaults with
     name = "inspect_get_type"; added = (1, 5, 3);
-    style = RString "name", [Mountable "root"], [];
+    style = RString "name", [String (Mountable, "root")], [];
     shortdesc = "get type of inspected operating system";
     longdesc = "\
 This returns the type of the inspected operating system.
@@ -115,7 +115,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_arch"; added = (1, 5, 3);
-    style = RString "arch", [Mountable "root"], [];
+    style = RString "arch", [String (Mountable, "root")], [];
     shortdesc = "get architecture of inspected operating system";
     longdesc = "\
 This returns the architecture of the inspected operating system.
@@ -129,7 +129,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_distro"; added = (1, 5, 3);
-    style = RString "distro", [Mountable "root"], [];
+    style = RString "distro", [String (Mountable, "root")], [];
     shortdesc = "get distro of inspected operating system";
     longdesc = "\
 This returns the distro (distribution) of the inspected operating
@@ -285,7 +285,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_major_version"; added = (1, 5, 3);
-    style = RInt "major", [Mountable "root"], [];
+    style = RInt "major", [String (Mountable, "root")], [];
     shortdesc = "get major version of inspected operating system";
     longdesc = "\
 This returns the major version number of the inspected operating
@@ -304,7 +304,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_minor_version"; added = (1, 5, 3);
-    style = RInt "minor", [Mountable "root"], [];
+    style = RInt "minor", [String (Mountable, "root")], [];
     shortdesc = "get minor version of inspected operating system";
     longdesc = "\
 This returns the minor version number of the inspected operating
@@ -317,7 +317,7 @@ See also C<guestfs_inspect_get_major_version>." };
 
   { defaults with
     name = "inspect_get_product_name"; added = (1, 5, 3);
-    style = RString "product", [Mountable "root"], [];
+    style = RString "product", [String (Mountable, "root")], [];
     shortdesc = "get product name of inspected operating system";
     longdesc = "\
 This returns the product name of the inspected operating
@@ -332,7 +332,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_mountpoints"; added = (1, 5, 3);
-    style = RHashtable "mountpoints", [Mountable "root"], [];
+    style = RHashtable "mountpoints", [String (Mountable, "root")], [];
     shortdesc = "get mountpoints of inspected operating system";
     longdesc = "\
 This returns a hash of where we think the filesystems
@@ -363,7 +363,7 @@ See also C<guestfs_inspect_get_filesystems>." };
 
   { defaults with
     name = "inspect_get_filesystems"; added = (1, 5, 3);
-    style = RStringList "filesystems", [Mountable "root"], [];
+    style = RStringList "filesystems", [String (Mountable, "root")], [];
     shortdesc = "get filesystems associated with inspected operating system";
     longdesc = "\
 This returns a list of all the filesystems that we think
@@ -379,7 +379,7 @@ See also C<guestfs_inspect_get_mountpoints>." };
 
   { defaults with
     name = "inspect_get_windows_systemroot"; added = (1, 5, 25);
-    style = RString "systemroot", [Mountable "root"], [];
+    style = RString "systemroot", [String (Mountable, "root")], [];
     shortdesc = "get Windows systemroot of inspected operating system";
     longdesc = "\
 This returns the Windows systemroot of the inspected guest.
@@ -407,7 +407,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_package_format"; added = (1, 7, 5);
-    style = RString "packageformat", [Mountable "root"], [];
+    style = RString "packageformat", [String (Mountable, "root")], [];
     shortdesc = "get package format used by the operating system";
     longdesc = "\
 This function and C<guestfs_inspect_get_package_management> return
@@ -429,7 +429,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_package_management"; added = (1, 7, 5);
-    style = RString "packagemanagement", [Mountable "root"], [];
+    style = RString "packagemanagement", [String (Mountable, "root")], [];
     shortdesc = "get package management tool used by the operating system";
     longdesc = "\
 C<guestfs_inspect_get_package_format> and this function return
@@ -451,7 +451,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_list_applications2"; added = (1, 19, 56);
-    style = RStructList ("applications2", "application2"), [Mountable "root"], [];
+    style = RStructList ("applications2", "application2"), [String (Mountable, "root")], [];
     shortdesc = "get list of applications installed in the operating system";
     longdesc = "\
 Return the list of applications installed in the operating system.
@@ -554,7 +554,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_hostname"; added = (1, 7, 9);
-    style = RString "hostname", [Mountable "root"], [];
+    style = RString "hostname", [String (Mountable, "root")], [];
     shortdesc = "get hostname of the operating system";
     longdesc = "\
 This function returns the hostname of the operating system
@@ -567,7 +567,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_format"; added = (1, 9, 4);
-    style = RString "format", [Mountable "root"], [];
+    style = RString "format", [String (Mountable, "root")], [];
     shortdesc = "get format of inspected operating system";
     longdesc = "\
 This returns the format of the inspected operating system.  You
@@ -599,7 +599,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_is_live"; added = (1, 9, 4);
-    style = RBool "live", [Mountable "root"], [];
+    style = RBool "live", [String (Mountable, "root")], [];
     shortdesc = "get live flag for install disk";
     longdesc = "\
 If C<guestfs_inspect_get_format> returns C<installer> (this
@@ -610,7 +610,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_is_netinst"; added = (1, 9, 4);
-    style = RBool "netinst", [Mountable "root"], [];
+    style = RBool "netinst", [String (Mountable, "root")], [];
     shortdesc = "get netinst (network installer) flag for install disk";
     longdesc = "\
 If C<guestfs_inspect_get_format> returns C<installer> (this
@@ -623,7 +623,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_is_multipart"; added = (1, 9, 4);
-    style = RBool "multipart", [Mountable "root"], [];
+    style = RBool "multipart", [String (Mountable, "root")], [];
     shortdesc = "get multipart flag for install disk";
     longdesc = "\
 If C<guestfs_inspect_get_format> returns C<installer> (this
@@ -634,7 +634,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_product_variant"; added = (1, 9, 13);
-    style = RString "variant", [Mountable "root"], [];
+    style = RString "variant", [String (Mountable, "root")], [];
     shortdesc = "get product variant of inspected operating system";
     longdesc = "\
 This returns the product variant of the inspected operating
@@ -662,7 +662,7 @@ C<guestfs_inspect_get_major_version>." };
 
   { defaults with
     name = "inspect_get_windows_current_control_set"; added = (1, 9, 17);
-    style = RString "controlset", [Mountable "root"], [];
+    style = RString "controlset", [String (Mountable, "root")], [];
     shortdesc = "get Windows CurrentControlSet of inspected operating system";
     longdesc = "\
 This returns the Windows CurrentControlSet of the inspected guest.
@@ -676,7 +676,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_drive_mappings"; added = (1, 9, 17);
-    style = RHashtable "drives", [Mountable "root"], [];
+    style = RHashtable "drives", [String (Mountable, "root")], [];
     shortdesc = "get drive letter mappings";
     longdesc = "\
 This call is useful for Windows which uses a primitive system
@@ -710,7 +710,7 @@ C<guestfs_inspect_get_filesystems>." };
 
   { defaults with
     name = "inspect_get_icon"; added = (1, 11, 12);
-    style = RBufferOut "icon", [Mountable "root"],  [OBool "favicon"; OBool "highquality"];
+    style = RBufferOut "icon", [String (Mountable, "root")],  [OBool "favicon"; OBool "highquality"];
     shortdesc = "get the icon corresponding to this operating system";
     longdesc = "\
 This function returns an icon corresponding to the inspected
@@ -775,7 +775,7 @@ advice before using trademarks in applications.
 
   { defaults with
     name = "inspect_get_windows_software_hive"; added = (1, 35, 26);
-    style = RString "path", [Mountable "root"], [];
+    style = RString "path", [String (Mountable, "root")], [];
     shortdesc = "get the path of the Windows software hive";
     longdesc = "\
 This returns the path to the hive (binary Windows Registry file)
@@ -792,7 +792,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
     name = "inspect_get_windows_system_hive"; added = (1, 35, 26);
-    style = RString "path", [Mountable "root"], [];
+    style = RString "path", [String (Mountable, "root")], [];
     shortdesc = "get the path of the Windows system hive";
     longdesc = "\
 This returns the path to the hive (binary Windows Registry file)
diff --git a/generator/actions_inspection_deprecated.ml b/generator/actions_inspection_deprecated.ml
index 5ca062cbe..342b0c8cd 100644
--- a/generator/actions_inspection_deprecated.ml
+++ b/generator/actions_inspection_deprecated.ml
@@ -25,7 +25,7 @@ open Types
 let non_daemon_functions = [
   { defaults with
     name = "inspect_list_applications"; added = (1, 7, 8);
-    style = RStructList ("applications", "application"), [Mountable "root"], [];
+    style = RStructList ("applications", "application"), [String (Mountable, "root")], [];
     deprecated_by = Replaced_by "inspect_list_applications2";
     shortdesc = "get list of applications installed in the operating system";
     longdesc = "\
diff --git a/generator/actions_internal_tests.ml b/generator/actions_internal_tests.ml
index 18d56bbfa..7ac7a8934 100644
--- a/generator/actions_internal_tests.ml
+++ b/generator/actions_internal_tests.ml
@@ -23,14 +23,14 @@ open Types
 (* These test functions are used in the language binding tests. *)
 
 let test_all_args = [
-  String "str";
+  String (PlainString, "str");
   OptString "optstr";
-  StringList "strlist";
+  StringList (PlainString, "strlist");
   Bool "b";
   Int "integer";
   Int64 "integer64";
-  FileIn "filein";
-  FileOut "fileout";
+  String (FileIn, "filein");
+  String (FileOut, "fileout");
   BufferIn "bufferin";
 ]
 
@@ -112,7 +112,7 @@ You probably don't want to call this function." }
     fun (name, ret) -> [
       { defaults with
         name = name;
-        style = ret, [String "val"], [];
+        style = ret, [String (PlainString, "val")], [];
         visibility = VBindTest;
         blocking = false;
         shortdesc = "internal test function - do not use";
@@ -145,7 +145,7 @@ You probably don't want to call this function." }
 let test_support_functions = [
   { defaults with
     name = "internal_test_set_output";
-    style = RErr, [String "filename"], [];
+    style = RErr, [String (PlainString, "filename")], [];
     visibility = VBindTest;
     blocking = false;
     shortdesc = "internal test function - do not use";
diff --git a/generator/actions_properties.ml b/generator/actions_properties.ml
index 87144b14f..ef31ffa5a 100644
--- a/generator/actions_properties.ml
+++ b/generator/actions_properties.ml
@@ -25,7 +25,7 @@ open Types
 let non_daemon_functions = [
   { defaults with
     name = "set_hv"; added = (1, 23, 17);
-    style = RErr, [String "hv"], [];
+    style = RErr, [String (PlainString, "hv")], [];
     fish_alias = ["hv"]; config_only = true;
     blocking = false;
     shortdesc = "set the hypervisor binary";
@@ -314,7 +314,7 @@ This returns the enable network flag." };
 
   { defaults with
     name = "set_backend"; added = (1, 21, 26);
-    style = RErr, [String "backend"], [];
+    style = RErr, [String (PlainString, "backend")], [];
     fish_alias = ["backend"]; config_only = true;
     blocking = false;
     shortdesc = "set the backend";
@@ -438,7 +438,7 @@ Get the directory used by the handle to store the appliance cache." };
 
   { defaults with
     name = "set_program"; added = (1, 21, 29);
-    style = RErr, [String "program"], [];
+    style = RErr, [String (PlainString, "program")], [];
     fish_alias = ["program"];
     blocking = false;
     shortdesc = "set the program name";
@@ -481,7 +481,7 @@ See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
 
   { defaults with
     name = "set_backend_settings"; added = (1, 25, 24);
-    style = RErr, [StringList "settings"], [];
+    style = RErr, [StringList (PlainString, "settings")], [];
     config_only = true;
     blocking = false;
     shortdesc = "replace per-backend settings strings";
@@ -505,7 +505,7 @@ See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
 
   { defaults with
     name = "get_backend_setting"; added = (1, 27, 2);
-    style = RString "val", [String "name"], [];
+    style = RString "val", [String (PlainString, "name")], [];
     blocking = false;
     shortdesc = "get a single per-backend settings string";
     longdesc = "\
@@ -522,7 +522,7 @@ See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
 
   { defaults with
     name = "set_backend_setting"; added = (1, 27, 2);
-    style = RErr, [String "name"; String "val"], [];
+    style = RErr, [String (PlainString, "name"); String (PlainString, "val")], [];
     config_only = true;
     blocking = false;
     shortdesc = "set a single per-backend settings string";
@@ -535,7 +535,7 @@ See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
 
   { defaults with
     name = "clear_backend_setting"; added = (1, 27, 2);
-    style = RInt "count", [String "name"], [];
+    style = RInt "count", [String (PlainString, "name")], [];
     config_only = true;
     blocking = false;
     shortdesc = "remove a single per-backend settings string";
@@ -551,7 +551,7 @@ See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
 
   { defaults with
     name = "set_identifier"; added = (1, 31, 14);
-    style = RErr, [String "identifier"], [];
+    style = RErr, [String (PlainString, "identifier")], [];
     fish_alias = ["identifier"];
     blocking = false;
     shortdesc = "set the handle identifier";
diff --git a/generator/actions_properties_deprecated.ml b/generator/actions_properties_deprecated.ml
index f36509e75..c1d988bff 100644
--- a/generator/actions_properties_deprecated.ml
+++ b/generator/actions_properties_deprecated.ml
@@ -99,7 +99,7 @@ see L<guestfs(3)>." };
 
   { defaults with
     name = "set_attach_method"; added = (1, 9, 8);
-    style = RErr, [String "backend"], [];
+    style = RErr, [String (PlainString, "backend")], [];
     fish_alias = ["attach-method"]; config_only = true;
     blocking = false;
     deprecated_by = Replaced_by "set_backend";
diff --git a/generator/actions_tsk.ml b/generator/actions_tsk.ml
index 6e09b7d41..88605bac3 100644
--- a/generator/actions_tsk.ml
+++ b/generator/actions_tsk.ml
@@ -25,7 +25,7 @@ open Types
 let non_daemon_functions = [
   { defaults with
     name = "filesystem_walk"; added = (1, 33, 39);
-    style = RStructList ("dirents", "tsk_dirent"), [Mountable "device";], [];
+    style = RStructList ("dirents", "tsk_dirent"), [String (Mountable, "device");], [];
     optional = Some "libtsk";
     progress = true; cancellable = true;
     shortdesc = "walk through the filesystem content";
@@ -173,7 +173,7 @@ Unknown file type
 
   { defaults with
     name = "find_inode"; added = (1, 35, 6);
-    style = RStructList ("dirents", "tsk_dirent"), [Mountable "device"; Int64 "inode";], [];
+    style = RStructList ("dirents", "tsk_dirent"), [String (Mountable, "device"); Int64 "inode";], [];
     optional = Some "libtsk";
     progress = true; cancellable = true;
     shortdesc = "search the entries associated to the given inode";
@@ -188,7 +188,7 @@ See C<filesystem_walk> for more information about C<tsk_dirent> structures." };
 let daemon_functions = [
   { defaults with
     name = "download_inode"; added = (1, 33, 14);
-    style = RErr, [Mountable "device"; Int64 "inode"; FileOut "filename"], [];
+    style = RErr, [String (Mountable, "device"); Int64 "inode"; String (FileOut, "filename")], [];
     optional = Some "sleuthkit";
     progress = true; cancellable = true;
     shortdesc = "download a file to the local machine given its inode";
@@ -202,7 +202,7 @@ The command is capable of downloading deleted or inaccessible files." };
 
   { defaults with
     name = "internal_filesystem_walk"; added = (1, 33, 39);
-    style = RErr, [Mountable "device"; FileOut "filename"], [];
+    style = RErr, [String (Mountable, "device"); String (FileOut, "filename")], [];
     visibility = VInternal;
     optional = Some "libtsk";
     shortdesc = "walk through the filesystem content";
@@ -210,7 +210,7 @@ The command is capable of downloading deleted or inaccessible files." };
 
   { defaults with
     name = "download_blocks"; added = (1, 33, 45);
-    style = RErr, [Mountable "device"; Int64 "start"; Int64 "stop"; FileOut "filename"], [OBool "unallocated"];
+    style = RErr, [String (Mountable, "device"); Int64 "start"; Int64 "stop"; String (FileOut, "filename")], [OBool "unallocated"];
     optional = Some "sleuthkit";
     progress = true; cancellable = true;
     shortdesc = "download the given data units from the disk";
@@ -233,7 +233,7 @@ which data units have not been overwritten yet." };
 
   { defaults with
     name = "internal_find_inode"; added = (1, 35, 6);
-    style = RErr, [Mountable "device"; Int64 "inode"; FileOut "filename";], [];
+    style = RErr, [String (Mountable, "device"); Int64 "inode"; String (FileOut, "filename");], [];
     visibility = VInternal;
     optional = Some "libtsk";
     shortdesc = "search the entries associated to the given inode";
diff --git a/generator/bindtests.ml b/generator/bindtests.ml
index 8ac503181..c3caebfce 100644
--- a/generator/bindtests.ml
+++ b/generator/bindtests.ml
@@ -153,13 +153,7 @@ fill_lvm_pv (guestfs_h *g, struct guestfs_lvm_pv *pv, size_t i)
 
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n -> pr "  fprintf (fp, \"%%s\\n\", %s);\n" n
+        | String (_, n) -> pr "  fprintf (fp, \"%%s\\n\", %s);\n" n
         | BufferIn n ->
           pr "  {\n";
           pr "    size_t i;\n";
@@ -167,10 +161,12 @@ fill_lvm_pv (guestfs_h *g, struct guestfs_lvm_pv *pv, size_t i)
           pr "      fprintf (fp, \"<%%02x>\", (unsigned) %s[i]);\n" n;
           pr "    fprintf (fp, \"\\n\");\n";
           pr "  }\n";
-        | OptString n -> pr "  fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | OptString n ->
+           pr "  fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
+        | StringList (_, n) ->
           pr "  print_strings (g, %s);\n" n
-        | Bool n -> pr "  fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
+        | Bool n ->
+           pr "  fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
         | Int n -> pr "  fprintf (fp, \"%%d\\n\", %s);\n" n
         | Int64 n -> pr "  fprintf (fp, \"%%\" PRIi64 \"\\n\", %s);\n" n
         | Pointer _ -> assert false
diff --git a/generator/c.ml b/generator/c.ml
index 606c89807..1c3ad027f 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -110,28 +110,23 @@ let rec generate_prototype ?(extern = true) ?(static = false)
   in
   List.iter (
     function
-    | Pathname n
-    | Device n | Dev_or_Path n
-    | String n
-    | OptString n
-    | Key n
-    | GUID n ->
+    | String ((PlainString|Device|Dev_or_Path|Pathname|Key|GUID|Filename), n)
+    | OptString n ->
         next ();
         pr "const char *%s" n
-    | Mountable n | Mountable_or_Path n ->
+    | String ((Mountable|Mountable_or_Path), n) ->
         next();
         if in_daemon then
           pr "const mountable_t *%s" n
         else
           pr "const char *%s" n
-    | StringList n | DeviceList n | FilenameList n ->
+    | StringList (_, n) ->
         next ();
         pr "char *const *%s" n
     | Bool n -> next (); pr "int %s" n
     | Int n -> next (); pr "int %s" n
     | Int64 n -> next (); pr "int64_t %s" n
-    | FileIn n
-    | FileOut n ->
+    | String ((FileIn|FileOut), n) ->
         if not in_daemon then (next (); pr "const char *%s" n)
     | BufferIn n ->
         next ();
@@ -177,7 +172,7 @@ and generate_c_call_args ?handle ?(implicit_size_ptr = "&size")
     | BufferIn n ->
         next ();
         pr "%s, %s_size" n n
-    | Mountable n | Mountable_or_Path n ->
+    | String ((Mountable|Mountable_or_Path), n) ->
         next ();
         (if in_daemon then pr "&%s" else pr "%s") n
     | arg ->
@@ -291,7 +286,7 @@ I<The caller must free the returned buffer after use>.\n\n"
     pr "%s\n\n" progress_message;
   if f.protocol_limit_warning then
     pr "%s\n\n" protocol_limit_warning;
-  if List.exists (function Key _ -> true | _ -> false) args then
+  if List.exists (function String (Key, _) -> true | _ -> false) args then
     pr "This function takes a key or passphrase parameter which
 could contain sensitive material.  Read the section
 L</KEYS AND PASSPHRASES> for more information.\n\n";
@@ -1372,20 +1367,10 @@ and generate_client_actions actions () =
     List.iter (
       function
       (* parameters which should not be NULL *)
-      | String n
-      | Device n
-      | Mountable n
-      | Pathname n
-      | Dev_or_Path n | Mountable_or_Path n
-      | FileIn n
-      | FileOut n
+      | String (_, n)
       | BufferIn n
-      | StringList n
-      | DeviceList n
-      | Key n
-      | Pointer (_, n)
-      | GUID n
-      | FilenameList n ->
+      | StringList (_, n)
+      | Pointer (_, n) ->
           pr "  if (%s == NULL) {\n" n;
           pr "    error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
           pr "           \"%s\", \"%s\");\n" c_name n;
@@ -1476,7 +1461,7 @@ and generate_client_actions actions () =
     let pr_newline = ref false in
     List.iter (
       function
-      | GUID n ->
+      | String (GUID, n) ->
           pr "  if (!guestfs_int_validate_guid (%s)) {\n" n;
           pr "    error (g, \"%%s: %%s: parameter is not a valid GUID\",\n";
           pr "           \"%s\", \"%s\");\n" c_name n;
@@ -1488,7 +1473,7 @@ and generate_client_actions actions () =
           pr "  }\n";
           pr_newline := true
 
-      | FilenameList n ->
+      | StringList (Filename, n) ->
           pr "  {\n";
           pr "    size_t i;\n";
           pr "    for (i = 0; %s[i] != NULL; ++i) {\n" n;
@@ -1506,17 +1491,11 @@ and generate_client_actions actions () =
           pr_newline := true
 
       (* not applicable *)
-      | String _
-      | Device _
-      | Mountable _
-      | Pathname _
-      | Dev_or_Path _ | Mountable_or_Path _
-      | FileIn _
-      | FileOut _
+      | String ((PlainString|Device|Mountable|Pathname|
+                 Dev_or_Path|Mountable_or_Path|
+                 FileIn|FileOut|Key|Filename), _)
       | BufferIn _
       | StringList _
-      | DeviceList _
-      | Key _
       | Pointer (_, _)
       | OptString _
       | Bool _
@@ -1533,7 +1512,7 @@ and generate_client_actions actions () =
 
     let needs_i =
       List.exists (function
-      | StringList _ | DeviceList _ | FilenameList _ -> true
+      | StringList _ -> true
       | _ -> false) args ||
       List.exists (function
       | OStringList _ -> true
@@ -1550,17 +1529,11 @@ and generate_client_actions actions () =
     (* Required arguments. *)
     List.iter (
       function
-      | String n			(* strings *)
-      | Device n
-      | Mountable n
-      | Pathname n
-      | Dev_or_Path n | Mountable_or_Path n
-      | FileIn n
-      | FileOut n
-      | GUID n ->
+      | String ((PlainString|Device|Mountable|Pathname|Filename
+                 |Dev_or_Path|Mountable_or_Path|FileIn|FileOut|GUID), n) ->
           (* guestfish doesn't support string escaping, so neither do we *)
           pr "    fprintf (trace_buffer.fp, \" \\\"%%s\\\"\", %s);\n" n
-      | Key n ->
+      | String (Key, n) ->
           (* don't print keys *)
           pr "    fprintf (trace_buffer.fp, \" \\\"***\\\"\");\n"
       | OptString n ->			(* string option *)
@@ -1568,9 +1541,7 @@ and generate_client_actions actions () =
           pr "      fprintf (trace_buffer.fp, \" \\\"%%s\\\"\", %s);\n" n;
           pr "    else\n";
           pr "      fprintf (trace_buffer.fp, \" null\");\n"
-      | StringList n
-      | DeviceList n
-      | FilenameList n ->			(* string list *)
+      | StringList (_, n) ->
           pr "    fputc (' ', trace_buffer.fp);\n";
           pr "    fputc ('\"', trace_buffer.fp);\n";
           pr "    for (i = 0; %s[i]; ++i) {\n" n;
@@ -1812,7 +1783,7 @@ and generate_client_actions actions () =
     handle_null_optargs optargs c_name;
 
     let args_passed_to_daemon =
-      List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
+      List.filter (function String ((FileIn| FileOut), _) -> false | _ -> true)
         args in
     (match args_passed_to_daemon, optargs with
     | [], [] -> ()
@@ -1848,7 +1819,7 @@ and generate_client_actions actions () =
     );
 
     let has_filein =
-      List.exists (function FileIn _ -> true | _ -> false) args in
+      List.exists (function String (FileIn, _) -> true | _ -> false) args in
     if has_filein then (
       pr "  uint64_t progress_hint = 0;\n";
       pr "  struct stat progress_stat;\n";
@@ -1867,7 +1838,7 @@ and generate_client_actions actions () =
      *)
     List.iter (
       function
-      | FileIn n ->
+      | String (FileIn, n) ->
         pr "  if (stat (%s, &progress_stat) == 0 &&\n" n;
         pr "      S_ISREG (progress_stat.st_mode))\n";
         pr "    progress_hint += progress_stat.st_size;\n";
@@ -1890,13 +1861,11 @@ and generate_client_actions actions () =
     ) else (
       List.iter (
         function
-        | Pathname n | Device n | Mountable n | Dev_or_Path n 
-        | Mountable_or_Path n | String n
-        | Key n | GUID n ->
+        | String (_, n) ->
           pr "  args.%s = (char *) %s;\n" n n
         | OptString n ->
           pr "  args.%s = %s ? (char **) &%s : NULL;\n" n n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
           pr "  args.%s.%s_val = (char **) %s;\n" n n n;
           pr "  for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
         | Bool n ->
@@ -1915,7 +1884,7 @@ and generate_client_actions actions () =
           pr "  }\n";
           pr "  args.%s.%s_val = (char *) %s;\n" n n n;
           pr "  args.%s.%s_len = %s_size;\n" n n n
-        | FileIn _ | FileOut _ | Pointer _ -> assert false
+        | Pointer _ -> assert false
       ) args_passed_to_daemon;
 
       List.iter (
@@ -1963,7 +1932,7 @@ and generate_client_actions actions () =
     let need_read_reply_label = ref false in
     List.iter (
       function
-      | FileIn n ->
+      | String (FileIn, n) ->
         pr "  r = guestfs_int_send_file (g, %s);\n" n;
         pr "  if (r == -1) {\n";
         trace_return_error ~indent:4 name style errcode;
@@ -2026,7 +1995,7 @@ and generate_client_actions actions () =
     (* Expecting to receive further files (FileOut)? *)
     List.iter (
       function
-      | FileOut n ->
+      | String (FileOut, n) ->
         pr "  if (guestfs_int_recv_file (g, %s) == -1) {\n" n;
         trace_return_error ~indent:4 name style errcode;
         pr "    return %s;\n" (string_of_errcode errcode);
diff --git a/generator/csharp.ml b/generator/csharp.ml
index 39fb7bf99..8181a26a6 100644
--- a/generator/csharp.ml
+++ b/generator/csharp.ml
@@ -190,15 +190,11 @@ namespace Guestfs
           (c_return_type ()) c_function;
         List.iter (
           function
-          | Pathname n | Device n | Mountable n
-          | Dev_or_Path n | Mountable_or_Path n | String n
+          | String (_, n)
           | OptString n
-          | FileIn n | FileOut n
-          | Key n
-          | BufferIn n
-          | GUID n ->
+          | BufferIn n ->
               pr ", [In] string %s" n
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
               pr ", [In] string[] %s" n
           | Bool n ->
               pr ", bool %s" n
@@ -219,15 +215,11 @@ namespace Guestfs
         in
         List.iter (
           function
-          | Pathname n | Device n | Mountable n
-          | Dev_or_Path n | Mountable_or_Path n | String n
+          | String (_, n)
           | OptString n
-          | FileIn n | FileOut n
-          | Key n
-          | BufferIn n
-          | GUID n ->
+          | BufferIn n ->
               next (); pr "string %s" n
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
               next (); pr "string[] %s" n
           | Bool n ->
               next (); pr "bool %s" n
diff --git a/generator/daemon.ml b/generator/daemon.ml
index e4ab7cc3e..b00627063 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -62,8 +62,8 @@ let generate_daemon_actions_h () =
     fun { name = name; style = ret, args, optargs } ->
       let args_passed_to_daemon = args @ args_of_optargs optargs in
       let args_passed_to_daemon =
-        List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
-          args_passed_to_daemon in
+        List.filter (function String ((FileIn|FileOut), _) -> false | _ -> true)
+                    args_passed_to_daemon in
       let style = ret, args_passed_to_daemon, [] in
       generate_prototype
         ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
@@ -123,8 +123,8 @@ let generate_daemon_stubs actions () =
 
       let args_passed_to_daemon = args @ args_of_optargs optargs in
       let args_passed_to_daemon =
-        List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
-          args_passed_to_daemon in
+        List.filter (function String ((FileIn|FileOut), _) -> false | _ -> true)
+                    args_passed_to_daemon in
 
       if args_passed_to_daemon <> [] then (
         pr "#ifdef HAVE_ATTRIBUTE_CLEANUP\n";
@@ -170,16 +170,17 @@ let generate_daemon_stubs actions () =
         pr "  memset (&args, 0, sizeof args);\n";
         List.iter (
           function
-          | Device n | Dev_or_Path n ->
+          | String ((Device|Dev_or_Path), n) ->
             pr "  CLEANUP_FREE char *%s = NULL;\n" n
-          | Pathname n | String n | Key n | OptString n | GUID n ->
+          | String ((Pathname|PlainString|Key|GUID), n)
+          | OptString n ->
             pr "  const char *%s;\n" n
-          | Mountable n | Mountable_or_Path n ->
+          | String ((Mountable|Mountable_or_Path), n) ->
             pr "  CLEANUP_FREE_MOUNTABLE mountable_t %s\n" n;
             pr "      = { .device = NULL, .volume = NULL };\n"
-          | StringList n | FilenameList n ->
+          | StringList ((PlainString|Filename), n) ->
             pr "  char **%s;\n" n
-          | DeviceList n ->
+          | StringList (Device, n) ->
             pr "  CLEANUP_FREE_STRING_LIST char **%s = NULL;\n" n
           | Bool n -> pr "  int %s;\n" n
           | Int n -> pr "  int %s;\n" n
@@ -187,13 +188,16 @@ let generate_daemon_stubs actions () =
           | BufferIn n ->
               pr "  const char *%s;\n" n;
               pr "  size_t %s_size;\n" n
-          | FileIn _ | FileOut _ | Pointer _ -> assert false
+          | String ((FileIn|FileOut|Filename), _)
+          | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
+                         |Dev_or_Path|Mountable_or_Path), _)
+          | Pointer _ -> assert false
         ) args_passed_to_daemon
       );
       pr "\n";
 
       let is_filein =
-        List.exists (function FileIn _ -> true | _ -> false) args in
+        List.exists (function String (FileIn, _) -> true | _ -> false) args in
 
       (* Reject Optional functions that are not available (RHBZ#679737). *)
       (match optional with
@@ -246,24 +250,24 @@ let generate_daemon_stubs actions () =
         in
         List.iter (
           function
-          | Pathname n ->
+          | String (Pathname, n) ->
               pr_args n;
               pr "  ABS_PATH (%s, %b, return);\n" n is_filein;
-          | Device n ->
+          | String (Device, n) ->
               pr "  RESOLVE_DEVICE (args.%s, %s, %b);\n" n n is_filein;
-          | Mountable n ->
+          | String (Mountable, n) ->
               pr "  RESOLVE_MOUNTABLE (args.%s, %s, %b);\n" n n is_filein;
-          | Dev_or_Path n ->
+          | String (Dev_or_Path, n) ->
               pr "  REQUIRE_ROOT_OR_RESOLVE_DEVICE (args.%s, %s, %b);\n"
                 n n is_filein;
-          | Mountable_or_Path n ->
+          | String (Mountable_or_Path, n) ->
               pr "  REQUIRE_ROOT_OR_RESOLVE_MOUNTABLE (args.%s, %s, %b);\n"
                 n n is_filein;
-          | String n | Key n | GUID n -> pr_args n
+          | String ((PlainString|Key|GUID), n) -> pr_args n
           | OptString n -> pr "  %s = args.%s ? *args.%s : NULL;\n" n n n
-          | StringList n | FilenameList n as arg ->
+          | StringList ((PlainString|Filename) as arg, n) ->
             (match arg with
-            | FilenameList n ->
+            | Filename ->
               pr "  {\n";
               pr "    size_t i;\n";
               pr "    for (i = 0; i < args.%s.%s_len; ++i) {\n" n n;
@@ -289,7 +293,7 @@ let generate_daemon_stubs actions () =
             pr "  }\n";
             pr "  %s[args.%s.%s_len] = NULL;\n" n n n;
             pr "  args.%s.%s_val = %s;\n" n n n
-          | DeviceList n ->
+          | StringList (Device, n) ->
             pr "  /* Copy the string list and apply device name translation\n";
             pr "   * to each one.\n";
             pr "   */\n";
@@ -307,13 +311,17 @@ let generate_daemon_stubs actions () =
           | BufferIn n ->
               pr "  %s = args.%s.%s_val;\n" n n n;
               pr "  %s_size = args.%s.%s_len;\n" n n n
-          | FileIn _ | FileOut _ | Pointer _ -> assert false
+          | String ((FileIn|FileOut|Filename), _)
+          | StringList ((Mountable|Pathname|FileIn|FileOut|Key|GUID
+                         |Dev_or_Path|Mountable_or_Path), _)
+          | Pointer _ -> assert false
         ) args_passed_to_daemon;
         pr "\n"
       );
 
       (* this is used at least for do_equal *)
-      if List.exists (function Pathname _ -> true | _ -> false) args then (
+      if List.exists (function String (Pathname, _) -> true
+                             | _ -> false) args then (
         (* Emit NEED_ROOT just once, even when there are two or
            more Pathname args *)
         pr "  NEED_ROOT (%b, return);\n" is_filein
@@ -325,7 +333,7 @@ let generate_daemon_stubs actions () =
       let () =
         let args' =
           List.filter
-            (function FileIn _ | FileOut _ -> false | _ -> true) args in
+            (function String ((FileIn|FileOut), _) -> false | _ -> true) args in
         let style = ret, args' @ args_of_optargs optargs, [] in
         pr "  r = do_%s " name;
         generate_c_call_args ~in_daemon:true style;
@@ -359,7 +367,7 @@ let generate_daemon_stubs actions () =
        * send its own reply.
        *)
       let no_reply =
-        List.exists (function FileOut _ -> true | _ -> false) args in
+        List.exists (function String (FileOut, _) -> true | _ -> false) args in
       if no_reply then
         pr "  /* do_%s has already sent a reply */\n" name
       else (
diff --git a/generator/erlang.ml b/generator/erlang.ml
index d0d219805..602380966 100644
--- a/generator/erlang.ml
+++ b/generator/erlang.ml
@@ -361,13 +361,7 @@ instead of erl_interface.
       iteri (
         fun i ->
           function
-          | Pathname n
-          | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-          | String n
-          | FileIn n
-          | FileOut n
-          | Key n
-          | GUID n ->
+          | String (_, n) ->
             pr "  CLEANUP_FREE char *%s = erl_iolist_to_string (ARG (%d));\n" n i
           | OptString n ->
             pr "  CLEANUP_FREE char *%s;\n" n;
@@ -379,7 +373,7 @@ instead of erl_interface.
             pr "  ETERM *%s_bin = erl_iolist_to_binary (ARG (%d));\n" n i;
             pr "  const void *%s = ERL_BIN_PTR (%s_bin);\n" n n;
             pr "  size_t %s_size = ERL_BIN_SIZE (%s_bin);\n" n n
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
             pr "  CLEANUP_FREE_STRING_LIST char **%s = get_string_list (ARG (%d));\n" n i
           | Bool n ->
             pr "  int %s = get_bool (ARG (%d));\n" n i
diff --git a/generator/fish.ml b/generator/fish.ml
index c3180be35..45289132f 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -176,19 +176,16 @@ let generate_fish_run_cmds actions () =
       );
       List.iter (
         function
-        | Device n | Mountable n
-        | String n
         | OptString n
-        | GUID n -> pr "  const char *%s;\n" n
-        | Pathname n
-        | Dev_or_Path n | Mountable_or_Path n
-        | FileIn n
-        | FileOut n
-        | Key n -> pr "  char *%s;\n" n
+        | String ((PlainString|Device|Mountable|GUID|Filename), n) ->
+           pr "  const char *%s;\n" n
+        | String ((Pathname|Dev_or_Path|Mountable_or_Path
+                   |FileIn|FileOut|Key), n) ->
+           pr "  char *%s;\n" n
         | BufferIn n ->
             pr "  const char *%s;\n" n;
             pr "  size_t %s_size;\n" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  char **%s;\n" n
         | Bool n -> pr "  int %s;\n" n
         | Int n -> pr "  int %s;\n" n
@@ -209,7 +206,7 @@ let generate_fish_run_cmds actions () =
       (* Check and convert parameters. *)
       let argc_minimum, argc_maximum =
         let args_no_keys =
-          List.filter (function Key _ -> false | _ -> true) args in
+          List.filter (function String (Key, _) -> false | _ -> true) args in
         let argc_minimum = List.length args_no_keys in
         let argc_maximum = argc_minimum + List.length optargs in
         argc_minimum, argc_maximum in
@@ -257,11 +254,9 @@ let generate_fish_run_cmds actions () =
 
       List.iter (
         function
-        | Device name | Mountable name
-        | String name | GUID name ->
+        | String ((Device|Mountable|PlainString|GUID|Filename), name) ->
             pr "  %s = argv[i++];\n" name
-        | Pathname name
-        | Dev_or_Path name | Mountable_or_Path name ->
+        | String ((Pathname|Dev_or_Path|Mountable_or_Path), name) ->
             pr "  %s = win_prefix (argv[i++]); /* process \"win:\" prefix */\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
         | OptString name ->
@@ -271,16 +266,16 @@ let generate_fish_run_cmds actions () =
             pr "  %s = argv[i];\n" name;
             pr "  %s_size = strlen (argv[i]);\n" name;
             pr "  i++;\n"
-        | FileIn name ->
+        | String (FileIn, name) ->
             pr "  %s = file_in (argv[i++]);\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
-        | FileOut name ->
+        | String (FileOut, name) ->
             pr "  %s = file_out (argv[i++]);\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
-        | StringList name | DeviceList name | FilenameList name ->
+        | StringList (_, name) ->
             pr "  %s = parse_string_list (argv[i++]);\n" name;
             pr "  if (%s == NULL) goto out_%s;\n" name name
-        | Key name ->
+        | String (Key, name) ->
             pr "  %s = read_key (\"%s\");\n" name name;
             pr "  if (keys_from_stdin)\n";
             pr "    input_lineno++;\n";
@@ -477,21 +472,19 @@ let generate_fish_run_cmds actions () =
       ) (List.rev optargs);
       List.iter (
         function
-        | Device _ | Mountable _ | String _
+        | String ((Device|Mountable|PlainString|GUID|Filename), _)
         | OptString _
-        | BufferIn _
-        | GUID _ -> ()
+        | BufferIn _ -> ()
         | Bool name
         | Int name | Int64 name ->
             pr " out_%s:\n" name
-        | Pathname name | Dev_or_Path name | Mountable_or_Path name
-        | FileOut name | Key name ->
+        | String ((Pathname|Dev_or_Path|Mountable_or_Path|FileOut|Key), name) ->
             pr "  free (%s);\n" name;
             pr " out_%s:\n" name
-        | FileIn name ->
+        | String (FileIn, name) ->
             pr "  free_file_in (%s);\n" name;
             pr " out_%s:\n" name
-        | StringList name | DeviceList name | FilenameList name ->
+        | StringList (_, name) ->
             pr "  guestfs_int_free_string_list (%s);\n" name;
             pr " out_%s:\n" name
         | Pointer _ -> assert false
@@ -548,7 +541,9 @@ let generate_fish_cmd_entries actions () =
         match args with
         | [] -> name2
         | args ->
-            let args = List.filter (function Key _ -> false | _ -> true) args in
+            let args =
+              List.filter (function String (Key, _) -> false
+                                  | _ -> true) args in
             sprintf "%s%s%s"
               name2
               (String.concat ""
@@ -559,7 +554,7 @@ let generate_fish_cmd_entries actions () =
                   ) optargs)) in
 
       let warnings =
-        if List.exists (function Key _ -> true | _ -> false) args then
+        if List.exists (function String (Key, _) -> true | _ -> false) args then
           "\n\nThis command has one or more key or passphrase parameters.
 Guestfish will prompt for these separately."
         else "" in
@@ -912,19 +907,18 @@ and generate_fish_actions_pod () =
       pr " %s" name;
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n
-        | GUID n ->
+        | String ((Pathname|Device|Mountable|Dev_or_Path|Mountable_or_Path
+                   |PlainString|GUID|Filename), n) ->
             pr " %s" n
         | OptString n -> pr " %s" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr " '%s ...'" n
         | Bool _ -> pr " true|false"
         | Int n -> pr " %s" n
         | Int64 n -> pr " %s" n
-        | FileIn n | FileOut n -> pr " (%s|-)" n
+        | String ((FileIn|FileOut), n) -> pr " (%s|-)" n
         | BufferIn n -> pr " %s" n
-        | Key _ -> () (* keys are entered at a prompt *)
+        | String (Key, _) -> () (* keys are entered at a prompt *)
         | Pointer _ -> assert false
       ) args;
       List.iter (
@@ -934,11 +928,11 @@ and generate_fish_actions_pod () =
       pr "\n";
       pr "%s\n\n" longdesc;
 
-      if List.exists (function FileIn _ | FileOut _ -> true
+      if List.exists (function String ((FileIn|FileOut), _) -> true
                       | _ -> false) args then
         pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
 
-      if List.exists (function Key _ -> true | _ -> false) args then
+      if List.exists (function String (Key, _) -> true | _ -> false) args then
         pr "This command has one or more key or passphrase parameters.
 Guestfish will prompt for these separately.\n\n";
 
diff --git a/generator/golang.ml b/generator/golang.ml
index fe74f446e..f32ccf2c1 100644
--- a/generator/golang.ml
+++ b/generator/golang.ml
@@ -307,19 +307,9 @@ func return_hashtable (argv **C.char) map[string]string {
           | Bool n -> pr "%s bool" n
           | Int n -> pr "%s int" n
           | Int64 n -> pr "%s int64" n
-          | String n
-          | Device n
-          | Mountable n
-          | Pathname n
-          | Dev_or_Path n
-          | Mountable_or_Path n
-          | Key n
-          | FileIn n | FileOut n
-          | GUID n -> pr "%s string" n
+          | String (_, n) -> pr "%s string" n
           | OptString n -> pr "%s *string" n
-          | StringList n
-          | DeviceList n
-          | FilenameList n -> pr "%s []string" n
+          | StringList (_, n) -> pr "%s []string" n
           | BufferIn n -> pr "%s []byte" n
           | Pointer (_, n) -> pr "%s int64" n
       ) args;
@@ -364,15 +354,7 @@ func return_hashtable (argv **C.char) map[string]string {
           pr "\n";
           pr "    var c_%s C.int\n" n;
           pr "    if %s { c_%s = 1 } else { c_%s = 0 }\n" n n n
-        | String n
-        | Device n
-        | Mountable n
-        | Pathname n
-        | Dev_or_Path n
-        | Mountable_or_Path n
-        | Key n
-        | FileIn n | FileOut n
-        | GUID n ->
+        | String (_, n) ->
           pr "\n";
           pr "    c_%s := C.CString (%s)\n" n n;
           pr "    defer C.free (unsafe.Pointer (c_%s))\n" n
@@ -383,9 +365,7 @@ func return_hashtable (argv **C.char) map[string]string {
           pr "        c_%s = C.CString (*%s)\n" n n;
           pr "        defer C.free (unsafe.Pointer (c_%s))\n" n;
           pr "    }\n"
-        | StringList n
-        | DeviceList n
-        | FilenameList n ->
+        | StringList (_, n) ->
           pr "\n";
           pr "    c_%s := arg_string_list (%s)\n" n n;
           pr "    defer free_string_list (c_%s)\n" n
@@ -449,19 +429,9 @@ func return_hashtable (argv **C.char) map[string]string {
           | Bool n -> pr "c_%s" n
           | Int n -> pr "C.int (%s)" n
           | Int64 n -> pr "C.int64_t (%s)" n
-          | String n
-          | Device n
-          | Mountable n
-          | Pathname n
-          | Dev_or_Path n
-          | Mountable_or_Path n
-          | OptString n
-          | Key n
-          | FileIn n | FileOut n
-          | GUID n -> pr "c_%s" n
-          | StringList n
-          | DeviceList n
-          | FilenameList n -> pr "c_%s" n
+          | String (_, n)
+          | OptString n -> pr "c_%s" n
+          | StringList (_, n) -> pr "c_%s" n
           | BufferIn n -> pr "c_%s, C.size_t (len (%s))" n n
           | Pointer _ -> pr "nil"
       ) args;
diff --git a/generator/haskell.ml b/generator/haskell.ml
index 1ab2820df..592d817fa 100644
--- a/generator/haskell.ml
+++ b/generator/haskell.ml
@@ -141,16 +141,12 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
         (* Convert pointer arguments using with* functions. *)
         List.iter (
           function
-          | FileIn n
-          | FileOut n
-          | Pathname n | Device n | Mountable n
-          | Dev_or_Path n | Mountable_or_Path n | String n
-          | Key n | GUID n ->
+          | String (_, n) ->
               pr "withCString %s $ \\%s -> " n n
           | BufferIn n ->
               pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
           | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
               pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
           | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
         ) args;
@@ -161,12 +157,9 @@ assocListOfHashtable (a:b:rest) = (a,b) : assocListOfHashtable rest
             | Bool n -> sprintf "(fromBool %s)" n
             | Int n -> sprintf "(fromIntegral %s)" n
             | Int64 n | Pointer (_, n) -> sprintf "(fromIntegral %s)" n
-            | FileIn n | FileOut n
-            | Pathname n | Device n | Mountable n
-            | Dev_or_Path n | Mountable_or_Path n
-            | String n | OptString n
-            | StringList n | DeviceList n | FilenameList n
-            | Key n | GUID n -> n
+            | String (_, n)
+            | OptString n
+            | StringList (_, n) -> n
             | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
           ) args in
         pr "withForeignPtr h (\\p -> c_%s %s)\n" name
@@ -220,22 +213,18 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
     List.iter (
       fun arg ->
         (match arg with
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _
-        | Key _ | GUID _ ->
-          pr "CString"
-        | BufferIn _ ->
-          pr "CString -> CInt"
-        | OptString _ ->
-          pr "CString"
-        | StringList _ | DeviceList _ | FilenameList _ ->
-          pr "Ptr CString"
-        | Bool _ -> pr "CInt"
-        | Int _ -> pr "CInt"
-        | Int64 _ -> pr "Int64"
-        | Pointer _ -> pr "CInt"
-        | FileIn _ -> pr "CString"
-        | FileOut _ -> pr "CString"
+         | String _ ->
+            pr "CString"
+         | BufferIn _ ->
+            pr "CString -> CInt"
+         | OptString _ ->
+            pr "CString"
+         | StringList _ ->
+            pr "Ptr CString"
+         | Bool _ -> pr "CInt"
+         | Int _ -> pr "CInt"
+         | Int64 _ -> pr "Int64"
+         | Pointer _ -> pr "CInt"
         );
         pr " -> ";
     ) args;
@@ -263,22 +252,18 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
     List.iter (
       fun arg ->
         (match arg with
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _
-        | Key _ | GUID _ ->
-          pr "String"
-        | BufferIn _ ->
-          pr "String"
-        | OptString _ ->
-          pr "Maybe String"
-        | StringList _ | DeviceList _ | FilenameList _ ->
-          pr "[String]"
-        | Bool _ -> pr "Bool"
-        | Int _ -> pr "Int"
-        | Int64 _ -> pr "Integer"
-        | Pointer _ -> pr "Int"
-        | FileIn _ -> pr "String"
-        | FileOut _ -> pr "String"
+         | String _ ->
+           pr "String"
+         | BufferIn _ ->
+           pr "String"
+         | OptString _ ->
+           pr "Maybe String"
+         | StringList _ ->
+           pr "[String]"
+         | Bool _ -> pr "Bool"
+         | Int _ -> pr "Int"
+         | Int64 _ -> pr "Integer"
+         | Pointer _ -> pr "Int"
         );
         pr " -> ";
     ) args;
diff --git a/generator/java.ml b/generator/java.ml
index eec1ab116..c44e669a0 100644
--- a/generator/java.ml
+++ b/generator/java.ml
@@ -503,18 +503,12 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
       needs_comma := true;
 
       match arg with
-      | Pathname n
-      | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-      | String n
-      | OptString n
-      | FileIn n
-      | FileOut n
-      | Key n
-      | GUID n ->
+      | String (_, n)
+      | OptString n ->
           pr "String %s" n
       | BufferIn n ->
           pr "byte[] %s" n
-      | StringList n | DeviceList n | FilenameList n ->
+      | StringList (_, n) ->
           pr "String[] %s" n
       | Bool n ->
           pr "boolean %s" n
@@ -641,18 +635,12 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
       pr "  (JNIEnv *env, jobject obj, jlong jg";
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | OptString n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n ->
+        | String (_, n)
+        | OptString n ->
             pr ", jstring j%s" n
         | BufferIn n ->
             pr ", jbyteArray j%s" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr ", jobjectArray j%s" n
         | Bool n ->
             pr ", jboolean j%s" n
@@ -713,19 +701,13 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
 
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | OptString n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n ->
+        | String (_, n)
+        | OptString n ->
             pr "  const char *%s;\n" n
         | BufferIn n ->
             pr "  char *%s;\n" n;
             pr "  size_t %s_size;\n" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  size_t %s_len;\n" n;
             pr "  CLEANUP_FREE char **%s = NULL;\n" n
         | Bool n
@@ -758,7 +740,6 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
          | RString _ | RBufferOut _ | RStruct _ -> false) ||
           List.exists (function
           | StringList _ -> true
-          | DeviceList _ -> true
           | _ -> false) args ||
           List.exists (function
           | OStringList _ -> true
@@ -772,13 +753,7 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
       let add_ret_error_label = ref false in
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n ->
+        | String (_, n) ->
             pr "  %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
         | OptString n ->
             (* This is completely undocumented, but Java null becomes
@@ -788,7 +763,7 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
         | BufferIn n ->
             pr "  %s = (char *) (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
             pr "  %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
             pr "  %s = malloc (sizeof (char *) * (%s_len+1));\n" n n;
             pr "  if (%s == NULL) {\n" n;
@@ -850,20 +825,14 @@ throw_out_of_memory (JNIEnv *env, const char *msg)
       (* Release the parameters. *)
       List.iter (
         function
-        | Pathname n
-        | Device n | Mountable n | Dev_or_Path n | Mountable_or_Path n
-        | String n
-        | FileIn n
-        | FileOut n
-        | Key n
-        | GUID n ->
+        | String (_, n) ->
             pr "  (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
         | OptString n ->
             pr "  if (j%s)\n" n;
             pr "    (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
         | BufferIn n ->
             pr "  (*env)->ReleaseByteArrayElements (env, j%s, (jbyte *) %s, 0);\n" n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  for (i = 0; i < %s_len; ++i) {\n" n;
             pr "    jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
               n;
diff --git a/generator/lua.ml b/generator/lua.ml
index e48bb3eff..c4ab4cc47 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -468,16 +468,14 @@ guestfs_int_lua_delete_event_callback (lua_State *L)
 
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n
-        | FileIn n | FileOut n | Key n | GUID n ->
+        | String (_, n) ->
           pr "  const char *%s;\n" n
         | BufferIn n ->
           pr "  const char *%s;\n" n;
           pr "  size_t %s_size;\n" n;
         | OptString n ->
           pr "  const char *%s;\n" n;
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
           pr "  char **%s;\n" n
         | Bool n -> pr "  int %s;\n" n
         | Int n -> pr "  int %s;\n" n
@@ -499,15 +497,13 @@ guestfs_int_lua_delete_event_callback (lua_State *L)
         fun i ->
           let i = i+2 in (* Lua indexes from 1(!), plus the handle. *)
           function
-          | Pathname n | Device n | Mountable n
-          | Dev_or_Path n | Mountable_or_Path n | String n
-          | FileIn n | FileOut n | Key n | GUID n ->
+          | String (_, n) ->
             pr "  %s = luaL_checkstring (L, %d);\n" n i
           | BufferIn n ->
             pr "  %s = luaL_checklstring (L, %d, &%s_size);\n" n i n
           | OptString n ->
             pr "  %s = luaL_optstring (L, %d, NULL);\n" n i
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
             pr "  %s = get_string_list (L, %d);\n" n i
           | Bool n ->
             pr "  %s = lua_toboolean (L, %d);\n" n i
@@ -561,13 +557,10 @@ guestfs_int_lua_delete_event_callback (lua_State *L)
       (* Free temporary data. *)
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _
-        | FileIn _ | FileOut _ | Key _
-        | BufferIn _ | OptString _
+        | String _ | BufferIn _ | OptString _
         | Bool _ | Int _ | Int64 _
-        | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | Pointer _ -> ()
+        | StringList (_, n) ->
           pr "  free (%s);\n" n
       ) args;
       List.iter (
diff --git a/generator/perl.ml b/generator/perl.ml
index d1b4763b8..beb6bab5a 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -356,9 +356,7 @@ PREINIT:
       iteri (
         fun i ->
           function
-          | Pathname n | Device n | Mountable n
-          | Dev_or_Path n | Mountable_or_Path n | String n
-          | FileIn n | FileOut n | Key n | GUID n ->
+          | String (_, n) ->
               pr "      char *%s;\n" n
           | BufferIn n ->
               pr "      char *%s;\n" n;
@@ -369,7 +367,7 @@ PREINIT:
                * to add 1 to the ST(x) operator.
                *)
               pr "      char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
-          | StringList n | DeviceList n | FilenameList n ->
+          | StringList (_, n) ->
               pr "      char **%s;\n" n
           | Bool n -> pr "      int %s;\n" n
           | Int n -> pr "      int %s;\n" n
@@ -511,12 +509,11 @@ PREINIT:
       (* Cleanup any arguments. *)
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _
-        | OptString _ | Bool _ | Int _ | Int64 _
-        | FileIn _ | FileOut _
-        | BufferIn _ | Key _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | String _ | OptString _
+        | Bool _ | Int _ | Int64 _
+        | BufferIn _
+        | Pointer _ -> ()
+        | StringList (_, n) ->
             pr "      free (%s);\n" n
       ) args;
 
@@ -953,25 +950,29 @@ C<$g-E<gt>feature-available>.\n\n" opt
       );
       pr ",\n";
       let pr_type i = function
-        | Pathname n -> pr "[ '%s', 'string(path)', %d ]" n i
-        | Device n -> pr "[ '%s', 'string(device)', %d ]" n i
-        | Mountable n -> pr "[ '%s', 'string(mountable)', %d ]" n i
-        | Dev_or_Path n -> pr "[ '%s', 'string(dev_or_path)', %d ]" n i
-        | Mountable_or_Path n ->
-          pr "[ '%s', 'string(mountable_or_path)', %d ]" n i
-        | String n | GUID n -> pr "[ '%s', 'string', %d ]" n i
-        | FileIn n -> pr "[ '%s', 'string(filename)', %d ]" n i
-        | FileOut n -> pr "[ '%s', 'string(filename)', %d ]" n i
-        | Key n -> pr "[ '%s', 'string(key)', %d ]" n i
+        | String (PlainString, n) -> pr "[ '%s', 'string', %d ]" n i
+        | String (Device, n) -> pr "[ '%s', 'string(device)', %d ]" n i
+        | String (Mountable, n) -> pr "[ '%s', 'string(mountable)', %d ]" n i
+        | String (Dev_or_Path, n) ->
+           pr "[ '%s', 'string(dev_or_path)', %d ]" n i
+        | String (Mountable_or_Path, n) ->
+           pr "[ '%s', 'string(mountable_or_path)', %d ]" n i
+        | String (GUID, n) -> pr "[ '%s', 'guid', %d ]" n i
+        | String ((FileIn|FileOut), n) ->
+           pr "[ '%s', 'string(filename)', %d ]" n i
+        | String (Key, n) -> pr "[ '%s', 'string(key)', %d ]" n i
+        | String (Filename, n) -> pr "[ '%s', 'string(file)', %d ]" n i
+        | String (Pathname, n) -> pr "[ '%s', 'string(path)', %d ]" n i
         | BufferIn n -> pr "[ '%s', 'buffer', %d ]" n i
         | OptString n -> pr "[ '%s', 'nullable string', %d ]" n i
-        | StringList n -> pr "[ '%s', 'string list', %d ]" n i
-        | DeviceList n -> pr "[ '%s', 'string(device) list', %d ]" n i
+        | StringList (Device, n) -> pr "[ '%s', 'string(device) list', %d ]" n i
+        | StringList (Filename, n) ->
+           pr "[ '%s', 'string(file) list', %d ]" n i
+        | StringList (_, n) -> pr "[ '%s', 'string list', %d ]" n i
         | Bool n -> pr "[ '%s', 'bool', %d ]" n i
         | Int n -> pr "[ '%s', 'int', %d ]" n i
         | Int64 n -> pr "[ '%s', 'int64', %d ]" n i
         | Pointer (t, n) -> pr "[ '%s', 'pointer(%s)', %d ]" n t i
-        | FilenameList n -> pr "[ '%s', 'string(path) list', %d ]" n i
       in
       pr "    args => [\n";
       iteri (fun i arg ->
@@ -1125,12 +1126,11 @@ and generate_perl_prototype name (ret, args, optargs) =
       if !comma then pr ", ";
       comma := true;
       match arg with
-      | Pathname n | Device n | Mountable n
-      | Dev_or_Path n | Mountable_or_Path n | String n
-      | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
-      | BufferIn n | Key n | Pointer (_, n) | GUID n ->
+      | String (_, n)
+      | OptString n | Bool n | Int n | Int64 n
+      | BufferIn n | Pointer (_, n) ->
           pr "$%s" n
-      | StringList n | DeviceList n | FilenameList n ->
+      | StringList (_, n) ->
           pr "\\@%s" n
   ) args;
   List.iter (
diff --git a/generator/php.ml b/generator/php.ml
index 90869ef93..48cd89fdc 100644
--- a/generator/php.ml
+++ b/generator/php.ml
@@ -279,19 +279,14 @@ PHP_FUNCTION (guestfs_last_error)
 
       List.iter (
         function
-        | String n | Device n | Mountable n | Pathname n
-        | Dev_or_Path n | Mountable_or_Path n
-        | FileIn n | FileOut n | Key n
-        | BufferIn n
-        | GUID n ->
+        | String (_, n)
+        | BufferIn n ->
             pr "  char *%s;\n" n;
             pr "  guestfs_string_length %s_size;\n" n
         | OptString n ->
             pr "  char *%s = NULL;\n" n;
             pr "  guestfs_string_length %s_size;\n" n
-        | StringList n
-        | DeviceList n
-        | FilenameList n ->
+        | StringList (_, n) ->
             pr "  zval *z_%s;\n" n;
             pr "  char **%s;\n" n;
         | Bool n ->
@@ -330,12 +325,10 @@ PHP_FUNCTION (guestfs_last_error)
       let param_string = String.concat "" (
         List.map (
           function
-          | String n | Device n | Mountable n | Pathname n
-          | Dev_or_Path n | Mountable_or_Path n
-          | FileIn n | FileOut n | BufferIn n | Key n
-          | GUID n -> "s"
+          | String (_, n)
+          | BufferIn n -> "s"
           | OptString n -> "s!"
-          | StringList n | DeviceList n | FilenameList n -> "a"
+          | StringList (_, n) -> "a"
           | Bool n -> "b"
           | Int n | Int64 n -> "l"
           | Pointer _ -> ""
@@ -365,12 +358,11 @@ PHP_FUNCTION (guestfs_last_error)
       pr "        &z_g";
       List.iter (
         function
-        | String n | Device n | Mountable n | Pathname n
-        | Dev_or_Path n | Mountable_or_Path n
-        | FileIn n | FileOut n | BufferIn n | Key n
-        | OptString n | GUID n ->
+        | String (_, n)
+        | BufferIn n
+        | OptString n ->
             pr ", &%s, &%s_size" n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr ", &z_%s" n
         | Bool n ->
             pr ", &%s" n
@@ -400,10 +392,7 @@ PHP_FUNCTION (guestfs_last_error)
 
       List.iter (
         function
-        | String n | Device n | Mountable n | Pathname n
-        | Dev_or_Path n | Mountable_or_Path n
-        | FileIn n | FileOut n | Key n
-        | GUID n ->
+        | String (_, n) ->
             (* Just need to check the string doesn't contain any ASCII
              * NUL characters, which won't be supported by the C API.
              *)
@@ -422,9 +411,7 @@ PHP_FUNCTION (guestfs_last_error)
             pr "  }\n";
             pr "\n"
         | BufferIn n -> ()
-        | StringList n
-        | DeviceList n
-        | FilenameList n ->
+        | StringList (_, n) ->
             pr "  %s = get_stringlist (z_%s);\n" n n;
             pr "\n"
         | Bool _ | Int _ | Int64 _ -> ()
@@ -499,14 +486,10 @@ PHP_FUNCTION (guestfs_last_error)
       (* Free up parameters. *)
       List.iter (
         function
-        | String n | Device n | Mountable n | Pathname n
-        | Dev_or_Path n | Mountable_or_Path n
-        | FileIn n | FileOut n | Key n
-        | OptString n | GUID n -> ()
-        | BufferIn n -> ()
-        | StringList n
-        | DeviceList n
-        | FilenameList n ->
+        | String _
+        | OptString _
+        | BufferIn _ -> ()
+        | StringList (_, n) ->
             pr "  guestfs_efree_stringlist (%s);\n" n;
             pr "\n"
         | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
diff --git a/generator/python.ml b/generator/python.ml
index 11dc48102..2e614b57b 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -314,15 +314,13 @@ and generate_python_actions actions () =
 
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n | Key n
-        | FileIn n | FileOut n | GUID n ->
+        | String (_, n) ->
             pr "  const char *%s;\n" n
         | OptString n -> pr "  const char *%s;\n" n
         | BufferIn n ->
             pr "  const char *%s;\n" n;
             pr "  Py_ssize_t %s_size;\n" n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
             pr "  PyObject *py_%s;\n" n;
             pr "  char **%s = NULL;\n" n
         | Bool n -> pr "  int %s;\n" n
@@ -352,11 +350,9 @@ and generate_python_actions actions () =
       pr "  if (!PyArg_ParseTuple (args, (char *) \"O";
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
-        | FileIn _ | FileOut _ | GUID _ -> pr "s"
+        | String _ -> pr "s"
         | OptString _ -> pr "z"
-        | StringList _ | DeviceList _ | FilenameList _ -> pr "O"
+        | StringList _ -> pr "O"
         | Bool _ -> pr "i" (* XXX Python has booleans? *)
         | Int _ -> pr "i"
         | Int64 _ ->
@@ -375,12 +371,9 @@ and generate_python_actions actions () =
       pr "                         &py_g";
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n | Key n
-        | FileIn n | FileOut n | GUID n -> pr ", &%s" n
+        | String (_, n) -> pr ", &%s" n
         | OptString n -> pr ", &%s" n
-        | StringList n | DeviceList n | FilenameList n ->
-            pr ", &py_%s" n
+        | StringList (_, n) -> pr ", &py_%s" n
         | Bool n -> pr ", &%s" n
         | Int n -> pr ", &%s" n
         | Int64 n -> pr ", &%s" n
@@ -399,11 +392,9 @@ and generate_python_actions actions () =
       pr "  g = get_handle (py_g);\n";
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
-        | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
-        | BufferIn _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | String _ | OptString _ | Bool _ | Int _ | Int64 _
+        | BufferIn _ -> ()
+        | StringList (_, n) ->
             pr "  %s = guestfs_int_py_get_string_list (py_%s);\n" n n;
             pr "  if (!%s) goto out;\n" n
         | Pointer (_, n) ->
@@ -549,11 +540,9 @@ and generate_python_actions actions () =
 
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
-        | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
-        | BufferIn _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | String _ | OptString _ | Bool _ | Int _ | Int64 _
+        | BufferIn _ | Pointer _ -> ()
+        | StringList (_, n) ->
             pr "  free (%s);\n" n
       ) args;
 
@@ -912,11 +901,9 @@ class GuestFS(object):
        *)
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
-        | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
-        | BufferIn _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | String _ | OptString _ | Bool _ | Int _ | Int64 _
+        | BufferIn _ -> ()
+        | StringList (_, n) ->
           pr "        %s = list(%s)\n" n n
         | Pointer (_, n) ->
           pr "        %s = %s.c_pointer()\n" n n
diff --git a/generator/ruby.ml b/generator/ruby.ml
index dd215d2e5..4d2ebbf0d 100644
--- a/generator/ruby.ml
+++ b/generator/ruby.ml
@@ -251,9 +251,7 @@ and generate_ruby_c actions () =
 
       List.iter (
         function
-        | Pathname n | Device n | Mountable n
-        | Dev_or_Path n | Mountable_or_Path n | String n | Key n
-        | FileIn n | FileOut n | GUID n ->
+        | String (_, n) ->
           pr "  const char *%s = StringValueCStr (%sv);\n" n n;
         | BufferIn n ->
           pr "  Check_Type (%sv, T_STRING);\n" n;
@@ -264,7 +262,7 @@ and generate_ruby_c actions () =
           pr "  size_t %s_size = RSTRING_LEN (%sv);\n" n n
         | OptString n ->
           pr "  const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
-        | StringList n | DeviceList n | FilenameList n ->
+        | StringList (_, n) ->
           pr "  char **%s;\n" n;
           pr "  Check_Type (%sv, T_ARRAY);\n" n;
           pr "  {\n";
@@ -355,11 +353,9 @@ and generate_ruby_c actions () =
 
       List.iter (
         function
-        | Pathname _ | Device _ | Mountable _
-        | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
-        | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
-        | BufferIn _ | Pointer _ | GUID _ -> ()
-        | StringList n | DeviceList n | FilenameList n ->
+        | String _ | OptString _ | Bool _ | Int _ | Int64 _
+        | BufferIn _ | Pointer _ -> ()
+        | StringList (_, n) ->
             pr "  free (%s);\n" n
       ) args;
 
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index 7f89e0ed6..f9f14f6dc 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -411,15 +411,9 @@ and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test
   List.iter (
     function
     | OptString _, "NULL", _ -> ()
-    | Pathname _, arg, sym
-    | Device _, arg, sym
-    | Mountable _, arg, sym
-    | Dev_or_Path _, arg, sym
-    | Mountable_or_Path _, arg, sym
-    | String _, arg, sym
-    | OptString _, arg, sym
-    | Key _, arg, sym
-    | GUID _, arg, sym ->
+    | String ((Pathname|Device|Mountable|Dev_or_Path|Mountable_or_Path
+               |PlainString|Key|GUID|Filename), _), arg, sym
+    | OptString _, arg, sym ->
       pr "  const char *%s = \"%s\";\n" sym (c_quote arg);
     | BufferIn _, arg, sym ->
       pr "  const char *%s = \"%s\";\n" sym (c_quote arg);
@@ -427,16 +421,13 @@ and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test
     | Int _, _, _
     | Int64 _, _, _
     | Bool _, _, _ -> ()
-    | FileIn _, arg, sym ->
+    | String (FileIn, _), arg, sym ->
       pr "  CLEANUP_FREE char *%s = substitute_srcdir (\"%s\");\n"
         sym (c_quote arg)
-    | FileOut _, _, _ -> ()
-    | StringList _, "", sym
-    | DeviceList _, "", sym ->
+    | String (FileOut, _), _, _ -> ()
+    | StringList (_, _), "", sym ->
       pr "  const char *const %s[1] = { NULL };\n" sym
-    | StringList _, arg, sym
-    | DeviceList _, arg, sym
-    | FilenameList _, arg, sym ->
+    | StringList (_, _), arg, sym ->
       let strs = String.nsplit " " arg in
       iteri (
         fun i str ->
@@ -532,20 +523,11 @@ and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test
   List.iter (
     function
     | OptString _, "NULL", _ -> pr ", NULL"
-    | Pathname _, _, sym
-    | Device _, _, sym
-    | Mountable _, _, sym
-    | Dev_or_Path _, _, sym
-    | Mountable_or_Path _, _, sym
+    | String (FileOut, _), arg, _ -> pr ", \"%s\"" (c_quote arg)
     | String _, _, sym
-    | OptString _, _, sym
-    | Key _, _, sym
-    | FileIn _, _, sym
-    | GUID _, _, sym -> pr ", %s" sym
+    | OptString _, _, sym -> pr ", %s" sym
     | BufferIn _, _, sym -> pr ", %s, %s_size" sym sym
-    | FileOut _, arg, _ -> pr ", \"%s\"" (c_quote arg)
-    | StringList _, _, sym | DeviceList _, _, sym
-    | FilenameList _, _, sym ->
+    | StringList _, _, sym ->
       pr ", (char **) %s" sym
     | Int _, arg, _ ->
       let i =
diff --git a/generator/types.ml b/generator/types.ml
index 3fa96fd7a..91d3d1543 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -130,15 +130,19 @@ and argt =
   | Bool of string	(* boolean *)
   | Int of string	(* int (smallish ints, signed, <= 31 bits) *)
   | Int64 of string	(* any 64 bit int *)
-  | String of string	(* const char *name, cannot be NULL *)
-  | Device of string	(* /dev device name, cannot be NULL *)
-  | Mountable of string	(* location of mountable filesystem, cannot be NULL *)
-  | Pathname of string	(* file name, cannot be NULL *)
-  | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *)
-  | Mountable_or_Path of string (* mount or Pathname, cannot be NULL *)
-  | OptString of string	(* const char *name, may be NULL *)
-  | StringList of string(* list of strings (each string cannot be NULL) *)
-  | DeviceList of string(* list of Device names (each cannot be NULL) *)
+
+    (* Strings: These can be plain strings, device names, mountable
+     * filesystems, etc.  They cannot be NULL.
+     *)
+  | String of stringt * string
+
+  | OptString of string	(* Plain string, may be NULL. *)
+
+    (* List of strings: The strings may be plain strings, device names
+     * etc., but all of the same type.  The strings cannot be NULL.
+     *)
+  | StringList of stringt * string
+
     (* Opaque buffer which can contain arbitrary 8 bit data.
      * In the C API, this is expressed as <const char *, size_t> pair.
      * Most other languages have a string type which can contain
@@ -149,24 +153,7 @@ and argt =
      * To return an arbitrary buffer, use RBufferOut.
      *)
   | BufferIn of string
-    (* Key material / passphrase.  Eventually we should treat this
-     * as sensitive and mlock it into physical RAM.  However this
-     * is highly complex because of all the places that XDR-encoded
-     * strings can end up.  So currently the only difference from
-     * 'String' is the way that guestfish requests these parameters
-     * from the user.
-     *)
-  | Key of string
-    (* These are treated as filenames (simple string parameters) in
-     * the C API and bindings.  But in the RPC protocol, we transfer
-     * the actual file content up to or down from the daemon.
-     * FileIn: local machine -> daemon (in request)
-     * FileOut: daemon -> local machine (in reply)
-     * In guestfish (only), the special name "-" means read from
-     * stdin or write to stdout.
-     *)
-  | FileIn of string
-  | FileOut of string
+
     (* This specifies an opaque pointer that is passed through
      * untouched.  Only non-daemon functions are supported.
      *
@@ -184,17 +171,52 @@ and argt =
      * tests, although we should fix this in future.
      *)
   | Pointer of (string * string)
-    (* const char * which represents a GUID string.
+
+and stringt =
+  | PlainString         (* none of the others *)
+  | Device              (* /dev device name *)
+  | Mountable           (* location of mountable filesystem *)
+
+    (* An absolute path within the appliance filesystem. *)
+  | Pathname
+
+    (* These are treated as filenames (simple string parameters) in
+     * the C API and bindings.  But in the RPC protocol, we transfer
+     * the actual file content up to or down from the daemon.
+     * FileIn: local machine -> daemon (in request)
+     * FileOut: daemon -> local machine (in reply)
+     * In guestfish (only), the special name "-" means read from
+     * stdin or write to stdout.
+     *)
+  | FileIn
+  | FileOut
+
+    (* Key material / passphrase.  Eventually we should treat this
+     * as sensitive and mlock it into physical RAM.  However this
+     * is highly complex because of all the places that XDR-encoded
+     * strings can end up.  So currently the only difference from
+     * 'PlainString' is the way that guestfish requests these
+     * parameters from the user.
+     *)
+  | Key
+
+    (* A GUID string.
      *
      * It cannot be NULL, and it will be validated using
      * guestfs_int_validate_guid.
      *)
-  | GUID of string
-    (* List of file names only, where the list cannot be NULL,
-     * and each element cannot be NULL, empty, or anything different than
-     * a simple file name (i.e. neither absolute nor relative paths).
+  | GUID
+
+    (* A simple filename (not a path nor a relative path).  It cannot
+     * be NULL, empty, or anything different than a simple file name.
+     *)
+  | Filename
+
+    (* The following two are DEPRECATED and must not be used in
+     * any new APIs.
      *)
-  | FilenameList of string
+  | Dev_or_Path         (* Device or Pathname. *)
+  | Mountable_or_Path   (* Mountable or Pathname. *)
 
 and optargs = optargt list
 
diff --git a/generator/utils.ml b/generator/utils.ml
index 7034065c9..a745a02b7 100644
--- a/generator/utils.ml
+++ b/generator/utils.ml
@@ -139,11 +139,10 @@ let files_equal n1 n2 =
   | i -> failwithf "%s: failed with error code %d" cmd i
 
 let name_of_argt = function
-  | Pathname n | Device n | Mountable n | Dev_or_Path n
-  | Mountable_or_Path n | String n | OptString n
-  | StringList n | DeviceList n | Bool n | Int n | Int64 n
-  | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n)
-  | GUID n | FilenameList n -> n
+  | String (_, n) | StringList (_, n)
+  | OptString n
+  | Bool n | Int n | Int64 n
+  | BufferIn n | Pointer (_, n) -> n
 
 let name_of_optargt = function
   | OBool n | OInt n | OInt64 n | OString n | OStringList n -> n
@@ -257,6 +256,6 @@ let args_of_optargs optargs =
     | OBool n -> Bool n
     | OInt n -> Int n
     | OInt64 n -> Int64 n
-    | OString n -> String n
-    | OStringList n -> StringList n
+    | OString n -> String (PlainString, n)
+    | OStringList n -> StringList (PlainString, n)
   ) optargs
-- 
2.12.0




More information about the Libguestfs mailing list