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