From stdcxx-commits-return-250-apmail-incubator-stdcxx-commits-archive=incubator.apache.org@incubator.apache.org Sun Dec 18 02:10:01 2005 Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 48971 invoked from network); 18 Dec 2005 02:10:01 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 18 Dec 2005 02:10:01 -0000 Received: (qmail 82552 invoked by uid 500); 18 Dec 2005 02:10:01 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 82517 invoked by uid 500); 18 Dec 2005 02:10:00 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 82506 invoked by uid 500); 18 Dec 2005 02:10:00 -0000 Delivered-To: apmail-incubator-stdcxx-cvs@incubator.apache.org Received: (qmail 82503 invoked by uid 99); 18 Dec 2005 02:10:00 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 17 Dec 2005 18:10:00 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 17 Dec 2005 18:09:59 -0800 Received: (qmail 48917 invoked by uid 65534); 18 Dec 2005 02:09:39 -0000 Message-ID: <20051218020939.48916.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r357416 - /incubator/stdcxx/trunk/tests/src/cmdopt.cpp Date: Sun, 18 Dec 2005 02:09:38 -0000 To: stdcxx-cvs@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: sebor Date: Sat Dec 17 18:09:34 2005 New Revision: 357416 URL: http://svn.apache.org/viewcvs?rev=357416&view=rev Log: 2005-12-17 Martin Sebor * cmdopt.cpp (cmdopts_t): Added minval_ and maxval_ for the lower and upper bound, respectively, of restricted numeric arguments. (rw_vsetopts): Enhanced to allow restricted numeric arguments to be specified. (rw_runopts): Handled restricted numeric argumments. Modified: incubator/stdcxx/trunk/tests/src/cmdopt.cpp Modified: incubator/stdcxx/trunk/tests/src/cmdopt.cpp URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/src/cmdopt.cpp?rev=357416&r1=357415&r2=357416&view=diff ============================================================================== --- incubator/stdcxx/trunk/tests/src/cmdopt.cpp (original) +++ incubator/stdcxx/trunk/tests/src/cmdopt.cpp Sat Dec 17 18:09:34 2005 @@ -1,6 +1,6 @@ /*************************************************************************** * - * $Id$ + * $Id$ * ************************************************************************ * @@ -23,6 +23,7 @@ #include #include // for assert +#include // isdigit(), isspace() #include // for errno #include // for va_arg, ... #include // for fprintf @@ -49,8 +50,10 @@ char *lopt_; // long option name char sopt_; // short option name - size_t maxcalls_; // how many times option can be invoked - size_t ncalls_; // how many times it has been invoked + int minval_; // minimum value of a numerical argument + int maxval_; // maximum value of a numerical argument + size_t maxcount_; // how many times option can be invoked + size_t count_; // how many times it has been invoked unsigned arg_ : 1; // option takes an argument? unsigned inv_ : 1; // callback invocation inverted @@ -148,11 +151,11 @@ printf ("%s%s%s", pfx, cmdopts [i].arg_ ? "" : "", sfx); - if (_RWSTD_SIZE_MAX == cmdopts [i].maxcalls_) + if (_RWSTD_SIZE_MAX == cmdopts [i].maxcount_) printf (" (each occurrence evaluated)\n"); - else if (1 < cmdopts [i].maxcalls_) + else if (1 < cmdopts [i].maxcount_) printf (" (at most %u occurrences evaluated)\n", - unsigned (cmdopts [i].maxcalls_)); + unsigned (cmdopts [i].maxcount_)); else printf (" (only the first occurrence evaluated)\n"); @@ -272,16 +275,6 @@ /**************************************************************************/ -////////////////////////////////////////////////////////////////////// -// syntax of the option description string: -// -// opts ::= opt [ ':' | '=' | '#' ] [ @N | @* | '!' ] [ opts ] -// opt ::= [ '|' ] -// ::= '|' -// sopt ::= char -// lopt ::= char char* -// char ::= A-Z a-z _ 0-9 - _TEST_EXPORT int rw_vsetopts (const char *opts, va_list va) { @@ -297,7 +290,7 @@ for ( ; ; ++ncmdopts) { - while (' ' == *next) + while (isspace (*next)) ++next; if ('\0' == *next) { @@ -360,23 +353,102 @@ // only the first occurrence of each command line option // causes an invocation of the callback, all subsequent // ones will be ignored by default - cmdopts [ncmdopts].maxcalls_ = 1; + cmdopts [ncmdopts].maxcount_ = 1; int arg_is_callback = true; if ('#' == *next) { - // insead 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 the value of the argument will be stored + // insead 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, the value of the argument will be stored + // instead arg_is_callback = false; ++next; - + + if ('+' == *next || '-' == *next || isdigit (*next)) { + + char *end = 0; + const long minval = strtol (next, &end, 10); + +#if _RWSTD_INT_SIZE < _RWSTD_LONG_SIZE + // validate + if (minval < _RWSTD_INT_MIN || _RWSTD_INT_MAX < minval) { + fprintf (stderr, + "lower bound %ld out of range [%d, %d]: " + "%s\n", minval, _RWSTD_INT_MIN, _RWSTD_INT_MAX, + next); + return -1; + } +#endif // INT_SIZE < LONG_SIZE + + next = end; + + cmdopts [ncmdopts].minval_ = minval; + + if ('-' == *next) { + ++next; + + if ( '+' == *next + || minval < 0 && '-' == *next + || isdigit (*next)) { + const long maxval = strtol (next, &end, 10); + +#if _RWSTD_INT_SIZE < _RWSTD_LONG_SIZE + // validate + if ( maxval < _RWSTD_INT_MIN + || _RWSTD_INT_MAX < maxval) { + + fprintf (stderr, + "upper bound %ld out of range [%ld, %d]: " + "%s\n", maxval, minval, _RWSTD_INT_MAX, + next); + return -1; + } +#endif // INT_SIZE < LONG_SIZE + + if (maxval < minval) { + // invalid range (upper bound < lower bound + fprintf (stderr, + "invalid range [%ld, %ld]: %s\n", + minval, maxval, next); + return -1; + } + + next = end; + cmdopts [ncmdopts].maxval_ = int (maxval); + } + else { + // syntax error in range + fprintf (stderr, + "syntax error in range specification: %s\n", + next); + return -1; + } + } + else if (*next && !isspace (*next)) { + // syntax error in numeric argument + fprintf (stderr, + "syntax error numeric argument: %s\n", + next); + return -1; + } + else { + // no upper bound on the value of the option argument + cmdopts [ncmdopts].maxval_ = _RWSTD_INT_MAX; + } + + } + else { + // no minimum/maximum value for this option is set + cmdopts [ncmdopts].minval_ = _RWSTD_INT_MIN; + cmdopts [ncmdopts].maxval_ = _RWSTD_INT_MAX; + } + // an unlimited number of occurrences of the option // are allowed and will be counted - cmdopts [ncmdopts].maxcalls_ = _RWSTD_SIZE_MAX; + cmdopts [ncmdopts].maxcount_ = _RWSTD_SIZE_MAX; } else if (':' == *next || '=' == *next) { // ':' : argument optional @@ -392,13 +464,13 @@ // at most how many occurrences of an option can be processed? if ('*' == *next) { // unlimited - cmdopts [ncmdopts].maxcalls_ = _RWSTD_SIZE_MAX; + cmdopts [ncmdopts].maxcount_ = _RWSTD_SIZE_MAX; ++next; } else { // at most this many char *end; - cmdopts [ncmdopts].maxcalls_ = strtoul (next, &end, 10); + cmdopts [ncmdopts].maxcount_ = strtoul (next, &end, 10); next = end; } } @@ -541,12 +613,12 @@ // set on the command line to override those set in the // environment) - if (cmdopts [j].ncalls_ && recursive) + if (cmdopts [j].count_ && recursive) continue; // if the option has been evaluated the maximum number // of times, avoid evaluating it and continue processing - if (cmdopts [j].maxcalls_ <= cmdopts [j].ncalls_) + if (cmdopts [j].maxcount_ <= cmdopts [j].count_) continue; if (cmdopts [j].callback_) { @@ -585,6 +657,18 @@ #endif // _RWSTD_INT_SIZE < _RWSTD_LONG_SIZE + else if ( optval < long (cmdopts [j].minval_) + || cmdopts [j].maxval_ < optval) { + + // numeric argument out of range + fprintf (stderr, "numeric argument %ld out of range" + " [%d, %d]: %s\n", optval, + cmdopts [j].minval_, + cmdopts [j].maxval_, optname); + ignenv = true; + errno = EINVAL; + status = 1; + } else { *cmdopts [j].pcntr_ = optval; } @@ -594,7 +678,7 @@ ++*cmdopts [j].pcntr_; } - ++cmdopts [j].ncalls_; + ++cmdopts [j].count_; if (recursive) cmdopts [j].envseen_ = true; @@ -656,7 +740,7 @@ // has been processed for (size_t j = 0; j != ncmdopts; ++j) { - if (cmdopts [j].inv_ && 0 == cmdopts [j].ncalls_ && 0 == status) { + if (cmdopts [j].inv_ && 0 == cmdopts [j].count_ && 0 == status) { if (cmdopts [j].callback_) status = cmdopts [j].callback_ (0, 0); @@ -666,7 +750,7 @@ } } - cmdopts [j].ncalls_ = 0; + cmdopts [j].count_ = 0; cmdopts [j].envseen_ = false; } @@ -715,13 +799,13 @@ continue; // split up unquoted space-separated arguments - if (argc == 0 || ' ' == *s) { + if (argc == 0 || isspace (*s)) { if (argc > 0) *s = 0; // skip over leading spaces - if (argc > 0 || ' ' == *s) - while (' ' == *++s); + if (argc > 0 || isspace (*s)) + while (isspace (*++s)); if (*s) { if (argc == argv_size) {