[netfilter-cvslog] r3433 - in trunk/nfsim: core doc

jk at netfilter.org jk at netfilter.org
Fri Dec 17 09:32:07 CET 2004


Author: jk at netfilter.org
Date: 2004-12-17 09:32:07 +0100 (Fri, 17 Dec 2004)
New Revision: 3433

Modified:
   trunk/nfsim/core/core.c
   trunk/nfsim/core/core.h
   trunk/nfsim/core/failtest.c
   trunk/nfsim/core/usage.h
   trunk/nfsim/doc/gen-usage
Log:
Use distributed argument handling


Modified: trunk/nfsim/core/core.c
===================================================================
--- trunk/nfsim/core/core.c	2004-12-17 08:00:44 UTC (rev 3432)
+++ trunk/nfsim/core/core.c	2004-12-17 08:32:07 UTC (rev 3433)
@@ -167,8 +167,6 @@
 	       VERSION);
 }
 
-static const struct option options[] = {
-	{"echo",   0, 0, 'x'},
 /*** XML Argument:
     <section id="a:echo">
      <title><option>--echo</option>, <option>-x</option></title>
@@ -177,7 +175,12 @@
       commands are read from a file</para>
     </section>
 */
-	{"quiet",  0, 0, 'q'},
+static void cmdline_echo(struct option *opt)
+{
+	tui_echo_commands = 1;
+}
+cmdline_opt("echo", 0, 'x', cmdline_echo);
+
 /*** XML Argument:
     <section id="a:quiet">
      <title><option>--quiet</option>, <option>-q</option></title>
@@ -187,7 +190,12 @@
      </para>
     </section>
 */
-	{"exit",  0, 0, 'e'},
+static void cmdline_quiet(struct option *opt)
+{
+	tui_quiet = 1;
+}
+cmdline_opt("quiet", 0, 'q', cmdline_quiet);
+
 /*** XML Argument:
     <section id="a:exit">
      <title><option>--exit</option>, <option>-e</option></title>
@@ -198,7 +206,12 @@
      non-interactive script</para>
     </section>
 */
-	{"no-modules",  0, 0, 'N'},
+static void cmdline_abort_on_fail(struct option *opt)
+{
+	tui_abort_on_fail = 1;
+}
+cmdline_opt("exit", 0, 'e', cmdline_abort_on_fail);
+
 /*** XML Argument:
     <section id="a:no-modules">
      <title><option>--no-modules</option></title>
@@ -208,14 +221,29 @@
      this argument, use the <command>insmod</command> command</para>
     </section>
 */
-	{"version",  0, 0, 'V'},
+static bool load_modules = true;
+static void cmdline_no_modules(struct option *opt)
+{
+	load_modules = false;
+}
+cmdline_opt("no-modules", 0, 'N', cmdline_no_modules);
+
+
 /*** XML Argument:
     <section id="a:version">
      <title><option>--version</option>, <option>-V</option></title>
      <subtitle>Print the version of the simulator and kernel</subtitle>
     </section>
 */
-	{"help",  0, 0, 'h'},
+static void cmdline_version(struct option *opt)
+{
+	printf("nfsim version %s\nkernel version %s\n",
+	       VERSION, UTS_RELEASE);
+	print_license();
+	exit(EXIT_SUCCESS);
+}
+cmdline_opt("version", 0, 'V', cmdline_version);
+
 /*** XML Argument:
     <section id="a:help">
      <title><option>--help</option></title>
@@ -223,55 +251,102 @@
      <para>Causes nfsim to print its command line arguments and then exit</para>
     </section>
 */
-	{"failtest",  0, 0, 1},
-	{"failpattern",  1, 0, 2},
-	{0,        0, 0, 0 }
-};
+static void cmdline_help(struct option *opt)
+{
+	print_license();
+	print_usage();
+	exit(EXIT_SUCCESS);
+}
+cmdline_opt("help", 0, 'h', cmdline_help);
 
+extern struct cmdline_option __start_cmdline[], __stop_cmdline[];
 
