[master] 467c5bf Renovate the very old tabelization of CLI commands.

Poul-Henning Kamp phk at FreeBSD.org
Sat May 21 15:36:05 CEST 2016


commit 467c5bfb2df9efb7a9a2f99b00e07c47a65859c6
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat May 21 13:24:33 2016 +0000

    Renovate the very old tabelization of CLI commands.
    
    This makes it possible to add a "varnishd -x dumprstcli" command.

diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 8e62c67..5719720 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -45,7 +45,6 @@
 #include "cache_pool.h"
 #include "common/heritage.h"
 
-#include "vcli.h"
 #include "vcli_priv.h"
 #include "vsa.h"
 #include "vtcp.h"
@@ -589,10 +588,8 @@ ccf_listen_address(struct cli *cli, const char * const *av, void *priv)
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto vca_cmds[] = {
-	{ CLI_SERVER_START,	"i", ccf_start },
-	{ "debug.listen_address", "debug.listen_address",
-	    "\tReport the actual listen address.", 0, 0,
-	    "d", ccf_listen_address },
+	{ CLICMD_SERVER_START,		"i", ccf_start },
+	{ CLICMD_DEBUG_LISTEN_ADDRESS,	"d", ccf_listen_address },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index a1ae800..ad94900 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -423,13 +423,8 @@ cli_backend_set_health(struct cli *cli, const char * const *av, void *priv)
 /*---------------------------------------------------------------------*/
 
 static struct cli_proto backend_cmds[] = {
-	{ "backend.list", "backend.list [-p] [<backend_expression>]",
-	    "\tList backends.",
-	    0, 2, "", cli_backend_list },
-	{ "backend.set_health",
-	    "backend.set_health <backend_expression> <state>",
-	    "\tSet health status on the backends.",
-	    2, 2, "", cli_backend_set_health },
+	{ CLICMD_BACKEND_LIST,		"", cli_backend_list },
+	{ CLICMD_BACKEND_SET_HEALTH,	"", cli_backend_set_health },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c
index a9740e1..302d1e9 100644
--- a/bin/varnishd/cache/cache_ban.c
+++ b/bin/varnishd/cache/cache_ban.c
@@ -748,8 +748,8 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv)
 }
 
 static struct cli_proto ban_cmds[] = {
-	{ CLI_BAN,				"", ccf_ban },
-	{ CLI_BAN_LIST,				"", ccf_ban_list },
+	{ CLICMD_BAN,				"", ccf_ban },
+	{ CLICMD_BAN_LIST,			"", ccf_ban_list },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c
index da8ee40..337c2dc 100644
--- a/bin/varnishd/cache/cache_cli.c
+++ b/bin/varnishd/cache/cache_cli.c
@@ -110,8 +110,8 @@ CLI_Run(void)
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto cli_cmds[] = {
-	{ CLI_PING,		"i", VCLS_func_ping },
-	{ CLI_HELP,             "i", VCLS_func_help, VCLS_func_help_json, cli_cmds },
+	{ CLICMD_PING,	"i", VCLS_func_ping },
+	{ CLICMD_HELP,	"i", VCLS_func_help, VCLS_func_help_json, cli_cmds },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c
index 9840b3d..49862db 100644
--- a/bin/varnishd/cache/cache_fetch_proc.c
+++ b/bin/varnishd/cache/cache_fetch_proc.c
@@ -233,8 +233,7 @@ debug_fragfetch(struct cli *cli, const char * const *av, void *priv)
 }
 
 static struct cli_proto debug_cmds[] = {
-	{ "debug.fragfetch", "debug.fragfetch",
-		"\tEnable fetch fragmentation.", 1, 1, "d", debug_fragfetch },
+	{ CLICMD_DEBUG_FRAGFETCH,		"d", debug_fragfetch },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 04b1ee4..413affb 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -182,15 +182,11 @@ cli_debug_srandom(struct cli *cli, const char * const *av, void *priv)
 }
 
 static struct cli_proto debug_cmds[] = {
-	{ "debug.xid", "debug.xid",
-		"\tExamine or set XID.", 0, 1, "d", cli_debug_xid },
-	{ "debug.srandom", "debug.srandom",
-		"\tSeed the random(3) function.", 0, 1, "d",
-		cli_debug_srandom },
+	{ CLICMD_DEBUG_XID,			"d", cli_debug_xid },
+	{ CLICMD_DEBUG_SRANDOM,			"d", cli_debug_srandom },
 	{ NULL }
 };
 
-
 /*--------------------------------------------------------------------
  * XXX: Think more about which order we start things
  */
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index dc02731..51aeb46 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -637,9 +637,7 @@ ccf_panic(struct cli *cli, const char * const *av, void *priv)
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto debug_cmds[] = {
-	{ "debug.panic.worker", "debug.panic.worker",
-		"\tPanic the worker process.",
-		0, 0, "d", ccf_panic },
+	{ CLICMD_DEBUG_PANIC_WORKER,		"d",	ccf_panic },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 0dcaa73..8b0ac91 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -947,12 +947,12 @@ VCL_##func##_method(struct vcl *vcl, struct worker *wrk,		\
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto vcl_cmds[] = {
-	{ CLI_VCL_LOAD,		"i", ccf_config_load },
-	{ CLI_VCL_LIST,		"i", ccf_config_list },
-	{ CLI_VCL_STATE,	"i", ccf_config_state },
-	{ CLI_VCL_DISCARD,	"i", ccf_config_discard },
-	{ CLI_VCL_USE,		"i", ccf_config_use },
-	{ CLI_VCL_SHOW,		"", ccf_config_show },
+	{ CLICMD_VCL_LOAD,		"i", ccf_config_load },
+	{ CLICMD_VCL_LIST,		"i", ccf_config_list },
+	{ CLICMD_VCL_STATE,		"i", ccf_config_state },
+	{ CLICMD_VCL_DISCARD,		"i", ccf_config_discard },
+	{ CLICMD_VCL_USE,		"i", ccf_config_use },
+	{ CLICMD_VCL_SHOW,		"", ccf_config_show },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c
index b18ae1d..3904f28 100644
--- a/bin/varnishd/cache/cache_vrt_vmod.c
+++ b/bin/varnishd/cache/cache_vrt_vmod.c
@@ -183,8 +183,7 @@ ccf_debug_vmod(struct cli *cli, const char * const *av, void *priv)
 }
 
 static struct cli_proto vcl_cmds[] = {
-	{ "debug.vmod", "debug.vmod", "\tShow loaded vmods.", 0, 0,
-		"d", ccf_debug_vmod },
+	{ CLICMD_DEBUG_VMOD,			"d", ccf_debug_vmod },
 	{ NULL }
 };
 
diff --git a/bin/varnishd/hash/hash_critbit.c b/bin/varnishd/hash/hash_critbit.c
index 4b9cc6b..9ac2518 100644
--- a/bin/varnishd/hash/hash_critbit.c
+++ b/bin/varnishd/hash/hash_critbit.c
@@ -305,50 +305,6 @@ hcb_delete(struct hcb_root *r, struct objhead *oh)
 
 /*--------------------------------------------------------------------*/
 
-static void
-dumptree(struct cli *cli, uintptr_t p, int indent)
-{
-	int i;
-	const struct objhead *oh;
-	const struct hcb_y *y;
-
-	if (p == 0)
-		return;
-	if (hcb_is_node(p)) {
-		oh = hcb_l_node(p);
-		VCLI_Out(cli, "%*.*sN %d r%u <%02x%02x%02x...>\n",
-		    indent, indent, "", indent / 2, oh->refcnt,
-		    oh->digest[0], oh->digest[1], oh->digest[2]);
-		return;
-	}
-	assert(hcb_is_y(p));
-	y = hcb_l_y(p);
-	VCLI_Out(cli, "%*.*sY c %u p %u b %02x i %d\n",
-	    indent, indent, "",
-	    y->critbit, y->ptr, y->bitmask, indent / 2);
-	indent += 2;
-	for (i = 0; i < 2; i++)
-		dumptree(cli, y->leaf[i], indent);
-}
-
-static void
-hcb_dump(struct cli *cli, const char * const *av, void *priv)
-{
-
-	(void)priv;
-	(void)av;
-	VCLI_Out(cli, "HCB dump:\n");
-	dumptree(cli, hcb_root.origo, 0);
-	VCLI_Out(cli, "Coollist:\n");
-}
-
-static struct cli_proto hcb_cmds[] = {
-	{ "hcb.dump", "hcb.dump", "\tDump HCB tree.", 0, 0, "d", hcb_dump },
-	{ NULL }
-};
-
-/*--------------------------------------------------------------------*/
-
 static void * __match_proto__(bgthread_t)
 hcb_cleaner(struct worker *wrk, void *priv)
 {
@@ -384,7 +340,6 @@ hcb_start(void)
 	pthread_t tp;
 
 	(void)oh;
-	CLI_AddFuncs(hcb_cmds);
 	Lck_New(&hcb_mtx, lck_hcb);
 	WRK_BgThread(&tp, "hcb-cleaner", hcb_cleaner, NULL);
 	memset(&hcb_root, 0, sizeof hcb_root);
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index e230ee6..3d03cc3 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -67,6 +67,7 @@ void mgt_cli_telnet(const char *T_arg);
 void mgt_cli_master(const char *M_arg);
 void mgt_cli_secret(const char *S_arg);
 void mgt_cli_close_all(void);
+void mgt_DumpRstCli(void);
 
 /* mgt_jail.c */
 
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index 06e1989..293a5e2 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -57,6 +57,19 @@
 
 #include "mgt_cli.h"
 
+#define CLI_CMD(U,l,s,h,d,m,M) \
+const struct cli_cmd_desc CLICMD_##U[1] = {{ l, s, h, d, m, M }};
+#include "tbl/cli_cmds.h"
+#undef CLI_CMD
+
+static const struct cli_cmd_desc *cmds[] = {
+#define CLI_CMD(U,l,s,h,d,m,M) CLICMD_##U,
+#include "tbl/cli_cmds.h"
+#undef CLI_CMD
+};
+
+static const int ncmds = sizeof cmds / sizeof cmds[0];
+
 static int		cli_i = -1, cli_o = -1;
 static struct VCLS	*cls;
 static const char	*secret_file;
@@ -89,20 +102,20 @@ mcf_banner(struct cli *cli, const char *const *av, void *priv)
 
 /* XXX: what order should this list be in ? */
 static struct cli_proto cli_proto[] = {
-	{ CLI_BANNER,		"", mcf_banner },
-	{ CLI_SERVER_STATUS,	"", mcf_server_status },
-	{ CLI_SERVER_START,	"", mcf_server_start },
-	{ CLI_SERVER_STOP,	"", mcf_server_stop },
-	{ CLI_VCL_LOAD,		"", mcf_vcl_load },
-	{ CLI_VCL_INLINE,	"", mcf_vcl_inline },
-	{ CLI_VCL_USE,		"", mcf_vcl_use },
-	{ CLI_VCL_STATE,	"", mcf_vcl_state },
-	{ CLI_VCL_DISCARD,	"", mcf_vcl_discard },
-	{ CLI_VCL_LIST,		"", mcf_vcl_list },
-	{ CLI_PARAM_SHOW,	"", mcf_param_show },
-	{ CLI_PARAM_SET,	"", mcf_param_set },
-	{ CLI_PANIC_SHOW,	"", mcf_panic_show },
-	{ CLI_PANIC_CLEAR,	"", mcf_panic_clear },
+	{ CLICMD_BANNER,		"", mcf_banner },
+	{ CLICMD_SERVER_STATUS,		"", mcf_server_status },
+	{ CLICMD_SERVER_START,		"", mcf_server_start },
+	{ CLICMD_SERVER_STOP,		"", mcf_server_stop },
+	{ CLICMD_VCL_LOAD,		"", mcf_vcl_load },
+	{ CLICMD_VCL_INLINE,		"", mcf_vcl_inline },
+	{ CLICMD_VCL_USE,		"", mcf_vcl_use },
+	{ CLICMD_VCL_STATE,		"", mcf_vcl_state },
+	{ CLICMD_VCL_DISCARD,		"", mcf_vcl_discard },
+	{ CLICMD_VCL_LIST,		"", mcf_vcl_list },
+	{ CLICMD_PARAM_SHOW,		"", mcf_param_show },
+	{ CLICMD_PARAM_SET,		"", mcf_param_set },
+	{ CLICMD_PANIC_SHOW,		"", mcf_panic_show },
+	{ CLICMD_PANIC_CLEAR,		"", mcf_panic_clear },
 	{ NULL }
 };
 
@@ -119,10 +132,7 @@ mcf_panic(struct cli *cli, const char * const *av, void *priv)
 }
 
 static struct cli_proto cli_debug[] = {
-	{ "debug.panic.master", "debug.panic.master",
-		"\tPanic the master process.",
-		0, 0, "d", mcf_panic},
-	{ NULL }
+	{ CLICMD_DEBUG_PANIC_MASTER,		"d", mcf_panic },
 };
 
 /*--------------------------------------------------------------------*/
@@ -177,9 +187,11 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv)
 	free(q);
 }
 
