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