1/*
2 * Description.
3 *
4 * Copyright (C) 1999-2010, Broadcom Corporation
5 *
6 *      Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
11 *
12 *      As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module.  An independent module is a module which is not
17 * derived from this software.  The special exception does not apply to any
18 * modifications of the software.
19 *
20 *      Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
23 * $Id: miniopt.c,v 1.1.6.4 2009/09/25 00:32:01 Exp $
24 */
25
26/* ---- Include Files ---------------------------------------------------- */
27
28#include <typedefs.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include "miniopt.h"
33
34
35/* ---- Public Variables ------------------------------------------------- */
36/* ---- Private Constants and Types -------------------------------------- */
37
38
39
40/* ---- Private Variables ------------------------------------------------ */
41/* ---- Private Function Prototypes -------------------------------------- */
42/* ---- Functions -------------------------------------------------------- */
43
44/* ----------------------------------------------------------------------- */
45void
46miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags)
47{
48	static const char *null_flags = "";
49
50	memset(t, 0, sizeof(miniopt_t));
51	t->name = name;
52	if (flags == NULL)
53		t->flags = null_flags;
54	else
55		t->flags = flags;
56	t->longflags = longflags;
57}
58
59
60/* ----------------------------------------------------------------------- */
61int
62miniopt(miniopt_t *t, char **argv)
63{
64	int keylen;
65	char *p, *eq, *valstr, *endptr = NULL;
66	int err = 0;
67
68	t->consumed = 0;
69	t->positional = FALSE;
70	memset(t->key, 0, MINIOPT_MAXKEY);
71	t->opt = '\0';
72	t->valstr = NULL;
73	t->good_int = FALSE;
74	valstr = NULL;
75
76	if (*argv == NULL) {
77		err = -1;
78		goto exit;
79	}
80
81	p = *argv++;
82	t->consumed++;
83
84	if (!t->opt_end && !strcmp(p, "--")) {
85		t->opt_end = TRUE;
86		if (*argv == NULL) {
87			err = -1;
88			goto exit;
89		}
90		p = *argv++;
91		t->consumed++;
92	}
93
94	if (t->opt_end) {
95		t->positional = TRUE;
96		valstr = p;
97	}
98	else if (!strncmp(p, "--", 2)) {
99		eq = strchr(p, '=');
100		if (eq == NULL && !t->longflags) {
101			fprintf(stderr,
102				"%s: missing \" = \" in long param \"%s\"\n", t->name, p);
103			err = 1;
104			goto exit;
105		}
106		keylen = eq ? (eq - (p + 2)) : (int)strlen(p) - 2;
107		if (keylen > 63) keylen = 63;
108		memcpy(t->key, p + 2, keylen);
109
110		if (eq) {
111			valstr = eq + 1;
112			if (*valstr == '\0') {
113				fprintf(stderr,
114				        "%s: missing value after \" = \" in long param \"%s\"\n",
115				        t->name, p);
116				err = 1;
117				goto exit;
118			}
119		}
120	}
121	else if (!strncmp(p, "-", 1)) {
122		t->opt = p[1];
123		if (strlen(p) > 2) {
124			fprintf(stderr,
125				"%s: only single char options, error on param \"%s\"\n",
126				t->name, p);
127			err = 1;
128			goto exit;
129		}
130		if (strchr(t->flags, t->opt)) {
131			/* this is a flag option, no value expected */
132			valstr = NULL;
133		} else {
134			if (*argv == NULL) {
135				fprintf(stderr,
136				"%s: missing value parameter after \"%s\"\n", t->name, p);
137				err = 1;
138				goto exit;
139			}
140			valstr = *argv;
141			argv++;
142			t->consumed++;
143		}
144	} else {
145		t->positional = TRUE;
146		valstr = p;
147	}
148
149	/* parse valstr as int just in case */
150	if (valstr) {
151		t->uval = (uint)strtoul(valstr, &endptr, 0);
152		t->val = (int)t->uval;
153		t->good_int = (*endptr == '\0');
154	}
155
156	t->valstr = valstr;
157
158exit:
159	if (err == 1)
160		t->opt = '?';
161
162	return err;
163}
164