Author: sebor
Date: Mon Jun 12 18:44:19 2006
New Revision: 413782
URL: http://svn.apache.org/viewvc?rev=413782&view=rev
Log:
2006-06-12 Martin Sebor <[EMAIL PROTECTED]>
* cmdopt.cpp (cmdopts_t): Renamed toggle_ to tristate_.
(_rw_getbounds): Added a formal argument and handled tristate_
bit number specification.
(_rw_match_tristate): Renamed from _rw_match_toggle.
(_rw_set_bits): New helper.
(rw_runopts): Handled tristate bit specifications.
* 0.cmdopts.cpp (test_tristate): Renamed from test_toggles
and exercised bit specification.
Modified:
incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
incubator/stdcxx/trunk/tests/src/cmdopt.cpp
Modified: incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp?rev=413782&r1=413781&r2=413782&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp (original)
+++ incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp Mon Jun 12 18:44:19 2006
@@ -219,6 +219,11 @@
}
if (strchr (expect, '#')) {
+ // when the expected result string contains the pound sign,
+ // treat the arguments as pointers to integers as opposed
+ // to pointers to callback functions and format the actual
+ // result as a sequence of integers at the given addresses
+
if (f0 == cntptrs [0].pfun) {
sprintf (argstr + strlen (argstr),
"%s%d", *argstr ? "; #" : "#", opt_counts [0]);
@@ -393,7 +398,7 @@
/**************************************************************************/
static void
-test_toggles ()
+test_tristate ()
{
// +-- expected result string
// | +-- expected return value from rw_getopts()
@@ -406,18 +411,93 @@
T ("#1", 0, A ("--enable-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--use-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--with-foo"), 1, "|-foo~", C0);
-
T ("#-1", 0, A ("--disable-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--no-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--without-foo"), 1, "|-foo~", C0);
- // the same toggle can be repeated any number of times
+ // the same tristate can be repeated any number of times
T ("#1", 0, A ("--enable-foo", "--use-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--no-foo", "--without-foo"), 1, "|-foo~", C0);
- // the last toggle wins
+ // the last tristate wins
T ("#-1", 0, A ("--use-foo", "--no-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--no-foo", "--use-foo"), 1, "|-foo~", C0);
+
+ //////////////////////////////////////////////////////////////////
+
+ // set bits using a bitmap
+ T ("#1", 0, A ("--enable-foo"), 1, "|-foo~:0", C0);
+ T ("#1", 0, A ("--enable-foo"), 1, "|-foo~:1", C0);
+ T ("#2", 0, A ("--enable-foo"), 1, "|-foo~:2", C0);
+ T ("#3", 0, A ("--enable-foo"), 1, "|-foo~:3", C0);
+ T ("#4", 0, A ("--enable-foo"), 1, "|-foo~:4", C0);
+
+ // unset bits using a bitmap
+ T ("#-2", 0, A ("--disable-foo"), 1, "|-foo~:1", C0);
+ T ("#-3", 0, A ("--disable-foo"), 1, "|-foo~:2", C0);
+ T ("#-4", 0, A ("--disable-foo"), 1, "|-foo~:3", C0);
+ T ("#-5", 0, A ("--disable-foo"), 1, "|-foo~:4", C0);
+
+ // set bits in word 2
+ T ("#0,1", 0, A ("--enable-bar"), 1, "|-bar~32:0", C0, C1);
+ T ("#0,1", 0, A ("--enable-bar"), 1, "|-bar~32:1", C0, C1);
+ T ("#0,2", 0, A ("--enable-bar"), 1, "|-bar~32:2", C0, C1);
+ T ("#0,3", 0, A ("--enable-bar"), 1, "|-bar~32:3", C0, C1);
+ T ("#0,4", 0, A ("--enable-bar"), 1, "|-bar~32:4", C0, C1);
+
+ // enable bits 0 through 4 in C0 one at a time
+ T ("#1", 0, A ("--with-0"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+ T ("#2", 0, A ("--with-1"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+ T ("#4", 0, A ("--with-2"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+ T ("#8", 0, A ("--with-3"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+
+ // enable multiple bits 0 through 4 in C0 simultaneously
+ T ("#3", 0, A ("--with-0", "--with-1"),
+ 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+
+ T ("#7", 0, A ("--with-0", "--with-1", "--with-2"),
+ 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+
+ T ("#15", 0, A ("--with-0", "--with-1", "--with-2", "--with-3"),
+ 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
+
+ // specify bit value
+ T ("#1", 0, A ("--with-0"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#2", 0, A ("--with-1"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#4", 0, A ("--with-2"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#8", 0, A ("--with-3"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#3", 0, A ("--with-0", "--with-1"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#7", 0, A ("--with-0", "--with-1", "--with-2"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#15", 0, A ("--with-0", "--with-1", "--with-2", "--with-3"),
+ 4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
+
+ T ("#-1073741824",
+ 0, A ("--enable-f30"),
+ 3, "|-f30~30:3 |-f28~28:2 |-f26~26:2", C0, C0, C0);
+
+ T ("#-2147483648",
+ 0, A ("--enable-f30"),
+ 3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
+
+ T ("#-1610612736",
+ 0, A ("--enable-f30","--enable-f28"),
+ 3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
+
+ T ("#-1476395008",
+ 0, A ("--enable-f30","--enable-f28","--enable-f26"),
+ 3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
}
/**************************************************************************/
@@ -581,8 +661,8 @@
// exercise the handling of options with an optional argument
test_optional_argument ();
- // exercise the handling of toggling options
- test_toggles ();
+ // exercise the handling of tristate options
+ test_tristate ();
// exercise the handling of options with a required argument
test_required_argument ();
Modified: incubator/stdcxx/trunk/tests/src/cmdopt.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/cmdopt.cpp?rev=413782&r1=413781&r2=413782&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/cmdopt.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/cmdopt.cpp Mon Jun 12 18:44:19 2006
@@ -62,7 +62,7 @@
unsigned arg_ : 1; // option takes an argument
unsigned inv_ : 1; // callback invocation inverted
- unsigned toggle_ : 1; // option is a toggle
+ unsigned tristate_ : 1; // option is a tristate
unsigned envseen_ : 1; // environment option already processed
};
@@ -327,25 +327,33 @@
static const char*
-_rw_getbounds (const char *next, RW_VA_LIST_ARG_PTR pva)
+_rw_getbounds (const char *next, char sep, RW_VA_LIST_ARG_PTR pva)
{
++next;
- if ('*' == *next || '+' == *next || '-' == *next || isdigit (*next)) {
+ if ( '*' == *next || '+' == *next || '-' == *next || sep == *next
+ || isdigit (*next)) {
+ bool have_maxval = false;
+
+ if (*next == sep && '-' != sep) {
+ have_maxval = true;
+ ++next;
+ }
+
char *end = 0;
// '*' designates an int va_arg argument
- const long minval = '*' == *next ?
+ const long val = '*' == *next ?
long (va_arg (RW_VA_LIST_PTR_ARG_TO_VA_LIST (pva), int))
: strtol (next, &end, 10);
#if _RWSTD_INT_SIZE < _RWSTD_LONG_SIZE
// validate
- if (minval < _RWSTD_INT_MIN || _RWSTD_INT_MAX < minval) {
+ if (val < _RWSTD_INT_MIN || _RWSTD_INT_MAX < val) {
fprintf (stderr,
"lower bound %ld out of range [%d, %d]: "
- "%s\n", minval, _RWSTD_INT_MIN, _RWSTD_INT_MAX,
+ "%s\n", val, _RWSTD_INT_MIN, _RWSTD_INT_MAX,
next);
return 0;
}
@@ -353,14 +361,19 @@
next = end ? end : next + 1;
- _rw_cmdopts [_rw_ncmdopts].minval_ = minval;
+ if (have_maxval) {
+ _rw_cmdopts [_rw_ncmdopts].minval_ = 0;
+ _rw_cmdopts [_rw_ncmdopts].maxval_ = val;
+ }
+ else
+ _rw_cmdopts [_rw_ncmdopts].minval_ = val;
- if ('-' == *next) {
+ if (sep == *next && !have_maxval) {
++next;
if ( '*' == *next
|| '+' == *next
- || minval < 0 && '-' == *next
+ || val < 0 && '-' == *next
|| isdigit (*next)) {
end = 0;
@@ -376,17 +389,17 @@
fprintf (stderr,
"upper bound %ld out of range [%ld, %d]: "
- "%s\n", maxval, minval, _RWSTD_INT_MAX,
+ "%s\n", maxval, val, _RWSTD_INT_MAX,
next);
return 0;
}
#endif // INT_SIZE < LONG_SIZE
- if (maxval < minval) {
+ if ('-' == sep && maxval < val) {
// invalid range (upper bound < lower bound
fprintf (stderr,
"invalid range [%ld, %ld]: %s\n",
- minval, maxval, next);
+ val, maxval, next);
return 0;
}
@@ -408,11 +421,15 @@
next);
return 0;
}
- else {
+ else if (!have_maxval) {
// no upper bound on the value of the option argument
_rw_cmdopts [_rw_ncmdopts].maxval_ = _RWSTD_INT_MAX;
}
-
+ }
+ else if (':' == sep) {
+ // special value indicating no bits specified for a tristate
+ _rw_cmdopts [_rw_ncmdopts].minval_ = 0;
+ _rw_cmdopts [_rw_ncmdopts].maxval_ = 0;
}
else {
// no minimum/maximum value for this option is set
@@ -517,12 +534,17 @@
int arg_is_callback = true;
if ('#' == *next) {
+ // examples of option specification:
+ // --foo# option takes an optional numeric argument
+ // --foo#3 numeric argument must be equal to 3
+ // --foo#1-5 numeric argument must be in the range [1,5]
+
// instead of a pointer to a callback, the argument is a pointer
// to an int counter that is to be incremented for each occurrence
// of the option during processing
// when the option is immediately followed by the equals sign ('=')
// and a numeric argument N, the value of N will be stored instead
- next = _rw_getbounds (next, RW_VA_LIST_ARG_TO_PTR (va));
+ next = _rw_getbounds (next, '-', RW_VA_LIST_ARG_TO_PTR (va));
if (0 == next)
return -1; // error
@@ -531,11 +553,20 @@
}
else if ('~' == *next) {
- ++next;
+ // examples of option specification:
+ // --foo~ word 0
+ // --foo~3 word 3
+ // --foo~:4 word 0, bit 2
+ // --foo~3:6 word 3, bits 2 and 3
- // unlimited number of toggles are allowed
- lastopt->toggle_ = 1;
- lastopt->maxcount_ = _RWSTD_SIZE_MAX;
+ // get the optional word number and bit number
+ next = _rw_getbounds (next, ':', RW_VA_LIST_ARG_TO_PTR (va));
+
+ if (0 == next)
+ return -1; // error
+
+ // unlimited number of tristates are allowed
+ lastopt->tristate_ = 1;
// no callback function expected
arg_is_callback = false;
@@ -546,7 +577,7 @@
lastopt->arg_ = true;
// check if the value of the argument is restricted
- next = _rw_getbounds (next, RW_VA_LIST_ARG_TO_PTR (va));
+ next = _rw_getbounds (next, '-', RW_VA_LIST_ARG_TO_PTR (va));
if (0 == next)
return -1; // error
@@ -754,8 +785,8 @@
status = _rw_getarg (optspec, argv [0], equals + 1);
}
else {
- // option must not be a toggle (those are handled elsewhere)
- RW_ASSERT (0 == optspec->toggle_);
+ // option must not be a tristate (those are handled elsewhere)
+ RW_ASSERT (0 == optspec->tristate_);
RW_ASSERT (0 != optspec->pcntr_);
++*optspec->pcntr_;
}
@@ -776,7 +807,7 @@
// option is being disabled and positive when it's being
// enabled
static int
-_rw_match_toggle (const cmdopts_t *opt, const char *optname)
+_rw_match_tristate (const cmdopts_t *opt, const char *optname)
{
RW_ASSERT (0 != opt);
RW_ASSERT (0 != optname);
@@ -787,7 +818,7 @@
0
};
- int toggle = 0;
+ int tristate = 0;
if ('-' == optname [0] && '-' != optname [2]) {
@@ -807,18 +838,34 @@
opt->lopt_ ? opt->lopt_ : opt->loptbuf_;
if (0 == strcmp (lopt, name)) {
- toggle = '+' == prefix [i][0] ? 1 : -1;
+ tristate = '+' == prefix [i][0] ? 1 : -1;
break;
}
}
}
}
- return toggle;
+ return tristate;
}
/**************************************************************************/
+// returns a bitmap all of whose bits are set starting with the most
+// significant non-zero bit corresponding to first such bit in val
+// e.g., _rw_set_bits(4) --> 7
+static int
+_rw_set_bits (int val)
+{
+ int res = 0;
+
+ for (unsigned uval = val; uval; uval >>= 1) {
+ res = (res << 1) | 1;
+ }
+
+ return res;
+}
+
+
_TEST_EXPORT int
rw_runopts (int argc, char *argv[])
{
@@ -889,15 +936,42 @@
const char* const lopt = opt->lopt_ ?
opt->lopt_ : opt->loptbuf_;
- if (opt->toggle_) {
- // option specification denotes a toggle, see if it
+ if (opt->tristate_) {
+ // option specification denotes a tristate, see if it
// matches and if so, whether it's being disabled or
// enabled (-1 or +1, respectively)
- const int toggle = _rw_match_toggle (opt, optname);
+ const int tristate = _rw_match_tristate (opt, optname);
- if (toggle) {
+ if (tristate) {
RW_ASSERT (0 != opt->pcntr_);
- *opt->pcntr_ = toggle < 0 ? -1 : 1;
+
+ const int word_bits = _RWSTD_CHAR_BIT * sizeof (int);
+
+ // the optional minval_ specifies the bit number
+ // of the first of a sequence of bits in an array
+ // stored at pcntr_
+ const int word_inx = opt->minval_ / word_bits;
+ const int bit_inx = opt->minval_ % word_bits;
+
+ const int bit_val = _RWSTD_INT_MAX == opt->maxval_
+ ? 1 : opt->maxval_;
+
+ if (bit_val) {
+ const int bit_mask =
+ _rw_set_bits (bit_val) << bit_inx;
+
+ // clear the bit field
+ opt->pcntr_ [word_inx] &= ~bit_mask;
+
+ if (tristate < 0)
+ opt->pcntr_ [word_inx] = ~(bit_val << bit_inx);
+ else
+ opt->pcntr_ [word_inx] |= bit_val << bit_inx;
+ }
+ else {
+ // special case
+ opt->pcntr_ [word_inx] = tristate < 0 ? -1 : +1;
+ }
// matching option has been found
found = true;