+static const struct cli_cmd_desc CLICMD_WILDCARD[1] =
+    {{ "*", "<wild-card-entry>", "<fall through to cacher>", "", 0, -1 }};
+
 static struct cli_proto cli_askchild[] = {
-	{ "*", "<wild-card-entry>", "\t<fall through to cacher>\n",
-		0, 9999, "h*", mcf_askchild},
+	{ CLICMD_WILDCARD, "h*", mcf_askchild },
 	{ NULL }
 };
 
@@ -310,10 +322,10 @@ mcf_auth(struct cli *cli, const char *const *av, void *priv)
 }
 
 static struct cli_proto cli_auth[] = {
-	{ CLI_HELP,		"", VCLS_func_help, VCLS_func_help_json },
-	{ CLI_PING,		"", VCLS_func_ping },
-	{ CLI_AUTH,		"", mcf_auth },
-	{ CLI_QUIT,		"", VCLS_func_close },
+	{ CLICMD_HELP,		"", VCLS_func_help, VCLS_func_help_json },
+	{ CLICMD_PING,		"", VCLS_func_ping },
+	{ CLICMD_AUTH,		"", mcf_auth },
+	{ CLICMD_QUIT,		"", VCLS_func_close },
 	{ NULL }
 };
 
@@ -691,3 +703,36 @@ mgt_cli_master(const char *M_arg)
 	M_poker->name = "-M poker";
 	AZ(vev_add(mgt_evb, M_poker));
 }
