#ifndef MP4V2_PLATFORM_PROG_OPTION_H
#define MP4V2_PLATFORM_PROG_OPTION_H
///////////////////////////////////////////////////////////////////////////////
///
/// @namespace mp4v2::platform::prog Command-line argument parsing.
/// WARNING: THIS IS A PRIVATE NAMESPACE. NOT FOR PUBLIC CONSUMPTION.
///
/// This namespace provides a mechanism to parse command-line arguments and
/// options for executables.
/// It is identical in behavior to getopt_long functions available
/// with many popular posix-platforms such as Darwin, FreeBSD and Linux.
/// Virtually any OS which has getopt_long will adequately document this
/// functionality. However, to avoid symbol ambiguity with the popular
/// posix implementation, the following identifiers have been renamed:
/// @li getopt_long() -> getOption()
/// @li getopt_long_only() -> getOptionSingle()
/// @li option -> Option
/// @li option.has_arg -> Option.type
//!
///////////////////////////////////////////////////////////////////////////////
namespace mp4v2 { namespace platform { namespace prog {
//! On return from getOption() or getOptionSingle(),
//! points to an option argument, if it is anticipated.
MP4V2_EXPORT extern const char* optarg;
//! On return from getOption() or getOptionSingle(),
//! contains the index to the next argv argument for a subsequent call to
//! getOption() or getOptionSingle().
//! Initialized to 1 and must be set manually to 1 prior to invoking
//! getOption() or getOptionSingle() to evaluate multiple sets of arguments.
MP4V2_EXPORT extern int optind;
//! On return from getOption() or getOptionSingle(),
//! saves the last known option character returned by
//! getOption() or getOptionSingle().
//! On error, contains the character/code of option which caused error.
MP4V2_EXPORT extern int optopt;
//! Initialized to 1 and may be set to 0 to disable error messages.
MP4V2_EXPORT extern int opterr;
//! Must be set to 1 before evaluating the 2nd or each additional set
//! of arguments.
MP4V2_EXPORT extern int optreset;
//! Structure describing a single option.
//! An instance of Option is required for each program option and is
//! initialized before use with getOption() or getOptionWord().
struct MP4V2_EXPORT Option
{
//! expectation-type indicating number of arguments expected
//! on the command-line following the option-argument itself
enum Type {
//! indicates exactly 0 arguments follow option
NO_ARG,
//! indicates exactly 1 argument follow option
REQUIRED_ARG,
//! indicates 0 or 1 arguments follow option
OPTIONAL_ARG,
};
//! contains the option name without leading double-dash
const char* name;
//! option expectation-type
Type type;
//! If not NULL, then the integer pointed to by it will be set to
//! the value in the val field. If the flag field is NULL, then the
//! val field will be returned.
int* flag;
//! Constant value representing option. This is usually a single-char
//! ASCII value but in case of long-options without a corresponding
//! single-char value it can be a unique integer (beyond ASCII range)
//! which represents the long-option.
int val;
};
///////////////////////////////////////////////////////////////////////////////
//!
//! Get option character from command line argument list.
//!
//! getOption() is similar to posix getopt() but it accepts options in two
//! forms: words and characters. The getOption() function provides a
//! superset of the functionality of getopt(). The getOption() function can
//! be used in two ways. In the first way, every long-option understood by
//! the program has a corresponding short-option, and the Option structure
//! is only used to translate from long-options to short-options. When used
//! in this fashion, getOption() behaves identically to getopt(). This is
//! a good way to add long-option processing to an esxisting program with
//! a minimum of rewriting.
//!
//! In the second mechanism, a long-option sets a flag in the Option
//! structure structure passed, or will store a pointer to the command line
//! argument in the Option structure passed to it for options that take
//! arguments. Additionally, the long-option's argument may be specified as
//! a single argument with an equal sign, eg:
//! @code myprogram --myoption=somevalue
//! @endcode
//!
//! When a long-option is processed, the call to getOption() will return 0.
//! For this reason, long-option processing without shortcuts is not
//! backwards compatible with getopt().
//!
//! It is possible to combine these methods, providing for long-options
//! processing with short-option equivalents for some options. Less
//! frequently used options would be processed as long-options only.
//!
//! @param argc number of arguments.
//! @param argv argument array of strings.
//! @param optstr string containing the following elements:
//! individual characters, and characters followed by a colon to indicate
//! an option argument is to follow. For example, an option string "x"
//! recognizes an option "-x", and an option string "x:" recognizes an
//! option and argument "-x argument".
//! @param longopts array of Option entries. The last element must be filled
//! with zeroes to indicate end-of-array.
//! @param idx If not NULL, then the integer pointed to it will be set to
//! the index of the long-option relative to longops.
//!
//! @return If the flag field is NULL, val field is returned,
//! which is usually just the corresponding short-option.
//! If flag is not NULL, 0 is returned and val is
//! stored in the location pointed to by flag field.
//! A ':' will be returned if there was a missing option argument.
//! A '?' will be returned if an unknown or ambiguous option was used.
//! A -1 will be returned when the argument list has been exhausted.
//!
///////////////////////////////////////////////////////////////////////////////
MP4V2_EXPORT
int getOption( int argc, char* const* argv, const char* optstr, const Option* longopts, int* idx );
///////////////////////////////////////////////////////////////////////////////
//!
//! Get option character from command line argument list and allow
//! long-options with single-hyphens.
//!
//! Behaves identically to getOption() with the exception that long-options
//! may start with '-' in addition to '--'.
//! If an option starting with '-' does not match a long option but does match
//! a single-character option, the single-character option is returned.
//!
//! @param argc number of arguments.
//! @param argv argument array of strings.
//! @param optstr string containing the following elements:
//! individual characters, and characters followed by a colon to indicate
//! an option argument is to follow. For example, an option string "x"
//! recognizes an option "-x", and an option string "x:" recognizes an
//! option and argument "-x argument".
//! @param longopts array of Option entries. The last element must be filled
//! with zeroes to indicate end-of-array.
//! @param idx If not NULL, then the integer pointed to it will be set to
//! the index of the long-option relative to longops.
//!
//! @return If the flag field is NULL, val field is returned,
//! which is usually just the corresponding short-option.
//! If flag is not NULL, 0 is returned and val is
//! stored in the location pointed to by flag field.
//! A ':' will be returned if there was a missing option argument.
//! A '?' will be returned if an unknown or ambiguous option was used.
//! A -1 will be returned when the argument list has been exhausted.
//!
///////////////////////////////////////////////////////////////////////////////
MP4V2_EXPORT
int getOptionSingle( int argc, char* const* argv, const char* optstr, const Option* longopts, int* idx );
///////////////////////////////////////////////////////////////////////////////
}}} // namespace mp4v2::platform::prog
#endif // MP4V2_PLATFORM_PROG_OPTION_H