This is arg_parser.info, produced by makeinfo version 4.13+ from arg_parser.texi. INFO-DIR-SECTION Libraries START-INFO-DIR-ENTRY * Arg_parser: (arg_parser). A POSIX/GNU command-line argument parser END-INFO-DIR-ENTRY  File: arg_parser.info, Node: Top, Next: Introduction, Up: (dir) Arg_parser Manual ***************** This manual is for Arg_parser (version 1.21, 10 March 2026). * Menu: * Introduction:: Purpose and features of Arg_parser * Argument syntax:: By convention, options start with a hyphen * C++ version:: Using the C++ version of Arg_parser * C version:: Using the C version of Arg_parser * C++ example:: Tutorial for the C++ version * C example:: Tutorial for the C version * Problems:: Reporting bugs * Concept index:: Index of concepts * Function index:: Index of functions, constants, and variables Copyright (C) 2006-2026 Antonio Diaz Diaz. This manual is free documentation: you have unlimited permission to copy, distribute, and modify it.  File: arg_parser.info, Node: Introduction, Next: Argument syntax, Prev: Top, Up: Top 1 Introduction ************** Arg_parser is an argument parser that follows POSIX and GNU conventions for command-line arguments. There exist C++ and C versions of Arg_parser. The C++ version is implemented as a C++ class, while the C version is implemented as a single struct plus associated functions. Both are simpler, easier to use, and safer than 'getopt_long'. For maximum stability, Arg_parser is self-contained. It extracts all the information it needs from its arguments to avoid referring to them later. This avoids index-out-of-bounds errors and allows the parser object to be passed as argument to other functions for further analysis. Arg_parser does not modify its arguments (argc, argv), nor uses any global variables. The C++ version of Arg_parser can also parse options from configuration files. Arg_parser was developed as the argument parser for GNU moe, because moe's argument parsing is rather complex. Then I used it in my other projects, including GNU ddrescue, GNU ed, lzip, GNU ocrad, tarlz, and zutils, with excellent results. 1.1 Differences with 'getopt' and 'getopt_long'. ================================================ 'getopt' parses the options one by one, which requires internal state. Part of this state is stored in several global variables, and part of it is hidden. For example, the POSIX specification of 'getopt' states that: When an element of argv[] contains multiple option characters, it is unspecified how getopt() determines which options have already been processed. Parsing the options one by one is also a lot of work for the application, which must check for errors (invalid option, missing option argument, etc) for each option. 'getopt' is the 1970s way of parsing command-line arguments. 'getopt_long' is a not-very-well-designed extension on top of 'getopt'. In addition to parsing the options one by one as 'getopt' does, 'getopt_long' accepts configuration data from two overlapping sources, which makes it easy for errors in the configuration to remain undetected. For example, a certain long option can be declared to be equivalent to a given short option, but both forms of the option may contain contradictory requirements for the option's argument. OTOH, Arg_parser parses the whole command line at once and fills a struct with the results, like 'gmtime_r' and 'stat' do. This way, errors are checked once, there is no need to permute the elements of argv, and the struct returned can be used undisturbed by later changes in argv. Finally, using Arg_parser instead of 'getopt_long' reduces the size of your source code because, as 'getopt_long' is not available on all systems, a portable program using it needs to ship its (larger) source anyway.  File: arg_parser.info, Node: Argument syntax, Next: C++ version, Prev: Introduction, Up: Top 2 Syntax of command-line arguments ********************************** POSIX recommends these conventions for command-line arguments. Arg_parser makes it easy to implement them. * A command-line argument is an option if it begins with a hyphen ('-'). * Option names are single alphanumeric characters. * Certain options require an argument. * An option and its argument may or may not appear as separate tokens. (In other words, the whitespace separating them is optional, unless the argument is the empty string). Thus, '-o foo' and '-ofoo' are equivalent. * One or more options without arguments, followed by at most one option that takes an argument, may follow a hyphen in a single token. Thus, '-abc' is equivalent to '-a -b -c'. * Options typically precede other non-option arguments. Arg_parser normally makes it appear as if all the options were specified before all the non-option arguments for the purposes of parsing, even if the user of your program intermixed options and non-option arguments. If you want the arguments in the exact order the user typed them, call 'Arg_parser' with FLAGS = 'in_order'. * The argument '--' terminates all options; any following arguments are treated as non-option arguments, even if they begin with a hyphen. * A token consisting of a single hyphen character is interpreted as an ordinary non-option argument. By convention, it is used to specify standard input, standard output, or a file named '-'. * Options may be supplied in any order, or appear multiple times. The interpretation is left up to the particular application program. GNU adds "long options" to these conventions: * A long option consists of two hyphens ('--') followed by a name made of alphanumeric characters and hyphens. Option names are typically one to three words long, with hyphens to separate words. Abbreviations can be used for the long option names as long as the abbreviations are unique. * A long option and its argument may or may not appear as separate tokens. In the latter case they must be separated by an equal sign '='. Thus, '--foo bar' and '--foo=bar' are equivalent. The syntax of options with an optional argument is '-' (without whitespace), or '--='. The syntax of options with an empty argument is '- ""', '-- ""', or '--=""'.  File: arg_parser.info, Node: C++ version, Next: C version, Prev: Argument syntax, Up: Top 3 Using the C++ version of Arg_parser ************************************* The C++ version of Arg_parser is provided in the files 'arg_parser.h' and 'arg_parser.cc'. To learn how to use Arg_parser in your C++ programs, *note C++ example::, and the file 'main.cc' in the source tarball. 3.1 Parsing arguments and reporting errors ========================================== The class 'Arg_parser' has two constructors; one to parse command-line arguments from ARGV, and the other to parse a single token from a configuration file or other source. -- Data Type: struct Option This structure describes a single option for the sake of 'Arg_parser'. The argument OPTIONS must be an array of these structures, one for each option. Terminate the array with an element containing a code which is zero. 'struct Option' has the following members: -- Member: 'int' code This member is the code that identifies the option, normally the short-option character. Must be different from 0. A code value outside the unsigned char range means a long-only option. -- Member: 'const char *' long_name This member is the long option name. It is a zero-terminated string. A null or empty long_name means a short-only option. -- Member: 'enum Has_arg' has_arg This member says whether the option takes an argument. It has four valid values: 'no', 'yes', 'maybe', and 'yesme', meaning respectively 'no argument', 'non-empty argument required', 'optional argument', and 'argument required, but it may be the empty string'. 'yesme' is not recommended. If an empty argument is passed to an option specified as 'yesme', it must be in a separate command-line argument or specified as a long option with the empty string after the '=' character. It can't be specified as the empty string after the short option. -- Data Type: enum Flags The argument FLAGS is a bit mask. You can bitwise-OR the following constants and assign them to FLAGS to modify the way in which the arguments are parsed. FLAGS = 0 chooses the default behavior (reorder the options to put them before the non-option arguments). -- Constant: 'Flags' in_order Store the arguments in the exact order the user typed them, without reordering the options to put them before the non-option arguments. -- Constant: 'Flags' in_order_stop Stop option processing when finding the first non-option argument as if the argument '--' had been found before it. Store the first non-option argument and all the arguments following it as non-option arguments, even if they begin with a hyphen. This is similar to the POSIX function 'getopt', which stops option processing after finding the first non-option argument. -- Constant: 'Flags' in_order_skip Parse only the heading options. Skip the first non-option argument and all the arguments following it; do not parse nor store them. The function 'argv_index' returns the index in ARGV of the first argument skipped (the first non-option argument), or ARGC if no arguments were skipped. This mode is useful for parsing the command line of programs that invoke other programs, like 'timeout', 'xargs', or 'valgrind'. -- Constant: 'Flags' neg_non_opt Parse the negative numbers, including '-inf', '-Inf', and '-INF', as non-option arguments without reordering them. Numbers start with a digit or a period and a digit. This mode is useful for parsing the command line of tools like 'seq' which take negative numbers as arguments. -- Function: Arg_parser ( const int ARGC, const char * const ARGV[], const Option OPTIONS[], const int FLAGS = 0 ) Constructor. Reads the arguments in ARGV and parses all options, option arguments, and non-option arguments contained in them. In case of error, 'error().size()' returns nonzero. -- Function: Arg_parser ( const char * const OPT, const char * const ARG, const Option OPTIONS[] ) Restricted constructor. Parses a single token (plus an optional second token in case an argument is needed for an option parsed). Can be used to parse options from a configuration file one at a time. Be warned that a single token may produce an undefined number of short options. In case of error, 'error().size()' returns nonzero. -- Function: const std::string & error () const Use this funtion to check that the arguments have been correctly parsed by the constructor. If there was an error parsing the arguments, 'error' returns an error message explaining the cause, else it returns an empty string. -- Function: int argv_index () const Return the index in ARGV of the first argument skipped (the first non-option argument) when FLAGS was set to 'in_order_skip'. If no arguments were skipped, ARGC is returned instead. 3.2 Reading the options and arguments parsed ============================================ After a successful call to the constructor, which must be checked by calling 'error', the options and arguments parsed can be accessed by means of the following functions: -- Function: int arguments () const This function returns the number of options and non-option arguments parsed. This number is usually different from argc. -- Function: int code ( const int I ) const This function returns the code of the option at position I. Valid values for I range from 0 to 'arguments() - 1'. If the code returned is nonzero, 'argument(I)' is the option's argument (or is empty if the option does not have an argument). If the code returned is zero, 'argument(I)' is a non-option argument. -- Function: const std::string & parsed_name ( const int I ) const This function returns the full name of the option parsed (short or long) at position I. It may be useful to produce more accurate diagnostic messages. For non-option arguments it returns the empty string. -- Function: const std::string & argument ( const int I ) const This function returns the argument at position I. It may be the argument of an option or a non-option argument, depending on the value returned by 'code(I)'. Valid values for I range from 0 to 'arguments() - 1'. If the argument does not exist, the empty string is returned.  File: arg_parser.info, Node: C version, Next: C++ example, Prev: C++ version, Up: Top 4 Using the C version of Arg_parser *********************************** The C version of Arg_parser is provided in the files 'carg_parser.h' and 'carg_parser.c'. To learn how to use Arg_parser in your C programs, *note C example::, and the file 'cmain.c' in the source tarball. 4.1 Parsing arguments and reporting errors ========================================== You need to declare a variable of type 'Arg_parser', pass its address to 'ap_init' to initialize it, and check that 'ap_error' returns 0. 'struct ap_Option' is identical to 'struct Option', except that 'Has_arg' becomes 'ap_Has_arg', and the names of its four values are also prefixed with 'ap_'. *Note struct Option::, for details about the members. 'enum ap_Flags' is identical to 'enum Flags', except that its constants are also prefixed with 'ap_'. *Note enum Flags::, for a description of the constants. -- Function: char ap_init ( Arg_parser * const AP, const int ARGC, const char * const ARGV[], const ap_Option OPTIONS[], const int FLAGS ) Reads the arguments in ARGV and parses all options, option arguments, and non-option arguments contained in them. Returns 0 if there is not enough memory, else 1 (even if errors are found). In case of error, 'ap_error' returns a non-null pointer. -- Function: void ap_free ( Arg_parser * const AP ) Frees all dynamically allocated data structures. -- Function: const char * ap_error ( const Arg_parser * const AP ) Use this funtion to check that the arguments have been correctly parsed by 'ap_init'. If there was an error parsing the arguments, 'ap_error' returns a pointer to an error message explaining the cause, else it returns a null pointer. -- Function: int ap_argv_index ( const Arg_parser * const AP ) Return the index in ARGV of the first argument skipped (the first non-option argument) when FLAGS was set to 'ap_in_order_skip'. If no arguments were skipped, ARGC is returned instead. 4.2 Reading the options and arguments parsed ============================================ After a successful call to 'ap_init', which must be checked by calling 'ap_error', the options and arguments parsed can be accessed by means of the following functions: -- Function: int ap_arguments ( const Arg_parser * const AP ) This function returns the number of options and non-option arguments parsed. This number is usually different from argc. -- Function: int ap_code ( const Arg_parser * const AP, const int I ) This function returns the code of the option at position I. Valid values for I range from 0 to 'ap_arguments() - 1'. If the code returned is nonzero, 'ap_argument(I)' is the option's argument (or is empty if the option does not have an argument). If the code returned is zero, 'ap_argument(I)' is a non-option argument. -- Function: const char * ap_parsed_name ( const Arg_parser * const AP, const int I ) This function returns the full name of the option parsed (short or long) at position I. It may be useful to produce more accurate diagnostic messages. For non-option arguments it returns the empty string. -- Function: const char * ap_argument ( const Arg_parser * const AP, const int I ) This function returns the argument at position I. It may be the argument of an option or a non-option argument, depending on the value returned by 'ap_code(I)'. Valid values for I range from 0 to 'ap_arguments() - 1'. If the argument does not exist, the empty string is returned. When you are finished, you should free all dynamically allocated data structures by calling 'ap_free'.  File: arg_parser.info, Node: C++ example, Next: C example, Prev: C version, Up: Top 5 Tutorial for the C++ version ****************************** This tutorial uses lzip as an example of how to use Arg_parser in a C++ program. You need to follow these 6 steps: First copy the files 'arg_parser.h' and 'arg_parser.cc' in your source tree, in the same directory as the file containing the function 'main' of your program. In lzip, 'main' is in 'main.cc'. Second, include these header files near the top of 'main.cc': #include #include #include "arg_parser.h" Third, define inside 'main' the option names and argument requirements. Lzip defines the following options: const Arg_parser::Option options[] = { { '0', "fast", Arg_parser::no }, { '1', 0, Arg_parser::no }, { '2', 0, Arg_parser::no }, { '3', 0, Arg_parser::no }, { '4', 0, Arg_parser::no }, { '5', 0, Arg_parser::no }, { '6', 0, Arg_parser::no }, { '7', 0, Arg_parser::no }, { '8', 0, Arg_parser::no }, { '9', "best", Arg_parser::no }, { 'a', "trailing-error", Arg_parser::no }, { 'b', "member-size", Arg_parser::yes }, { 'c', "stdout", Arg_parser::no }, { 'd', "decompress", Arg_parser::no }, { 'f', "force", Arg_parser::no }, { 'F', "recompress", Arg_parser::no }, { 'h', "help", Arg_parser::no }, { 'k', "keep", Arg_parser::no }, { 'l', "list", Arg_parser::no }, { 'm', "match-length", Arg_parser::yes }, { 'n', "threads", Arg_parser::yes }, { 'o', "output", Arg_parser::yes }, { 'q', "quiet", Arg_parser::no }, { 's', "dictionary-size", Arg_parser::yes }, { 'S', "volume-size", Arg_parser::yes }, { 't', "test", Arg_parser::no }, { 'v', "verbose", Arg_parser::no }, { 'V', "version", Arg_parser::no }, { opt_lt, "loose-trailing", Arg_parser::no }, { 0, 0, Arg_parser::no } }; Fourth, declare and initialize the parser: const Arg_parser parser( argc, argv, options ); if( parser.error().size() ) // bad option { show_error( parser.error().c_str(), 0, true ); return 1; } Fifth, perform the actions corresponding to each option parsed. Lzip performs the following actions: int argind = 0; for( ; argind < parser.arguments(); ++argind ) { const int code = parser.code( argind ); if( !code ) break; // no more options const char * const pn = parser.parsed_name( argind ).c_str(); const std::string & sarg = parser.argument( argind ); const char * const arg = sarg.c_str(); switch( code ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': zero = code == '0'; encoder_options = option_mapping[code-'0']; break; case 'a': cl_opts.ignore_trailing = false; break; case 'b': member_size = getnum(arg, pn, 100000, max_member_size); break; case 'c': to_stdout = true; break; case 'd': set_mode( program_mode, m_decompress ); break; case 'f': force = true; break; case 'F': recompress = true; break; case 'h': show_help(); return 0; case 'k': keep_input_files = true; break; case 'l': set_mode( program_mode, m_list ); break; case 'm': encoder_options.match_len_limit = getnum( arg, pn, min_match_len_limit, max_match_len ); zero = false; break; case 'n': break; // ignored case 'o': if( sarg == "-" ) to_stdout = true; else { default_output_filename = sarg; } break; case 'q': verbosity = -1; break; case 's': encoder_options.dictionary_size = get_dict_size( arg, pn ); zero = false; break; case 'S': volume_size = getnum(arg, pn, 100000, max_volume_size); break; case 't': set_mode( program_mode, m_test ); break; case 'v': if( verbosity < 4 ) ++verbosity; break; case 'V': show_version(); return 0; case opt_lt: cl_opts.loose_trailing = true; break; default: internal_error( "uncaught option." ); } } // end process options Sixth, process any remaining non-option arguments (file names in the case of lzip): std::vector< std::string > filenames; bool filenames_given = false; for( ; argind < parser.arguments(); ++argind ) { filenames.push_back( parser.argument( argind ) ); if( filenames.back() != "-" ) filenames_given = true; } if( filenames.empty() ) filenames.push_back("-"); // do something with 'filenames'  File: arg_parser.info, Node: C example, Next: Problems, Prev: C++ example, Up: Top 6 Tutorial for the C version **************************** This tutorial uses GNU ed as an example of how to use Arg_parser in a C program. You need to follow these 6 steps: First copy the files 'carg_parser.h' and 'carg_parser.c' in your source tree, in the same directory as the file containing the function 'main' of your program. In GNU ed, 'main' is in 'main.c'. Second, include the header 'carg_parser.h' near the top of 'main.c': #include "carg_parser.h" Third, define inside 'main' the option names and argument requirements. Ed defines the following options: const ap_Option options[] = { { 'E', "extended-regexp", ap_no }, { 'G', "traditional", ap_no }, { 'h', "help", ap_no }, { 'l', "loose-exit-status", ap_no }, { 'p', "prompt", ap_yes }, { 'q', "quiet", ap_no }, { 'q', "silent", ap_no }, { 'r', "restricted", ap_no }, { 's', "script", ap_no }, { 'v', "verbose", ap_no }, { 'V', "version", ap_no }, { opt_cr, "strip-trailing-cr", ap_no }, { opt_un, "unsafe-names", ap_no }, { 0, 0, ap_no } }; Fourth, declare and initialize the parser: Arg_parser parser; if( !ap_init( &parser, argc, argv, options, 0 ) ) { show_error( "Memory exhausted.", 0, false ); return 1; } if( ap_error( &parser ) ) /* bad option */ { show_error( ap_error( &parser ), 0, true ); return 1; } Fifth, perform the actions corresponding to each option parsed. Ed performs the following actions: int argind = 0; for( ; argind < ap_arguments( &parser ); ++argind ) { const int code = ap_code( &parser, argind ); if( !code ) break; /* no more options */ const char * const arg = ap_argument( &parser, argind ); switch( code ) { case 'E': extended_regexp_ = true; break; case 'G': traditional_ = true; break; /* backward compatibility */ case 'h': show_help(); return 0; case 'l': loose = true; break; case 'p': if( set_prompt( arg ) ) break; else return 1; case 'q': quiet = true; break; case 'r': restricted_ = true; break; case 's': scripted_ = true; break; case 'v': set_verbose(); break; case 'V': show_version(); return 0; case opt_cr: strip_cr_ = true; break; case opt_un: safe_names = false; break; default: show_error( "internal error: uncaught option.", 0, false ); return 3; } } /* end process options */ Sixth, process any remaining non-option arguments (line number and file name in the case of ed): for( ; argind < ap_arguments( &parser ); ++argind ) { const char * const arg = ap_argument( &parser, argind ); /* do something with 'arg' */ }  File: arg_parser.info, Node: Problems, Next: Concept index, Prev: C example, Up: Top 7 Reporting bugs **************** There are probably bugs in Arg_parser. There are certainly errors and omissions in this manual. If you report them, they will get fixed. If you don't, no one will ever know about them and they will remain unfixed for all eternity, if not longer. If you find a bug in Arg_parser, please send electronic mail to . Include the version number, which you can find by running 'arg_parser --version'.  File: arg_parser.info, Node: Concept index, Next: Function index, Prev: Problems, Up: Top Concept index ************* [index] * Menu: * argument syntax: Argument syntax. (line 6) * bugs: Problems. (line 6) * C example: C example. (line 6) * C version: C version. (line 6) * C++ example: C++ example. (line 6) * C++ version: C++ version. (line 6) * getting help: Problems. (line 6) * introduction: Introduction. (line 6)  File: arg_parser.info, Node: Function index, Prev: Concept index, Up: Top Index of constants and variables ******************************** [index] * Menu: * code: C++ version. (line 24) * has_arg: C++ version. (line 33) * in_order: C++ version. (line 51) * in_order_skip: C++ version. (line 64) * in_order_stop: C++ version. (line 56) * long_name: C++ version. (line 29) * neg_non_opt: C++ version. (line 73) Index of functions ****************** [index] * Menu: * ap_argument: C version. (line 72) * ap_arguments: C version. (line 53) * ap_argv_index: C version. (line 41) * ap_code: C version. (line 57) * ap_error: C version. (line 35) * ap_free: C version. (line 32) * ap_init: C version. (line 26) * ap_parsed_name: C version. (line 65) * Arg_parser: C++ version. (line 81) * argument: C++ version. (line 129) * arguments: C++ version. (line 112) * argv_index: C++ version. (line 100) * code: C++ version. (line 116) * error: C++ version. (line 94) * parsed_name: C++ version. (line 123)  Tag Table: Node: Top224 Node: Introduction1048 Node: Argument syntax3879 Node: C++ version6484 Ref: struct Option7131 Ref: enum Flags8551 Node: C version13221 Node: C++ example17007 Node: C example21870 Node: Problems24803 Node: Concept index25353 Node: Function index26117  End Tag Table  Local Variables: coding: iso-8859-15 End: