diff --git a/.gitignore b/.gitignore index bd7b808f44..a8da10e5cc 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ qemu-nbd qemu-nbd.8 qemu-nbd.pod qemu-options.texi +qemu-img-cmds.texi +qemu-img-cmds.h qemu-io .gdbinit *.a diff --git a/Makefile b/Makefile index 0e045bb57c..767d6c5d8d 100644 --- a/Makefile +++ b/Makefile @@ -238,6 +238,8 @@ libqemu_user.a: $(USER_OBJS) ###################################################################### +qemu-img.o: qemu-img-cmds.h + qemu-img$(EXESUF): qemu-img.o qemu-tool.o tool-osdep.o $(BLOCK_OBJS) qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o tool-osdep.o $(BLOCK_OBJS) @@ -246,6 +248,9 @@ qemu-io$(EXESUF): qemu-io.o qemu-tool.o tool-osdep.o cmd.o $(BLOCK_OBJS) qemu-img$(EXESUF) qemu-nbd$(EXESUF) qemu-io$(EXESUF): LIBS += -lz +qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx + $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") + clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h @@ -257,7 +262,7 @@ clean: done distclean: clean - rm -f config-host.mak config-host.h $(DOCS) qemu-options.texi + rm -f config-host.mak config-host.h $(DOCS) qemu-options.texi qemu-img-cmds.texi rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr} for d in $(TARGET_DIRS) libhw32 libhw64; do \ rm -rf $$d || exit 1 ; \ @@ -335,13 +340,16 @@ qemu-options.texi: $(SRC_PATH)/qemu-options.hx qemu-monitor.texi: $(SRC_PATH)/qemu-monitor.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@") +qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx + $(call quiet-command,sh $(SRC_PATH)/hxtool -t < $< > $@," GEN $@") + qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi $(call quiet-command, \ perl -Ww -- $(SRC_PATH)/texi2pod.pl $< qemu.pod && \ pod2man --section=1 --center=" " --release=" " qemu.pod > $@, \ " GEN $@") -qemu-img.1: qemu-img.texi +qemu-img.1: qemu-img.texi qemu-img-cmds.texi $(call quiet-command, \ perl -Ww -- $(SRC_PATH)/texi2pod.pl $< qemu-img.pod && \ pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@, \ @@ -359,7 +367,7 @@ dvi: qemu-doc.dvi qemu-tech.dvi html: qemu-doc.html qemu-tech.html -qemu-doc.dvi qemu-doc.html qemu-doc.info: qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-monitor.texi +qemu-doc.dvi qemu-doc.html qemu-doc.info: qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-monitor.texi qemu-img-cmds.texi VERSION ?= $(shell cat VERSION) FILE = qemu-$(VERSION) diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx new file mode 100644 index 0000000000..ddb86f0487 --- /dev/null +++ b/qemu-img-cmds.hx @@ -0,0 +1,47 @@ +HXCOMM Use DEFHEADING() to define headings in both help text and texi +HXCOMM Text between STEXI and ETEXI are copied to texi version and +HXCOMM discarded from C version +HXCOMM DEF(command, callback, arg_string) is used to construct +HXCOMM command structures and help message. +HXCOMM HXCOMM can be used for comments, discarded from both texi and C + +STEXI +@table @option +STEXI + +DEF("check", img_check, + "check [-f fmt] filename") +STEXI +@item check [-f @var{fmt}] @var{filename} +ETEXI + +DEF("create", img_create, + "create [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]") +STEXI +@item create [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] +ETEXI + +DEF("commit", img_commit, + "commit [-f fmt] filename") +STEXI +@item commit [-f @var{fmt}] @var{filename} +ETEXI + +DEF("convert", img_convert, + "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename") +STEXI +@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename} +ETEXI + +DEF("info", img_info, + "info [-f fmt] filename") +STEXI +@item info [-f @var{fmt}] @var{filename} +ETEXI + +DEF("snapshot", img_snapshot, + "snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename") +STEXI +@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename} +@end table +ETEXI diff --git a/qemu-img.c b/qemu-img.c index aff3980806..d806cfa193 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -31,6 +31,11 @@ #include #endif +typedef struct img_cmd_t { + const char *name; + int (*handler)(int argc, char **argv); +} img_cmd_t; + /* Default to cache=writeback as data integrity is not important for qemu-tcg. */ #define BRDV_O_FLAGS BDRV_O_CACHE_WB @@ -58,12 +63,11 @@ static void help(void) "QEMU disk image utility\n" "\n" "Command syntax:\n" - " check [-f fmt] filename\n" - " create [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]\n" - " commit [-f fmt] filename\n" - " convert [-c] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename\n" - " info [-f fmt] filename\n" - " snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename\n" +#define DEF(option, callback, arg_string) \ + " " arg_string "\n" +#include "qemu-img-cmds.h" +#undef DEF +#undef GEN_DOCS "\n" "Command parameters:\n" " 'filename' is a disk image filename\n" @@ -919,7 +923,7 @@ static int img_info(int argc, char **argv) #define SNAPSHOT_APPLY 3 #define SNAPSHOT_DELETE 4 -static void img_snapshot(int argc, char **argv) +static int img_snapshot(int argc, char **argv) { BlockDriverState *bs; QEMUSnapshotInfo sn; @@ -936,18 +940,18 @@ static void img_snapshot(int argc, char **argv) switch(c) { case 'h': help(); - return; + return 0; case 'l': if (action) { help(); - return; + return 0; } action = SNAPSHOT_LIST; break; case 'a': if (action) { help(); - return; + return 0; } action = SNAPSHOT_APPLY; snapshot_name = optarg; @@ -955,7 +959,7 @@ static void img_snapshot(int argc, char **argv) case 'c': if (action) { help(); - return; + return 0; } action = SNAPSHOT_CREATE; snapshot_name = optarg; @@ -963,7 +967,7 @@ static void img_snapshot(int argc, char **argv) case 'd': if (action) { help(); - return; + return 0; } action = SNAPSHOT_DELETE; snapshot_name = optarg; @@ -1021,31 +1025,38 @@ static void img_snapshot(int argc, char **argv) /* Cleanup */ bdrv_delete(bs); + + return 0; } +static const img_cmd_t img_cmds[] = { +#define DEF(option, callback, arg_string) \ + { option, callback }, +#include "qemu-img-cmds.h" +#undef DEF +#undef GEN_DOCS + { NULL, NULL, }, +}; + int main(int argc, char **argv) { - const char *cmd; + const img_cmd_t *cmd; + const char *cmdname; bdrv_init(); if (argc < 2) help(); - cmd = argv[1]; + cmdname = argv[1]; argc--; argv++; - if (!strcmp(cmd, "create")) { - img_create(argc, argv); - } else if (!strcmp(cmd, "check")) { - img_check(argc, argv); - } else if (!strcmp(cmd, "commit")) { - img_commit(argc, argv); - } else if (!strcmp(cmd, "convert")) { - img_convert(argc, argv); - } else if (!strcmp(cmd, "info")) { - img_info(argc, argv); - } else if (!strcmp(cmd, "snapshot")) { - img_snapshot(argc, argv); - } else { - help(); + + /* find the command */ + for(cmd = img_cmds; cmd->name != NULL; cmd++) { + if (!strcmp(cmdname, cmd->name)) { + return cmd->handler(argc, argv); + } } + + /* not found */ + help(); return 0; } diff --git a/qemu-img.texi b/qemu-img.texi index dae7b826ed..49d4e590af 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -7,13 +7,8 @@ usage: qemu-img command [command options] @c man begin OPTIONS The following commands are supported: -@table @option -@item create [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] -@item commit [-f @var{fmt}] @var{filename} -@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename} -@item info [-f @var{fmt}] @var{filename} -@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename} -@end table + +@include qemu-img-cmds.texi Command parameters: @table @var