1 // SPDX-License-Identifier: GPL-2.0-only
3 * getopt.c - a simple getopt(3) implementation. See getopt.h for explanation.
5 * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
6 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
9 #define LOG_CATEGORY LOGC_CORE
15 void getopt_init_state(struct getopt_state *gs)
21 int __getopt(struct getopt_state *gs, int argc, char *const argv[],
22 const char *optstring, bool silent)
24 char curopt; /* current option character */
25 const char *curoptp; /* pointer to the current option in optstring */
28 log_debug("arg_index: %d index: %d\n", gs->arg_index,
31 /* `--` indicates the end of options */
32 if (gs->arg_index == 1 && argv[gs->index] &&
33 !strcmp(argv[gs->index], "--")) {
38 /* Out of arguments */
39 if (gs->index >= argc)
42 /* Can't parse non-options */
43 if (*argv[gs->index] != '-')
46 /* We have found an option */
47 curopt = argv[gs->index][gs->arg_index];
51 * no more options in current argv[] element; try the next one
57 /* look up current option in optstring */
58 curoptp = strchr(optstring, curopt);
62 printf("%s: invalid option -- %c\n", argv[0], curopt);
68 if (*(curoptp + 1) != ':') {
69 /* option with no argument. Just return it */
75 if (*(curoptp + 1) && *(curoptp + 2) == ':') {
76 /* optional argument */
77 if (argv[gs->index][gs->arg_index + 1]) {
78 /* optional argument with directly following arg */
79 gs->arg = argv[gs->index++] + gs->arg_index + 1;
83 if (gs->index + 1 == argc) {
84 /* We are at the last argv[] element */
89 if (*argv[gs->index + 1] != '-') {
91 * optional argument with arg in next argv[] element
94 gs->arg = argv[gs->index++];
99 /* no optional argument found */
106 if (argv[gs->index][gs->arg_index + 1]) {
107 /* required argument with directly following arg */
108 gs->arg = argv[gs->index++] + gs->arg_index + 1;
116 if (gs->index >= argc || argv[gs->index][0] == '-') {
118 printf("option requires an argument -- %c\n", curopt);
123 gs->arg = argv[gs->index++];