1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * getopt.h - a simple getopt(3) implementation. 4 * 5 * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com> 6 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 7 */ 8 9#ifndef __GETOPT_H 10#define __GETOPT_H 11 12#include <stdbool.h> 13 14/** 15 * struct getopt_state - Saved state across getopt() calls 16 */ 17struct getopt_state { 18 /** 19 * @index: Index of the next unparsed argument of @argv. If getopt() has 20 * parsed all of @argv, then @index will equal @argc. 21 */ 22 int index; 23 /* private: */ 24 /** @arg_index: Index within the current argument */ 25 int arg_index; 26 union { 27 /* public: */ 28 /** 29 * @opt: Option being parsed when an error occurs. @opt is only 30 * valid when getopt() returns ``?`` or ``:``. 31 */ 32 int opt; 33 /** 34 * @arg: The argument to an option, NULL if there is none. @arg 35 * is only valid when getopt() returns an option character. 36 */ 37 char *arg; 38 /* private: */ 39 }; 40}; 41 42/** 43 * getopt_init_state() - Initialize a &struct getopt_state 44 * @gs: The state to initialize 45 * 46 * This must be called before using @gs with getopt(). 47 */ 48void getopt_init_state(struct getopt_state *gs); 49 50int __getopt(struct getopt_state *gs, int argc, char *const argv[], 51 const char *optstring, bool silent); 52 53/** 54 * getopt() - Parse short command-line options 55 * @gs: Internal state and out-of-band return arguments. This must be 56 * initialized with getopt_init_context() beforehand. 57 * @argc: Number of arguments, not including the %NULL terminator 58 * @argv: Argument list, terminated by %NULL 59 * @optstring: Option specification, as described below 60 * 61 * getopt() parses short options. Short options are single characters. They may 62 * be followed by a required argument or an optional argument. Arguments to 63 * options may occur in the same argument as an option (like ``-larg``), or 64 * in the following argument (like ``-l arg``). An argument containing 65 * options begins with a ``-``. If an option expects no arguments, then it may 66 * be immediately followed by another option (like ``ls -alR``). 67 * 68 * @optstring is a list of accepted options. If an option is followed by ``:`` 69 * in @optstring, then it expects a mandatory argument. If an option is followed 70 * by ``::`` in @optstring, it expects an optional argument. @gs.arg points 71 * to the argument, if one is parsed. 72 * 73 * getopt() stops parsing options when it encounters the first non-option 74 * argument, when it encounters the argument ``--``, or when it runs out of 75 * arguments. For example, in ``ls -l foo -R``, option parsing will stop when 76 * getopt() encounters ``foo``, if ``l`` does not expect an argument. However, 77 * the whole list of arguments would be parsed if ``l`` expects an argument. 78 * 79 * An example invocation of getopt() might look like:: 80 * 81 * char *argv[] = { "program", "-cbx", "-a", "foo", "bar", 0 }; 82 * int opt, argc = ARRAY_SIZE(argv) - 1; 83 * struct getopt_state gs; 84 * 85 * getopt_init_state(&gs); 86 * while ((opt = getopt(&gs, argc, argv, "a::b:c")) != -1) 87 * printf("opt = %c, index = %d, arg = \"%s\"\n", opt, gs.index, gs.arg); 88 * printf("%d argument(s) left\n", argc - gs.index); 89 * 90 * and would produce an output of:: 91 * 92 * opt = c, index = 1, arg = "<NULL>" 93 * opt = b, index = 2, arg = "x" 94 * opt = a, index = 4, arg = "foo" 95 * 1 argument(s) left 96 * 97 * For further information, refer to the getopt(3) man page. 98 * 99 * Return: 100 * * An option character if an option is found. @gs.arg is set to the 101 * argument if there is one, otherwise it is set to ``NULL``. 102 * * ``-1`` if there are no more options, if a non-option argument is 103 * encountered, or if an ``--`` argument is encountered. 104 * * ``'?'`` if we encounter an option not in @optstring. @gs.opt is set to 105 * the unknown option. 106 * * ``':'`` if an argument is required, but no argument follows the 107 * option. @gs.opt is set to the option missing its argument. 108 * 109 * @gs.index is always set to the index of the next unparsed argument in @argv. 110 */ 111static inline int getopt(struct getopt_state *gs, int argc, 112 char *const argv[], const char *optstring) 113{ 114 return __getopt(gs, argc, argv, optstring, false); 115} 116 117/** 118 * getopt_silent() - Parse short command-line options silently 119 * @gs: State 120 * @argc: Argument count 121 * @argv: Argument list 122 * @optstring: Option specification 123 * 124 * Same as getopt(), except no error messages are printed. 125 */ 126static inline int getopt_silent(struct getopt_state *gs, int argc, 127 char *const argv[], const char *optstring) 128{ 129 return __getopt(gs, argc, argv, optstring, true); 130} 131 132#endif /* __GETOPT_H */ 133