1 /*
2 * Generic Options Support Header File
3 *
4 * Copyright (c) 2001 Stanislav Karchebny <berk@madfire.net>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of other contributors
15 * may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include <util.h>
31 #include <ctype.h>
32
33 #include "yasm-options.h"
34
35
36 #ifdef __DEBUG__
37 #define DEBUG(x) fprintf ## x ;
38 #else
39 #define DEBUG(x)
40 #endif
41
42
43 /* Options Parser */
44 int
parse_cmdline(int argc,char ** argv,opt_option * options,size_t nopts,void (* print_error)(const char * fmt,...))45 parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts,
46 void (*print_error) (const char *fmt, ...))
47 {
48 int errors = 0, warnings = 0;
49 size_t i;
50 int got_it;
51
52 DEBUG((stderr, "parse_cmdline: entered\n"));
53
54 fail:
55 while (--argc) {
56 argv++;
57
58 if (argv[0][0] == '-') { /* opt */
59 got_it = 0;
60 if (argv[0][1] == '-') { /* lopt */
61 if (argv[0][2] == '\0') { /* --, end of options */
62 /* Handle rest of args as non-options */
63 while (--argc) {
64 argv++;
65 if (not_an_option_handler(argv[0]))
66 errors++;
67 }
68 return errors;
69 }
70
71 for (i = 0; i < nopts; i++) {
72 size_t optlen;
73 if (options[i].lopt &&
74 strncmp(&argv[0][2], options[i].lopt,
75 (optlen = strlen(options[i].lopt))) == 0) {
76 char *param;
77 char c = argv[0][2 + optlen];
78
79 if (c != '\0' && c != '=' && !isspace(c))
80 continue;
81
82 if (options[i].takes_param) {
83 param = strchr(&argv[0][2], '=');
84 if (!param) {
85 print_error(
86 _("option `--%s' needs an argument!"),
87 options[i].lopt);
88 errors++;
89 goto fail;
90 } else {
91 *param = '\0';
92 param++;
93 }
94 } else
95 param = NULL;
96
97 if (!options[i].
98 handler(&argv[0][2], param, options[i].extra))
99 got_it = 1;
100 break;
101 }
102 }
103 if (!got_it && !other_option_handler(argv[0]))
104 got_it = 1;
105 if (!got_it) {
106 print_error(_("warning: unrecognized option `%s'"),
107 argv[0]);
108 warnings++;
109 }
110 } else if (argv[0][1] == '\0') { /* just -, is non-option */
111 if (not_an_option_handler(argv[0]))
112 errors++;
113 } else { /* sopt */
114 for (i = 0; i < nopts; i++) {
115 if (argv[0][1] == options[i].sopt) {
116 char *cmd = &argv[0][1];
117 char *param;
118
119 if (options[i].takes_param) {
120 param = argv[1];
121 if (argv[0][2] != '\0')
122 param = &argv[0][2];
123 else if (param == NULL || *param == '-') {
124 print_error(
125 _("option `-%c' needs an argument!"),
126 options[i].sopt);
127 errors++;
128 goto fail;
129 } else {
130 argc--;
131 argv++;
132 }
133 } else
134 param = NULL;
135
136 if (!options[i].handler(cmd, param, options[i].extra))
137 got_it = 1;
138 break;
139 }
140 }
141 if (!got_it && !other_option_handler(argv[0]))
142 got_it = 1;
143 if (!got_it) {
144 print_error(_("warning: unrecognized option `%s'"),
145 argv[0]);
146 warnings++;
147 }
148 }
149 } else { /* not an option, then it should be a file or something */
150
151 if (not_an_option_handler(argv[0]))
152 errors++;
153 }
154 }
155
156 DEBUG((stderr, "parse_cmdline: finished\n"));
157 return errors;
158 }
159
160 void
help_msg(const char * msg,const char * tail,opt_option * options,size_t nopts)161 help_msg(const char *msg, const char *tail, opt_option *options, size_t nopts)
162 {
163 char optbuf[100], optopt[100];
164 size_t i;
165
166 printf("%s", gettext(msg));
167
168 for (i = 0; i < nopts; i++) {
169 size_t shortopt_len = 0;
170 size_t longopt_len = 0;
171
172 optbuf[0] = 0;
173 optopt[0] = 0;
174
175 if (options[i].takes_param) {
176 if (options[i].sopt) {
177 sprintf(optbuf, "-%c <%s>", options[i].sopt,
178 options[i].param_desc ? options[i].
179 param_desc : _("param"));
180 shortopt_len = strlen(optbuf);
181 }
182 if (options[i].sopt && options[i].lopt)
183 strcat(optbuf, ", ");
184 if (options[i].lopt) {
185 sprintf(optopt, "--%s=<%s>", options[i].lopt,
186 options[i].param_desc ? options[i].
187 param_desc : _("param"));
188 strcat(optbuf, optopt);
189 longopt_len = strlen(optbuf);
190 }
191 } else {
192 if (options[i].sopt) {
193 sprintf(optbuf, "-%c", options[i].sopt);
194 shortopt_len = strlen(optbuf);
195 }
196 if (options[i].sopt && options[i].lopt)
197 strcat(optbuf, ", ");
198 if (options[i].lopt) {
199 sprintf(optopt, "--%s", options[i].lopt);
200 strcat(optbuf, optopt);
201 longopt_len = strlen(optbuf);
202 }
203 }
204
205 /* split [-s <desc>], [--long <desc>] if it destroys columns */
206 if (shortopt_len && longopt_len && longopt_len > 22) {
207 optbuf[shortopt_len] = '\0';
208 printf(" %-22s %s\n", optopt, gettext(options[i].description));
209 printf(" %s\n", optbuf);
210 }
211 else
212 printf(" %-22s %s\n", optbuf, gettext(options[i].description));
213 }
214
215 printf("%s", gettext(tail));
216 }
217