This source file includes following definitions.
- __argmatch_die
- argmatch
- argmatch_invalid
- argmatch_valid
- __xargmatch_internal
- argmatch_to_argument
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24
25 #include "argmatch.h"
26
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #define _(msgid) gettext (msgid)
33
34 #include "error.h"
35 #include "quotearg.h"
36 #include "getprogname.h"
37
38 #if USE_UNLOCKED_IO
39 # include "unlocked-io.h"
40 #endif
41
42
43
44
45 #ifndef ARGMATCH_QUOTING_STYLE
46 # define ARGMATCH_QUOTING_STYLE locale_quoting_style
47 #endif
48
49
50 #ifndef ARGMATCH_DIE
51 # include "exitfail.h"
52 # define ARGMATCH_DIE exit (exit_failure)
53 #endif
54
55 #ifdef ARGMATCH_DIE_DECL
56 ARGMATCH_DIE_DECL;
57 #endif
58
59 static void
60 __argmatch_die (void)
61 {
62 ARGMATCH_DIE;
63 }
64
65
66
67 argmatch_exit_fn argmatch_die = __argmatch_die;
68
69
70
71
72
73
74
75
76
77
78
79
80
81 ptrdiff_t
82 argmatch (const char *arg, const char *const *arglist,
83 const void *vallist, size_t valsize)
84 {
85 size_t i;
86 size_t arglen;
87 ptrdiff_t matchind = -1;
88 bool ambiguous = false;
89
90 arglen = strlen (arg);
91
92
93 for (i = 0; arglist[i]; i++)
94 {
95 if (!strncmp (arglist[i], arg, arglen))
96 {
97 if (strlen (arglist[i]) == arglen)
98
99 return i;
100 else if (matchind == -1)
101
102 matchind = i;
103 else
104 {
105
106 if (vallist == NULL
107 || memcmp ((char const *) vallist + valsize * matchind,
108 (char const *) vallist + valsize * i, valsize))
109 {
110
111
112 ambiguous = true;
113 }
114 }
115 }
116 }
117 if (ambiguous)
118 return -2;
119 else
120 return matchind;
121 }
122
123
124
125
126
127
128 void
129 argmatch_invalid (const char *context, const char *value, ptrdiff_t problem)
130 {
131 char const *format = (problem == -1
132 ? _("invalid argument %s for %s")
133 : _("ambiguous argument %s for %s"));
134
135 error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value),
136 quote_n (1, context));
137 }
138
139
140
141
142
143 void
144 argmatch_valid (const char *const *arglist,
145 const void *vallist, size_t valsize)
146 {
147 size_t i;
148 const char *last_val = NULL;
149
150
151
152 fputs (_("Valid arguments are:"), stderr);
153 for (i = 0; arglist[i]; i++)
154 if ((i == 0)
155 || memcmp (last_val, (char const *) vallist + valsize * i, valsize))
156 {
157 fprintf (stderr, "\n - %s", quote (arglist[i]));
158 last_val = (char const *) vallist + valsize * i;
159 }
160 else
161 {
162 fprintf (stderr, ", %s", quote (arglist[i]));
163 }
164 putc ('\n', stderr);
165 }
166
167
168
169
170
171
172
173 ptrdiff_t
174 __xargmatch_internal (const char *context,
175 const char *arg, const char *const *arglist,
176 const void *vallist, size_t valsize,
177 argmatch_exit_fn exit_fn)
178 {
179 ptrdiff_t res = argmatch (arg, arglist, vallist, valsize);
180 if (res >= 0)
181
182 return res;
183
184
185 argmatch_invalid (context, arg, res);
186 argmatch_valid (arglist, vallist, valsize);
187 (*exit_fn) ();
188
189 return -1;
190 }
191
192
193
194 const char *
195 argmatch_to_argument (const void *value,
196 const char *const *arglist,
197 const void *vallist, size_t valsize)
198 {
199 size_t i;
200
201 for (i = 0; arglist[i]; i++)
202 if (!memcmp (value, (char const *) vallist + valsize * i, valsize))
203 return arglist[i];
204 return NULL;
205 }
206
207 #ifdef TEST
208
209
210
211
212
213 enum backup_type
214 {
215
216 no_backups,
217
218
219 simple_backups,
220
221
222
223 numbered_existing_backups,
224
225
226 numbered_backups
227 };
228
229
230
231 static const char *const backup_args[] =
232 {
233 "no", "none", "off",
234 "simple", "never",
235 "existing", "nil",
236 "numbered", "t",
237 0
238 };
239
240 static const enum backup_type backup_vals[] =
241 {
242 no_backups, no_backups, no_backups,
243 simple_backups, simple_backups,
244 numbered_existing_backups, numbered_existing_backups,
245 numbered_backups, numbered_backups
246 };
247
248 int
249 main (int argc, const char *const *argv)
250 {
251 const char *cp;
252 enum backup_type backup_type = no_backups;
253
254 if (argc > 2)
255 {
256 fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", getprogname ());
257 exit (1);
258 }
259
260 if ((cp = getenv ("VERSION_CONTROL")))
261 backup_type = XARGMATCH ("$VERSION_CONTROL", cp,
262 backup_args, backup_vals);
263
264 if (argc == 2)
265 backup_type = XARGMATCH (getprogname (), argv[1],
266 backup_args, backup_vals);
267
268 printf ("The version control is '%s'\n",
269 ARGMATCH_TO_ARGUMENT (&backup_type, backup_args, backup_vals));
270
271 return 0;
272 }
273 #endif