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
miniopt_init(miniopt_t * t,const char * name,const char * flags,bool longflags)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
miniopt(miniopt_t * t,char ** argv)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