+
+static int
+cli_cmp(const void *a, const void *b)
+{
+	struct cli_cmd_desc * const * const aa = a;
+	struct cli_cmd_desc * const * const bb = b;
+
+	return (strcmp((*aa)->request, (*bb)->request));
+}
+
+void
+mgt_DumpRstCli(void)
+{
+	const struct cli_cmd_desc *cp;
+	int i, j;
+
+	qsort(cmds, ncmds, sizeof cmds[0], cli_cmp);
+	for (i = 0; i < ncmds; i++, cp++) {
+		cp = cmds[i];
+		if (!strncmp(cp->request, "debug.", 6))
+			continue;
+		printf(".. _ref_cli_%s:\n\n", cp->syntax);
+		printf("%s\n", cp->syntax);
+		for (j = 0; j < strlen(cp->syntax); j++)
+			printf("~");
+		printf("\n");
+		printf("  %s\n", cp->help);
+		if (*cp->doc != '\0')
+			printf("\n%s\n", cp->doc);
+
+		printf("\n");
+	}
+}
diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c
index 7e598b5..47ae1ea 100644
--- a/bin/varnishd/mgt/mgt_main.c
+++ b/bin/varnishd/mgt/mgt_main.c
@@ -680,6 +680,10 @@ main(int argc, char * const *argv)
 				mgt_DumpRstVsl();
 				exit(0);
 			}
