1 /* 2 * Description. 3 * 4 * Copyright (C) 1999-2013, Broadcom Corporation 5 * 6 * Permission to use, copy, modify, and/or 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 ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: miniopt.c 310902 2012-01-26 19:45:33Z $ 19 */ 20 21 /* ---- Include Files ---------------------------------------------------- */ 22 23 #include <typedefs.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <miniopt.h> 28 29 30 /* ---- Public Variables ------------------------------------------------- */ 31 /* ---- Private Constants and Types -------------------------------------- */ 32 33 34 35 /* ---- Private Variables ------------------------------------------------ */ 36 /* ---- Private Function Prototypes -------------------------------------- */ 37 /* ---- Functions -------------------------------------------------------- */ 38 39 /* ----------------------------------------------------------------------- */ 40 void 41 miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags) 42 { 43 static const char *null_flags = ""; 44 45 memset(t, 0, sizeof(miniopt_t)); 46 t->name = name; 47 if (flags == NULL) 48 t->flags = null_flags; 49 else 50 t->flags = flags; 51 t->longflags = longflags; 52 } 53 54 55 /* ----------------------------------------------------------------------- */ 56 int 57 miniopt(miniopt_t *t, char **argv) 58 { 59 int keylen; 60 char *p, *eq, *valstr, *endptr = NULL; 61 int err = 0; 62 63 t->consumed = 0; 64 t->positional = FALSE; 65 memset(t->key, 0, MINIOPT_MAXKEY); 66 t->opt = '\0'; 67 t->valstr = NULL; 68 t->good_int = FALSE; 69 valstr = NULL; 70 71 if (*argv == NULL) { 72 err = -1; 73 goto exit; 74 } 75 76 p = *argv++; 77 t->consumed++; 78 79 if (!t->opt_end && !strcmp(p, "--")) { 80 t->opt_end = TRUE; 81 if (*argv == NULL) { 82 err = -1; 83 goto exit; 84 } 85 p = *argv++; 86 t->consumed++; 87 } 88 89 if (t->opt_end) { 90 t->positional = TRUE; 91 valstr = p; 92 } 93 else if (!strncmp(p, "--", 2)) { 94 eq = strchr(p, '='); 95 if (eq == NULL && !t->longflags) { 96 fprintf(stderr, 97 "%s: missing \" = \" in long param \"%s\"\n", t->name, p); 98 err = 1; 99 goto exit; 100 } 101 keylen = eq ? (eq - (p + 2)) : (int)strlen(p) - 2; 102 if (keylen > 63) keylen = 63; 103 memcpy(t->key, p + 2, keylen); 104 105 if (eq) { 106 valstr = eq + 1; 107 if (*valstr == '\0') { 108 fprintf(stderr, 109 "%s: missing value after \" = \" in long param \"%s\"\n", 110 t->name, p); 111 err = 1; 112 goto exit; 113 } 114 } 115 } 116 else if (!strncmp(p, "-", 1)) { 117 t->opt = p[1]; 118 if (strlen(p) > 2) { 119 fprintf(stderr, 120 "%s: only single char options, error on param \"%s\"\n", 121 t->name, p); 122 err = 1; 123 goto exit; 124 } 125 if (strchr(t->flags, t->opt)) { 126 /* this is a flag option, no value expected */ 127 valstr = NULL; 128 } else { 129 if (*argv == NULL) { 130 fprintf(stderr, 131 "%s: missing value parameter after \"%s\"\n", t->name, p); 132 err = 1; 133 goto exit; 134 } 135 valstr = *argv; 136 argv++; 137 t->consumed++; 138 } 139 } else { 140 t->positional = TRUE; 141 valstr = p; 142 } 143 144 /* parse valstr as int just in case */ 145 if (valstr) { 146 t->uval = (uint)strtoul(valstr, &endptr, 0); 147 t->val = (int)t->uval; 148 t->good_int = (*endptr == '\0'); 149 } 150 151 t->valstr = valstr; 152 153 exit: 154 if (err == 1) 155 t->opt = '?'; 156 157 return err; 158 } 159