+static struct cmdline_option *get_cmdline_option(int opt)
+{
+	struct cmdline_option *copt;
+
+	/* if opt is < '0', we have been passed a long option, which is
+	 * indexed directly */
+	if (opt < '0')
+		return __start_cmdline + opt;
+
+	/* otherwise search for the short option in the .val member */
+	for (copt = __start_cmdline; copt < __stop_cmdline; copt++)
+		if (copt->opt.val == opt)
+			return copt;
+
+	return NULL;
+}
+
+static struct option *get_cmdline_options(void)
+{
+	struct cmdline_option *copts;
+	struct option *opts;
+	unsigned int x, n_opts;
+
+	n_opts = ((void *)__stop_cmdline - (void *)__start_cmdline) /
+		sizeof(struct cmdline_option);
+
+	opts = talloc_zero_array(NULL, struct option, n_opts + 1);
+	copts = __start_cmdline;
+
+	for (x = 0; x < n_opts; x++) {
+		unsigned int y;
+
+		if (copts[x].opt.has_arg > 2)
+			barf("Bad argument `%s'", copts[x].opt.name);
+
+		for (y = 0; y < x; y++)
+			if ((copts[x].opt.val && copts[x].opt.val == opts[y].val)
+					|| streq(copts[x].opt.name,
+						opts[y].name))
+				barf("Conflicting arguments %s = %s\n",
+					copts[x].opt.name, opts[y].name);
+
+		opts[x] = copts[x].opt;
+		opts[x].val = x;
+	}
+
+	return opts;
+}
+
+static char *get_cmdline_optstr(void)
+{
+	struct cmdline_option *copts;
+	unsigned int x, n_opts;
+	char *optstr, tmpstr[3], *colonstr = "::";
+
+	n_opts = ((void *)__stop_cmdline - (void *)__start_cmdline) /
+		sizeof(struct cmdline_option);
+
+	optstr = talloc_size(NULL, 3 * n_opts * sizeof(*optstr) + 1);
+	*optstr = '\0';
+
+	for (x = 0; x < n_opts; x++) {
+		if (!copts[x].opt.val)
+			continue;
+		snprintf(tmpstr, 4, "%c%s", copts[x].opt.val,
+			colonstr + 2 - copts[x].opt.has_arg);
+		strcat(optstr, tmpstr);
+	}
+	return optstr;
+}
+		
 int main(int argc, char **argv)
 {
-	bool failtest = false, load_modules = true;
 	char c;
-	char *p;
-	char *failpattern = NULL;
+	char *p, *optstr;
+	struct option *options;
 
-	while ((c = getopt_long(argc, argv, "xqeNVh", options, NULL)) != EOF) {
-		switch (c) {
-		case 'x':
-			tui_echo_commands = 1;
-			break;
-		case 'q':
-			tui_quiet = 1;
-			break;
-		case 'e':
-			tui_abort_on_fail = 1;
-			break;
-		case 'N':
-			load_modules = false;
-			break;
-		case 'V':
-			printf("nfsim version %s\nkernel version %s\n",
-			       VERSION, UTS_RELEASE);
-			print_license();
-			exit(EXIT_SUCCESS);
-			break;
-		case 'h':
-			print_license();
-			print_usage(argv[0]);
-			exit(EXIT_SUCCESS);
-			break;
-		case 1:
-			failtest = true;
-			break;
-		case 2:
-			failpattern = optarg;
-			break;
-		default:
-			fprintf(stderr, "Unknown argument %c\n", c);
-			print_usage(argv[0]);
-			return EXIT_FAILURE;
-		}
+	options = get_cmdline_options();
+	optstr = get_cmdline_optstr();
+
+	while ((c = getopt_long(argc, argv, optstr, options, NULL)) != EOF) {
+		struct cmdline_option *copt = get_cmdline_option(c);
+		if (!copt)
+			barf("Unknown argument");
+
+		copt->parse(&copt->opt);
 	}
 
 	if (optind < argc) {
@@ -282,9 +357,6 @@
 		close(input);
 	}
 
-	if (failtest && isatty(STDIN_FILENO))
-		barf("Not clever enough to use --failtest interactively");
-
 	/* Hack to make users' lives easier: set LD_LIBRARY_PATH for
 	 * fakesockopt.so, based on where we are. */
 	p = strrchr(argv[0], '/');
@@ -324,11 +396,9 @@
 	
 	nfsim_log(LOG_UI, "initialisation done");
 
-	set_failtest(failtest, failpattern);
-	
 	message_init();
 
-	tui_run(!failtest, STDIN_FILENO);
+	tui_run(!get_failtest(), STDIN_FILENO);
 
 	message_cleanup();
 	unload_all_modules();

Modified: trunk/nfsim/core/core.h
===================================================================
--- trunk/nfsim/core/core.h	2004-12-17 08:00:44 UTC (rev 3432)
+++ trunk/nfsim/core/core.h	2004-12-17 08:32:07 UTC (rev 3433)
@@ -28,6 +28,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <kernelenv.h>
 
 #include <linux/list.h>
@@ -263,7 +264,7 @@
 /* For failtest to test malloc etc failures. */
 bool should_i_fail(const char *func);
 bool should_i_fail_once(const char *location);
-void set_failtest(bool failtest, const char *initial_failpattern);
+bool get_failtest(void);
 
 enum exitcodes
 {
@@ -279,4 +280,17 @@
 	__attribute__((__unused__)) \
 	__attribute__((__section__("init_call"))) = &fn
 
+/* distributed command line options */
+struct cmdline_option
+{
+       struct option opt;
+       void (*parse)(struct option *opt);
+};
+#define cmdline_opt(_name, _has_arg, _c, _fn)                                \
+       static struct cmdline_option __cat(__cmdlnopt_,__unique_id(_fn))      \
+       __attribute__((__unused__))                                           \
+       __attribute__((__section__("cmdline")))                               \
+       = { .opt = { .name = _name, .has_arg = _has_arg, .val = _c },         \
+	   .parse = _fn }
+
 #endif /* __HAVE_CORE_H */

Modified: trunk/nfsim/core/failtest.c
===================================================================
--- trunk/nfsim/core/failtest.c	2004-12-17 08:00:44 UTC (rev 3432)
+++ trunk/nfsim/core/failtest.c	2004-12-17 08:32:07 UTC (rev 3433)
@@ -50,7 +50,15 @@
      which can be replayed using <option>--failpattern</option></para>
     </section>
 */
+static void cmdline_failtest(struct option *opt)
+{
+	if (isatty(STDIN_FILENO))
+		barf("Not clever enough to use --failtest interactively");
+	failtest = true;
+}
+cmdline_opt("failtest", 0, 0, cmdline_failtest);
 
+
 /*** XML Argument:
     <section id="a:failpattern">
      <title><option>--failpattern
@@ -66,7 +74,20 @@
      automatically.</para>
     </section>
 */
+static void cmdline_failpattern(struct option *opt)
+{
+	extern char *optarg;
+	if (!optarg)
+		barf("failtest option requires an argument");
+	orig_failpattern = failpattern = optarg;
+}
+cmdline_opt("failpattern", 1, 0, cmdline_failpattern);
 
+bool get_failtest(void)
+{
+	return failtest;
+}
+
 static bool do_failpattern(const char *func)
 {
 	if (*failpattern == '[') {
@@ -162,8 +183,3 @@
 	exit(EXIT_SILENT);
 }
 
-void set_failtest(bool ft, const char *initial_failpattern)
-{
-	failtest = ft;
-	orig_failpattern = failpattern = initial_failpattern;
-}

Modified: trunk/nfsim/core/usage.h
===================================================================
--- trunk/nfsim/core/usage.h	2004-12-17 08:00:44 UTC (rev 3432)
+++ trunk/nfsim/core/usage.h	2004-12-17 08:32:07 UTC (rev 3433)
@@ -1 +1 @@
-void print_usage(const char *progname);
+void print_usage(void);

Modified: trunk/nfsim/doc/gen-usage
===================================================================
--- trunk/nfsim/doc/gen-usage	2004-12-17 08:00:44 UTC (rev 3432)
+++ trunk/nfsim/doc/gen-usage	2004-12-17 08:32:07 UTC (rev 3433)
@@ -14,7 +14,7 @@
 #include "usage.h"
 
 static const char *usagestr =
-"Usage %s [options]\n"
+"Usage: nfsim [options]\n"
 "Options available:\n"
 "\n"
 EOF
@@ -52,7 +52,8 @@
 cat <<EOF
 ;
 
-void print_usage(const char *progname) {
-	fprintf(stderr, usagestr, progname);
+void print_usage(void)
+{
+	fprintf(stderr, usagestr);
 }
 EOF




More information about the netfilter-cvslog mailing list