+			if (!strcmp(optarg, "dumprstcli")) {
+				mgt_DumpRstCli();
+				exit(0);
+			}
 			usage();
 			break;
 		default:
diff --git a/bin/varnishd/storage/mgt_stevedore.c b/bin/varnishd/storage/mgt_stevedore.c
index b2acaa8..644b899 100644
--- a/bin/varnishd/storage/mgt_stevedore.c
+++ b/bin/varnishd/storage/mgt_stevedore.c
@@ -70,8 +70,7 @@ stv_cli_list(struct cli *cli, const char * const *av, void *priv)
 /*--------------------------------------------------------------------*/
 
 struct cli_proto cli_stv[] = {
-	{ "storage.list", "storage.list", "\tList storage devices.",
-	    0, 0, "", stv_cli_list },
+	{ CLICMD_STORAGE_LIST,		"", stv_cli_list },
 	{ NULL}
 };
 
diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c
index d52c2cc..d439517 100644
--- a/bin/varnishd/storage/storage_persistent.c
+++ b/bin/varnishd/storage/storage_persistent.c
@@ -669,14 +669,7 @@ debug_persistent(struct cli *cli, const char * const * av, void *priv)
 }
 
 static struct cli_proto debug_cmds[] = {
-	{ "debug.persistent", "debug.persistent",
-		"Persistent debugging magic:\n"
-		"\tdebug.persistent [<stevedore> [<cmd>]]\n"
-		"With no cmd arg, a summary of the silo is returned.\n"
-		"Possible commands:\n"
-		"\tsync\tClose current segment, open a new one\n"
-		"\tdump\tinclude objcores in silo summary",
-		0, 2, "d", debug_persistent },
+	{ CLICMD_DEBUG_PERSISTENT,		"d", debug_persistent },
 	{ NULL }
 };
 
diff --git a/bin/varnishtest/tests/c00023.vtc b/bin/varnishtest/tests/c00023.vtc
index f8b6a84..74b3cc0 100644
--- a/bin/varnishtest/tests/c00023.vtc
+++ b/bin/varnishtest/tests/c00023.vtc
@@ -146,8 +146,6 @@ client c1 {
 	expect resp.http.X-Varnish == "1028 1018"
 } -run
 
-varnish v1 -cliok "hcb.dump"
-
 varnish v1 -expect sess_conn == 2
 varnish v1 -expect cache_hit == 9
 varnish v1 -expect cache_miss == 9
