- Timestamp:
- Nov 26, 2008, 12:33:26 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 11 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bin/Parameter.cc
r699 r705 24 24 25 25 #include "ColumnStream.h" 26 #include "subversion_info.h" 26 #include "OptionArg.h" 27 #include "OptionHelp.h" 28 #include "OptionSwitch.h" 29 #include "OptionVersion.h" 27 30 #include "utility.h" 28 31 #include <config.h> // this header file is created by configure 29 32 33 #include <cassert> 34 #include <cerrno> 30 35 #include <cstddef> 31 36 #include <fstream> … … 40 45 41 46 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()); 57 119 } 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()); 60 125 } 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()); 63 131 } 132 target_->value(concatenate_path(pwd(), base_root)); 133 chdir(save_wd.c_str()); 64 134 } 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()); 67 148 } 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 185 172 186 173 std::string Parameter::config_file(void) const 187 174 { 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"); 191 241 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 267 282 268 283 }} // of namespace svndigest and namespace theplu -
trunk/bin/Parameter.h
r693 r705 24 24 */ 25 25 26 #include "Option.h" 26 #include "CommandLine.h" 27 #include "OptionArg.h" 27 28 28 #include <map>29 29 #include <string> 30 30 … … 32 32 namespace svndigest { 33 33 34 class OptionHelp; 35 class OptionSwitch; 36 class OptionVersion; 37 34 38 // class for command line options. 35 39 class Parameter { 36 40 public: 37 41 Parameter( int argc, char *argv[]); 42 virtual ~Parameter(void); 38 43 std::string config_file(void) const; 39 inline bool copyright(void) const { return copyright_.value(); }40 /// @todo41 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; 46 51 /// @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; 50 53 /// @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; 54 56 55 57 private: 56 58 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; 60 65 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 72 82 }; 73 83 -
trunk/bin/svndigest.cc
r693 r705 26 26 #include "css.h" 27 27 #include "Directory.h" 28 #include "Exception.h" 28 29 #include "first_page.h" 29 30 #include "GnuplotFE.h" … … 59 60 std::cout << "Done parsing parameters" << std::endl; 60 61 } 61 catch ( std::runtime_errore) {62 catch (cmd_error& e) { 62 63 std::cerr << e.what() << std::endl; 63 64 exit(-1); -
trunk/lib/Makefile.am
r696 r705 29 29 30 30 noinst_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 \ 33 34 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 \ 35 37 Stats.h StatsCollection.h subversion_info.h SVN.h SVNblame.h \ 36 38 SVNinfo.h SVNlog.h SVNproperty.h Trac.h utility.h … … 38 40 libsvndigest_a_SOURCES = AddStats.cc Alias.cc BlameStats.cc \ 39 41 ClassicStats.cc ColumnStream.cc \ 40 Comm itment.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\ 42 44 Functor.cc Gnuplot.cc GnuplotFE.cc HtmlBuf.cc HtmlStream.cc \ 43 45 html_utility.cc LineTypeParser.cc Node.cc \ 46 Option.cc OptionHelp.cc OptionSwitch.cc OptionVersion.cc \ 44 47 rmdirhier.cc Stats.cc StatsCollection.cc subversion_info.cc SVN.cc \ 45 48 SVNblame.cc SVNinfo.cc SVNlog.cc SVNproperty.cc Trac.cc utility.cc -
trunk/lib/Option.h
r693 r705 5 5 6 6 /* 7 Copyright (C) 2007 Jari Häkkinen, Peter Johansson 7 8 Copyright (C) 2008 Peter Johansson 8 9 … … 23 24 */ 24 25 26 #include <iostream> 25 27 #include <string> 28 #include <vector> 26 29 27 namespace theplu {28 namespace svndigest {30 namespace theplu { 31 namespace svndigest { 29 32 33 class CommandLine; 30 34 /// 31 /// Class taking care of cmd options in Parameter35 /// @brief Container of variables for an option. @see CommandLine 32 36 /// 33 template<typename T>34 37 class Option 35 38 { 36 39 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; 42 115 43 116 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; 46 119 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&); 47 150 }; 48 151 49 }} // end of namespace svndigest end of namespacetheplu152 }} // of namespace svndigest, and theplu 50 153 51 #endif 154 #endif -
trunk/lib/utility.cc
r693 r705 33 33 #include <string> 34 34 #include <sys/param.h> 35 #include <sys/stat.h> 35 36 #include <unistd.h> 36 37 … … 63 64 64 65 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 65 76 void copy_file(const std::string& source, const std::string& target) 66 77 { … … 85 96 { 86 97 size_t pos = path.find_last_of("/"); 98 if (pos==std::string::npos) 99 return "."; 87 100 if (pos==path.size()-1) 88 101 return directory_name(path.substr(0,path.size()-2)); -
trunk/lib/utility.h
r693 r705 27 27 #include <functional> 28 28 #include <iosfwd> 29 #include <sstream> 29 30 #include <string> 31 #include <stdexcept> 30 32 #include <utility> 31 33 #include <vector> … … 53 55 54 56 /** 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 /** 55 70 @brief Copy file \a source to \a target. 56 71 … … 103 118 std::string htrim(std::string str); 104 119 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 105 127 /// 106 128 /// @return true if \a str is an integer 107 129 /// 108 130 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); 109 136 110 137 /// … … 221 248 std::string); 222 249 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 223 278 }} // end of namespace svndigest end of namespace theplu 224 279
Note: See TracChangeset
for help on using the changeset viewer.