Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | // 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; } |