diff --git a/include/Makefile.am b/include/Makefile.am
index d1c2670..caae1c7 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -8,6 +8,7 @@ nobase_pkginclude_HEADERS = \
 	tbl/ban_vars.h \
 	tbl/bo_flags.h \
 	tbl/body_status.h \
+	tbl/cli_cmds.h \
 	tbl/debug_bits.h \
 	tbl/feature_bits.h \
 	tbl/http_headers.h \
diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h
new file mode 100644
index 0000000..4e9d1ba
--- /dev/null
+++ b/include/tbl/cli_cmds.h
@@ -0,0 +1,316 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2011 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * These macros define the common data for requests in the CLI protocol.
+ * The fields are:
+ *	const char *	upper-case C-ident request_name
+ *	const char *	request_name
+ *	const char *	request_syntax (for short help)
+ *	const char *	request_help (for long help)
+ *	const char *	documentation (for sphinx)
+ *	int		minimum_arguments
+ *	int		maximum_arguments
+ */
+
+CLI_CMD(BAN,
+	"ban",
+	"ban <field> <operator> <arg> [&& <field> <oper> <arg> ...]",
+	"Mark obsolete all objects where all the conditions match.",
+	"",
+	3, -1
+)
+
+CLI_CMD(BAN_LIST,
+	"ban.list",
+	"ban.list",
+	"List the active bans.",
+
+	"  The output format is:\n\n"
+	"  * Time the ban was issued.\n\n"
+	"  * Objects referencing this ban.\n\n"
+	"  * ``C`` if ban is completed = no further testing against it.\n\n"
+	"  * if ``lurker`` debugging is enabled:\n\n"
+	"    * ``R`` for req.* tests\n\n"
+	"    * ``O`` for obj.* tests\n\n"
+	"    * Pointer to ban object\n\n"
+	"  * Ban specification",
+
+	0, 0
+)
+
+CLI_CMD(VCL_LOAD,
+	"vcl.load",
+	"vcl.load <configname> <filename> [auto|cold|warm]",
+	"Compile and load the VCL file under the name provided.",
+	"",
+	2, 3
+)
+
+CLI_CMD(VCL_INLINE,
+	"vcl.inline",
+	"vcl.inline <configname> <quoted_VCLstring> [auto|cold|warm]",
+	"Compile and load the VCL data under the name provided.",
+
+	"  Multi-line VCL can be input using the here document"
+	" :ref:`ref_syntax`.",
+
+	2, 3
+)
+
+CLI_CMD(VCL_STATE,
+	"vcl.state",
+	"vcl.state <configname> [auto|cold|warm]",
+	"Force the state of the named configuration.",
+	"",
+	2, 2
+)
+
+CLI_CMD(VCL_DISCARD,
+	"vcl.discard",
+	"vcl.discard <configname>",
+	"Unload the named configuration (when possible).",
+	"",
+	1, 1
+)
+
+CLI_CMD(VCL_LIST,
+	"vcl.list",
+	"vcl.list",
+	"List all loaded configuration.",
+	"",
+	0, 0
+)
+
+CLI_CMD(VCL_SHOW,
+	"vcl.show",
+	"vcl.show [-v] <configname>",
+	"Display the source code for the specified configuration.",
+	"",
+	1, 2
+)
+
+CLI_CMD(VCL_USE,
+	"vcl.use",
+	"vcl.use <configname>",
+	"Switch to the named configuration immediately.",
+	"",
+	1, 1
+)
+
+CLI_CMD(PARAM_SHOW,
+	"param.show",
+	"param.show [-l] [<param>]",
+	"Show parameters and their values.",
+	"",
+	0, 2
+)
+
+CLI_CMD(PARAM_SET,
+	"param.set",
+	"param.set <param> <value>",
+	"Set parameter value.",
+	"",
+	2,2
+)
+
+CLI_CMD(SERVER_STOP,
+	"stop",
+	"stop",
+	"Stop the Varnish cache process.",
+	"",
+	0, 0
+)
+
+CLI_CMD(SERVER_START,
+	"start",
+	"start",
+	"Start the Varnish cache process.",
+	"",
+	0, 0
+)
+
+CLI_CMD(PING,
+	"ping",
+	"ping [<timestamp>]",
+	"Keep connection alive.",
+	"",
+	0, 1
+)
+
+CLI_CMD(HELP,
+	"help",
+	"help [<command>]",
+	"Show command/protocol help.",
+	"",
+	0, 1
+)
+
+CLI_CMD(QUIT,
+	"quit",
+	"quit",
+	"Close connection.",
+	"",
+	0, 0
+)
+
+CLI_CMD(SERVER_STATUS,
+	"status",
+	"status",
+	"Check status of Varnish cache process.",
+	"",
+	0, 0
+)
+
+CLI_CMD(BANNER,
+	"banner",
+	"banner",
+	"Print welcome banner.",
+	"",
+	0, 0
+)
+
+CLI_CMD(AUTH,
+	"auth",
+	"auth <response>",
+	"Authenticate.",
+	"",
+	1, 1
+)
+
+CLI_CMD(PANIC_SHOW,
+	"panic.show",
+	"panic.show",
+	"Return the last panic, if any.",
+	"",
+	0, 0
+)
+
+CLI_CMD(PANIC_CLEAR,
+	"panic.clear",
+	"panic.clear [-z]",
+	"Clear the last panic, if any,"
+	" -z will clear related varnishstat counter(s)",
+	"",
+	0, 1
+)
+
+CLI_CMD(DEBUG_LISTEN_ADDRESS,
+	"debug.listen_address",
+	"debug.listen_address",
+	"Report the actual listen address.",
+	"",
+	0, 0
+)
+
+CLI_CMD(BACKEND_LIST,
+	"backend.list",
+	"baclend.list [-p] [<backend_pattern>]",
+	"List backends.  -p also shows probe status.",
+	"",
+	0, 2
+)
+
+CLI_CMD(BACKEND_SET_HEALTH,
+	"backend.set_health",
+	"backend.set_health <backend_pattern> [auto|healthy|sick]",
+	"Set health status on the backends.",
+	"",
+	2, 2
+)
+
+CLI_CMD(DEBUG_FRAGFETCH,
+	"debug.fragfetch",
+	"debug.fragfetch",
+	"Enable fetch fragmentation.",
+	"",
+	1, 1
+)
+
+CLI_CMD(DEBUG_XID,
+	"debug.xid",
+	"debug.xid",
+	"Examine or set XID.",
+	"",
+	0, 1
+)
+
+CLI_CMD(DEBUG_SRANDOM,
+	"debug.srandom",
+	"debug.srandom",
+	"Seed the random(3) function.",
+	"",
+	0, 1
+)
+
+CLI_CMD(DEBUG_PANIC_WORKER,
+	"debug.panic.worker",
+	"debug.panic.worker",
+	"Panic the worker process.",
+	"",
+	0, 0
+)
+
+CLI_CMD(DEBUG_PANIC_MASTER,
+	"debug.panic.master",
+	"debug.panic.master",
+	"Panic the master process.",
+	"",
+	0, 0
+)
+
+CLI_CMD(DEBUG_VMOD,
+	"debug.vmod",
+	"debug.vmod",
+	"Show loaded vmods.",
+	"",
+	0, 0
+)
+
+CLI_CMD(DEBUG_PERSISTENT,
+	"debug.persistent",
+	"debug.persistent [<stevedore>] [<cmd>]",
+	"Persistent debugging magic:\n"
+	"With no cmd arg, a summary of the silo is returned.\n"
+	"Possible commands:\n"
+	"\tsync\tClose current segment, open a new one\n"
+	"\tdump\tinclude objcores in silo summary",
+	"",
+	0, 2
+)
+
+CLI_CMD(STORAGE_LIST,
+	"storage.list",
+	"storage.list",
+	"List storage devices.",
+	"",
+	0, 0
+)
+
diff --git a/include/vcli.h b/include/vcli.h
index de6e324..f147ef0 100644
--- a/include/vcli.h
+++ b/include/vcli.h
@@ -36,142 +36,6 @@
  */
 
 /*
- * These macros define the common data for requests in the CLI protocol.
- * The fields are:
- *	const char *	request_name
- *	const char *	request_syntax (for short help)
- *	const char *	request_help (for long help)
- *	unsigned	minimum_arguments
- *	unsigned	maximum_arguments
- */
-
-#define CLI_BAN								\
-	"ban",								\
-	"ban <field> <operator> <arg> [&& <field> <oper> <arg> ...]",	\
-	"\tMark obsolete all objects where all the conditions match.",	\
-	3, UINT_MAX
-
-#define CLI_BAN_LIST							\
-	"ban.list",							\
-	"ban.list",							\
-	"\tList the active bans.",					\
-	0, 0
-
-#define CLI_VCL_LOAD							\
-	"vcl.load",							\
-	"vcl.load <configname> <filename> [auto|cold|warm]",		\
-	"\tCompile and load the VCL file under the name provided.",	\
-	2, 3
-
-#define CLI_VCL_INLINE							\
-	"vcl.inline",							\
-	"vcl.inline <configname> <quoted_VCLstring> [auto|cold|warm]",	\
-	"\tCompile and load the VCL data under the name provided.",	\
-	2, 3
-
-#define CLI_VCL_STATE							\
-	"vcl.state",							\
-	"vcl.state <configname> [auto|cold|warm]",			\
-	"\tForce the state of the named configuration.",		\
-	2, 2
-
-#define CLI_VCL_DISCARD							\
-	"vcl.discard",							\
-	"vcl.discard <configname>",					\
-	"\tUnload the named configuration (when possible).",		\
-	1, 1
-
-#define CLI_VCL_LIST							\
-	"vcl.list",							\
-	"vcl.list",							\
-	"\tList all loaded configuration.",				\
-	0, 0
-
-#define CLI_VCL_SHOW							\
-	"vcl.show",							\
-	"vcl.show [-v] <configname>",					\
-	"\tDisplay the source code for the specified configuration.",	\
-	1, 2
-
-#define CLI_VCL_USE							\
-	"vcl.use",							\
-	"vcl.use <configname>",						\
-	"\tSwitch to the named configuration immediately.",		\
-	1, 1
-
-#define CLI_PARAM_SHOW							\
-	"param.show",							\
-	"param.show [-l] [<param>]",					\
-	"\tShow parameters and their values.",				\
-	0, 2
-
-#define CLI_PARAM_SET							\
-	"param.set",							\
-	"param.set <param> <value>",					\
-	"\tSet parameter value.",					\
-	2,2
-
-#define CLI_SERVER_STOP							\
-	"stop",								\
-	"stop",								\
-	"\tStop the Varnish cache process.",				\
-	0, 0
-
-#define CLI_SERVER_START						\
-	"start",							\
-	"start",							\
-	"\tStart the Varnish cache process.",				\
-	0, 0
-
-#define CLI_PING							\
-	"ping",								\
-	"ping [<timestamp>]",						\
-	"\tKeep connection alive.",					\
-	0, 1
-
-#define CLI_HELP							\
-	"help",								\
-	"help [<command>]",						\
-	"\tShow command/protocol help.",				\
-	0, 1
-
-#define CLI_QUIT							\
-	"quit",								\
-	"quit",								\
-	"\tClose connection.",						\
-	0, 0
-
-#define CLI_SERVER_STATUS						\
-	"status",							\
-	"status",							\
-	"\tCheck status of Varnish cache process.",			\
-	0, 0
-
-#define CLI_BANNER							\
-	"banner",							\
-	"banner",							\
-	"\tPrint welcome banner.",					\
-	0, 0
-
-#define CLI_AUTH							\
-	"auth",								\
-	"auth <response>",						\
-	"\tAuthenticate.",						\
-	1, 1
-
-#define CLI_PANIC_SHOW							\
-	"panic.show",							\
-	"panic.show",							\
-	"\tReturn the last panic, if any.",				\
-	0, 0
-
-#define CLI_PANIC_CLEAR							\
-	"panic.clear",							\
-	"panic.clear [-z]",						\
-	"\tClear the last panic, if any. -z will clear related varnishstat counter(s)",	\
-	0, 1
-
-/*
  * Status/return codes in the CLI protocol
  */
 
