//----------------------------------------------------------------------------//
// 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