u-boot/lib/getopt.c
Tom Rini 467382ca03 lib: Remove <common.h> inclusion from these files
After some header file cleanups to add missing include files, remove
common.h from all files in the lib directory. This primarily means just
dropping the line but in a few cases we need to add in other header
files now.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Rini <trini@konsulko.com>
2023-12-21 08:54:37 -05:00

125 lines
2.7 KiB
C

// 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 <getopt.h>
#include <log.h>
#include <linux/string.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;
}