qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PATCH RFC 2/3] pxtool: Add new qemu-img command info gener


From: John Snow
Subject: [Qemu-block] [PATCH RFC 2/3] pxtool: Add new qemu-img command info generation tool
Date: Tue, 9 Apr 2019 21:24:12 -0400

Presently we use hxtool and a .hx format to generate a few things like
the qemu_img subcommand dispatch table, the qemu_img help() display output,
and a help output in qemu-img.texi.

Unfortunately, this means that this information is duplicated in at least
three places:

(1) in qemu-img-cmds.hx as a human readable string
(2) in qemu-img-cmds.hx as a texi string
(3) in qemu-img.texi again, as a texi string

We can do a little better, though: all of these sources can be generated
from a single json file. Add a new small tool ("pxtool") that can do this.

This tool can at least handle generating (1) and (2) from the same source
without needing to reduplicate that information. Deduplicating (3) happens
in the next patch.

Notes:
 - The json format was chosen to be very "stupid", and the command line
   documentation is being kept one-per-line to make future diffs easier
   to read.
 - It's easy enough to generate the human-readable output from the texi
   output by removing '@var{foo}' with 'foo'.
 - The qemu-img command dispatch always calls img_cmdname, so we don't
   need to store this information separately, either.
 - The need for DEF() macros could be removed as well, but I left it in
   to create a minimally disruptive patch.
Signed-off-by: John Snow <address@hidden>
---
 Makefile           |   8 +--
 qemu-img-cmds.json | 165 +++++++++++++++++++++++++++++++++++++++++++++
 qemu-img-cmds.hx   | 102 ----------------------------
 scripts/pxtool.py  |  49 ++++++++++++++
 4 files changed, 218 insertions(+), 106 deletions(-)
 create mode 100644 qemu-img-cmds.json
 delete mode 100644 qemu-img-cmds.hx
 create mode 100755 scripts/pxtool.py

diff --git a/Makefile b/Makefile
index 04a0d45050..d203bb90dc 100644
--- a/Makefile
+++ b/Makefile
@@ -524,8 +524,8 @@ ifdef CONFIG_MPATH
 scsi/qemu-pr-helper$(EXESUF): LIBS += -ludev -lmultipath -lmpathpersist
 endif
 
-qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
-       $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > 
$@,"GEN","$@")
+qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.json $(SRC_PATH)/scripts/pxtool.py
+       $(call quiet-command,$(PYTOHN) $(SRC_PATH)/scripts/pxtool.py --macros 
$< > $@,"GEN","$@")
 
 qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
 qemu-ga$(EXESUF): QEMU_CFLAGS += -I qga/qapi-generated
@@ -918,8 +918,8 @@ qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx 
$(SRC_PATH)/scripts/hxtool
 qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx 
$(SRC_PATH)/scripts/hxtool
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > 
$@,"GEN","$@")
 
-qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
-       $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > 
$@,"GEN","$@")
+qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.json 
$(SRC_PATH)/scripts/pxtool.py
+       $(call quiet-command,$(PYTON) $(SRC_PATH)/scripts/pxtool.py --texi $< > 
$@,"GEN","$@")
 
 docs/interop/qemu-qmp-qapi.texi: qapi/qapi-doc.texi
        @cp -p $< $@
