You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2005/12/18 00:38:01 UTC
svn commit: r357403 - /incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
Author: sebor
Date: Sat Dec 17 15:37:54 2005
New Revision: 357403
URL: http://svn.apache.org/viewcvs?rev=357403&view=rev
Log:
2005-12-17 Martin Sebor <se...@roguewave.com>
STDCXX-4
* 0.cmdopts.cpp: New test exercising the rw_runopts() and rw_setopts()
utility functions.
Added:
incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp (with props)
Added: incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp?rev=357403&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp (added)
+++ incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp Sat Dec 17 15:37:54 2005
@@ -0,0 +1,422 @@
+/************************************************************************
+ *
+ * 0.cmdopts.cpp - test exercising the rw_runopts() and rw_setopts()
+ * utility functions
+ *
+ * $Id$
+ *
+ ************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
+ * Software division. Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0. Unless required by
+ * applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License
+ * for the specific language governing permissions and limitations under
+ * the License.
+ *
+ **************************************************************************/
+
+#include <cmdopt.h>
+
+#include <stdio.h>
+#include <string.h>
+
+// global buffer containing the names of all all callbacks along with
+// their arguments called in response to each invocation to rw_runopts()
+static char argstr [4096];
+
+// the maximum number of callbacks to be invoked by a single call
+// to rw_runopts()
+#define MAXCALLBACKS 32
+
+// the values to be returned by each callback
+static int retvals [MAXCALLBACKS];
+
+// the cumulative number of callback invocations
+static size_t ncalls;
+
+// the exit status of the whole test
+static int exit_status;
+
+// the current line number
+static int current_line;
+
+// prints its arguments in a human-readable form to buf
+static int
+pargs (char *buf, const char *funcname, int argc, char *argv [])
+{
+ _RWSTD_ASSERT (0 != buf);
+
+ char* next = buf + strlen (buf);
+
+ if ('\0' != *buf) {
+ next [0] = ';';
+ next [1] = '\0';
+ ++next;
+ }
+
+ if (funcname)
+ next += sprintf (next, "%s(%d,{", funcname, argc);
+ else
+ next += sprintf (next, "%d,{", argc);
+
+ for (int i = 0; i < argc; ++i) {
+
+ if (argv [i])
+ next += sprintf (next, "\"%s\"", argv [i]);
+ else {
+ strcpy (next, "(null)");
+ next += strlen (next);
+ }
+
+ if (i + 1 < argc) {
+ next [0] = ',';
+ next [1] = '\0';
+ ++next;
+ }
+ }
+
+ next [0] = '}';
+ next [1] = ')';
+ next [2] = '\0';
+
+ // verify that the number of calls hasn't exceeded the size
+ // of the array of return values
+ _RWSTD_ASSERT (ncalls < MAXCALLBACKS);
+
+ return retvals [ncalls];
+}
+
+
+static int
+callback_imp (const char *cbname, int argc, char *argv[])
+{
+ const int status = pargs (argstr, cbname, argc, argv);
+
+ ++ncalls;
+
+ return status;
+}
+
+
+static int
+foo (int argc, char *argv[])
+{
+ return callback_imp ("foo", argc, argv);
+}
+
+
+static int
+bar (int argc, char *argv[])
+{
+ return callback_imp ("bar", argc, argv);
+}
+
+static int
+err (int argc, char *argv[])
+{
+ return callback_imp ("ERR", argc, argv);
+}
+
+
+typedef int (cbfun_t)(int, char*[]);
+
+static int opt_counts [4];
+
+// hackery to allow passing int* and cbfun_t* in the same argument
+static const union {
+ int *pint;
+ cbfun_t *pfun;
+} cntptrs [] = {
+ { opt_counts + 0 },
+ { opt_counts + 1 },
+ { opt_counts + 2 },
+ { opt_counts + 3 }
+};
+
+
+static void
+test_opts (const char *expect,
+ int get_exp,
+ char *argv [],
+ int set_exp,
+ const char *argspec,
+ cbfun_t *f0,
+ cbfun_t *f1 = 0,
+ cbfun_t *f2 = 0,
+ cbfun_t *f3 = 0)
+{
+ argstr [0] = '\0';
+
+ // reset all previously set options
+ rw_setopts (0, 0);
+
+ // set new options
+ const int set_res = rw_setopts (argspec, f0, f1, f2, f3);
+
+ if (set_res != set_exp) {
+
+ // convert function pointers to void pointers
+ // to avoid compiler error and warnings
+ union {
+ cbfun_t *pfun;
+ void *pvoid;
+ } uptr[] = {
+ { f0 }, { f1 }, { f2 }, { f3 }
+ };
+
+ fprintf (stderr,
+ "line %d: rw_setopts (\"%s\", %p, %p, %p, %p) == %d, got %d\n",
+ current_line, argspec,
+ uptr [0].pvoid, uptr [1].pvoid, uptr [2].pvoid, uptr [3].pvoid,
+ set_exp, set_res);
+
+ exit_status = 1;
+ }
+
+ argstr [0] = '\0';
+
+ // compute the value of argc from argv
+ int argc = 0;
+ for (; argv [argc]; ++argc);
+
+ // reset the number of callback invocations
+ ncalls = 0;
+
+ // reset the option counters
+ memset (opt_counts, 0, sizeof opt_counts);
+
+ const int get_res = rw_runopts (argc, argv);
+
+ if (get_res != get_exp) {
+
+ static char tmp [4096];
+
+ tmp [0] = '\0';
+ pargs (tmp, 0, argc, argv);
+
+ fprintf (stderr,
+ "line %d: rw_runopts (%s) == %d, got %d\n",
+ current_line, tmp, get_exp, get_res);
+
+ exit_status = 1;
+ }
+
+ if (strchr (expect, '#')) {
+ if (f0 == cntptrs [0].pfun) {
+ sprintf (argstr + strlen (argstr),
+ "%s%d", *argstr ? "; #" : "#", opt_counts [0]);
+
+ if (f1 == cntptrs [1].pfun) {
+ sprintf (argstr + strlen (argstr),
+ ",%d", opt_counts [1]);
+
+ if (f2 == cntptrs [2].pfun) {
+ sprintf (argstr + strlen (argstr),
+ ",%d", opt_counts [2]);
+
+ if (f3 == cntptrs [3].pfun) {
+ sprintf (argstr + strlen (argstr),
+ ",%d", opt_counts [3]);
+ }
+ }
+ }
+ }
+ }
+
+ if (strcmp (argstr, expect)) {
+ fprintf (stderr,
+ "line %d: \"%s\" != \"%s\"\n",
+ current_line, argstr, expect);
+
+ exit_status = 1;
+ }
+}
+
+
+static char**
+mkargv (const char *s0,
+ const char *s1 = 0,
+ const char *s2 = 0,
+ const char *s3 = 0,
+ const char *s4 = 0,
+ const char *s5 = 0,
+ const char *s6 = 0,
+ const char *s7 = 0,
+ const char *s8 = 0,
+ const char *s9 = 0)
+{
+ static char argbuf [10][1024];
+ static char* argv [10];
+
+ argv [0] = s0 ? strcpy (argbuf [0], s0) : 0;
+ argv [1] = s1 ? strcpy (argbuf [1], s1) : 0;
+ argv [2] = s2 ? strcpy (argbuf [2], s2) : 0;
+ argv [3] = s3 ? strcpy (argbuf [3], s3) : 0;
+ argv [4] = s4 ? strcpy (argbuf [4], s4) : 0;
+ argv [5] = s5 ? strcpy (argbuf [5], s5) : 0;
+ argv [6] = s6 ? strcpy (argbuf [6], s6) : 0;
+ argv [7] = s7 ? strcpy (argbuf [7], s7) : 0;
+ argv [8] = s8 ? strcpy (argbuf [8], s8) : 0;
+ argv [9] = s9 ? strcpy (argbuf [9], s9) : 0;
+
+ return argv;
+}
+
+
+int main ()
+{
+#define A mkargv
+#define B bar
+#define F foo
+#define E err
+#define C0 cntptrs [0].pfun
+#define C1 cntptrs [1].pfun
+#define C2 cntptrs [2].pfun
+#define C3 cntptrs [3].pfun
+#define T (current_line = __LINE__), test_opts
+
+ // +--------- expected resul string formatted by callbacks
+ // | +----- expected rw_runopts() return value
+ // | | +-- rw_runopts() second argument (argv)
+ // | | |
+ // | | | +---------- expected rw_setopts() result
+ // | | | | +------- rw_setopts() first argument
+ // | | | | | +-- rw_setopts() callbacks...
+ // | | | | | |
+ // V V V V V V
+ T ("", 0, A (""), 0, "", 0);
+ T ("", 0, A ("a"), 0, "", 0);
+ T ("", 0, A ("a", "b"), 0, "", 0);
+ T ("", 0, A ("a", "b"), 0, "", 0);
+
+ T ("", 0, A (""), 1, "f", F);
+ T ("", 0, A ("a"), 1, "f", F);
+ T ("", 0, A ("a", "b"), 1, "f", F);
+ T ("", 0, A ("a", "b"), 1, "f", F);
+ T ("", 0, A ("a", "f"), 1, "f", F);
+ T ("", 0, A ("f", "f"), 1, "f", F);
+
+ // exercise setting up the "unknown option" handler
+ T ("", 0, A (""), 1, "-", 0);
+ T ("", 0, A (""), 1, "-", E);
+
+ // exercise the "unknown option" handler
+ T ("ERR(1,{\"-x\"})", 0, A ("-x"), 2, "- f", E, F);
+
+ // exercise short and/or long options
+ T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a", F);
+ T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "|-a", F);
+ T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a|-a", F);
+ T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "a|-a", F);
+
+ // exercise options with a counter instead of a callback
+ T ("#1", 0, A ("-b"), 1, "b#", C0);
+ T ("#1", 0, A ("--cc"), 1, "|-cc#", C0);
+ T ("#2", 0, A ("-d", "-d"), 1, "d#", C0);
+ T ("#2", 0, A ("-e", "--ee"), 1, "e|-ee#", C0);
+ T ("#3", 0, A ("-e", "-e", "-e"), 1, "e#", C0);
+ T ("#1,2", 0, A ("-f", "-g", "-g"), 2, "f# g#", C0, C1);
+
+ // exercise an option with an optional argument
+ T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a:", F);
+ T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a:", F);
+ T ("foo(2,{\"-a\",\"x\"})", 0, A ("-a", "x"), 1, "a:", F);
+ T ("foo(1,{\"-ay\"})", 0, A ("-ay"), 1, "a:", F);
+ T ("foo(1,{\"-axyz\"})", 0, A ("-axyz"), 1, "a:", F);
+ T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "|-a:", F);
+ T ("ERR(1,{\"--ab\"})", 0, A ("--ab"), 2, "- |-a:", E, F);
+
+ // exercise the processing of two optional command line options
+ T ("foo(2,{\"-a\",\"-b\"});"
+ "bar(1,{\"-b\"})",
+ 0, A ("-a", "-b"), 2, "a: b", F, B);
+
+ T ("foo(3,{\"-a\",\"x\",\"-b\"});"
+ "bar(1,{\"-b\"})",
+ 0, A ("-a", "x", "-b"), 2, "a: b", F, B);
+
+ // exercise the processing of an option with a required argument
+
+ // the equals sign missing
+ T ("ERR(1,{\"--a\"})", 0, A ("--a"), 2, "- |-a=", E, F);
+
+ // required argument empty
+ T ("foo(1,{\"--a=\"})", 0, A ("--a="), 1, "|-a=", F);
+
+ // required argument contains funky characters
+ T ("foo(1,{\"--a=1\"})", 0, A ("--a=1"), 1, "|-a=", F);
+ T ("foo(1,{\"--b=1-\"})", 0, A ("--b=1-"), 1, "|-b=", F);
+ T ("foo(1,{\"--c=-2\"})", 0, A ("--c=-2"), 1, "|-c=", F);
+ T ("foo(1,{\"--d=1-2\"})", 0, A ("--d=1-2"), 1, "|-d=", F);
+ T ("foo(1,{\"--e=-1=2\"})", 0, A ("--e=-1=2"), 1, "|-e=", F);
+ T ("foo(1,{\"--f=-1=-2\"})", 0, A ("--f=-1=-2"), 1, "|-f=", F);
+ T ("foo(1,{\"--g=2,3\"})", 0, A ("--g=2,3"), 1, "|-g=", F);
+ T ("foo(1,{\"--h=3:4\"})", 0, A ("--h=3:4"), 1, "|-h=", F);
+ T ("foo(1,{\"--i=\"j\"\"})", 0, A ("--i=\"j\""), 1, "|-i=", F);
+
+ // exercise callback errors
+ retvals [0] = 1;
+ T ("foo(2,{\"-a\",\"-b\"})",
+ retvals [0], A ("-a", "-b"), 2, "a b", F, B);
+
+ retvals [0] = 0;
+ retvals [1] = 2;
+
+ T ("foo(3,{\"-a\",\"-b\",\"-c\"});"
+ "bar(2,{\"-b\",\"-c\"})",
+ retvals [1], A ("-a", "-b", "-c"), 3, "a b c", F, B, E);
+
+ retvals [1] = 0;
+
+ // exercise repeated options
+ // only the first occurrence of each command line option
+ // causes an invocation of the callback, all subsequent
+ // ones will be ignored by default
+ T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a", F);
+
+ // unlimited number of invocations
+ T ("foo(2,{\"-a\",\"-a\"});"
+ "foo(1,{\"-a\"})",
+ 0, A ("-a", "-a"), 1, "a@*", F);
+
+ // no invocation (option is disabled)
+ T ("", 0, A ("-a"), 1, "a@0", F);
+ T ("", 0, A ("-a", "-a"), 1, "a@0", F);
+
+ T ("bar(1,{\"-b\"})", 0, A ("-a", "-a", "-b"), 2, "a@0 b", F, B);
+ T ("bar(2,{\"-b\",\"-a\"})", 0, A ("-a", "-b", "-a"), 2, "a@0 b", F, B);
+
+ T ("bar(3,{\"-b\",\"-a\",\"-b\"})",
+ 0, A ("-b", "-a", "-b"), 2, "b a@0", B, F);
+
+ T ("bar(4,{\"-b\",\"-a\",\"-b\",\"-a\"})",
+ 0, A ("-b", "-a", "-b", "-a"), 2, "b a@0", B, F);
+
+ // at most one invocation (default)
+ T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a@1", F);
+ T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a@1", F);
+
+ // at most two invocations
+ T ("foo(2,{\"-a\",\"-a\"});"
+ "foo(1,{\"-a\"})",
+ 0, A ("-a", "-a"), 1, "a@2", F);
+
+ T ("foo(3,{\"-a\",\"-a\",\"-a\"});"
+ "foo(2,{\"-a\",\"-a\"})",
+ 0, A ("-a", "-a", "-a"), 1, "a@2", F);
+
+ // inverted option (callback invoked iff option is not specified)
+ T ("", 0, A ("-i"), 1, "i!", F);
+ T ("foo(0,{})", 0, A (""), 1, "i!", F);
+ T ("", 0, A ("--j"), 1, "i|-j!", F);
+
+ T ("foo(1,{\"-k\"});"
+ "foo(0,{})", 0, A ("-k"), 2, "k l!", F, F);
+
+ return exit_status;
+}
Propchange: incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/self/0.cmdopts.cpp
------------------------------------------------------------------------------
svn:keywords = Id