669 lines
26 KiB
Text
669 lines
26 KiB
Text
\input texinfo @c -*-texinfo-*-
|
|
@c %**start of header
|
|
@setfilename arg_parser.info
|
|
@documentencoding ISO-8859-15
|
|
@settitle Arg_parser Manual
|
|
@finalout
|
|
@c %**end of header
|
|
|
|
@set UPDATED 10 March 2026
|
|
@set VERSION 1.21
|
|
|
|
@dircategory Libraries
|
|
@direntry
|
|
* Arg_parser: (arg_parser). A POSIX/GNU command-line argument parser
|
|
@end direntry
|
|
|
|
|
|
@ifnothtml
|
|
@titlepage
|
|
@title Arg_parser
|
|
@subtitle A POSIX/GNU command-line argument parser
|
|
@subtitle for Arg_parser version @value{VERSION}, @value{UPDATED}
|
|
@author by Antonio Diaz Diaz
|
|
|
|
@page
|
|
@vskip 0pt plus 1filll
|
|
@end titlepage
|
|
|
|
@contents
|
|
@end ifnothtml
|
|
|
|
@ifnottex
|
|
@node Top
|
|
@top
|
|
|
|
This manual is for Arg_parser (version @value{VERSION}, @value{UPDATED}).
|
|
|
|
@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
|
|
@end menu
|
|
|
|
@sp 1
|
|
Copyright @copyright{} 2006-2026 Antonio Diaz Diaz.
|
|
|
|
This manual is free documentation: you have unlimited permission to copy,
|
|
distribute, and modify it.
|
|
@end ifnottex
|
|
|
|
|
|
@node Introduction
|
|
@chapter Introduction
|
|
@cindex introduction
|
|
|
|
@uref{http://www.nongnu.org/arg-parser/arg_parser.html,,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 @samp{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
|
|
@uref{http://www.gnu.org/software/moe/moe.html,,GNU moe}, because moe's
|
|
argument parsing is rather complex. Then I used it in my other projects,
|
|
including
|
|
@uref{http://www.gnu.org/software/ddrescue/ddrescue.html,,GNU ddrescue},
|
|
@uref{http://www.gnu.org/software/ed/ed.html,,GNU ed},
|
|
@uref{http://www.nongnu.org/lzip/lzip.html,,lzip},
|
|
@uref{http://www.gnu.org/software/ocrad/ocrad.html,,GNU ocrad},
|
|
@uref{http://www.nongnu.org/lzip/tarlz.html,,tarlz}, and
|
|
@uref{http://www.nongnu.org/zutils/zutils.html,,zutils}, with excellent
|
|
results.
|
|
|
|
@section Differences with @samp{getopt} and @samp{getopt_long}.
|
|
|
|
@samp{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 @samp{getopt} states that:
|
|
@quotation
|
|
When an element of argv[] contains multiple option characters, it is
|
|
unspecified how getopt() determines which options have already been
|
|
processed.
|
|
@end quotation
|
|
|
|
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. @samp{getopt} is the 1970s way of parsing command-line
|
|
arguments.
|
|
|
|
@samp{getopt_long} is a not-very-well-designed extension on top of
|
|
@samp{getopt}. In addition to parsing the options one by one as
|
|
@samp{getopt} does, @samp{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 @samp{gmtime_r} and @samp{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 @samp{getopt_long} reduces the size of
|
|
your source code because, as @samp{getopt_long} is not available on all
|
|
systems, a portable program using it needs to ship its (larger) source
|
|
anyway.
|
|
|
|
|
|
@node Argument syntax
|
|
@chapter Syntax of command-line arguments
|
|
@cindex argument syntax
|
|
|
|
POSIX recommends these conventions for command-line arguments.
|
|
Arg_parser makes it easy to implement them.
|
|
|
|
@itemize @bullet
|
|
@item A command-line argument is an option if it begins with a hyphen
|
|
(@samp{-}).
|
|
|
|
@item Option names are single alphanumeric characters.
|
|
|
|
@item Certain options require an argument.
|
|
|
|
@item 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, @w{@option{-o foo}} and @option{-ofoo} are equivalent.
|
|
|
|
@item 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, @option{-abc} is equivalent to @w{@option{-a -b -c}}.
|
|
|
|
@item 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
|
|
@samp{Arg_parser} with @w{@var{flags} = @samp{in_order}}.
|
|
|
|
@item The argument @samp{--} terminates all options; any following arguments
|
|
are treated as non-option arguments, even if they begin with a hyphen.
|
|
|
|
@item 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 @samp{-}.
|
|
|
|
@item Options may be supplied in any order, or appear multiple times.
|
|
The interpretation is left up to the particular application program.
|
|
@end itemize
|
|
|
|
GNU adds @dfn{long options} to these conventions:
|
|
|
|
@itemize @bullet
|
|
@item A long option consists of two hyphens (@samp{--}) 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.
|
|
|
|
@item 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 @samp{=}.
|
|
Thus, @w{@option{--foo bar}} and @option{--foo=bar} are equivalent.
|
|
@end itemize
|
|
|
|
The syntax of options with an optional argument is
|
|
@option{-<short_option><argument>} (without whitespace), or
|
|
@option{--<long_option>=<argument>}.
|
|
|
|
The syntax of options with an empty argument is @option{-<short_option> ""},
|
|
@option{--<long_option> ""}, or @option{--<long_option>=""}.
|
|
|
|
|
|
@node C++ version
|
|
@chapter Using the C++ version of Arg_parser
|
|
@cindex C++ version
|
|
|
|
The C++ version of Arg_parser is provided in the files @file{arg_parser.h}
|
|
and @file{arg_parser.cc}. To learn how to use Arg_parser in your C++
|
|
programs, @pxref{C++ example}, and the file @file{main.cc} in the
|
|
@uref{http://download.savannah.nongnu.org/releases/arg-parser/,,source tarball}.
|
|
|
|
@section Parsing arguments and reporting errors
|
|
|
|
The class @samp{Arg_parser} has two constructors; one to parse command-line
|
|
arguments from @var{argv}, and the other to parse a single token from a
|
|
configuration file or other source.
|
|
|
|
@anchor{struct Option}
|
|
@deftp {Data Type} struct Option
|
|
This structure describes a single option for the sake of @samp{Arg_parser}.
|
|
The argument @var{options} must be an array of these structures, one for
|
|
each option. Terminate the array with an element containing a code which is
|
|
zero. @samp{struct Option} has the following members:
|
|
|
|
@deftypevr Member @code{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.
|
|
@end deftypevr
|
|
|
|
@deftypevr Member @code{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.
|
|
@end deftypevr
|
|
|
|
@deftypevr Member @code{enum Has_arg} has_arg
|
|
This member says whether the option takes an argument. It has four valid
|
|
values: @samp{no}, @samp{yes}, @samp{maybe}, and @samp{yesme}, meaning
|
|
respectively @samp{no argument}, @samp{non-empty argument required},
|
|
@samp{optional argument}, and @samp{argument required, but it may be the
|
|
empty string}. @samp{yesme} is not recommended.
|
|
|
|
If an empty argument is passed to an option specified as @samp{yesme}, it
|
|
must be in a separate command-line argument or specified as a long option
|
|
with the empty string after the @samp{=} character. It can't be specified as
|
|
the empty string after the short option.
|
|
@end deftypevr
|
|
@end deftp
|
|
|
|
@anchor{enum Flags}
|
|
@deftp {Data Type} enum Flags
|
|
The argument @var{flags} is a bit mask. You can bitwise-OR the following
|
|
constants and assign them to @var{flags} to modify the way in which the
|
|
arguments are parsed. @w{@var{flags} = 0} chooses the default behavior
|
|
(reorder the options to put them before the non-option arguments).
|
|
|
|
@deftypevr Constant @code{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.
|
|
@end deftypevr
|
|
|
|
@deftypevr Constant @code{Flags} in_order_stop
|
|
Stop option processing when finding the first non-option argument as if the
|
|
argument @samp{--} 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 @samp{getopt},
|
|
which stops option processing after finding the first non-option argument.
|
|
@end deftypevr
|
|
|
|
@deftypevr Constant @code{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
|
|
@samp{argv_index} returns the index in @var{argv} of the first argument
|
|
skipped (the first non-option argument), or @var{argc} if no arguments were
|
|
skipped. This mode is useful for parsing the command line of programs that
|
|
invoke other programs, like @command{timeout}, @command{xargs}, or
|
|
@command{valgrind}.
|
|
@end deftypevr
|
|
|
|
@deftypevr Constant @code{Flags} neg_non_opt
|
|
Parse the negative numbers, including @samp{-inf}, @samp{-Inf}, and
|
|
@samp{-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 @command{seq} which take negative numbers as
|
|
arguments.
|
|
@end deftypevr
|
|
@end deftp
|
|
|
|
@defun Arg_parser ( const int @var{argc}, const char * const @var{argv}[], const Option @var{options}[], const int @var{flags} = 0 )
|
|
Constructor. Reads the arguments in @var{argv} and parses all options,
|
|
option arguments, and non-option arguments contained in them. In case of
|
|
error, @samp{error().size()} returns nonzero.
|
|
@end defun
|
|
|
|
@defun Arg_parser ( const char * const @var{opt}, const char * const @var{arg}, const Option @var{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,
|
|
@samp{error().size()} returns nonzero.
|
|
@end defun
|
|
|
|
@deftypefun {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, @samp{error}
|
|
returns an error message explaining the cause, else it returns an empty
|
|
string.
|
|
@end deftypefun
|
|
|
|
@deftypefun {int} argv_index () const
|
|
Return the index in @var{argv} of the first argument skipped (the first
|
|
non-option argument) when @var{flags} was set to @samp{in_order_skip}. If no
|
|
arguments were skipped, @var{argc} is returned instead.
|
|
@end deftypefun
|
|
|
|
@section Reading the options and arguments parsed
|
|
|
|
After a successful call to the constructor, which must be checked by calling
|
|
@samp{error}, the options and arguments parsed can be accessed by means of
|
|
the following functions:
|
|
|
|
@deftypefun int arguments () const
|
|
This function returns the number of options and non-option arguments parsed.
|
|
This number is usually different from argc.
|
|
@end deftypefun
|
|
|
|
@deftypefun int code ( const int @var{i} ) const
|
|
This function returns the code of the option at position @var{i}. Valid
|
|
values for @var{i} range from 0 to @w{@samp{arguments() - 1}}. If the code
|
|
returned is nonzero, @samp{argument(@var{i})} is the option's argument (or
|
|
is empty if the option does not have an argument). If the code returned is
|
|
zero, @samp{argument(@var{i})} is a non-option argument.
|
|
@end deftypefun
|
|
|
|
@deftypefun {const std::string &} parsed_name ( const int @var{i} ) const
|
|
This function returns the full name of the option parsed (short or long) at
|
|
position @var{i}. It may be useful to produce more accurate diagnostic
|
|
messages. For non-option arguments it returns the empty string.
|
|
@end deftypefun
|
|
|
|
@deftypefun {const std::string &} argument ( const int @var{i} ) const
|
|
This function returns the argument at position @var{i}. It may be the
|
|
argument of an option or a non-option argument, depending on the value
|
|
returned by @samp{code(@var{i})}. Valid values for @var{i} range from 0 to
|
|
@w{@samp{arguments() - 1}}. If the argument does not exist, the empty string
|
|
is returned.
|
|
@end deftypefun
|
|
|
|
|
|
@node C version
|
|
@chapter Using the C version of Arg_parser
|
|
@cindex C version
|
|
|
|
The C version of Arg_parser is provided in the files @file{carg_parser.h}
|
|
and @file{carg_parser.c}. To learn how to use Arg_parser in your C programs,
|
|
@pxref{C example}, and the file @file{cmain.c} in the
|
|
@uref{http://download.savannah.nongnu.org/releases/arg-parser/,,source tarball}.
|
|
|
|
@section Parsing arguments and reporting errors
|
|
|
|
You need to declare a variable of type @samp{Arg_parser}, pass its address
|
|
to @samp{ap_init} to initialize it, and check that @samp{ap_error} returns 0.
|
|
|
|
@samp{struct ap_Option} is identical to @samp{struct Option}, except that
|
|
@samp{Has_arg} becomes @samp{ap_Has_arg}, and the names of its four values
|
|
are also prefixed with @samp{ap_}. @xref{struct Option}, for details about
|
|
the members.
|
|
|
|
@samp{enum ap_Flags} is identical to @samp{enum Flags}, except that its
|
|
constants are also prefixed with @samp{ap_}. @xref{enum Flags}, for a
|
|
description of the constants.
|
|
|
|
@deftypefun char ap_init ( Arg_parser * const @var{ap}, const int @var{argc}, const char * const @var{argv}[], const ap_Option @var{options}[], const int @var{flags} )
|
|
Reads the arguments in @var{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, @samp{ap_error}
|
|
returns a non-null pointer.
|
|
@end deftypefun
|
|
|
|
@deftypefun void ap_free ( Arg_parser * const @var{ap} )
|
|
Frees all dynamically allocated data structures.
|
|
@end deftypefun
|
|
|
|
@deftypefun {const char *} ap_error ( const Arg_parser * const @var{ap} )
|
|
Use this funtion to check that the arguments have been correctly parsed by
|
|
@samp{ap_init}. If there was an error parsing the arguments, @samp{ap_error}
|
|
returns a pointer to an error message explaining the cause, else it returns
|
|
a null pointer.
|
|
@end deftypefun
|
|
|
|
@deftypefun {int} ap_argv_index ( const Arg_parser * const @var{ap} )
|
|
Return the index in @var{argv} of the first argument skipped (the first
|
|
non-option argument) when @var{flags} was set to @samp{ap_in_order_skip}. If
|
|
no arguments were skipped, @var{argc} is returned instead.
|
|
@end deftypefun
|
|
|
|
@section Reading the options and arguments parsed
|
|
|
|
After a successful call to @samp{ap_init}, which must be checked by calling
|
|
@samp{ap_error}, the options and arguments parsed can be accessed by means
|
|
of the following functions:
|
|
|
|
@deftypefun int ap_arguments ( const Arg_parser * const @var{ap} )
|
|
This function returns the number of options and non-option arguments parsed.
|
|
This number is usually different from argc.
|
|
@end deftypefun
|
|
|
|
@deftypefun int ap_code ( const Arg_parser * const @var{ap}, const int @var{i} )
|
|
This function returns the code of the option at position @var{i}. Valid
|
|
values for @var{i} range from 0 to @w{@samp{ap_arguments() - 1}}. If the
|
|
code returned is nonzero, @samp{ap_argument(@var{i})} is the option's
|
|
argument (or is empty if the option does not have an argument). If the code
|
|
returned is zero, @samp{ap_argument(@var{i})} is a non-option argument.
|
|
@end deftypefun
|
|
|
|
@deftypefun {const char *} ap_parsed_name ( const Arg_parser * const @var{ap}, const int @var{i} )
|
|
This function returns the full name of the option parsed (short or long) at
|
|
position @var{i}. It may be useful to produce more accurate diagnostic
|
|
messages. For non-option arguments it returns the empty string.
|
|
@end deftypefun
|
|
|
|
@deftypefun {const char *} ap_argument ( const Arg_parser * const @var{ap}, const int @var{i} )
|
|
This function returns the argument at position @var{i}. It may be the
|
|
argument of an option or a non-option argument, depending on the value
|
|
returned by @samp{ap_code(@var{i})}. Valid values for @var{i} range from 0
|
|
to @w{@samp{ap_arguments() - 1}}. If the argument does not exist, the empty
|
|
string is returned.
|
|
@end deftypefun
|
|
|
|
When you are finished, you should free all dynamically allocated data
|
|
structures by calling @samp{ap_free}.
|
|
|
|
|
|
@node C++ example
|
|
@chapter Tutorial for the C++ version
|
|
@cindex C++ example
|
|
|
|
This tutorial uses @uref{http://www.nongnu.org/lzip/lzip.html,,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 @file{arg_parser.h} and @file{arg_parser.cc} in your
|
|
source tree, in the same directory as the file containing the function
|
|
@samp{main} of your program. In lzip, @samp{main} is in @file{main.cc}.
|
|
|
|
Second, include these header files near the top of @file{main.cc}:
|
|
|
|
@verbatim
|
|
#include <string>
|
|
#include <vector>
|
|
#include "arg_parser.h"
|
|
@end verbatim
|
|
|
|
Third, define inside @samp{main} the option names and argument requirements.
|
|
Lzip defines the following options:
|
|
|
|
@verbatim
|
|
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 } };
|
|
@end verbatim
|
|
|
|
Fourth, declare and initialize the parser:
|
|
|
|
@verbatim
|
|
const Arg_parser parser( argc, argv, options );
|
|
if( parser.error().size() ) // bad option
|
|
{ show_error( parser.error().c_str(), 0, true ); return 1; }
|
|
@end verbatim
|
|
|
|
Fifth, perform the actions corresponding to each option parsed. Lzip
|
|
performs the following actions:
|
|
|
|
@verbatim
|
|
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
|
|
@end verbatim
|
|
|
|
Sixth, process any remaining non-option arguments (file names in the case of
|
|
lzip):
|
|
|
|
@verbatim
|
|
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'
|
|
@end verbatim
|
|
|
|
|
|
@node C example
|
|
@chapter Tutorial for the C version
|
|
@cindex C example
|
|
|
|
This tutorial uses @uref{http://www.gnu.org/software/ed/ed.html,,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 @file{carg_parser.h} and @file{carg_parser.c} in your
|
|
source tree, in the same directory as the file containing the function
|
|
@samp{main} of your program. In GNU ed, @samp{main} is in @file{main.c}.
|
|
|
|
Second, include the header @file{carg_parser.h} near the top of @file{main.c}:
|
|
|
|
@verbatim
|
|
#include "carg_parser.h"
|
|
@end verbatim
|
|
|
|
Third, define inside @samp{main} the option names and argument requirements.
|
|
Ed defines the following options:
|
|
|
|
@verbatim
|
|
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 } };
|
|
@end verbatim
|
|
|
|
Fourth, declare and initialize the parser:
|
|
|
|
@verbatim
|
|
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; }
|
|
@end verbatim
|
|
|
|
Fifth, perform the actions corresponding to each option parsed. Ed performs
|
|
the following actions:
|
|
|
|
@verbatim
|
|
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 */
|
|
@end verbatim
|
|
|
|
Sixth, process any remaining non-option arguments (line number and file
|
|
name in the case of ed):
|
|
|
|
@verbatim
|
|
for( ; argind < ap_arguments( &parser ); ++argind )
|
|
{
|
|
const char * const arg = ap_argument( &parser, argind );
|
|
/* do something with 'arg' */
|
|
}
|
|
@end verbatim
|
|
|
|
|
|
@node Problems
|
|
@chapter Reporting bugs
|
|
@cindex bugs
|
|
@cindex getting help
|
|
|
|
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
|
|
@email{arg-parser-bug@@nongnu.org}. Include the version number, which
|
|
you can find by running @w{@samp{arg_parser --version}}.
|
|
|
|
|
|
@node Concept index
|
|
@unnumbered Concept index
|
|
|
|
@printindex cp
|
|
|
|
@node Function index
|
|
@unnumbered Index of constants and variables
|
|
|
|
@printindex vr
|
|
|
|
@sp 1
|
|
@unnumbered Index of functions
|
|
|
|
@printindex fn
|
|
|
|
@bye
|