diff --git a/include/vcli_priv.h b/include/vcli_priv.h
index 61f5720..c1b44f0 100644
--- a/include/vcli_priv.h
+++ b/include/vcli_priv.h
@@ -37,19 +37,28 @@ struct cli;	/* NB: struct cli is opaque at this level.  */
 
 typedef void cli_func_t(struct cli*, const char * const *av, void *priv);
 
+struct cli_cmd_desc {
+	const char			*request;
+	const char			*syntax;
+	const char			*help;
+	const char			*doc;
+	int				minarg;
+	int				maxarg;
+};
+
+#define CLI_CMD(U,l,s,h,d,m,M) extern const struct cli_cmd_desc CLICMD_##U[1];
+#include "tbl/cli_cmds.h"
+#undef CLI_CMD
+
 struct cli_proto {
 	/* These must match the CLI_* macros in cli.h */
-	const char		*request;
-	const char		*syntax;
-	const char		*help;
-	unsigned		minarg;
-	unsigned		maxarg;
-	char			flags[4];
+	const struct cli_cmd_desc	*desc;
+	char				flags[4];
 
 	/* Dispatch information */
-	cli_func_t		*func;
-	cli_func_t		*jsonfunc;
-	void			*priv;
+	cli_func_t			*func;
+	cli_func_t			*jsonfunc;
+	void				*priv;
 };
 
 /* The implementation must provide these functions */
diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c
index 6e3e41f..5c3e2f5 100644
--- a/lib/libvarnish/cli_serve.c
+++ b/lib/libvarnish/cli_serve.c
@@ -138,10 +138,10 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
 		VTAILQ_FOREACH(cfn, &cs->funcs, list) {
 			if (cfn->auth > cli->auth)
 				continue;
-			for (cp = cfn->clp; cp->request != NULL; cp++) {
-				if (!strcmp(cp->request, av[2])) {
+			for (cp = cfn->clp; cp->desc != NULL; cp++) {
+				if (!strcmp(cp->desc->request, av[2])) {
 					VCLI_Out(cli, "%s\n%s\n",
-					    cp->syntax, cp->help);
+					    cp->desc->syntax, cp->desc->help);
 					return;
 				}
 				for (u = 0; u < sizeof cp->flags; u++) {
@@ -159,7 +159,7 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
 	VTAILQ_FOREACH(cfn, &cs->funcs, list) {
 		if (cfn->auth > cli->auth)
 			continue;
-		for (cp = cfn->clp; cp->request != NULL; cp++) {
+		for (cp = cfn->clp; cp->desc != NULL; cp++) {
 			d = 0;
 			h = 0;
 			i = 0;
@@ -186,8 +186,8 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
 				continue;
 			if (h && !all)
 				continue;
-			if (cp->syntax != NULL)
-				VCLI_Out(cli, "%s\n", cp->syntax);
+			if (cp->desc->syntax != NULL)
+				VCLI_Out(cli, "%s\n", cp->desc->syntax);
 		}
 	}
 }
@@ -209,7 +209,7 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
 	VTAILQ_FOREACH(cfn, &cs->funcs, list) {
 		if (cfn->auth > cli->auth)
 			continue;
-		for (cp = cfn->clp; cp->request != NULL; cp++) {
+		for (cp = cfn->clp; cp->desc != NULL; cp++) {
 			f_wc = f_i = 0;
 			for (u = 0; u < sizeof cp->flags; u++) {
 				if (cp->flags[u] == '*')
@@ -225,13 +225,13 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
 				continue;
 			VCLI_Out(cli, ",\n  {");
 			VCLI_Out(cli, "\n  \"request\": ");
-			VCLI_JSON_str(cli, cp->request);
+			VCLI_JSON_str(cli, cp->desc->request);
 			VCLI_Out(cli, ",\n  \"syntax\": ");
-			VCLI_JSON_str(cli, cp->syntax);
+			VCLI_JSON_str(cli, cp->desc->syntax);
 			VCLI_Out(cli, ",\n  \"help\": ");
-			VCLI_JSON_str(cli, cp->help);
-			VCLI_Out(cli, ",\n  \"minarg\": %d", cp->minarg);
-			VCLI_Out(cli, ", \"maxarg\": %d", cp->maxarg);
+			VCLI_JSON_str(cli, cp->desc->help);
+			VCLI_Out(cli, ",\n  \"minarg\": %d", cp->desc->minarg);
+			VCLI_Out(cli, ", \"maxarg\": %d", cp->desc->maxarg);
 			VCLI_Out(cli, ", \"flags\": ");
 			VCLI_JSON_str(cli, cp->flags);
 			VCLI_Out(cli, ", \"json\": %s",
@@ -255,13 +255,13 @@ cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
 	int json = 0;
 
 	AN(av);
-	for (cp = clp; cp->request != NULL; cp++) {
-		if (!strcmp(av[1], cp->request))
+	for (cp = clp; cp->desc != NULL; cp++) {
+		if (!strcmp(av[1], cp->desc->request))
 			break;
-		if (!strcmp("*", cp->request))
+		if (!strcmp("*", cp->desc->request))
 			break;
 	}
-	if (cp->request == NULL)
+	if (cp->desc == NULL)
 		return (0);
 
 	if (ac > 1 && !strcmp(av[2], "-j"))
@@ -278,13 +278,13 @@ cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
 		return(1);
 	}
 
-	if (ac - 1 < cp->minarg + json) {
+	if (ac - 1 < cp->desc->minarg + json) {
 		VCLI_Out(cli, "Too few parameters\n");
 		VCLI_SetResult(cli, CLIS_TOOFEW);
 		return(1);
 	}
 
-	if (ac - 1> cp->maxarg + json) {
+	if (ac - 1> cp->desc->maxarg + json) {
 		VCLI_Out(cli, "Too many parameters\n");
 		VCLI_SetResult(cli, CLIS_TOOMANY);
 		return(1);
@@ -524,7 +524,6 @@ cls_close_fd(struct VCLS *cs, struct VCLS_fd *cfd)
 	FREE_OBJ(cfd);
 }
 
-
 int
 VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp)
 {



More information about the varnish-commit mailing list