/* -*- C++ -*- */ //============================================================================= /** * @file Get_Opt.h * * $Id$ * * @author Douglas C. Schmidt * * Long option support added by Don Hinton . */ //============================================================================= #ifndef ACE_GET_OPT_H #define ACE_GET_OPT_H #include "ace/pre.h" #include "ace/ACE.h" #include "ace/SString.h" #include "ace/Containers.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #undef optind #undef optarg #undef opterr /* * These definitions are for backward compatibility with previous versions. * of ACE_Get_Opt. */ /** * @class ACE_Get_Opt * * @brief Iterator for parsing command-line arguments. * * This is a C++ wrapper for getopt(3c) and getopt_long(3c). */ class ACE_Export ACE_Get_Opt { public: /// Mutually exclusive ordering values. enum { /// The options must come first, return as soon as a /// non-option argument is encountered. REQUIRE_ORDER = 1, /// Reorder the arguments so that all the options come first (the /// order of the options and the following arguments are /// maintained). PERMUTE_ARGS = 2, /// Continue processing the command line for each argument. The /// return value '1' signifies a non-option argument. RETURN_IN_ORDER = 3 }; /// Mutually exclusive option argument mode used by long options. enum OPTION_ARG_MODE { /// Doesn't take an argument. NO_ARG = 0, /// Requires an argument, same as passing ":" after a short option /// character in . ARG_REQUIRED = 1, /// Argument is optional, same as passing "::" after a short /// option character in . ARG_OPTIONAL = 2 }; /** * Initialize the internal data when the first call is made. Start * processing options with -element 0 + ; the * sequence of previously skipped non-option -elements is * empty. * * is a string containing the legitimate short option * characters. A single colon ":" in means that the * previous character is an option that wants, requires, an argument, * whereas a double colon "::" signifies the argument is optional. * The argument is taken from the rest of the current -element, * or from the following -element (only valid for required * arguments, optional arguments must always reside in the same * -element), and returned in by . * * Multiple short options can be combined as long as only the last * one can takes an argument, e.g., if is defined as * "abc:" or "abc::" then the command line "program -abcxxx" short * options a, b, and c are found with "xxx" as the argument for c. * However, if the command line is specified as "program -acb" only * options a and c are found with "b" as the argument for c. Also, * for options with optional arguments, e.g., those followed by "::" * the argument must be in the same -element, so "program -abc * xxx" will only find "xxx" as the argument for c if is * specified as "abc:" not "abc::". * * If a missing required option argument is detected, return the * colon character ':' if the first character of was a * colon, or a '?' otherwise. (Note that the standards are unclear in * this respect, so we scan the initial *characters* of * up unto the first short option character for '+', '-', and ':' in * order to determine ordering and missing argument behavior.) * * If an short option character is seen that is not listed in * , return '?' after printing an error message. If you * set to zero, the error message is suppressed but * we still return '?'. * * can be extended by adding long options, * , that have corresponding short options. If the * short option already appears in they argument * characteristics must match, otherwise it is added -- see * for more information. * * If 'W', followed by a semi-colon ';' appears in , then * any time a 'W' appears on the command line, the following argument * is treated as a long option, e.g., if the command line contains * "program -W foo" "foo" is treated as a long option, i.e., as if * "program --foo" had been passed. * * refers to how the -elements are processed. * means that we stop processing and return as * soon as a non-option argument is found, and * holds the index of the next -element so the program can * continue processing the rest of the -elements. If * (default) is passed, the -elements are * reordered dynamically, permuted, so that all options appear first. * When the last option has been process, is returned and * holds the index into the next non-option * element. If is passed, then each -element * is processed in the order is it seen. If the element is not * recognized as an option, '1' is returned and * contains the -element found. * * If is non-zero, then all options are treated as long * options. If a long option is not recognized, we try to find a * matching short option. */ ACE_Get_Opt (int argc, ACE_TCHAR **argv, const ACE_TCHAR *optstring, int skip_argv0 = 1, int report_errors = 0, int ordering = PERMUTE_ARGS, int long_only = 0); /// Default dtor. ~ACE_Get_Opt (void); /** * Scan elements of (whose length is ) for short option * characters given in or long options (with no short * option equivilents). * * If an element of starts with '-', and is not exactly "-" * or "--", then it is a short option element. The characters of this * element (aside from the initial '-') are option characters. If * it starts with "--" followed by other characters it is treated as * a long option. If is called repeatedly, it returns * successively each of the option characters from each of the option * elements. * * If finds another option character, it returns that * character, updating and so that the next call * to can resume the scan with the following option * character or -element. * * If returns 0, it found a long option, '?' indicates * an unknown option character, and '1' means that * was specified and we found an non-option argument. * * If there are no more option characters, returns * . Then is the index in of the first * -element that is not an option. (If was * specified, the -elements have been permuted so that those * that are not options now come last.) */ int operator () (void); /** * For communication from to the caller. When * finds an option that takes an argument, the argument * value is returned here, otherwise it returns 0. */ ACE_TCHAR *opt_arg (void) const; /** * Index in of the next element to be scanned. This is used * for communication to and from the caller and for communication * between successive calls to . On entry to * , zero means this is the first call; initialize. * * When returns , this is the index of the first of * the non-option elements that the caller should itself scan. * * Otherwise, communicates from one call to the next how * much of has been scanned so far. */ int &opt_ind (void); // Adds a long option with no corresponding short option. int long_option (const ACE_TCHAR *name, OPTION_ARG_MODE has_arg = NO_ARG); /// Adds a long option with a corresponding short option. If the /// short option has already been supplied in the , /// has_arg match match or an error is returned, otherwise the new /// short option it is added to the . /// Returns 0 on success and -1 if the long option can not be added. int long_option (const ACE_TCHAR *name, int short_option, OPTION_ARG_MODE has_arg = NO_ARG); /// Returns the name of the long option found on the last call to /// or 0 if none was found. const ACE_TCHAR *long_option (void) const; /// Accessor for the pointer. ACE_TCHAR **argv (void) const; /// Dump the state of an object. void dump (void) const; /// Return the . This is handy to verify that calls to /// long_option added short options as expected. const ACE_TCHAR *optstring (void) const; public: /** * The following five data members should be private, but that * would break backwards compatibility. However, we recommend not * writing code that uses these fields directly. */ /// Holds the count. int argc_; /// Holds the pointer. ACE_TCHAR **argv_; /// Index in argv_ of the next element to be scanned. int optind; /// Callers store zero here to inhibit the error message for /// unrecognized options. int opterr; /// Points to the option argument when one is found on last call to /// . ACE_TCHAR *optarg; private: class ACE_Get_Opt_Long_Option { public: /// ctor ACE_Get_Opt_Long_Option (const ACE_TCHAR *name, int has_arg, int val = 0); /// Default dtor. ~ACE_Get_Opt_Long_Option (void); int operator < (const ACE_Get_Opt_Long_Option &rhs); /// Long option name. const ACE_TCHAR *name_; /// Contains value for . int has_arg_; /// Contains a valid short option character or zero if it doesn't /// have a corresponding short option. It can also contain a /// non-printable value that cannot be passed to but /// will be returned by . This is handy for /// simplifying long option handling, see tests/Get_Opt_Test.cpp /// for an example of this technique. int val_; }; /// Updates nextchar_. int nextchar_i (void); /// Handles long options. int long_option_i (void); /// Handles short options. int short_option_i (void); /// If permuting args, this functions manages the nonopt_start_ and /// nonopt_end_ indexes and makes calls to permute to actually /// reorder the -elements. void permute_args (void); /// Handles reordering -elements. int permute (void); /// Holds the option string. ACE_TString optstring_; /// Treat all options as long options. int long_only_; /// Keeps track of whether or not a colon was passed in . /// This is used to determine the return value when required /// arguments are missing. int has_colon_; /** * The next char to be scanned in the option-element in which the * last option character we returned was found. This allows us to * pick up the scan where we left off * * If this is zero, or a null string, it means resume the scan * by advancing to the next -element. */ ACE_TCHAR *nextchar_; /// Keeps track of ordering mode (default ). int ordering_; /// Index of the first non-option -element found (only valid /// when permuting). int nonopt_start_; /// Index of the -element following the last non-option element /// (only valid when permuting). int nonopt_end_; /// Points to the long_option found on last call to . ACE_Get_Opt_Long_Option *long_option_; /// Array of long options. ACE_Array long_opts_; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; ACE_UNIMPLEMENTED_FUNC (ACE_Get_Opt (const ACE_Get_Opt &)) ACE_UNIMPLEMENTED_FUNC (ACE_Get_Opt &operator= (const ACE_Get_Opt &)) }; #if defined (__ACE_INLINE__) #include "ace/Get_Opt.i" #endif /* __ACE_INLINE__ */ #include "ace/post.h" #endif /* ACE_GET_OPT_H */