//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: Command line parsing utilities // // // // // // Copyright © 2018-2019 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #ifndef _KALBASE_H #include #endif #ifndef _KALEXTRAS_ARGV_H #define _KALEXTRAS_ARGV_H #ifdef __cplusplus extern "C" { #endif typedef enum CmdOptionFlag_t CmdOptionFlag_t; typedef enum CmdParserFlags_t CmdParserFlags_t; typedef enum CmdParserReturn_t CmdParserReturn_t; typedef struct CmdOption_t CmdOption_t; typedef struct CmdDocStrings_t CmdDocStrings_t; typedef struct CmdParserState_t CmdParserState_t; //------------------------------------------// // // Maximal total size of argv, including the pointers, // the pointed-to strings and their null-terminators // This is a 32-bit integer // #define ARG_MAX (1 << 16) // 64 KB //------------------------------------------// // // Flags for options // enum CmdOptionFlag_t { // The option parameter is optional KALOPT_OPTIONAL = (1 << 0), // Do not show option in any help message KALOPT_HIDDEN = (1 << 1), // This option is an alias for the previous one KALOPT_ALIAS = (1 << 2), // This isn't an option but a docstring KALOPT_DOCSTR = (1 << 3), // Only show in long help messages KALOPT_LONGDOC = (1 << 4), }; // // Flags for KalParse(CmdLine|ArgVec) // enum CmdParserFlags_t { // Don't exit on errors KALOPT_NO_EXIT = (1 << 0), // Don't react to --help KALOPT_NO_HELP = (1 << 1), // Don't react to --version KALOPT_NO_VERSION = (1 << 2), // Alias -h for --help and -V for --version KALOPT_ALIASES = (1 << 3), // Don't print any error message // Implies KALOPT_NO_EXIT KALOPT_NO_ERRORS = (1 << 4) | KALOPT_NO_EXIT, // Use KalGetProgName() instead of argv[0] // as program name KALOPT_DONT_USE_ARGV0 = (1 << 5), // Call argument parser for non-options // Non-options arguments will be indicated by // a key of 0, the argument passed as a parameter KALOPT_PARSE_ALL = (1 << 6), // Call argument parser with options and non-options in the // order they were found, instead of parsing options first KALOPT_IN_ORDER = (1 << 7) | KALOPT_PARSE_ALL, // Stay silent all along KALOPT_SILENT = KALOPT_NO_EXIT | KALOPT_NO_ERRORS | KALOPT_NO_HELP | KALOPT_NO_VERSION, }; // // Return values for the command parser // These flags can be combined and are applied in order // // "Continue" and "Break" actions do not prevent // later actions from applying // enum CmdParserReturn_t { // Continue parsing new options KALOPT_CONTINUE = 0, // Stop parsing further options KALOPT_BREAK = (1 << 0), // Show help/version message (by default, continue parsing) KALOPT_SHOWHELP = (1 << 1), KALOPT_SHOWVERS = (1 << 2), }; //------------------------------------------// // // An option for a command, e.g. "-o file" in "cc -o file" // struct CmdOption_t { // The option's name, e.g. "help" for "--help" // May be 0, but only if letter is not zero const char *longName; // The option's letter, e.g. 'h' for '-h' int letter; // Address of the variable to put the parameter into const char *param; // Option flags, see above CmdOptionFlag_t flags; // The option's help text // If this is 0, this option is hidden const char *helpText; // The option's group, for sorting during --help // Must be positive and < 256, or option won't shop up // during help texts int group; }; // // Program help/documentation strings; any can be 0 // // Help messages are printed in this format: // (letting "this" be a CmdDocStrings_t* variable) // // Usage: (this->usage) // (this->header) // // (this->groups[0]) // -o, --option-name option description // ... // ... // // (this->bottom) // // XXX progname/version // struct CmdDocStrings_t { const char *usage; const char *header; const char *bottom; // Groups documentation // groups[n] should be either 0 or contain the // description of the option group n const char **groups; }; // // The state variable passed to the parser containing useful infos // struct CmdParserState_t { // Option we're currently parsing const CmdOption_t *option; // Index (in argv) of the option we're parsing int argvIndex; // Flags passed to KalParse(CmdLine|ArgV) CmdParserFlags_t flags; // Has help/version messages been displayed already? bool shownHelp; bool shownVersion; // Output streams (may be NULL) /*FILE*/ void *outStream; /*FILE*/ void *errStream; // Private, internal data; do not touch void *priv; }; // // The argument parser function // typedef CmdParserReturn_t (*CmdParser_t)(int key, const char *param, CmdParserState_t *state); //------------------------------------------// // // Misc. simple functions // int KalComputeArgCount(const char **argv); size_t KalComputeArgVecSize(const char **argv); // // Command line to argument vector // error_t KalCmdLineToArgVecEx(const char *cmdLine, int *argcPtr, char **argv, bool doEscaping); // // KalCmdLineToArgVecEx but doEscaping = false // error_t KalCmdLineToArgVec(const char *cmdLine, int *argcPtr, char **argv); // // Argument vector to command line // error_t KalArgVecToCmdLineEx(char *cmdLine, size_t lengthMax, int argc, const char **argv, bool doUnEscaping); // // KalArgVecToCmdLineEx but doUnEscapign = false // error_t KalArgVecToCmdLine(char *cmdLine, size_t lengthMax, int argc, const char **argv); // // Command line parser; only takes an argument vector // The argv argument *will* be modified and all parsed // options and arguments will be removed, except argv[0] // which is guanranteed to be left // error_t KalParseArgVecEx(int argc, char **argv, const CmdOption_t *options, const CmdDocStrings_t *docStrings, CmdParserFlags_t *flags, CmdParser_t *parser, /*FILE*/ void *outStream, /*FILE*/ void *errStream); // // KalParseArgVecEx(argc, argv, options, docString, stdin, stdout, parser, NULL) // error_t KalParseArgVec(int argc, char **argv, const CmdOption_t *options, const CmdDocStrings_t *docStrings, CmdParserFlags_t *flags, CmdParser_t *parser); //------------------------------------------// #ifdef __cplusplus } #endif #endif