LCOV - code coverage report
Current view: top level - toolbox - Option.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 76 10.5 %
Date: 2017-07-14 10:03:36 Functions: 3 13 23.1 %

          Line data    Source code
       1             : /* src/toolbox/Option.cpp - Command line option parsing library
       2             : 
       3             :    Copyright (C) 1996-2014
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #include "toolbox/Option.hpp"
      26             : #include "toolbox/Debug.hpp"
      27             : #include "toolbox/logging.hpp"
      28             : #include "toolbox/OStream.hpp"
      29             : 
      30             : namespace cacao {
      31             : 
      32             : namespace option {
      33             : 
      34           0 : OptionPrefix& root(){
      35           0 :         static OptionPrefix prefix("-");
      36           0 :         return prefix;
      37             : }
      38             : 
      39        1980 : OptionPrefix& xx_root(){
      40        1980 :         static OptionPrefix prefix("-XX:");
      41        1980 :         return prefix;
      42             : }
      43             : 
      44             : } // end namespace option
      45             : 
      46         165 : OptionPrefix::OptionPrefix(const char* name) : name(name), s(std::strlen(name)) {
      47         165 : }
      48        1980 : void OptionPrefix::insert(OptionEntry* oe) {
      49        1980 :         children.insert(oe);
      50        1980 : }
      51             : 
      52           0 : void OptionParser::print_usage(OptionPrefix& root, FILE *fp) {
      53             :         static const char* blank29 = "                             "; // 29 spaces
      54           0 :         static const char* blank25 = blank29 + 4;                     // 25 spaces
      55           0 :         OStream OS(fp);
      56             : 
      57           0 :         std::set<OptionEntry*> sorted(root.begin(),root.end());
      58             : 
      59           0 :         for(std::set<OptionEntry*>::iterator i = sorted.begin(), e = sorted.end();
      60             :                         i != e; ++i) {
      61           0 :                 OptionEntry& oe = **i;
      62           0 :                 OS << "    " << root.get_name();
      63           0 :                 std::size_t name_len = root.size() + oe.print(OS);
      64           0 :                 if (name_len < (25-1)) {
      65           0 :                         OS << (blank25 + name_len);
      66             :                 } else {
      67           0 :                         OS << nl << blank29;
      68             :                 }
      69             : 
      70           0 :                 const char* c = oe.get_desc();
      71           0 :                 for (std::size_t i = 29; *c != 0; c++, i++) {
      72             :                         /* If we are at the end of the line, break it. */
      73           0 :                         if (i == 80) {
      74           0 :                                 OS << nl << blank29;
      75           0 :                                 i = 29;
      76             :                         }
      77           0 :                         OS << *c;
      78             :                 }
      79           0 :                 OS << nl;
      80           0 :         }
      81             : 
      82           0 : }
      83             : 
      84           0 : std::size_t option_print(OptionEntry& option, OStream& OS) {
      85           0 :         OS << option.get_name() << "=<value>";
      86           0 :         return option.size() + 8;
      87             : }
      88             : 
      89           0 : std::size_t option_print(OptionBase<bool>& option, OStream& OS) {
      90           0 :         OS << '+' << option.get_name();
      91           0 :         return option.size() + 1;
      92             : }
      93             : 
      94             : 
      95             : namespace {
      96             : 
      97           0 : bool option_matcher(const char* a, std::size_t a_len,
      98             :                 const char* b, std::size_t b_len) {
      99           0 :         return (a_len == b_len) && std::strncmp(a, b, a_len) == 0;
     100             : }
     101             : 
     102             : } // end anonymous namespace
     103             : 
     104           0 : bool OptionParser::parse_option(OptionPrefix& root, const char* name, size_t name_len,
     105             :                 const char* value, size_t value_len) {
     106           0 :         assert(std::strncmp(root.get_name(), name, std::strlen(root.get_name())) == 0);
     107           0 :         name += root.size();
     108           0 :         name_len -= root.size();
     109           0 :         assert(name_len > 0);
     110           0 :         if (name[0] == '-' || name[0] == '+') {
     111           0 :                 assert(value_len == 0);
     112           0 :                 assert(value == 0);
     113           0 :                 value = name;
     114           0 :                 value_len = 1;
     115           0 :                 ++name;
     116           0 :                 --name_len;
     117             :         }
     118           0 :         for(OptionPrefix::iterator i = root.begin(), e = root.end();
     119             :                         i != e; ++i) {
     120           0 :                 OptionEntry& oe = **i;
     121           0 :                 if (option_matcher(oe.get_name(), oe.size(), name, name_len)) {
     122           0 :                         if (oe.parse(value,value_len))
     123           0 :                                 return true;
     124           0 :                         return false;
     125             :                 }
     126             :         }
     127           0 :         return false;
     128             : }
     129             : 
     130             : template<>
     131           0 : bool Option<const char*>::parse(const char* value, std::size_t value_len) {
     132           0 :         set_value(value);
     133           0 :         return true;
     134             : }
     135             : 
     136             : template<>
     137           0 : bool Option<bool>::parse(const char* value, std::size_t value_len) {
     138           0 :         assert(value_len == 1);
     139           0 :         char first = value[0];
     140           0 :         if (first == '-') {
     141           0 :                 set_value(false);
     142           0 :                 return true;
     143             :         }
     144           0 :         if (first == '+') {
     145           0 :                 set_value(true);
     146           0 :                 return true;
     147             :         }
     148           0 :         ABORT_MSG("ERROR", "boolean option not valid: " << value);
     149           0 :         return false;
     150             : }
     151             : 
     152             : template<>
     153           0 : bool Option<unsigned int>::parse(const char* value, std::size_t value_len) {
     154           0 :         int verb = os::atoi(value);
     155           0 :         set_value(verb >= 0 ? verb : 0);
     156           0 :         return true;
     157             : }
     158             : 
     159             : } // end namespace cacao
     160             : 
     161             : /*
     162             :  * These are local overrides for various environment variables in Emacs.
     163             :  * Please do not remove this and leave it at the end of the file, where
     164             :  * Emacs will automagically detect them.
     165             :  * ---------------------------------------------------------------------
     166             :  * Local variables:
     167             :  * mode: c++
     168             :  * indent-tabs-mode: t
     169             :  * c-basic-offset: 4
     170             :  * tab-width: 4
     171             :  * End:
     172             :  * vim:noexpandtab:sw=4:ts=4:
     173             :  */

Generated by: LCOV version 1.11