stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/opt_lines.cpp
changeset 0 e4d67989cc36
child 22 ddc455616bd6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/opt_lines.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,328 @@
+/************************************************************************
+ *
+ * opt_lines.cpp - definitions of line option handlers
+ *
+ * $Id: opt_lines.cpp 290026 2005-09-19 00:12:38Z sebor $
+ *
+ ************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+// expand _TEST_EXPORT macros
+#define _RWSTD_TEST_SRC
+
+#include "opt_lines.h"
+
+#include <cmdopt.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+enum {
+    l_enabled  = 1,   // line is enabled
+    l_disabled = 2,   // line is disabled
+    l_expected = 4    // diagnostic on line is expected to be active
+};
+
+struct linerange_t {
+    int      first;
+    int      last;
+    unsigned flags: 8;
+    char     id [80];
+};
+
+static size_t nlineranges;
+static linerange_t *lineranges;
+static size_t rangebufsize;
+
+/**************************************************************************/
+
+static int
+_rw_enable_lines (int first, int last, int flags)
+{
+    if (nlineranges == rangebufsize) {
+        const size_t newbufsize = 2 * nlineranges + 1;
+            
+        linerange_t* const newranges =
+            (linerange_t*)malloc (newbufsize * sizeof (linerange_t));
+
+        if (0 == newranges) {
+            abort ();
+        }
+
+        memcpy (newranges, lineranges, nlineranges * sizeof (linerange_t));
+
+        free (lineranges);
+
+        lineranges   = newranges;
+        rangebufsize = newbufsize;
+    }
+
+    lineranges [nlineranges].first = first;
+    lineranges [nlineranges].last  = last;
+
+    lineranges [nlineranges].flags = flags;
+
+    ++nlineranges;
+
+    return 0;
+}
+
+
+static int
+_rw_enable_line (int argc, char *argv[], int flags)
+{
+    char *parg = strchr (argv [0], '=');
+    assert (0 != parg);
+
+    const char* const argbeg = ++parg;
+
+    // the lower bound of a range of lines to be enabled or disabled
+    // negative values are not valid and denote an implicit lower bound
+    // of 1 (such as in "-3" which is a shorthand for "1-3")
+    long first = -1;
+
+    for ( ; '\0' != *parg ; ) {
+
+        // skip any leading whitespace
+        for ( ; ' ' == *parg; ++parg);
+
+        if ('-' == *parg) {
+            if (first < 0) {
+                first = 0;
+                ++parg;
+            }
+            else {
+                fprintf (stderr,
+                         "invalid character '%c' at position %d: \"%s\"\n",
+                         *parg, int (parg - argbeg), argv [0]);
+                return 2;
+            }
+        }
+
+        // parse a numeric argument
+        char *end;
+        long line = strtol (parg, &end, 0);
+
+        // skip any trailing whitespace
+        for ( ; ' ' == *end; ++end);
+
+        if (end == parg || '-' != *end && ',' != *end && '\0' != *end) {
+            fprintf (stderr,
+                     "invalid character '%c' at position %d: \"%s\"\n",
+                     *end, int (parg - argbeg), argv [0]);
+            return 2;
+        }
+
+        if (0 <= first) {
+            if (line < 0) {
+                fprintf (stderr,
+                         "invalid value %ld at position %d: \"%s\"\n",
+                         line, int (parg - argbeg), argv [0]);
+                return 2;
+            }
+
+            ++line;
+
+            if ((',' == *end || '-' == *end) && end [1])
+                ++end;
+        }
+        else if (',' == *end) {
+            first = line++;
+            if ('\0' == end [1]) {
+                fprintf (stderr,
+                         "invalid character '%c' at position %d: \"%s\"\n",
+                         *end, int (parg - argbeg), argv [0]);
+                return 2;
+            }
+
+            ++end;
+        }
+        else if ('-' == *end) {
+            first = line;
+            while (' ' == *++end);
+            if ('\0' == *end) {
+                line = _RWSTD_INT_MAX;
+            }
+            else if  (',' == *end) {
+                line = _RWSTD_INT_MAX;
+                ++end;
+            }
+            else
+                line = -1;
+        }
+        else if ('\0' == *end) {
+            first = line++;
+        }
+        else {
+            fprintf (stderr,
+                     "invalid character '%c' at position %d: \"%s\"\n",
+                     *end, int (parg - argbeg), argv [0]);
+            return 2;
+        }
+
+        parg = end;
+
+        if (0 <= first && first < line) {
+            _rw_enable_lines (first, line, flags);
+            first = -1;
+        }
+    }
+
+    return 0;
+}
+
+/**************************************************************************/
+
+static int
+_rw_opt_enable_line (int argc, char *argv[])
+{
+    if (1 == argc && argv && 0 == argv [0]) {
+
+        static const char helpstr[] = {
+            "Enables the line or lines specified by <arg>.\n"
+            "The syntax of <arg> is as follows: \n"
+            "<arg>   ::= <range> [ , <range> ]\n"
+            "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    return _rw_enable_line (argc, argv, l_enabled);
+}
+
+/**************************************************************************/
+
+static int
+_rw_opt_no_line (int argc, char *argv[])
+{
+    if (1 == argc && argv && 0 == argv [0]) {
+
+        static const char helpstr[] = {
+            "Disables the line or lines specified by <arg>.\n"
+            "The syntax of <arg> is as follows: \n"
+            "<arg>   ::= <range> [ , <range> ]\n"
+            "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    return _rw_enable_line (argc, argv, l_disabled);
+}
+
+/**************************************************************************/
+
+static int
+_rw_opt_expect_line (int argc, char *argv[])
+{
+    if (1 == argc && argv && 0 == argv [0]) {
+
+        static const char helpstr[] = {
+            "Marks the line or lines specified by <arg> as \"expected\".\n"
+            "Inactive diagnostics on such lines will be issued as unexpected.\n"
+            "The syntax of <arg> is as follows: \n"
+            "<arg>   ::= <range> [ , <range> ]\n"
+            "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    return _rw_enable_line (argc, argv, l_expected);
+}
+
+/************************************************************************/
+
+/* extern */ int
+_rw_setopts_lines ()
+{
+    const int result =
+        rw_setopts ("|-enable-line="   // argument required
+                    "|-expect= "       // argument required
+                    "|-no-line= ",     // argument required
+                    _rw_opt_enable_line,
+                    _rw_opt_expect_line,
+                    _rw_opt_no_line);
+
+    return result;
+}
+
+/************************************************************************/
+
+/* extern */ int
+_rw_expected (int line)
+{
+    int line_expected = 0;
+
+    for (size_t i = 0; i != nlineranges; ++i) {
+
+        const int first = lineranges [i].first;
+        const int last  = lineranges [i].last;
+
+        if (lineranges [i].flags & (l_disabled | l_enabled)) {
+            continue;
+        }
+
+        if (first <= line && line < last)
+            line_expected = 0 != (lineranges [i].flags & l_expected);
+    }
+
+    return line_expected;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_enabled (int line)
+{
+    int nenabled = 0;
+    int ndisabled = 0;
+
+    int line_enabled = -1;
+
+    for (size_t i = 0; i != nlineranges; ++i) {
+
+        const int first = lineranges [i].first;
+        const int last  = lineranges [i].last;
+
+        if (lineranges [i].flags & l_disabled) {
+            ++ndisabled;
+        }
+        else if (lineranges [i].flags & l_enabled) {
+            ++nenabled;
+        }
+        else {
+            continue;
+        }
+
+        if (first <= line && line < last)
+            line_enabled = 0 != (lineranges [i].flags & l_enabled);
+    }
+
+    if (nenabled && -1 == line_enabled)
+        line_enabled = 0;
+
+    return line_enabled;
+}