[Commit] grrobot/src args.c,1.4,1.5

Carl Worth commit at keithp.com
Thu Jun 16 11:42:19 PDT 2005


Committed by: cworth

Update of /local/src/CVS/grrobot/src
In directory home.keithp.com:/tmp/cvs-serv2189/src

Modified Files:
	args.c 
Log Message:

        * README: Update to refer to cairo instead of Xr.

        * src/args.c: (args_help), (args_usage), (args_parse): Fix
        command-line option parsing. Use getopt rather than argp.


Index: args.c
===================================================================
RCS file: /local/src/CVS/grrobot/src/args.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- args.c	16 Jun 2005 18:11:46 -0000	1.4
+++ args.c	16 Jun 2005 18:42:16 -0000	1.5
@@ -24,66 +24,95 @@
  * Author: Carl Worth <carl at theworths.org>
  */
 
+#include <stdio.h>
 #include <stdlib.h>
-#include <argp.h>
+#include <string.h>
+#include <libgen.h>
+#include <getopt.h>
 
 #include "args.h"
 
-const char *argp_program_version = "grrobot " VERSION;
+static const char ARGS_PROGRAM_VERSION[] = VERSION;
+static const char ARGS_PROGRAM_DESCRIPTION[] = "Ricochet Robot using GTK+ and cairo";
+static const char ARGS_PROGRAM_BUG_ADDRESS[] = "<cworth at cworth.org>";
 
-const char *argp_program_bug_address = "<carl at theworths.org>";
+static const char ARGS_PROGRAM_ARGDOC[] = "[<file>]";
 
-static char doc[] = "grrobot - Ricochet Robot using GTK+ and Xr";
+/* XXX: getopt is rather annoying in that you must maintain a
+ * string-encoding of the options in addition to the table. For
+ * example, to enable the sample display option below, one would have
+ * to add "d:" to the optstring.
+ *
+ * A useful exercise would be to write a function to generate the
+ * optstring from the table.
+ *
+ * The other annoying thing is that the table does not include help
+ * strings, so the args_help function below must also be maintained
+ * manually.
+ */
 
-static char args_doc[] = "[file]";
+enum {
+    ARGS_VAL_HELP = 256
+};
 
-static struct option options[] = {
-    {"host",		required_argument,	0,	'h'},
-    {"port",		required_argument,	0,	'p'},
-    {"user",		required_argument,	0,	'u'},
-    {"game",		required_argument,	0,	'g'},
-    {"watch",		no_argument,		0,	'w'},
-    {0, 		0,			0,	0}
+static const char args_optstring[] = "h:p:u:g:wHV";
+static const struct option args_options[] = {
+    /* name,		has_arg,flag,	val */
+    {"host",		1,	0,	'h'},
+    {"port",		1,	0,	'p'},
+    {"user",		1,	0,	'u'},
+    {"game",		1,	0,	'g'},
+    {"watch",		0,	0,	'w'},
+    {"help",		0,	0,	ARGS_VAL_HELP},
+    {"version",		0,	0,	'V'},
+    { 0 }
 };
 
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
+static void
+args_help (const char *argv0)
 {
-    struct args *args = state->input;
+    char *argv0_copy = strdup (argv0);
+    char *argv0_base = basename (argv0_copy);
 
-    switch (key) {
-    case 'h':
-	args->host = arg;
-	break;
-    case 'p':
-	args->port = arg;
-	break;
-    case 'u':
-	args->user = arg;
-	break;
-    case 'g':
-	args->game = arg;
-	break;
-    case 'w':
-	args->watch = 1;
-	break;
+    printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC);
+    printf ("%s - %s\n", argv0, ARGS_PROGRAM_DESCRIPTION);
+    printf ("Connect to HOST:PORT as USER and join GAME to play ricochet robot.\n");
+    printf ("Or play locally with the position from <file> if provided.\n");
+    printf ("\n");
+    printf ("  -h, --host=HOST\tHost to connect to running rrserve [%s]\n",
+	    ARGS_HOST_DEFAULT);
+    printf ("  -p, --port=PORT\tPort to connect to on HOST [%s]\n",
+	    ARGS_PORT_DEFAULT);
+    printf ("  -u, --user=NAME\tUsername to connect as [%s]\n",
+	    ARGS_USER_DEFAULT);
+    printf ("  -g, --game=GAME\tGame to join initially [%s]\n",
+	    ARGS_GAME_DEFAULT);
+    printf ("\n");
+    printf ("  -w, --watch    \tJust watch games instead of playing\n");
+    printf ("\n");
+    printf ("  -?, --help     \tPrint this help message\n");
+    printf ("  -V, --version  \tPrint program version\n");
 
-    case ARGP_KEY_ARG:
-	args->file = arg;
-	break;
+    free (argv0_copy);
+}
 
-    default:
-	return ARGP_ERR_UNKNOWN;
-    }
+static void
+args_usage (const char *argv0)
+{
+    char *argv0_copy = strdup (argv0);
+    char *argv0_base = basename (argv0_copy);
 
-    return 0;
+    printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC);
+    printf ("Try `%s --help' for more information.\n", argv0_base);
+
+    free (argv0_copy);
 }
-	    
-static struct argp argp = { options, parse_opt, args_doc, doc };
 
-error_t
-args_parse(args_t *args, int argc, char *argv[])
+int
+args_parse (args_t *args, int argc, char *argv[])
 {
+    int c;
+
     args->host = getenv ("RR_HOST");
     if (args->host == NULL)
 	args->host = ARGS_HOST_DEFAULT;
@@ -99,8 +128,49 @@
     args->watch = 0;
 
     args->file = NULL;
+
+    while (1) {
+	c = getopt_long (argc, argv, args_optstring, args_options, NULL);
+	if (c == -1)
+	    break;
+
+	switch (c) {
+	case 'h':
+	    args->host = optarg;
+	    break;
+	case 'p':
+	    args->port = optarg;
+	    break;
+	case 'u':
+	    args->user = optarg;
+	    break;
+	case 'g':
+	    args->game = optarg;
+	    break;
+	case 'w':
+	    args->watch = 1;
+	    break;
+	case 'V':
+	    printf ("%s\n", ARGS_PROGRAM_VERSION);
+	    exit (0);
+	    break;
+	case ARGS_VAL_HELP:
+	    args_help (argv[0]);
+	    exit (0);
+	    break;
+	case '?':
+	    args_usage (argv[0]);
+	    exit (1);
+	    break;
+	default:
+	    fprintf (stderr, "Unhandled option: %d\n", c);
+	    exit (1);
+	    break;
+	}
+    }
+ 
+    if (argc - optind == 1)
+	args->file = argv[optind];
+
     return 0;
-    return argp_parse (&argp, argc, argv,
-		       ARGP_LONG_ONLY,
-		       NULL, args);
 }




More information about the Commit mailing list