summaryrefslogtreecommitdiff
path: root/ace/Get_Opt.h
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>2001-12-23 22:52:12 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>2001-12-23 22:52:12 +0000
commit4b22dd68be809e04f2ec6fa21599663e3dac2bf6 (patch)
tree6959fb80568907f75327096ca9b49bb37bc4f9ed /ace/Get_Opt.h
parent265a4a5f953152732541d55789aa7805ec94c18d (diff)
downloadATCD-4b22dd68be809e04f2ec6fa21599663e3dac2bf6.tar.gz
ChangeLogTag:Sun Dec 23 12:25:55 2001 Don Hinton <dhinton@gmx.net>
Diffstat (limited to 'ace/Get_Opt.h')
-rw-r--r--ace/Get_Opt.h281
1 files changed, 239 insertions, 42 deletions
diff --git a/ace/Get_Opt.h b/ace/Get_Opt.h
index 68afb7e6775..6d2e9a93386 100644
--- a/ace/Get_Opt.h
+++ b/ace/Get_Opt.h
@@ -1,5 +1,4 @@
/* -*- C++ -*- */
-
//=============================================================================
/**
* @file Get_Opt.h
@@ -7,6 +6,8 @@
* $Id$
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ *
+ * Long option support added by Don Hinton <dhinton@gmx.net>.
*/
//=============================================================================
@@ -15,6 +16,8 @@
#include "ace/pre.h"
#include "ace/ACE.h"
+#include "ace/SString.h"
+#include "ace/Containers.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -24,76 +27,170 @@
#undef optarg
#undef opterr
+/*
+ * These definitions are for backward compatibility with previous versions.
+ * of ACE_Get_Opt.
+ */
+#define optarg opt_arg ()
+#define optind opt_ind ()
+
/**
* @class ACE_Get_Opt
*
* @brief Iterator for parsing command-line arguments.
*
- * This is a C++ wrapper for getopt(3c).
+ * 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 <EOF> 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 <optstring>.
+ ARG_REQUIRED = 1,
+
+ /// Argument is optional, same as passing "::" after a short
+ /// option character in <optstring>.
+ ARG_OPTIONAL = 2
+ };
+
/**
* Initialize the internal data when the first call is made. Start
* processing options with <argv>-element 0 + <skip_argv0>; the
* sequence of previously skipped non-option <argv>-elements is
* empty.
*
- * <optstring> is a string containing the legitimate option
- * characters. A colon in <optstring> means that the previous
- * character is an option that wants an argument. The argument is
- * taken from the rest of the current <argv>-element, or from the
- * following <argv>-element, and returned in <optarg>.
+ * <optstring> is a string containing the legitimate short option
+ * characters. A single colon ":" in <optstring> 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 <argv>-element,
+ * or from the following <argv>-element (only valid for required
+ * arguments, optional arguments must always reside in the same
+ * <argv>-element), and returned in by <opt_arg ()>.
+ *
+ * Multiple short options can be combined as long as only the last
+ * one can takes an argument, e.g., if <optstring> 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 <argv>-element, so "program -abc
+ * xxx" will only find "xxx" as the argument for c if <optstring> is
+ * specified as "abc:" not "abc::".
+ *
+ * If a missing required option argument is detected, return the
+ * colon character ':' if the first character of <optstring> was a
+ * colon, or a '?' otherwise. (Note that the standards are unclear in
+ * this respect, so we scan the initial *characters* of <optstring>
+ * 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
+ * <optstring>, return '?' after printing an error message. If you
+ * set <report_errors> to zero, the error message is suppressed but
+ * we still return '?'.
*
- * If an option character is seen that is not listed in <optstring>,
- * return '?' after printing an error message. If you set
- * <report_errors> to zero, the error message is suppressed but we
- * still return '?'.
+ * <optstring> can be extended by adding long options,
+ * <long_option()>, that have corresponding short options. If the
+ * short option already appears in <optstring> they argument
+ * characteristics must match, otherwise it is added -- see
+ * <long_option()> for more information.
*
- * If a char in <optstring> is followed by a colon, that means it
- * wants an arg, so the following text in the same <argv>-element,
- * or the text of the following <argv>-element, is returned in
- * <optarg>. */
+ * If 'W', followed by a semi-colon ';' appears in <optstring>, 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.
+ *
+ * <ordering> refers to how the <argv>-elements are processed.
+ * <REQUIRE_ORDER> means that we stop processing and return <EOF> as
+ * soon as a non-option argument is found, and <opt_ind ()>
+ * holds the index of the next <argv>-element so the program can
+ * continue processing the rest of the <argv>-elements. If
+ * <PERMUTE_ARGS> (default) is passed, the <argv>-elements are
+ * reordered dynamically, permuted, so that all options appear first.
+ * When the last option has been process, <EOF> is returned and
+ * <opt_ind()> holds the index into the next non-option
+ * element. If <RETURN_IN_ORDER> is passed, then each <argv>-element
+ * is processed in the order is it seen. If the element is not
+ * recognized as an option, '1' is returned and <opt_arg()>
+ * contains the <argv>-element found.
+ *
+ * If <long_only> 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 report_errors = 0,
+ int ordering = PERMUTE_ARGS,
+ int long_only = 0);
/// Default dtor.
~ACE_Get_Opt (void);
/**
- * Scan elements of <argv> (whose length is <argc>) for option
- * characters given in <optstring>.
+ * Scan elements of <argv> (whose length is <argc>) for short option
+ * characters given in <optstring> or long options (with no short
+ * option equivilents).
*
* If an element of <argv> starts with '-', and is not exactly "-"
- * or "--", then it is an option element. The characters of this
- * element (aside from the initial '-') are option characters. If
- * <operator()> is called repeatedly, it returns successively each
- * of the option characters from each of the option elements.
+ * 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 <operator()> is called repeatedly, it returns
+ * successively each of the option characters from each of the option
+ * elements.
*
* If <operator()> finds another option character, it returns that
* character, updating <optind> and <nextchar> so that the next call
* to <operator()> can resume the scan with the following option
* character or <argv>-element.
*
+ * If <operator()> returns 0, it found a long option, '?' indicates
+ * an unknown option character, and '1' means that <RETURN_IN_ORDER>
+ * was specified and we found an non-option argument.
+ *
* If there are no more option characters, <operator()> returns
- * <EOF>. Then <optind> is the index in <argv> of the first
- * <argv>-element that is not an option. (The <argv>-elements have
- * been permuted so that those that are not options now come last.)
+ * <EOF>. Then <opt_ind()> is the index in <argv> of the first
+ * <argv>-element that is not an option. (If <PERMUTE_ARGS> was
+ * specified, the <argv>-elements have been permuted so that those
+ * that are not options now come last.)
*/
int operator () (void);
- // = Public data members (should be hidden...).
-
/**
* For communication from <operator()> to the caller. When
* <operator()> finds an option that takes an argument, the argument
- * value is returned here.
+ * value is returned here, otherwise it returns 0.
*/
- ACE_TCHAR *optarg;
+ ACE_TCHAR *opt_arg (void) const;
/**
* Index in <argv> of the next element to be scanned. This is used
@@ -101,17 +198,86 @@ public:
* between successive calls to <operator()>. On entry to
* <operator()>, zero means this is the first call; initialize.
*
- * When <get_opt> returns <EOF>, this is the index of the first of
+ * When <operator()> returns <EOF>, this is the index of the first of
* the non-option elements that the caller should itself scan.
*
- * Otherwise, <optind> communicates from one call to the next how
+ * Otherwise, <opt_ind()> communicates from one call to the next how
* much of <argv> has been scanned so far.
*/
- int optind;
+ int opt_ind (void) const;
+
+ // Adds a long option with no corresponding short option.
+ int long_option (const ACE_TCHAR *name,
+ OPTION_ARG_MODE has_arg = NO_ARG);
- /// Callers store zero here to inhibit the error message for
- /// unrecognized options.
- int opterr;
+ /// Adds a long option with a corresponding short option. If the
+ /// short option has already been supplied in the <optstring>,
+ /// has_arg match match or an error is returned, otherwise the new
+ /// short option it is added to the <optstring>.
+ /// 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
+ /// <operator()> or 0 if none was found.
+ const ACE_TCHAR *long_option (void) const;
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Return the <optstring>. This is handy to verify that calls to
+ /// long_option added short options as expected.
+ const ACE_TCHAR *optstring (void) const;
+
+private:
+ class ACE_Get_Opt_Long_Option
+ {
+ public:
+ /// ctor
+ ACE_Get_Opt_Long_Option (const ACE_TString name,
+ int has_arg,
+ int val = 0)
+ : name_ (name),
+ has_arg_ (has_arg),
+ val_ (val) {};
+
+ /// Default dtor.
+ ~ACE_Get_Opt_Long_Option (void) {};
+
+ int operator < (const ACE_Get_Opt_Long_Option &rhs);
+
+ /// Long option name.
+ const ACE_TString name_;
+
+ /// Contains value for <OPTION_ARG_MODE>.
+ 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 <optstring> but
+ /// will be returned by <operator()>. 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 <argv>-elements.
+ void permute_args (void);
+
+ /// Handles reordering <argv>-elements.
+ int permute (void);
/// Holds the <argc> count.
int argc_;
@@ -119,13 +285,27 @@ public:
/// Holds the <argv> pointer.
ACE_TCHAR **argv_;
- /// Dump the state of an object.
- void dump (void) const;
+ /// Holds the option string.
+ ACE_TString optstring_;
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
+ /// Index in argv_ of the next element to be scanned.
+ int opt_ind_;
-private:
+ /// Callers store zero here to inhibit the error message for
+ /// unrecognized options.
+ int opt_err_;
+
+ /// Treat all options as long options.
+ int long_only_;
+
+ /// Keeps track of whether or not a colon was passed in <optstring>.
+ /// This is used to determine the return value when required
+ /// arguments are missing.
+ int has_colon_;
+
+ /// Points to the option argument when one is found on last call to
+ /// <operator()>.
+ ACE_TCHAR *opt_arg_;
/**
* The next char to be scanned in the option-element in which the
@@ -137,8 +317,25 @@ private:
*/
ACE_TCHAR *nextchar_;
- /// Holds the option string.
- const ACE_TCHAR *optstring_;
+ /// Keeps track of ordering mode (default <PERMUTE_ARGS>).
+ int ordering_;
+
+ /// Index of the first non-option <argv>-element found (only valid
+ /// when permuting).
+ int nonopt_start_;
+
+ /// Index of the <argv>-element following the last non-option element
+ /// (only valid when permuting).
+ int nonopt_end_;
+
+ /// Points to the long_option found on last call to <operator()>.
+ ACE_Get_Opt_Long_Option *long_option_;
+
+ /// Array of long options.
+ ACE_Array<ACE_Get_Opt_Long_Option*> 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 &))