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