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