fish: Generate list of prepared disk image types.
authorRichard Jones <rjones@redhat.com>
Wed, 8 Sep 2010 08:05:18 +0000 (09:05 +0100)
committerRichard Jones <rjones@redhat.com>
Wed, 8 Sep 2010 08:59:29 +0000 (09:59 +0100)
This commit shouldn't change the semantics of the code.

.gitignore
fish/Makefile.am
fish/fish.h
fish/prep.c
fish/prep_disk.c [new file with mode: 0644]
fish/prep_fs.c [new file with mode: 0644]
fish/prep_part.c [new file with mode: 0644]
po/POTFILES.in
src/generator.ml

index cfea549..55bd91b 100644 (file)
@@ -61,6 +61,8 @@ fish/cmds.c
 fish/completion.c
 fish/guestfish
 fish/guestfish.static
+fish/prepopts.c
+fish/prepopts.h
 fish/rc_protocol.c
 fish/rc_protocol.h
 fuse/guestmount
index f75e4e0..fa8068a 100644 (file)
@@ -22,7 +22,9 @@ bin_PROGRAMS = guestfish
 generator_built = \
        cmds.c \
        completion.c \
-       guestfish-actions.pod
+       guestfish-actions.pod \
+       prepopts.h \
+       prepopts.c
 
 BUILT_SOURCES = \
        $(generator_built) \
@@ -49,6 +51,9 @@ guestfish_SOURCES = \
        man.c \
        more.c \
        prep.c \
+       prep_disk.c \
+       prep_part.c \
+       prep_fs.c \
        progress.c \
        rc.c \
        reopen.c \
index be357f5..7c9c955 100644 (file)
@@ -116,12 +116,18 @@ extern int do_man (const char *cmd, int argc, char *argv[]);
 extern int do_more (const char *cmd, int argc, char *argv[]);
 
 /* in prep.c */
+struct prep_data {
+  const struct prep *prep;
+  const char *orig_type_string;
+  const char **params;
+};
 typedef struct prep_data prep_data;
 extern void list_prepared_drives (void);
 extern prep_data *create_prepared_file (const char *type_string,
                                         const char *filename);
 extern void prepare_drive (const char *filename, prep_data *data,
                            const char *device);
+extern void prep_error (prep_data *data, const char *filename, const char *fs, ...) __attribute__((noreturn, format (printf,3,4)));
 
 /* in progress.c */
 extern void reset_progress_bar (void);
index 7186622..369dd6d 100644 (file)
 #include <unistd.h>
 
 #include "fish.h"
+#include "prepopts.h"
 
 static prep_data *parse_type_string (const char *type_string);
-static void prep_error (prep_data *data, const char *filename, const char *fs, ...) __attribute__((noreturn, format (printf,3,4)));
-
-struct prep {
-  const char *name;             /* eg. "fs" */
-
-  size_t nr_params;             /* optional parameters */
-  struct param *params;
-
-  const char *shortdesc;        /* short description */
-  const char *longdesc;         /* long description */
-
-                                /* functions to implement it */
-  void (*prelaunch) (const char *filename, prep_data *);
-  void (*postlaunch) (const char *filename, prep_data *, const char *device);
-};
-
-struct param {
-  const char *pname;            /* parameter name */
-  const char *pdefault;         /* parameter default */
-  const char *pdesc;            /* parameter description */
-};
-
-static void prelaunch_disk (const char *filename, prep_data *data);
-static struct param disk_params[] = {
-  { "size", "100M", "the size of the disk image" },
-};
-
-static void prelaunch_part (const char *filename, prep_data *data);
-static void postlaunch_part (const char *filename, prep_data *data, const char *device);
-static struct param part_params[] = {
-  { "size", "100M", "the size of the disk image" },
-  { "partition", "mbr", "partition table type" },
-};
-
-static void prelaunch_fs (const char *filename, prep_data *data);
-static void postlaunch_fs (const char *filename, prep_data *data, const char *device);
-static struct param fs_params[] = {
-  { "filesystem", "ext2", "the type of filesystem to use" },
-  { "size", "100M", "the size of the disk image" },
-  { "partition", "mbr", "partition table type" },
-};
-
-static const struct prep preps[] = {
-  { "disk",
-    1, disk_params,
-    "create a blank disk",
-    "\
-  Create a blank disk, size 100MB (by default).\n\
-\n\
-  The default size can be changed by supplying an optional parameter.",
-    prelaunch_disk, NULL
-  },
-  { "part",
-    2, part_params,
-    "create a partitioned disk",
-    "\
-  Create a disk with a single partition.  By default the size of the disk\n\
-  is 100MB (the available space in the partition will be a tiny bit smaller)\n\
-  and the partition table will be MBR (old DOS-style).\n\
-\n\
-  These defaults can be changed by supplying optional parameters.",
-    prelaunch_part, postlaunch_part
-  },
-  { "fs",
-    3, fs_params,
-    "create a filesystem",
-    "\
-  Create a disk with a single partition, with the partition containing\n\
-  an empty filesystem.  This defaults to creating a 100MB disk (the available\n\
-  space in the filesystem will be a tiny bit smaller) with an MBR (old\n\
-  DOS-style) partition table and an ext2 filesystem.\n\
-\n\
-  These defaults can be changed by supplying optional parameters.",
-    prelaunch_fs, postlaunch_fs
-  },
-};
-
-#define nr_preps (sizeof preps / sizeof preps[0])
 
 void
 list_prepared_drives (void)
