stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/opt_lines.cpp
changeset 0 e4d67989cc36
child 22 ddc455616bd6
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /************************************************************************
       
     2  *
       
     3  * opt_lines.cpp - definitions of line option handlers
       
     4  *
       
     5  * $Id: opt_lines.cpp 290026 2005-09-19 00:12:38Z sebor $
       
     6  *
       
     7  ************************************************************************
       
     8  *
       
     9  * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
       
    10  * Software division. Licensed under the Apache License, Version 2.0 (the
       
    11  * "License");  you may  not use this file except  in compliance with the
       
    12  * License.    You    may   obtain   a   copy   of    the   License    at
       
    13  * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
       
    14  * applicable law  or agreed to  in writing,  software  distributed under
       
    15  * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
       
    16  * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
       
    17  * for the specific language governing permissions  and limitations under
       
    18  * the License.
       
    19  *
       
    20  **************************************************************************/
       
    21 
       
    22 // expand _TEST_EXPORT macros
       
    23 #define _RWSTD_TEST_SRC
       
    24 
       
    25 #include "opt_lines.h"
       
    26 
       
    27 #include <cmdopt.h>
       
    28 
       
    29 #include <assert.h>
       
    30 #include <stdio.h>
       
    31 #include <stdlib.h>
       
    32 #include <string.h>
       
    33 
       
    34 
       
    35 enum {
       
    36     l_enabled  = 1,   // line is enabled
       
    37     l_disabled = 2,   // line is disabled
       
    38     l_expected = 4    // diagnostic on line is expected to be active
       
    39 };
       
    40 
       
    41 struct linerange_t {
       
    42     int      first;
       
    43     int      last;
       
    44     unsigned flags: 8;
       
    45     char     id [80];
       
    46 };
       
    47 
       
    48 static size_t nlineranges;
       
    49 static linerange_t *lineranges;
       
    50 static size_t rangebufsize;
       
    51 
       
    52 /**************************************************************************/
       
    53 
       
    54 static int
       
    55 _rw_enable_lines (int first, int last, int flags)
       
    56 {
       
    57     if (nlineranges == rangebufsize) {
       
    58         const size_t newbufsize = 2 * nlineranges + 1;
       
    59             
       
    60         linerange_t* const newranges =
       
    61             (linerange_t*)malloc (newbufsize * sizeof (linerange_t));
       
    62 
       
    63         if (0 == newranges) {
       
    64             abort ();
       
    65         }
       
    66 
       
    67         memcpy (newranges, lineranges, nlineranges * sizeof (linerange_t));
       
    68 
       
    69         free (lineranges);
       
    70 
       
    71         lineranges   = newranges;
       
    72         rangebufsize = newbufsize;
       
    73     }
       
    74 
       
    75     lineranges [nlineranges].first = first;
       
    76     lineranges [nlineranges].last  = last;
       
    77 
       
    78     lineranges [nlineranges].flags = flags;
       
    79 
       
    80     ++nlineranges;
       
    81 
       
    82     return 0;
       
    83 }
       
    84 
       
    85 
       
    86 static int
       
    87 _rw_enable_line (int argc, char *argv[], int flags)
       
    88 {
       
    89     char *parg = strchr (argv [0], '=');
       
    90     assert (0 != parg);
       
    91 
       
    92     const char* const argbeg = ++parg;
       
    93 
       
    94     // the lower bound of a range of lines to be enabled or disabled
       
    95     // negative values are not valid and denote an implicit lower bound
       
    96     // of 1 (such as in "-3" which is a shorthand for "1-3")
       
    97     long first = -1;
       
    98 
       
    99     for ( ; '\0' != *parg ; ) {
       
   100 
       
   101         // skip any leading whitespace
       
   102         for ( ; ' ' == *parg; ++parg);
       
   103 
       
   104         if ('-' == *parg) {
       
   105             if (first < 0) {
       
   106                 first = 0;
       
   107                 ++parg;
       
   108             }
       
   109             else {
       
   110                 fprintf (stderr,
       
   111                          "invalid character '%c' at position %d: \"%s\"\n",
       
   112                          *parg, int (parg - argbeg), argv [0]);
       
   113                 return 2;
       
   114             }
       
   115         }
       
   116 
       
   117         // parse a numeric argument
       
   118         char *end;
       
   119         long line = strtol (parg, &end, 0);
       
   120 
       
   121         // skip any trailing whitespace
       
   122         for ( ; ' ' == *end; ++end);
       
   123 
       
   124         if (end == parg || '-' != *end && ',' != *end && '\0' != *end) {
       
   125             fprintf (stderr,
       
   126                      "invalid character '%c' at position %d: \"%s\"\n",
       
   127                      *end, int (parg - argbeg), argv [0]);
       
   128             return 2;
       
   129         }
       
   130 
       
   131         if (0 <= first) {
       
   132             if (line < 0) {
       
   133                 fprintf (stderr,
       
   134                          "invalid value %ld at position %d: \"%s\"\n",
       
   135                          line, int (parg - argbeg), argv [0]);
       
   136                 return 2;
       
   137             }
       
   138 
       
   139             ++line;
       
   140 
       
   141             if ((',' == *end || '-' == *end) && end [1])
       
   142                 ++end;
       
   143         }
       
   144         else if (',' == *end) {
       
   145             first = line++;
       
   146             if ('\0' == end [1]) {
       
   147                 fprintf (stderr,
       
   148                          "invalid character '%c' at position %d: \"%s\"\n",
       
   149                          *end, int (parg - argbeg), argv [0]);
       
   150                 return 2;
       
   151             }
       
   152 
       
   153             ++end;
       
   154         }
       
   155         else if ('-' == *end) {
       
   156             first = line;
       
   157             while (' ' == *++end);
       
   158             if ('\0' == *end) {
       
   159                 line = _RWSTD_INT_MAX;
       
   160             }
       
   161             else if  (',' == *end) {
       
   162                 line = _RWSTD_INT_MAX;
       
   163                 ++end;
       
   164             }
       
   165             else
       
   166                 line = -1;
       
   167         }
       
   168         else if ('\0' == *end) {
       
   169             first = line++;
       
   170         }
       
   171         else {
       
   172             fprintf (stderr,
       
   173                      "invalid character '%c' at position %d: \"%s\"\n",
       
   174                      *end, int (parg - argbeg), argv [0]);
       
   175             return 2;
       
   176         }
       
   177 
       
   178         parg = end;
       
   179 
       
   180         if (0 <= first && first < line) {
       
   181             _rw_enable_lines (first, line, flags);
       
   182             first = -1;
       
   183         }
       
   184     }
       
   185 
       
   186     return 0;
       
   187 }
       
   188 
       
   189 /**************************************************************************/
       
   190 
       
   191 static int
       
   192 _rw_opt_enable_line (int argc, char *argv[])
       
   193 {
       
   194     if (1 == argc && argv && 0 == argv [0]) {
       
   195 
       
   196         static const char helpstr[] = {
       
   197             "Enables the line or lines specified by <arg>.\n"
       
   198             "The syntax of <arg> is as follows: \n"
       
   199             "<arg>   ::= <range> [ , <range> ]\n"
       
   200             "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
       
   201         };
       
   202 
       
   203         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   204 
       
   205         return 0;
       
   206     }
       
   207 
       
   208     return _rw_enable_line (argc, argv, l_enabled);
       
   209 }
       
   210 
       
   211 /**************************************************************************/
       
   212 
       
   213 static int
       
   214 _rw_opt_no_line (int argc, char *argv[])
       
   215 {
       
   216     if (1 == argc && argv && 0 == argv [0]) {
       
   217 
       
   218         static const char helpstr[] = {
       
   219             "Disables the line or lines specified by <arg>.\n"
       
   220             "The syntax of <arg> is as follows: \n"
       
   221             "<arg>   ::= <range> [ , <range> ]\n"
       
   222             "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
       
   223         };
       
   224 
       
   225         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   226 
       
   227         return 0;
       
   228     }
       
   229 
       
   230     return _rw_enable_line (argc, argv, l_disabled);
       
   231 }
       
   232 
       
   233 /**************************************************************************/
       
   234 
       
   235 static int
       
   236 _rw_opt_expect_line (int argc, char *argv[])
       
   237 {
       
   238     if (1 == argc && argv && 0 == argv [0]) {
       
   239 
       
   240         static const char helpstr[] = {
       
   241             "Marks the line or lines specified by <arg> as \"expected\".\n"
       
   242             "Inactive diagnostics on such lines will be issued as unexpected.\n"
       
   243             "The syntax of <arg> is as follows: \n"
       
   244             "<arg>   ::= <range> [ , <range> ]\n"
       
   245             "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
       
   246         };
       
   247 
       
   248         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   249 
       
   250         return 0;
       
   251     }
       
   252 
       
   253     return _rw_enable_line (argc, argv, l_expected);
       
   254 }
       
   255 
       
   256 /************************************************************************/
       
   257 
       
   258 /* extern */ int
       
   259 _rw_setopts_lines ()
       
   260 {
       
   261     const int result =
       
   262         rw_setopts ("|-enable-line="   // argument required
       
   263                     "|-expect= "       // argument required
       
   264                     "|-no-line= ",     // argument required
       
   265                     _rw_opt_enable_line,
       
   266                     _rw_opt_expect_line,
       
   267                     _rw_opt_no_line);
       
   268 
       
   269     return result;
       
   270 }
       
   271 
       
   272 /************************************************************************/
       
   273 
       
   274 /* extern */ int
       
   275 _rw_expected (int line)
       
   276 {
       
   277     int line_expected = 0;
       
   278 
       
   279     for (size_t i = 0; i != nlineranges; ++i) {
       
   280 
       
   281         const int first = lineranges [i].first;
       
   282         const int last  = lineranges [i].last;
       
   283 
       
   284         if (lineranges [i].flags & (l_disabled | l_enabled)) {
       
   285             continue;
       
   286         }
       
   287 
       
   288         if (first <= line && line < last)
       
   289             line_expected = 0 != (lineranges [i].flags & l_expected);
       
   290     }
       
   291 
       
   292     return line_expected;
       
   293 }
       
   294 
       
   295 /************************************************************************/
       
   296 
       
   297 _TEST_EXPORT int
       
   298 rw_enabled (int line)
       
   299 {
       
   300     int nenabled = 0;
       
   301     int ndisabled = 0;
       
   302 
       
   303     int line_enabled = -1;
       
   304 
       
   305     for (size_t i = 0; i != nlineranges; ++i) {
       
   306 
       
   307         const int first = lineranges [i].first;
       
   308         const int last  = lineranges [i].last;
       
   309 
       
   310         if (lineranges [i].flags & l_disabled) {
       
   311             ++ndisabled;
       
   312         }
       
   313         else if (lineranges [i].flags & l_enabled) {
       
   314             ++nenabled;
       
   315         }
       
   316         else {
       
   317             continue;
       
   318         }
       
   319 
       
   320         if (first <= line && line < last)
       
   321             line_enabled = 0 != (lineranges [i].flags & l_enabled);
       
   322     }
       
   323 
       
   324     if (nenabled && -1 == line_enabled)
       
   325         line_enabled = 0;
       
   326 
       
   327     return line_enabled;
       
   328 }