diff --git a/qemu-img-cmds.json b/qemu-img-cmds.json
new file mode 100644
index 0000000000..35d96f92a3
--- /dev/null
+++ b/qemu-img-cmds.json
@@ -0,0 +1,165 @@
+{
+    "amend": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-p]",
+        "[-q]",
+        "[-f @var{fmt}]",
+        "[-t @var{cache}]",
+        "-o @var{options}",
+        "@var{filename}"
+    ],
+    "bench": [
+        "[-c @var{count}]",
+        "[-d @var{depth}]",
+        "[-f @var{fmt}]",
+        "address@hidden",
+        "[-n]",
+        "[--no-drain]",
+        "[-o @var{offset}]",
+        "address@hidden",
+        "[-q]",
+        "[-s @var{buffer_size}]",
+        "[-S @var{step_size}]",
+        "[-t @var{cache}]",
+        "[-w]",
+        "[-U]",
+        "@var{filename}"
+    ],
+    "check": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-q]",
+        "[-f @var{fmt}]",
+        "address@hidden",
+        "[-r [leaks | all]]",
+        "[-T @var{src_cache}]",
+        "[-U]",
+        "@var{filename}"
+    ],
+    "commit": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-q]",
+        "[-f @var{fmt}]",
+        "[-t @var{cache}]",
+        "[-b @var{base}]",
+        "[-d]",
+        "[-p]",
+        "@var{filename}"
+    ],
+    "compare": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-f @var{fmt}]",
+        "[-F @var{fmt}]",
+        "[-T @var{src_cache}]",
+        "[-p]",
+        "[-q]",
+        "[-s]",
+        "[-U]",
+        "@var{filename1}",
+        "@var{filename2}"
+    ],
+    "convert": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[--target-image-opts]",
+        "[-U]",
+        "[-C]",
+        "[-c]",
+        "[-p]",
+        "[-q]",
+        "[-n]",
+        "[-f @var{fmt}]",
+        "[-t @var{cache}]",
+        "[-T @var{src_cache}]",
+        "[-O @var{output_fmt}]",
+        "[-B @var{backing_file}]",
+        "[-o @var{options}]",
+        "[-l @var{snapshot_param}]",
+        "[-S @var{sparse_size}]",
+        "[-m @var{num_coroutines}]",
+        "[-W]",
+        "@var{filename}",
+        "address@hidden [...]]",
+        "@var{output_filename}"
+    ],
+    "create": [
+        "[--object @var{objectdef}]",
+        "[-q]",
+        "[-f @var{fmt}]",
+        "[-b @var{backing_file}]",
+        "[-F @var{backing_fmt}]",
+        "[-u]",
+        "[-o @var{options}]",
+        "@var{filename}",
+        "address@hidden"
+    ],
+    "dd": [
+        "[--image-opts]",
+        "[-U]",
+        "[-f @var{fmt}]",
+        "[-O @var{output_fmt}]",
+        "address@hidden",
+        "address@hidden",
+        "address@hidden",
+        "address@hidden",
+        "address@hidden"
+    ],
+    "info": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-f @var{fmt}]",
+        "address@hidden",
+        "[--backing-chain]",
+        "[-U]",
+        "@var{filename}"
+    ],
+    "map": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-f @var{fmt}]",
+        "address@hidden",
+        "[-U]",
+        "@var{filename}"
+    ],
+    "measure": [
+        "address@hidden",
+        "[-O @var{output_fmt}]",
+        "[-o @var{options}]",
+        "[--size @var{N} | [--object @var{objectdef}] [--image-opts] [-f 
@var{fmt}] [-l @var{snapshot_param}] @var{filename}]"
+    ],
+    "snapshot": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-U]",
+        "[-q]",
+        "[-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}]",
+        "@var{filename}"
+    ],
+    "rebase": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-U]",
+        "[-q]",
+        "[-f @var{fmt}]",
+        "[-t @var{cache}]",
+        "[-T @var{src_cache}]",
+        "[-p]",
+        "[-u]",
+        "-b @var{backing_file}",
+        "[-F @var{backing_fmt}]",
+        "@var{filename}"
+    ],
+    "resize": [
+        "[--object @var{objectdef}]",
+        "[--image-opts]",
+        "[-f @var{fmt}]",
+        "address@hidden",
+        "[-q]",
+        "[--shrink]",
+        "@var{filename}",
+        "[+ | address@hidden"
+    ]
+}
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
deleted file mode 100644
index 4b47f7495d..0000000000
--- a/qemu-img-cmds.hx
+++ /dev/null
@@ -1,102 +0,0 @@
-HXCOMM Keep the list of subcommands sorted by name.
-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
-
-HXCOMM When amending the TEXI sections, please remember to copy the usage
-HXCOMM over to the per-command sections in qemu-img.texi.
-
-STEXI
address@hidden @option
-ETEXI
-
-DEF("amend", img_amend,
-    "amend [--object objectdef] [--image-opts] [-p] [-q] [-f fmt] [-t cache] 
-o options filename")
-STEXI
address@hidden amend [--object @var{objectdef}] [--image-opts] [-p] [-q] [-f 
@var{fmt}] [-t @var{cache}] -o @var{options} @var{filename}
-ETEXI
-
-DEF("bench", img_bench,
-    "bench [-c count] [-d depth] [-f fmt] [--flush-interval=flush_interval] 
[-n] [--no-drain] [-o offset] [--pattern=pattern] [-q] [-s buffer_size] [-S 
step_size] [-t cache] [-w] [-U] filename")
-STEXI
address@hidden bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] 
address@hidden [-n] [--no-drain] [-o @var{offset}] address@hidden [-q] [-s 
@var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] [-U] 
@var{filename}
-ETEXI
-
-DEF("check", img_check,
-    "check [--object objectdef] [--image-opts] [-q] [-f fmt] [--output=ofmt] 
[-r [leaks | all]] [-T src_cache] [-U] filename")
-STEXI
address@hidden check [--object @var{objectdef}] [--image-opts] [-q] [-f 
@var{fmt}] address@hidden [-r [leaks | all]] [-T @var{src_cache}] [-U] 
@var{filename}
-ETEXI
-
-DEF("commit", img_commit,
-    "commit [--object objectdef] [--image-opts] [-q] [-f fmt] [-t cache] [-b 
base] [-d] [-p] filename")
-STEXI
address@hidden commit [--object @var{objectdef}] [--image-opts] [-q] [-f 
@var{fmt}] [-t @var{cache}] [-b @var{base}] [-d] [-p] @var{filename}
-ETEXI
-
-DEF("compare", img_compare,
-    "compare [--object objectdef] [--image-opts] [-f fmt] [-F fmt] [-T 
src_cache] [-p] [-q] [-s] [-U] filename1 filename2")
-STEXI
address@hidden compare [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] 
[-F @var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] [-U] @var{filename1} 
@var{filename2}
-ETEXI
-
-DEF("convert", img_convert,
-    "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] 
[-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B 
backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m 
num_coroutines] [-W] filename [filename2 [...]] output_filename")
-STEXI
address@hidden convert [--object @var{objectdef}] [--image-opts] 
[--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t 
@var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] 
[-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m 
@var{num_coroutines}] [-W] @var{filename} address@hidden [...]] 
@var{output_filename}
-ETEXI
-
-DEF("create", img_create,
-    "create [--object objectdef] [-q] [-f fmt] [-b backing_file] [-F 
backing_fmt] [-u] [-o options] filename [size]")
-STEXI
address@hidden create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-b 
@var{backing_file}] [-F @var{backing_fmt}] [-u] [-o @var{options}] 
@var{filename} address@hidden
-ETEXI
-
-DEF("dd", img_dd,
-    "dd [--image-opts] [-U] [-f fmt] [-O output_fmt] [bs=block_size] 
[count=blocks] [skip=blocks] if=input of=output")
-STEXI
address@hidden dd [--image-opts] [-U] [-f @var{fmt}] [-O @var{output_fmt}] 
address@hidden address@hidden address@hidden address@hidden address@hidden
-ETEXI
-
-DEF("info", img_info,
-    "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] [-U] filename")
-STEXI
address@hidden info [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] 
address@hidden [--backing-chain] [-U] @var{filename}
-ETEXI
-
-DEF("map", img_map,
-    "map [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-U] 
filename")
-STEXI
address@hidden map [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] 
address@hidden [-U] @var{filename}
-ETEXI
-
-DEF("measure", img_measure,
-"measure [--output=ofmt] [-O output_fmt] [-o options] [--size N | [--object 
objectdef] [--image-opts] [-f fmt] [-l snapshot_param] filename]")
-STEXI
address@hidden measure address@hidden [-O @var{output_fmt}] [-o @var{options}] 
[--size @var{N} | [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [-l 
@var{snapshot_param}] @var{filename}]
-ETEXI
-
-DEF("snapshot", img_snapshot,
-    "snapshot [--object objectdef] [--image-opts] [-U] [-q] [-l | -a snapshot 
| -c snapshot | -d snapshot] filename")
-STEXI
address@hidden snapshot [--object @var{objectdef}] [--image-opts] [-U] [-q] [-l 
| -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename}
-ETEXI
-
-DEF("rebase", img_rebase,
-    "rebase [--object objectdef] [--image-opts] [-U] [-q] [-f fmt] [-t cache] 
[-T src_cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
-STEXI
address@hidden rebase [--object @var{objectdef}] [--image-opts] [-U] [-q] [-f 
@var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-p] [-u] -b 
@var{backing_file} [-F @var{backing_fmt}] @var{filename}
-ETEXI
-
-DEF("resize", img_resize,
-    "resize [--object objectdef] [--image-opts] [-f fmt] 
[--preallocation=prealloc] [-q] [--shrink] filename [+ | -]size")
-STEXI
address@hidden resize [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] 
address@hidden [-q] [--shrink] @var{filename} [+ | address@hidden
-ETEXI
-
-STEXI
address@hidden table
-ETEXI
diff --git a/scripts/pxtool.py b/scripts/pxtool.py
new file mode 100755
index 0000000000..008fea839e
--- /dev/null
+++ b/scripts/pxtool.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import argparse
+from collections import OrderedDict
+import json
+import re
+
+# Helpers:
+def scrub_texi_string(tstring):
+    return re.sub(r"@var{([^{}]*?)}", r"\1", tstring)
+
+def human_readable_usage(usage_list):
+    return scrub_texi_string(" ".join(usage_list))
+
+def callback_name(command):
+    return "img_{:s}".format(command)
+
+# Output modes:
+def generate_def_header(conf):
+    """Print DEF() macros to be used by qemu-img.c"""
+    for command, usage_strs in conf.items():
+        print("DEF(\"{}\", {}, \"{} {}\")".format(
+            command,
+            callback_name(command),
+            command,
+            human_readable_usage(usage_strs)))
+
+def generate_texi(conf):
+    """Generate texi command summary table"""
+    print("@table @option")
+    for command, usage_strs in conf.items():
+        usage = " ".join(usage_strs)
+        print("@item {} {}".format(command, usage))
+    print("@end table")
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Generate qemu-img command 
information")
+    parser.add_argument("--macros", action="store_true", dest="macros")
+    parser.add_argument("--texi", action="store_true")
+    parser.add_argument("commands_json")
+    args = parser.parse_args()
+
+    with open(args.commands_json, "r") as f:
+        conf = json.load(f, object_pairs_hook=OrderedDict)
+
+    if args.macros:
+        generate_def_header(conf)
+    if args.texi:
+        generate_texi(conf)
-- 
2.17.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]