]> git.cworth.org Git - grrobot/blob - src/args.c
Update to 2020
[grrobot] / src / args.c
1 /* args.c - Parse command-line arguments for grrobot using argp
2  *
3  * Copyright © 2003 Carl Worth
4  *
5  * Permission to use, copy, modify, distribute, and sell this software
6  * and its documentation for any purpose is hereby granted without
7  * fee, provided that the above copyright notice appear in all copies
8  * and that both that copyright notice and this permission notice
9  * appear in supporting documentation, and that the name of Carl Worth
10  * not be used in advertising or publicity pertaining to distribution
11  * of the software without specific, written prior permission.
12  * Carl Worth makes no representations about the suitability of this
13  * software for any purpose.  It is provided "as is" without express
14  * or implied warranty.
15  * 
16  * CARL WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18  * NO EVENT SHALL CARL WORTH BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  *
24  * Author: Carl Worth <carl@theworths.org>
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <libgen.h>
31 #include <getopt.h>
32
33 #include "args.h"
34
35 static const char ARGS_PROGRAM_VERSION[] = VERSION;
36 static const char ARGS_PROGRAM_DESCRIPTION[] = "Ricochet Robot using GTK+ and cairo";
37 static const char ARGS_PROGRAM_BUG_ADDRESS[] = "<cworth@cworth.org>";
38
39 static const char ARGS_PROGRAM_ARGDOC[] = "[<file>]";
40
41 /* XXX: getopt is rather annoying in that you must maintain a
42  * string-encoding of the options in addition to the table. For
43  * example, to enable the sample display option below, one would have
44  * to add "d:" to the optstring.
45  *
46  * A useful exercise would be to write a function to generate the
47  * optstring from the table.
48  *
49  * The other annoying thing is that the table does not include help
50  * strings, so the args_help function below must also be maintained
51  * manually.
52  */
53
54 enum {
55     ARGS_VAL_HELP = 256
56 };
57
58 static const char args_optstring[] = "h:p:u:g:wHV";
59 static const struct option args_options[] = {
60     /* name,            has_arg,flag,   val */
61     {"host",            1,      0,      'h'},
62     {"port",            1,      0,      'p'},
63     {"user",            1,      0,      'u'},
64     {"game",            1,      0,      'g'},
65     {"watch",           0,      0,      'w'},
66     {"help",            0,      0,      ARGS_VAL_HELP},
67     {"version",         0,      0,      'V'},
68     { 0 }
69 };
70
71 static void
72 args_help (const char *argv0)
73 {
74     char *argv0_copy = strdup (argv0);
75     char *argv0_base = basename (argv0_copy);
76
77     printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC);
78     printf ("%s - %s\n", argv0, ARGS_PROGRAM_DESCRIPTION);
79     printf ("Connect to HOST:PORT as USER and join GAME to play ricochet robot.\n");
80     printf ("Or play locally with the position from <file> if provided.\n");
81     printf ("\n");
82     printf ("  -h, --host=HOST\tHost to connect to running rrserve [%s]\n",
83             ARGS_HOST_DEFAULT);
84     printf ("  -p, --port=PORT\tPort to connect to on HOST [%s]\n",
85             ARGS_PORT_DEFAULT);
86     printf ("  -u, --user=NAME\tUsername to connect as [%s]\n",
87             ARGS_USER_DEFAULT);
88     printf ("  -g, --game=GAME\tGame to join initially [%s]\n",
89             ARGS_GAME_DEFAULT);
90     printf ("\n");
91     printf ("  -w, --watch    \tJust watch games instead of playing\n");
92     printf ("\n");
93     printf ("  -?, --help     \tPrint this help message\n");
94     printf ("  -V, --version  \tPrint program version\n");
95
96     free (argv0_copy);
97 }
98
99 static void
100 args_usage (const char *argv0)
101 {
102     char *argv0_copy = strdup (argv0);
103     char *argv0_base = basename (argv0_copy);
104
105     printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC);
106     printf ("Try `%s --help' for more information.\n", argv0_base);
107
108     free (argv0_copy);
109 }
110
111 int
112 args_parse (args_t *args, int argc, char *argv[])
113 {
114     int c;
115
116     args->host = getenv ("RR_HOST");
117     if (args->host == NULL)
118         args->host = ARGS_HOST_DEFAULT;
119     args->port = getenv ("RR_PORT");
120     if (args->port == NULL)
121         args->port = ARGS_PORT_DEFAULT;
122     args->user = getenv ("USER");
123     if (args->user == NULL)
124         args->user = ARGS_USER_DEFAULT;
125     args->game = getenv ("RR_GAME");
126     if (args->game == NULL)
127         args->game = ARGS_GAME_DEFAULT;
128     args->watch = 0;
129
130     args->file = NULL;
131
132     while (1) {
133         c = getopt_long (argc, argv, args_optstring, args_options, NULL);
134         if (c == -1)
135             break;
136
137         switch (c) {
138         case 'h':
139             args->host = optarg;
140             break;
141         case 'p':
142             args->port = optarg;
143             break;
144         case 'u':
145             args->user = optarg;
146             break;
147         case 'g':
148             args->game = optarg;
149             break;
150         case 'w':
151             args->watch = 1;
152             break;
153         case 'V':
154             printf ("%s\n", ARGS_PROGRAM_VERSION);
155             exit (0);
156             break;
157         case ARGS_VAL_HELP:
158             args_help (argv[0]);
159             exit (0);
160             break;
161         case '?':
162             args_usage (argv[0]);
163             exit (1);
164             break;
165         default:
166             fprintf (stderr, "Unhandled option: %d\n", c);
167             exit (1);
168             break;
169         }
170     }
171  
172     if (argc - optind == 1)
173         args->file = argv[optind];
174
175     return 0;
176 }