• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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