@@ -113,7 +36,7 @@ list_prepared_drives (void)
 
   printf (_("List of available prepared disk images:\n\n"));
 
-  for (i = 0; i < nr_preps; ++i) {
+  for (i = 0; i < NR_PREPS; ++i) {
     printf (_("\
 guestfish -N %-16s %s\n\
 \n\
@@ -145,12 +68,6 @@ directory.  (\"test2.img\" etc if -N option is given multiple times).\n\
 For more information see the guestfish(1) manual.\n"));
 }
 
-struct prep_data {
-  const struct prep *prep;
-  const char *orig_type_string;
-  const char **params;
-};
-
 /* Parse the type string (from the command line) and create the output
  * file 'filename'.  This is called before launch.  Return the opaque
  * prep_data which will be passed back to us in prepare_drive below.
@@ -171,11 +88,11 @@ parse_type_string (const char *type_string)
 
   /* Match on the type part (without parameters). */
   size_t len = strcspn (type_string, ":");
-  for (i = 0; i < nr_preps; ++i)
+  for (i = 0; i < NR_PREPS; ++i)
     if (STRCASEEQLEN (type_string, preps[i].name, len))
       break;
 
-  if (i == nr_preps) {
+  if (i == NR_PREPS) {
     fprintf (stderr, _("\
 guestfish: -N parameter '%s': no such prepared disk image known.\n\
 Use 'guestfish -N list' to list possible values for the -N parameter.\n"),
@@ -234,7 +151,7 @@ prepare_drive (const char *filename, prep_data *data,
     data->prep->postlaunch (filename, data, device);
 }
 
-static void
+void
 prep_error (prep_data *data, const char *filename, const char *fs, ...)
 {
   fprintf (stderr,
@@ -250,52 +167,3 @@ prep_error (prep_data *data, const char *filename, const char *fs, ...)
 
   exit (EXIT_FAILURE);
 }
-
-static void
-prelaunch_disk (const char *filename, prep_data *data)
-{
-  if (alloc_disk (filename, data->params[0], 0, 1) == -1)
-    prep_error (data, filename, _("failed to allocate disk"));
-}
-
-static void
-prelaunch_part (const char *filename, prep_data *data)
-{
-  if (alloc_disk (filename, data->params[0], 0, 1) == -1)
-    prep_error (data, filename, _("failed to allocate disk"));
-}
-
-static void
-postlaunch_part (const char *filename, prep_data *data, const char *device)
-{
-  if (guestfs_part_disk (g, device, data->params[1]) == -1)
-    prep_error (data, filename, _("failed to partition disk: %s"),
-                guestfs_last_error (g));
-}
-
-static void
-prelaunch_fs (const char *filename, prep_data *data)
-{
-  if (alloc_disk (filename, data->params[1], 0, 1) == -1)
-    prep_error (data, filename, _("failed to allocate disk"));
-}
-
-static void
-postlaunch_fs (const char *filename, prep_data *data, const char *device)
-{
-  if (guestfs_part_disk (g, device, data->params[2]) == -1)
-    prep_error (data, filename, _("failed to partition disk: %s"),
-                guestfs_last_error (g));
-
-  char *part;
-  if (asprintf (&part, "%s1", device) == -1) {
-    perror ("asprintf");
-    exit (EXIT_FAILURE);
-  }
-
-  if (guestfs_mkfs (g, data->params[0], part) == -1)
-    prep_error (data, filename, _("failed to create filesystem (%s): %s"),
-                data->params[0], guestfs_last_error (g));
-
-  free (part);
-}
diff --git a/fish/prep_disk.c b/fish/prep_disk.c
new file mode 100644 (file)
index 0000000..d393d8d
--- /dev/null
@@ -0,0 +1,41 @@
+/* guestfish - the filesystem interactive shell
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fish.h"
+#include "prepopts.h"
+
+void
+prep_prelaunch_disk (const char *filename, prep_data *data)
+{
+  if (alloc_disk (filename, data->params[0], 0, 1) == -1)
+    prep_error (data, filename, _("failed to allocate disk"));
+}
+
+void
+prep_postlaunch_disk (const char *filename, prep_data *data, const char *device)
+{
+  /* nothing */
+}
diff --git a/fish/prep_fs.c b/fish/prep_fs.c
new file mode 100644 (file)
index 0000000..d8fa609
--- /dev/null
@@ -0,0 +1,55 @@
+/* guestfish - the filesystem interactive shell
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fish.h"
+#include "prepopts.h"
+
+void
+prep_prelaunch_fs (const char *filename, prep_data *data)
+{
+  if (alloc_disk (filename, data->params[1], 0, 1) == -1)
+    prep_error (data, filename, _("failed to allocate disk"));
+}
+
+void
+prep_postlaunch_fs (const char *filename, prep_data *data, const char *device)
+{
+  if (guestfs_part_disk (g, device, data->params[2]) == -1)
+    prep_error (data, filename, _("failed to partition disk: %s"),
+                guestfs_last_error (g));
+
+  char *part;
+  if (asprintf (&part, "%s1", device) == -1) {
+    perror ("asprintf");
+    exit (EXIT_FAILURE);
+  }
+
+  if (guestfs_mkfs (g, data->params[0], part) == -1)
+    prep_error (data, filename, _("failed to create filesystem (%s): %s"),
+                data->params[0], guestfs_last_error (g));
+
+  free (part);
+}
diff --git a/fish/prep_part.c b/fish/prep_part.c
new file mode 100644 (file)
index 0000000..ac46f37
--- /dev/null
@@ -0,0 +1,43 @@
+/* guestfish - the filesystem interactive shell
+ * Copyright (C) 2010 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fish.h"
+#include "prepopts.h"
+
+void
+prep_prelaunch_part (const char *filename, prep_data *data)
+{
+  if (alloc_disk (filename, data->params[0], 0, 1) == -1)
+    prep_error (data, filename, _("failed to allocate disk"));
+}
+
+void
+prep_postlaunch_part (const char *filename, prep_data *data, const char *device)
+{
+  if (guestfs_part_disk (g, device, data->params[1]) == -1)
+    prep_error (data, filename, _("failed to partition disk: %s"),
+                guestfs_last_error (g));
+}
index a06249a..d65ccfd 100644 (file)
@@ -81,6 +81,10 @@ fish/lcd.c
 fish/man.c
 fish/more.c
 fish/prep.c
+fish/prep_disk.c
+fish/prep_fs.c
+fish/prep_part.c
+fish/prepopts.c
 fish/progress.c
 fish/rc.c
 fish/reopen.c
index 2a5ecfb..2f2e391 100755 (executable)
@@ -5619,6 +5619,40 @@ type callt =
   | CallBool of bool
   | CallBuffer of string
 
+(* Used for the guestfish -N (prepared disk images) option.
+ * Note that the longdescs are indented by 2 spaces.
+ *)
+let prepopts = [
+  ("disk",
+   "create a blank disk",
+   [ "size", "100M", "the size of the disk image" ],
+   "  Create a blank disk, size 100MB (by default).
+
+  The default size can be changed by supplying an optional parameter.");
+
+  ("part",
+   "create a partitioned disk",
+   [ "size", "100M", "the size of the disk image";
+     "partition", "mbr", "partition table type" ],
+   "  Create a disk with a single partition.  By default the size of the disk
+  is 100MB (the available space in the partition will be a tiny bit smaller)
+  and the partition table will be MBR (old DOS-style).
+
+  These defaults can be changed by supplying optional parameters.");
+
+  ("fs",
+   "create a filesystem",
+   [ "filesystem", "ext2", "the type of filesystem to use";
+     "size", "100M", "the size of the disk image";
+     "partition", "mbr", "partition table type" ],
+   "  Create a disk with a single partition, with the partition containing
+  an empty filesystem.  This defaults to creating a 100MB disk (the available
+  space in the filesystem will be a tiny bit smaller) with an MBR (old
+  DOS-style) partition table and an ext2 filesystem.
+
+  These defaults can be changed by supplying optional parameters.");
+]
+
 (* Used to memoize the result of pod2text. *)
 let pod2text_memo_filename = "src/.pod2text.data"
 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
@@ -8810,6 +8844,84 @@ Guestfish will prompt for these separately.\n\n";
       | Some txt -> pr "%s\n\n" txt
   ) all_functions_sorted
 
+and generate_fish_prep_options_h () =
+  generate_header CStyle GPLv2plus;
+
+  pr "#ifndef PREPOPTS_H\n";
+  pr "\n";
+
+  pr "\
+struct prep {
+  const char *name;             /* eg. \"fs\" */
+
+  size_t nr_params;             /* optional parameters */
+  struct prep_param *params;
+
+  const char *shortdesc;        /* short description */
+  const char *longdesc;         /* long description */
+
+                                /* functions to implement it */
+  void (*prelaunch) (const char *filename, prep_data *);
+  void (*postlaunch) (const char *filename, prep_data *, const char *device);
+};
+
+struct prep_param {
+  const char *pname;            /* parameter name */
+  const char *pdefault;         /* parameter default */
+  const char *pdesc;            /* parameter description */
+};
+
+extern const struct prep preps[];
+#define NR_PREPS %d
+
+" (List.length prepopts);
+
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "\
+extern void prep_prelaunch_%s (const char *filename, prep_data *data);
+extern void prep_postlaunch_%s (const char *filename, prep_data *data, const char *device);
+
+" name name;
+  ) prepopts;
+
+  pr "\n";
+  pr "#endif /* PREPOPTS_H */\n"
+
+and generate_fish_prep_options_c () =
+  generate_header CStyle GPLv2plus;
+
+  pr "\
+#include \"fish.h\"
+#include \"prepopts.h\"
+
+";
+
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "static struct prep_param %s_args[] = {\n" name;
+      List.iter (
+        fun (n, default, desc) ->
+          pr "  { \"%s\", \"%s\", \"%s\" },\n" n default desc
+      ) args;
+      pr "};\n";
+      pr "\n";
+  ) prepopts;
+
+  pr "const struct prep preps[] = {\n";
+  List.iter (
+    fun (name, shortdesc, args, longdesc) ->
+      pr "  { \"%s\", %d, %s_args,
+    \"%s\",
+    \"%s\",
+    prep_prelaunch_%s, prep_postlaunch_%s },
+"
+        name (List.length args) name
+        (c_quote shortdesc) (c_quote longdesc)
+        name name;
+  ) prepopts;
+  pr "};\n"
+
 (* Generate a C function prototype. *)
 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
     ?(single_line = false) ?(newline = false) ?(in_daemon = false)
@@ -12915,6 +13027,8 @@ Run it from the top source directory using the command
   output_to "fish/cmds.c" generate_fish_cmds;
   output_to "fish/completion.c" generate_fish_completion;
   output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
+  output_to "fish/prepopts.c" generate_fish_prep_options_c;
+  output_to "fish/prepopts.h" generate_fish_prep_options_h;
   output_to "ocaml/guestfs.mli" generate_ocaml_mli;
   output_to "ocaml/guestfs.ml" generate_ocaml_ml;
   output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;