From: Carl Worth Date: Thu, 16 Jun 2005 18:44:44 +0000 (+0000) Subject: * README: Update to refer to cairo instead of Xr. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=4baa6b2b7d0b62a765675d154733b8551dce2d4f;p=grrobot * 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. --- diff --git a/ChangeLog b/ChangeLog index b09591a..45823e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,9 @@ 2005-06-16 Carl Worth - * README: - * src/args.c: (args_help), (args_usage), (args_parse): + * 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. 2005-06-16 Carl Worth diff --git a/README b/README index 4be5a59..212287b 100644 --- a/README +++ b/README @@ -1,12 +1,9 @@ -grrobot - Ricochet Robot using GTK+, Xr, and libxsvg +grrobot - Ricochet Robot using GTK+ and cairo Some pointers for satisfying build dependencies: GTK+ http://gtk.org -Xr http://xr.xwin.org - (You'll need libpixregion, libic, Xc, and Xr) - -libxsvg http://xsvg.org - (You'll need libsvg, and libxsvg) +cairo http://cairographics.org + (You'll need libpixman, cairo, libsvg, and libsvg-cairo) diff --git a/src/args.c b/src/args.c index 1498dbb..9e8d34c 100644 --- a/src/args.c +++ b/src/args.c @@ -24,66 +24,95 @@ * Author: Carl Worth */ +#include #include -#include +#include +#include +#include #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[] = ""; -const char *argp_program_bug_address = ""; +static const char ARGS_PROGRAM_ARGDOC[] = "[]"; -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; - - 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; - - case ARGP_KEY_ARG: - args->file = arg; - break; - - default: - return ARGP_ERR_UNKNOWN; - } + 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 ("%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 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"); + + free (argv0_copy); } - -static struct argp argp = { options, parse_opt, args_doc, doc }; -error_t -args_parse(args_t *args, int argc, char *argv[]) +static void +args_usage (const char *argv0) { + char *argv0_copy = strdup (argv0); + char *argv0_base = basename (argv0_copy); + + printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC); + printf ("Try `%s --help' for more information.\n", argv0_base); + + free (argv0_copy); +} + +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_parse(args_t *args, int argc, char *argv[]) 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); }