Changeset 705


Ignore:
Timestamp:
Nov 26, 2008, 12:33:26 AM (12 years ago)
Author:
Peter Johansson
Message:

importing classes for commandline parsing from yat. This fixes #349 and #265

Location:
trunk
Files:
11 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/Parameter.cc

    r699 r705  
    2424
    2525#include "ColumnStream.h"
    26 #include "subversion_info.h"
     26#include "OptionArg.h"
     27#include "OptionHelp.h"
     28#include "OptionSwitch.h"
     29#include "OptionVersion.h"
    2730#include "utility.h"
    2831#include <config.h> // this header file is created by configure
    2932
     33#include <cassert>
     34#include <cerrno>
    3035#include <cstddef>
    3136#include <fstream>
     
    4045
    4146  Parameter::Parameter( int argc, char *argv[])
    42     : config_file_(""), copyright_(false), force_(false),
    43       generate_config_(false), ignore_cache_(true), report_(true),
    44       revisions_(false), root_("."), root_node_("."), targetdir_("."),
    45       verbose_(false)
    46   {
    47     for (int i=1; i<argc; ++i) {
    48       std::stringstream ss(argv[i]);
    49       std::string myargv("");
    50       std::string value("");
    51       getline(ss, myargv, '=');
    52       getline(ss, value);
    53 
    54       if (myargv=="--config-file"){
    55         if (value.size()) {
    56           config_file_.value()= value;
     47    : cmd_(
     48     "Mandatory arguments to long options are mandatory for short options too.")
     49  {
     50    init();
     51    try {
     52      cmd_.parse(argc, argv);
     53    }
     54    catch (cmd_error& e) {
     55      std::cerr << e.what() << std::endl;
     56      exit (-1);
     57    }
     58
     59    // set default values
     60    if (!root_->present())
     61      root_->value(".");
     62
     63    if (!target_->present())
     64      target_->value(".");
     65
     66    if (!config_file_->present())
     67      config_file_->value(root_->value()+"/.svndigest/config");
     68
     69    // analyse arguments
     70    analyse();
     71  }
     72
     73
     74  Parameter::~Parameter(void)
     75  {
     76    delete config_file_;
     77    delete copyright_;
     78    delete force_;
     79    delete generate_config_;
     80    delete help_;
     81    delete ignore_cache_;
     82    delete report_;
     83    delete revisions_;
     84    delete root_;
     85    delete target_;
     86    delete verbose_;
     87    delete version_;
     88  }
     89
     90
     91  void Parameter::analyse(void)
     92  {
     93    std::string save_wd = pwd();
     94
     95    // check root but not if -g option given
     96    if (!generate_config()) {
     97      check_existence(root_->value());
     98      check_readable(root_->value());
     99      if (chdir(root_->value().c_str())) {
     100        std::stringstream ss;
     101        ss << "svndigest: cannot read `" << root_->value() << "': "
     102           << strerror(errno);
     103        throw cmd_error(ss.str());
     104      }
     105      root_->value(pwd());
     106      chdir(save_wd.c_str());
     107
     108      // check target (only if we write report)
     109      if (report()) {
     110        check_existence(target_->value());
     111        check_readable(target_->value());
     112        std::string base_root = file_name(root_->value());
     113        std::string path = concatenate_path(target_->value(),base_root);
     114        if (access_rights(target_->value().c_str(), "w")) {
     115          std::stringstream ss;
     116          ss << "svndigest: cannot create directory `" << path
     117             << "': " << strerror(errno);
     118          throw cmd_error(ss.str());
    57119        }
    58         else if (++i<argc){
    59           config_file_.value()= std::string(argv[i]);
     120        if (node_exist(path) && !force()) {
     121          std::stringstream ss;
     122          ss << "svndigest: cannot create directory `" << path << "' "
     123             << strerror(EEXIST);
     124          throw cmd_error(ss.str());
    60125        }
    61         else {
    62           missing_argument(myargv);
     126        if (chdir(target_->value().c_str())) {
     127          std::stringstream ss;
     128          ss << "svndigest: cannot read `" << target_->value() << "': "
     129             << strerror(errno);
     130          throw cmd_error(ss.str());
    63131        }
     132        target_->value(concatenate_path(pwd(), base_root));
     133        chdir(save_wd.c_str());
    64134      }
    65       else if (myargv=="--copyright"){
    66           copyright_.value()=true;
     135    }
     136
     137    // check config file
     138    if (config_file_->present())
     139      check_existence(config_file_->value());
     140    if (node_exist(config_file_->value())) {
     141      check_readable(config_file_->value());
     142      struct stat nodestat;
     143      stat(config_file_->value().c_str(), &nodestat);
     144      if (!S_ISREG(nodestat.st_mode)) {
     145        std::stringstream ss;
     146        ss << "svndigest: `" << root_->value() << "' is not a regular file";
     147        throw cmd_error(ss.str());
    67148      }
    68       else if (myargv=="-f" || myargv=="--force"){
    69           force_.value()=true;
    70       }
    71       else if (myargv=="-g" || myargv=="--generate-config"){
    72           generate_config_.value()=true;
    73       }
    74       else if (myargv=="-h" || myargv=="--help"){
    75         help();
    76         exit(0);      // always exit after printing help
    77       }
    78       else if (myargv=="--ignore-cache"){
    79           ignore_cache_.value()=true;
    80       }
    81       else if (myargv=="-r" || myargv=="--root"){
    82         if (value.size()) {
    83           root_.value()= value;
    84         }
    85         else if (++i<argc){
    86           root_.value()= std::string(argv[i]);
    87         }
    88         else {
    89           missing_argument(myargv);
    90         }
    91       }
    92       else if (myargv=="--report") {
    93           report_.value()=true;
    94       }
    95       else if (myargv=="--no-report") {
    96           report_.value()=false;
    97       }
    98       else if (myargv=="--revisions") {
    99           revisions_.value()=true;
    100       }
    101       else if (myargv=="-t" || myargv=="--target"){
    102         if (value.size()) {
    103           targetdir_.value()= value;
    104         }
    105         else if (++i<argc){
    106           targetdir_.value()= std::string(argv[i]);
    107         }
    108         else {
    109           missing_argument(myargv);
    110         }
    111       }
    112       else if (myargv=="-v" || myargv=="--verbose"){
    113           verbose_.value()=true;
    114       }
    115       else if (myargv=="--version"){
    116         version();
    117         exit(0);
    118       }
    119       else if (myargv=="-vf" || myargv=="-fv"){
    120           verbose_.value()=true;
    121           force_.value()=true;
    122       }
    123       else {
    124         throw std::runtime_error("svndigest: invalid option: " + myargv +
    125                                  "\nTry `svndigest --help' for usage.");
    126       }
    127   }
    128 
    129     analyse();
    130   }
    131 
    132 
    133   void Parameter::analyse(void)
    134   {
    135     using namespace std;
    136 
    137     string workdir(pwd()); // remember current working directory (cwd).
    138 
    139     if (!node_exist(root_.value()))
    140       throw runtime_error(string("svndigest: cannot stat `" + root_.value() +
    141                                  "': no such file or directory"));
    142 
    143     if (access_rights(root_.value(), "r"))
    144       throw runtime_error(string("svndigest: cannot open `" + root_.value() +
    145                                  "' for reading: Permission denied"));
    146 
    147     // Check whether root is directory or file
    148     struct stat nodestat;
    149     stat(root_.value().c_str(), &nodestat);
    150     if (S_ISDIR(nodestat.st_mode)) {
    151       chdir(root_.value().c_str());
    152       root_node_.value() = root_.value() = pwd();
    153     }
    154     else {
    155       std::string fname = file_name(root_.value());
    156       root_.value() = directory_name(root_.value());
    157       chdir(root_.value().c_str());
    158       root_.value() = pwd();
    159       root_node_.value() = root_.value() + "/" + fname;
    160     }
    161 
    162     // need to get back to cwd if relative paths are used.
    163     if (chdir(workdir.c_str()))
    164       runtime_error(string("svndigest: Failed to access cwd: ") + workdir);
    165 
    166     // Checking that targetdir_ exists and retrieve the absolute path
    167     // to targetdir_
    168     if (report()) {
    169       if (chdir(targetdir_.value().c_str()))
    170         throw runtime_error(string("svndigest: Target directory (") +
    171                             targetdir_.value() + ") access failed.");
    172       targetdir_.value() = pwd();
    173       // Checking write permissions for targetdir_
    174       if (access_rights(targetdir_.value(),"w"))
    175         throw runtime_error(string("svndigest: No write permission on target ") +
    176                             "directory (" + targetdir_.value() +").");
    177     }
    178 
    179     // return back to cwd
    180     if (chdir(workdir.c_str()))
    181       throw runtime_error(string("svndigest: Failed to access cwd: ") + workdir);
    182 
    183   }
    184 
     149    }
     150  }
     151
     152
     153  void Parameter::check_existence(std::string path) const
     154  {
     155    if (node_exist(path))
     156      return;
     157    std::stringstream ss;
     158    ss << "svndigest: cannot stat `" << path << "': " << strerror(errno);
     159    throw cmd_error(ss.str());
     160  }
     161
     162 
     163  void Parameter::check_readable(std::string path) const
     164  {
     165    if (!access_rights(path, "r"))
     166      return;
     167    std::stringstream ss;
     168    ss << "svndigest: cannot open `" << path << "': " << strerror(errno);
     169    throw cmd_error(ss.str());
     170  }
     171 
    185172
    186173  std::string Parameter::config_file(void) const
    187174  {
    188     // not default
    189     if (!config_file_.value().empty())
    190       return config_file_.value();
     175    return config_file_->value();
     176  }
     177
     178
     179  bool Parameter::copyright(void) const
     180  {
     181    return copyright_->present();
     182  }
     183
     184
     185  bool Parameter::force(void) const
     186  {
     187    return force_->present();
     188  }
     189
     190
     191  bool Parameter::generate_config(void) const
     192  {
     193    return generate_config_->present();
     194  }
     195
     196
     197  bool Parameter::ignore_cache(void) const
     198  {
     199    return ignore_cache_->present();
     200  }
     201
     202
     203  void Parameter::init(void)
     204  {
     205    // don't use argv[0] because user may rename the binary
     206    cmd_.program_name() = PACKAGE_NAME;
     207    config_file_=new OptionArg<std::string>(cmd_, "config-file",
     208                                "configuration file [<ROOT>/.svndigest/config]");
     209    config_file_->print_arg("=FILE");
     210    std::stringstream ss;
     211    copyright_ = new OptionSwitch(cmd_, "copyright",
     212                                  "update copyright statement");
     213
     214    ss << "if sub-directory named <ROOT> exists in target directory, remove "
     215       << "sub-directory before writing results";
     216    force_ = new OptionSwitch(cmd_, "f,force", ss.str());
     217    ss.str("");
     218
     219    help_ = new OptionHelp(cmd_);
     220    generate_config_ =
     221      new OptionSwitch(cmd_, "g,generate-config",
     222                       "write configuration file to standard output");
     223
     224    ss.str("");
     225    ss << "ignore cache files and analyze everything from repository";
     226    ignore_cache_ = new OptionSwitch(cmd_, "ignore-cache", ss.str());
     227         
     228    report_ = new OptionSwitch(cmd_, "report", "create no HTML report", true);
     229
     230    ss.str("");
     231    ss << "use revision numbers as time scale instead of dates [dates]";
     232    revisions_ = new OptionSwitch(cmd_, "revisions", ss.str());
     233
     234    root_=
     235      new OptionArg<std::string>(cmd_, "r,root",
     236                     "svn controlled directory to perform statistics on [.]");
     237    root_->print_arg("=ROOT");
     238    target_ = new OptionArg<std::string>(cmd_, "t,target",
     239                                         "output directory [.]");
     240    target_->print_arg("=TARGET");
    191241   
    192     // default behaviour
    193     return root()+"/.svndigest/config";
    194   }
    195 
    196 
    197   void Parameter::help(void) const
    198   {
    199     ColumnStream cs(std::cout, 1);
    200     cs.width(0)=79;
    201     cs.margin(0)=0;
    202     ColumnStream cs2(std::cout, 2);
    203     // Widest line should fit exactly
    204     cs2.width(0)=21;
    205     cs2.width(1)=52;
    206     cs2.margin(0)=2;
    207     // Gnits standard suggest three characters gap between option and description
    208     cs2.margin(1)=3;
    209 
    210     std::cout << "Usage: svndigest [OPTION]...\n"
    211               << "\n";
    212 
    213     cs << "Generate statistical report for a subversion repository.\n";
    214 
    215     cs << "\nMandatory arguments to long options are mandatory for "
    216        << "short options too.\n";
    217 
    218     cs2  << "    --config-file=ARG\tconfiguration file "
    219          << "[<ROOT>/.svndigest/config]\n"
    220          << "    --copyright\tupdate copyright statement\n"
    221          << "-f, --force\tif sub-directory named <ROOT> exists in "
    222          << "target directory, remove sub-directory before writing results\n"
    223          << "-g, --generate-config\twrite configuration file "
    224          << "to standard output and exit\n"
    225          << "-h, --help\tdisplay this help and exit\n"
    226          << "    --ignore-cache\tignore cache files and analyze "
    227          << "everything from repository\n"
    228          << "    --no-report\tcreate no HTML report\n"
    229          << "    --revisions\tuse revision numbers as time scale "
    230          << "instead of dates [dates]\n"
    231          << "-r, --root=ROOT\tsvn controlled directory to perform "
    232          << "statistics calculation on [" << root_.default_value() << "]\n"
    233          << "-t, --target=TARGET\toutput directory ["
    234          << targetdir_.default_value() << "]\n"
    235          << "-v, --verbose\texplain what is being done\n"
    236          << "    --version\tprint version information and exit\n";
    237 
    238     std::cout << "\nReport bugs to <" << PACKAGE_BUGREPORT << ">."
    239               << std::endl;
    240   }
    241 
    242 
    243   void Parameter::missing_argument(std::string opt) const
    244   {
    245     if (opt.size()>0 && opt[0]=='-')
    246       opt = opt.substr(1);
    247     if (opt.size()>0 && opt[0]=='-')
    248       opt = opt.substr(1);
    249     std::stringstream ss;
    250     ss << "svndigest: option requires an argument -- " << opt << "\n"
    251        << "Try `svndigest --help' for usage.";
    252     throw std::runtime_error(ss.str());
    253   }
    254 
    255   void Parameter::version(bool verbose) const
    256   {
    257     ColumnStream cs(std::cout, 1);
    258     cs.width(0)=79;
    259     cs << PACKAGE_STRING << version_string() << "\n";
    260     cs << "\nCopyright (C) " << svn_year()
    261        << " Jari H\u00E4kkinen and Peter Johansson.\n"
    262        << "This is free software. You may redistribute copies of it under "
    263        << "the terms of the GNU General Public License "
    264        << "<http://www.gnu.org/licenses/gpl.html>.\n"
    265        << "There is NO WARRANTY; to the extent permitted by law.\n";
    266   }
     242    verbose_ = new OptionSwitch(cmd_, "v,verbose", "explain what is being done");
     243    version_ = new OptionVersion(cmd_);
     244
     245    ss.str("");
     246    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n";
     247    help_->post_arguments() = ss.str();
     248    help_->synopsis() =
     249      "Generate statistical report for a subversion repository\n";
     250  }
     251
     252
     253  bool Parameter::report(void) const
     254  {
     255    return report_->value();
     256  }
     257
     258
     259  bool Parameter::revisions(void) const
     260  {
     261    return revisions_->present();
     262  }
     263
     264
     265  std::string Parameter::root(void) const
     266  {
     267    return root_->value();
     268  }
     269
     270 
     271  std::string Parameter::targetdir(void) const
     272  {
     273    return target_->value();
     274  }
     275
     276 
     277  bool Parameter::verbose(void) const
     278  {
     279    return verbose_->present();
     280  }
     281
    267282
    268283}} // of namespace svndigest and namespace theplu
  • trunk/bin/Parameter.h

    r693 r705  
    2424*/
    2525
    26 #include "Option.h"
     26#include "CommandLine.h"
     27#include "OptionArg.h"
    2728
    28 #include <map>
    2929#include <string>
    3030
     
    3232namespace svndigest {
    3333
     34  class OptionHelp;
     35  class OptionSwitch;
     36  class OptionVersion;
     37
    3438  // class for command line options.
    3539  class Parameter {
    3640  public:
    3741    Parameter( int argc, char *argv[]);
     42    virtual ~Parameter(void);
    3843    std::string config_file(void) const;
    39     inline bool copyright(void) const { return copyright_.value(); }
    40     /// @todo
    41     inline bool force(void) const { return force_.value(); }
    42     inline bool generate_config(void) const { return generate_config_.value(); }
    43     inline bool ignore_cache(void) const { return ignore_cache_.value(); }
    44     inline bool report(void) const { return report_.value(); }
    45     inline bool revisions(void) const { return revisions_.value(); }
     44   
     45    bool copyright(void) const;
     46    bool force(void) const;
     47    bool generate_config(void) const ;
     48    bool ignore_cache(void) const;
     49    bool report(void) const;
     50    bool revisions(void) const;
    4651    /// @return absolute path to root directory
    47     inline const std::string& root(void) const { return root_.value(); }
    48     /// @return absolute path to root node
    49     inline const std::string& root_node(void) const {return root_node_.value();}
     52    std::string root(void) const;
    5053    /// @return absolute path to target directory
    51     inline const std::string& targetdir(void) const
    52     { return targetdir_.value(); }
    53     inline bool verbose(void) const { return verbose_.value(); }
     54    std::string targetdir(void) const;
     55    bool verbose(void) const;
    5456
    5557  private:
    5658    void analyse(void);
    57     void help(void) const;
    58     void missing_argument(std::string opt) const;
    59     void version(bool=false) const;
     59    // throw cmd_error if path doesn't exist
     60    void check_existence(std::string path) const;
     61    // throw cmd_error if path is not dir
     62    void check_is_dir(std::string path) const;
     63    // throw cmd_error if path is not readable
     64    void check_readable(std::string path) const;
    6065
    61     Option<std::string> config_file_;
    62     Option<bool> copyright_;
    63     Option<bool> force_;
    64     Option<bool> generate_config_;
    65     Option<bool> ignore_cache_;
    66     Option<bool> report_;
    67     Option<bool> revisions_;
    68     Option<std::string> root_;
    69     Option<std::string> root_node_;
    70     Option<std::string> targetdir_;
    71     Option<bool> verbose_;
     66    void init(void);
     67
     68    CommandLine cmd_;
     69    OptionArg<std::string>* config_file_;
     70    OptionSwitch* copyright_;
     71    OptionSwitch* force_;
     72    OptionSwitch* generate_config_;
     73    OptionHelp* help_;
     74    OptionSwitch* ignore_cache_;
     75    OptionSwitch* report_;
     76    OptionSwitch* revisions_;
     77    OptionArg<std::string>* root_;
     78    OptionArg<std::string>* target_;
     79    OptionSwitch* verbose_;
     80    OptionVersion* version_;
     81
    7282  };
    7383
  • trunk/bin/svndigest.cc

    r693 r705  
    2626#include "css.h"
    2727#include "Directory.h"
     28#include "Exception.h"
    2829#include "first_page.h"
    2930#include "GnuplotFE.h"
     
    5960      std::cout << "Done parsing parameters" << std::endl;
    6061  }
    61   catch (std::runtime_error e) {
     62  catch (cmd_error& e) {
    6263    std::cerr << e.what() << std::endl;
    6364    exit(-1);
  • trunk/lib/Makefile.am

    r696 r705  
    2929
    3030noinst_HEADERS = AddStats.h Alias.h BlameStats.h ClassicStats.h ColumnStream.h \
    31   Commitment.h Configuration.h css.h\
    32   Date.h Directory.h File.h first_page.h Functor.h Gnuplot.h GnuplotFE.h \
     31  CommandLine.h Commitment.h Configuration.h css.h\
     32  Date.h Directory.h Exception.h File.h first_page.h Functor.h \
     33  Gnuplot.h GnuplotFE.h \
    3334  HtmlBuf.h HtmlStream.h html_utility.h LineTypeParser.h \
    34   Node.h Option.h rmdirhier.h \
     35  Node.h Option.h OptionArg.h OptionHelp.h OptionSwitch.h \
     36  OptionVersion.h rmdirhier.h \
    3537  Stats.h StatsCollection.h subversion_info.h SVN.h SVNblame.h  \
    3638  SVNinfo.h SVNlog.h SVNproperty.h Trac.h utility.h
     
    3840libsvndigest_a_SOURCES = AddStats.cc Alias.cc BlameStats.cc \
    3941  ClassicStats.cc ColumnStream.cc \
    40   Commitment.cc Configuration.cc \
    41   css.cc Date.cc Directory.cc File.cc first_page.cc\
     42  CommandLine.cc Commitment.cc Configuration.cc \
     43  css.cc Date.cc Directory.cc File.cc FileUtil.cc first_page.cc\
    4244  Functor.cc Gnuplot.cc GnuplotFE.cc  HtmlBuf.cc HtmlStream.cc \
    4345  html_utility.cc LineTypeParser.cc Node.cc \
     46  Option.cc OptionHelp.cc OptionSwitch.cc OptionVersion.cc \
    4447  rmdirhier.cc Stats.cc StatsCollection.cc subversion_info.cc SVN.cc \
    4548  SVNblame.cc SVNinfo.cc SVNlog.cc SVNproperty.cc Trac.cc utility.cc
  • trunk/lib/Option.h

    r693 r705  
    55
    66/*
     7  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
    78  Copyright (C) 2008 Peter Johansson
    89
     
    2324*/
    2425
     26#include <iostream>
    2527#include <string>
     28#include <vector>
    2629
    27 namespace theplu{
    28 namespace svndigest{
     30namespace theplu {
     31namespace svndigest {
    2932
     33  class CommandLine;
    3034  ///
    31   /// Class taking care of cmd options in Parameter
     35  /// @brief Container of variables for an option. @see CommandLine
    3236  ///
    33   template<typename T>
    3437  class Option
    3538  {
    3639  public:
    37     Option(T value): default_(value), value_(value) {}
    38     inline const T& default_value(void) const { return default_; }
    39     inline void reset(void) { value_=default_; }
    40     inline T& value(void) { return value_; }
    41     inline const T& value(void) const { return value_; }
     40    /**
     41       @brief Constructor
     42       
     43       \param cmd Commandline to be hooked up with.
     44       @param name string such as "help" for --help, "h" for -h or
     45       "h,help" for having both short and long option name
     46       @param desc string used in help display
     47    */
     48    Option(CommandLine& cmd, std::string name, std::string desc);
     49
     50    /**
     51       @brief destructor
     52    */
     53    virtual ~Option(void);
     54   
     55    /**
     56       @return description
     57    */
     58    std::string description(void) const;
     59
     60    /**
     61       \return long name e.g. 'help' for --help option.
     62    */
     63    std::string long_name(void) const;
     64
     65    /**
     66       \brief parsing the commandline
     67     */
     68    void parse(std::vector<std::string>::iterator&,
     69               const std::vector<std::string>::iterator&);
     70
     71    /**
     72       @brief Get if option was found in cmd.
     73       
     74       @return true if option has been detected in parsing
     75    */
     76    bool present(void) const;
     77
     78    /**
     79       \brief print help output
     80
     81       This function calls the four virtual private functions print1,
     82       print2, print3, and print4. This allows an inherited class to
     83       implement one (or several) of these functions and keep the
     84       default output of the others. The default behavior is that:
     85
     86       - print1 prints the short name, '-h', as short_name(void) const
     87       - print2 prints the long name, '--help', as long_name(void) const
     88       - print3 is empty
     89       - print4 prints the description as description(void) const.
     90     */
     91    std::string print(void);
     92
     93    /**
     94       \brief sets present to false
     95    */
     96    void reset(void);
     97
     98    /**
     99       \return short name e.g. 'h' for -h option.
     100    */
     101    char short_name(void) const;
     102
     103    /**
     104       \brief Validate the Option
     105
     106       This function is called after commandline is parsed.
     107     */
     108    void validate(void);
     109
     110  protected:
     111    /**
     112       \return const reference to CommandLine Option belongs to.
     113     */
     114    const CommandLine& cmd(void) const;
    42115
    43116  private:
    44     const T default_;
    45     T value_;
     117    virtual void do_parse(std::vector<std::string>::iterator&,
     118                          const std::vector<std::string>::iterator&)=0;
    46119
     120    /**
     121     */
     122    virtual std::string print1(void) const;
     123
     124    /**
     125     */
     126    virtual std::string print2(void) const;
     127
     128    /**
     129     */
     130    virtual std::string print3(void) const;
     131
     132    /**
     133     */
     134    virtual std::string print4(void) const;
     135
     136    /**
     137     */
     138    virtual void do_validate(void) const=0;
     139
     140
     141    const CommandLine& cmd_;
     142    std::string description_;
     143    std::string long_name_;
     144    bool present_;
     145    char short_name_;
     146
     147    // copy not allowed
     148    Option(const Option&);
     149    Option& operator=(const Option&);
    47150  };
    48151
    49 }} // end of namespace svndigest end of namespace theplu
     152}} // of namespace svndigest, and theplu
    50153
    51 #endif 
     154#endif
  • trunk/lib/utility.cc

    r693 r705  
    3333#include <string>
    3434#include <sys/param.h>
     35#include <sys/stat.h>
    3536#include <unistd.h>
    3637
     
    6364
    6465
     66  std::string concatenate_path(std::string dir, std::string base)
     67  {
     68    if (dir.empty())
     69      return base;
     70    if (dir[dir.size()-1]!='/')
     71      dir.append("/");
     72    return dir+base;
     73  }
     74
     75
    6576  void copy_file(const std::string& source, const std::string& target)
    6677  {
     
    8596  {
    8697    size_t pos = path.find_last_of("/");
     98    if (pos==std::string::npos)
     99      return ".";
    87100    if (pos==path.size()-1)
    88101      return directory_name(path.substr(0,path.size()-2));
  • trunk/lib/utility.h

    r693 r705  
    2727#include <functional>
    2828#include <iosfwd>
     29#include <sstream>
    2930#include <string>
     31#include <stdexcept>
    3032#include <utility>
    3133#include <vector>
     
    5355
    5456  /**
     57     \return dir+base if dir ends with '/', else dir+'/'+base
     58   */
     59  std::string concatenate_path(std::string dir, std::string base);
     60
     61  /**
     62     \brief convert string to (numerical) type
     63
     64     \throw runtime_error if conversion fails
     65   */
     66  template<typename T>
     67  T convert(const std::string& s);
     68
     69  /**
    5570     @brief Copy file \a source to \a target.
    5671
     
    103118  std::string htrim(std::string str);
    104119
     120  /**
     121     @return true if string \a s fulfills regular expression \verbatim
     122     ^\w* \endverbatim \a other \verbatim \w*$ \endverbatim (case
     123     insensitive)
     124  */
     125  bool is_equal(std::string s, std::string other);
     126
    105127  ///
    106128  /// @return true if \a str is an integer
    107129  ///
    108130  bool is_int(std::string str);
     131
     132  ///
     133  /// @return true if string is "nan" (case-insensitive)
     134  ///
     135  bool is_nan(const std::string& s);
    109136
    110137  ///
     
    221248                    std::string);
    222249
     250  // template implementations
     251  template<typename T>
     252  T convert(const std::string& s)
     253  {
     254    if (is_nan(s))
     255      return std::numeric_limits<T>::quiet_NaN();
     256    if (is_equal(s, "inf"))
     257      return std::numeric_limits<T>::infinity();
     258    if (is_equal(s, "-inf"))
     259      if (std::numeric_limits<T>::is_signed)
     260        return -std::numeric_limits<T>::infinity();
     261      else
     262        throw std::runtime_error(std::string("convert(\"")+s+
     263                                 std::string("\"): type is unsigned") );
     264    std::stringstream ss(s);
     265    T a;
     266    ss >> a;
     267    bool ok = true;
     268    if(ss.fail())
     269      ok = false;
     270    // Check that nothing is left on stream
     271    std::string b;
     272    ss >> b;
     273    if (!b.empty() || !ok)
     274      throw std::runtime_error(std::string("convert(\"")+s+std::string("\")"));
     275    return a;
     276  }
     277
    223278}} // end of namespace svndigest end of namespace theplu
    224279
Note: See TracChangeset for help on using the changeset viewer.