123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * getopt.c - a simple getopt(3) implementation. See getopt.h for explanation.
- *
- * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
- * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- */
- #define LOG_CATEGORY LOGC_CORE
- #include <common.h>
- #include <getopt.h>
- #include <log.h>
- void getopt_init_state(struct getopt_state *gs)
- {
- gs->index = 1;
- gs->arg_index = 1;
- }
- int __getopt(struct getopt_state *gs, int argc, char *const argv[],
- const char *optstring, bool silent)
- {
- char curopt; /* current option character */
- const char *curoptp; /* pointer to the current option in optstring */
- while (1) {
- log_debug("arg_index: %d index: %d\n", gs->arg_index,
- gs->index);
- /* `--` indicates the end of options */
- if (gs->arg_index == 1 && argv[gs->index] &&
- !strcmp(argv[gs->index], "--")) {
- gs->index++;
- return -1;
- }
- /* Out of arguments */
- if (gs->index >= argc)
- return -1;
- /* Can't parse non-options */
- if (*argv[gs->index] != '-')
- return -1;
- /* We have found an option */
- curopt = argv[gs->index][gs->arg_index];
- if (curopt)
- break;
- /*
- * no more options in current argv[] element; try the next one
- */
- gs->index++;
- gs->arg_index = 1;
- }
- /* look up current option in optstring */
- curoptp = strchr(optstring, curopt);
- if (!curoptp) {
- if (!silent)
- printf("%s: invalid option -- %c\n", argv[0], curopt);
- gs->opt = curopt;
- gs->arg_index++;
- return '?';
- }
- if (*(curoptp + 1) != ':') {
- /* option with no argument. Just return it */
- gs->arg = NULL;
- gs->arg_index++;
- return curopt;
- }
- if (*(curoptp + 1) && *(curoptp + 2) == ':') {
- /* optional argument */
- if (argv[gs->index][gs->arg_index + 1]) {
- /* optional argument with directly following arg */
- gs->arg = argv[gs->index++] + gs->arg_index + 1;
- gs->arg_index = 1;
- return curopt;
- }
- if (gs->index + 1 == argc) {
- /* We are at the last argv[] element */
- gs->arg = NULL;
- gs->index++;
- return curopt;
- }
- if (*argv[gs->index + 1] != '-') {
- /*
- * optional argument with arg in next argv[] element
- */
- gs->index++;
- gs->arg = argv[gs->index++];
- gs->arg_index = 1;
- return curopt;
- }
- /* no optional argument found */
- gs->arg = NULL;
- gs->arg_index = 1;
- gs->index++;
- return curopt;
- }
- if (argv[gs->index][gs->arg_index + 1]) {
- /* required argument with directly following arg */
- gs->arg = argv[gs->index++] + gs->arg_index + 1;
- gs->arg_index = 1;
- return curopt;
- }
- gs->index++;
- gs->arg_index = 1;
- if (gs->index >= argc || argv[gs->index][0] == '-') {
- if (!silent)
- printf("option requires an argument -- %c\n", curopt);
- gs->opt = curopt;
- return ':';
- }
- gs->arg = argv[gs->index++];
- return curopt;
- }
|