Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 223 lines (185 sloc) 4.849 kB
7216c39 @kfebert Imported Upstream version 1.5
kfebert authored
1 /* $Id: arguments.c 2553 2011-07-09 09:42:33Z tcunha $ */
2
3 /*
4 * Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "tmux.h"
25
26 /* Create an arguments set with no flags. */
27 struct args *
28 args_create(int argc, ...)
29 {
30 struct args *args;
31 va_list ap;
32 int i;
33
34 args = xcalloc(1, sizeof *args);
35 if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
36 fatal("bit_alloc failed");
37
38 args->argc = argc;
39 if (argc == 0)
40 args->argv = NULL;
41 else
42 args->argv = xcalloc(argc, sizeof *args->argv);
43
44 va_start(ap, argc);
45 for (i = 0; i < argc; i++)
46 args->argv[i] = xstrdup(va_arg(ap, char *));
47 va_end(ap);
48
49 return (args);
50 }
51
52 /* Parse an argv and argc into a new argument set. */
53 struct args *
54 args_parse(const char *template, int argc, char **argv)
55 {
56 struct args *args;
57 char *ptr;
58 int opt;
59
60 args = xcalloc(1, sizeof *args);
61 if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
62 fatal("bit_alloc failed");
63
64 optreset = 1;
65 optind = 1;
66
67 while ((opt = getopt(argc, argv, template)) != -1) {
68 if (opt < 0 || opt >= SCHAR_MAX)
69 continue;
70 if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
71 xfree(args->flags);
72 xfree(args);
73 return (NULL);
74 }
75
76 bit_set(args->flags, opt);
77 if (ptr[1] == ':') {
78 if (args->values[opt] != NULL)
79 xfree(args->values[opt]);
80 args->values[opt] = xstrdup(optarg);
81 }
82 }
83 argc -= optind;
84 argv += optind;
85
86 args->argc = argc;
87 args->argv = cmd_copy_argv(argc, argv);
88
89 return (args);
90 }
91
92 /* Free an arguments set. */
93 void
94 args_free(struct args *args)
95 {
96 u_int i;
97
98 cmd_free_argv(args->argc, args->argv);
99
100 for (i = 0; i < SCHAR_MAX; i++) {
101 if (args->values[i] != NULL)
102 xfree(args->values[i]);
103 }
104
105 xfree(args->flags);
106 xfree(args);
107 }
108
109 /* Print a set of arguments. */
110 size_t
111 args_print(struct args *args, char *buf, size_t len)
112 {
113 size_t off;
114 int i;
115 const char *quotes;
116
117 /* There must be at least one byte at the start. */
118 if (len == 0)
119 return (0);
120 off = 0;
121
122 /* Process the flags first. */
123 buf[off++] = '-';
124 for (i = 0; i < SCHAR_MAX; i++) {
125 if (!bit_test(args->flags, i) || args->values[i] != NULL)
126 continue;
127
128 if (off == len - 1) {
129 buf[off] = '\0';
130 return (len);
131 }
132 buf[off++] = i;
133 buf[off] = '\0';
134 }
135 if (off == 1)
136 buf[--off] = '\0';
137
138 /* Then the flags with arguments. */
139 for (i = 0; i < SCHAR_MAX; i++) {
140 if (!bit_test(args->flags, i) || args->values[i] == NULL)
141 continue;
142
143 if (off >= len) {
144 /* snprintf will have zero terminated. */
145 return (len);
146 }
147
148 if (strchr(args->values[i], ' ') != NULL)
149 quotes = "\"";
150 else
151 quotes = "";
152 off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
153 off != 0 ? " " : "", i, quotes, args->values[i], quotes);
154 }
155
156 /* And finally the argument vector. */
157 for (i = 0; i < args->argc; i++) {
158 if (off >= len) {
159 /* snprintf will have zero terminated. */
160 return (len);
161 }
162
163 if (strchr(args->argv[i], ' ') != NULL)
164 quotes = "\"";
165 else
166 quotes = "";
167 off += xsnprintf(buf + off, len - off, "%s%s%s%s",
168 off != 0 ? " " : "", quotes, args->argv[i], quotes);
169 }
170
171 return (off);
172 }
173
174 /* Return if an argument is present. */
175 int
176 args_has(struct args *args, u_char ch)
177 {
178 return (bit_test(args->flags, ch));
179 }
180
181 /* Set argument value. */
182 void
183 args_set(struct args *args, u_char ch, const char *value)
184 {
185 if (args->values[ch] != NULL)
186 xfree(args->values[ch]);
187 if (value != NULL)
188 args->values[ch] = xstrdup(value);
189 else
190 args->values[ch] = NULL;
191 bit_set(args->flags, ch);
192 }
193
194 /* Get argument value. Will be NULL if it isn't present. */
195 const char *
196 args_get(struct args *args, u_char ch)
197 {
198 return (args->values[ch]);
199 }
200
201 /* Convert an argument value to a number. */
202 long long
203 args_strtonum(struct args *args,
204 u_char ch, long long minval, long long maxval, char **cause)
205 {
206 const char *errstr;
207 long long ll;
208
209 if (!args_has(args, ch)) {
210 *cause = xstrdup("missing");
211 return (0);
212 }
213
214 ll = strtonum(args->values[ch], minval, maxval, &errstr);
215 if (errstr != NULL) {
216 *cause = xstrdup(errstr);
217 return (0);
218 }
219
220 *cause = NULL;
221 return (ll);
222 }
Something went wrong with that request. Please try again.