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 */ 44int 45parse_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 160void 161help_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