source: trunk/bin/Parameter.cc @ 1241

Last change on this file since 1241 was 1241, checked in by Peter Johansson, 11 years ago

prefer let exception pass to main from Parameter class rather than catch and exit.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1// $Id: Parameter.cc 1241 2010-10-24 00:57:51Z peter $
2
3/*
4  Copyright (C) 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2009, 2010 Peter Johansson
6
7  This file is part of svndigest, http://dev.thep.lu.se/svndigest
8
9  svndigest is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13
14  svndigest is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include <config.h> // this header file is created by configure
24
25#include "Parameter.h"
26
27#include "lib/OptionVersion.h"
28#include "lib/utility.h" // to avoid inclusion of yat file
29
30#include "yat/ColumnStream.h"
31#include "yat/Exception.h"
32#include "yat/OptionArg.h"
33#include "yat/OptionHelp.h"
34#include "yat/OptionSwitch.h"
35
36#include <cassert>
37#include <cerrno>
38#include <cstddef>
39#include <cstring>
40#include <fstream>
41#include <iostream>
42#include <sstream>
43#include <stdexcept>
44#include <string>
45#include <sys/stat.h>
46
47namespace theplu {
48namespace svndigest {
49
50  Parameter::Parameter(void)
51    : cmd_( std::string("Mandatory arguments to long options ") + 
52            std::string("are mandatory for short options too.")), 
53      config_file_(cmd_, "config-file", 
54                   "configuration file [<ROOT>/.svndigest/config]"),
55      generate_config_(cmd_, "g,generate-config", 
56                       "write configuration to standard output"),
57      help_(cmd_),
58      ignore_cache_(cmd_, "ignore-cache", 
59                    std::string("ignore cache files and analyze ") +
60                    std::string("everything from repository")),
61      root_(cmd_, "r,root", 
62            "svn controlled directory to perform statistics on [.]"),
63      verbose_(cmd_, "v,verbose", "explain what is being done"),
64      version_(cmd_, "version", "print version information and exit", &verbose_)
65  {
66  }
67
68
69  void Parameter::parse(int argc, char* argv[])
70  {
71    init();
72    cmd_.parse(argc, argv);
73    set_default();
74    // analyse arguments
75    analyse();
76  }
77
78
79  Parameter::~Parameter(void)
80  {
81  }
82
83
84  void Parameter::analyse(void)
85  {
86    std::string save_wd = pwd();
87
88    // check root but not if -g option given
89    if (!generate_config()) {
90      check_existence(root_.value());
91      check_readable(root_.value());
92      check_is_dir(root_.value());
93      chdir(root_.value());
94      root_.value(pwd());
95      chdir(save_wd);
96    }
97
98    // check config file
99    struct stat nodestat;
100    // true also if there is a broken symlink named...
101    bool config_exists = !lstat(config_file_.value().c_str(), &nodestat);
102    // the latter case in order to catch broken symlink
103    if (config_file_.present() || config_exists)
104      // throws if file does not exists
105      check_existence(config_file_.value());
106    if (config_exists) {
107      // throws if file is not readable
108      check_readable(config_file_.value());
109      stat(config_file_.value().c_str(), &nodestat);
110      if (S_ISDIR(nodestat.st_mode)) {
111        std::stringstream ss;
112        ss << cmd_.program_name() << ": '" << config_file_.value() 
113           << "' is a directory";
114        throw yat::utility::cmd_error(ss.str());
115      }
116    }
117    analyse2();
118  }
119
120
121  void Parameter::check_existence(std::string path) const
122  {
123    if (node_exist(path))
124      return;
125    std::stringstream ss;
126    ss << cmd_.program_name() << ": cannot stat '" << path << "': " 
127       << strerror(errno);
128    throw yat::utility::cmd_error(ss.str());
129  }
130
131 
132  void Parameter::check_is_dir(std::string path) const
133  {
134    if (node_exist(path)) {
135      struct stat buf;
136      stat(path.c_str(), &buf);
137      if (S_ISDIR(buf.st_mode))
138        return;
139    }
140    std::stringstream ss;
141    ss << cmd_.program_name() << ": '" << path << "': " 
142       << strerror(errno);
143    throw yat::utility::cmd_error(ss.str());
144  }
145
146 
147  void Parameter::check_readable(std::string path) const
148  {
149    if (!access_rights(path, "r"))
150      return;
151    std::stringstream ss;
152    ss << cmd_.program_name() << ": cannot open '" << path << "': " 
153       << strerror(errno);
154    throw yat::utility::cmd_error(ss.str());
155  }
156 
157
158  std::string Parameter::config_file(void) const
159  {
160    return config_file_.value();
161  }
162
163
164  bool Parameter::generate_config(void) const
165  {
166    return generate_config_.present();
167  }
168
169
170  bool Parameter::ignore_cache(void) const
171  {
172    return ignore_cache_.present();
173  }
174
175
176  void Parameter::init(void)
177  {
178    // we like the options sorted alphabetically
179    cmd_.sort();
180    config_file_.print_arg("=FILE");
181    root_.print_arg("=ROOT");
182    std::stringstream ss;
183    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n"
184       << PACKAGE << " home page: <" << PACKAGE_URL << ">.\n";
185    help_.post_arguments() = ss.str();
186    init2();
187  }
188
189
190  std::string Parameter::root(void) const
191  {
192    return root_.value();
193  }
194
195  void Parameter::set_default(void)
196  {
197    if (!root_.present())
198      root_.value(".");
199
200    if (!config_file_.present())
201      config_file_.value(concatenate_path(root_.value(),".svndigest/config"));
202
203    set_default2();
204  }
205
206
207  bool Parameter::verbose(void) const
208  {
209    return verbose_.present();
210  }
211
212
213}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.