source: trunk/lib/utility.cc @ 745

Last change on this file since 745 was 724, checked in by Peter Johansson, 13 years ago
  • README.developer: adding text on Requirements for building from svn checkout
  • configure.ac: support for help2man and new man/Makefile
  • lib/OptionVersion.cc lib/OptionVersion.h bin/Parameter.cc: changed --version output so when used in combination with --no-verbose it is compliant with help2man
  • lib/utility.cc: removed function version_string not used anymore

closes #361

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1// $Id: utility.cc 724 2008-12-09 13:34:16Z peter $
2
3/*
4  Copyright (C) 2006, 2007 Jari Häkkinen, Peter Johansson
5
6  This file is part of svndigest, http://dev.thep.lu.se/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  svndigest 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 svndigest. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "utility.h"
23
24#include "subversion_info.h"
25#include "config.h"
26
27#include <cassert>
28#include <cerrno> 
29#include <cstdlib>
30#include <fstream>
31#include <sstream>
32#include <stdexcept>
33#include <string>
34#include <sys/param.h>
35#include <sys/stat.h>
36#include <unistd.h>
37
38#include <iostream>
39
40namespace theplu{
41namespace svndigest{
42
43  int access_rights(const std::string& path, const std::string& bits)
44  {
45    if (access(path.c_str(),F_OK)) {
46      throw std::runtime_error(std::string("access_rights: ") + path +
47                               "' does not exist.");
48    }
49    int mode=0;
50    for (unsigned int i=0; i<bits.length(); ++i)
51      switch (bits[i]) {
52          case 'r':
53            mode|=R_OK;
54            break;
55          case 'w':
56            mode|=W_OK;
57            break;
58          case 'x':
59            mode|=X_OK;
60            break;
61      }
62    return access(path.c_str(),mode);
63  }
64
65
66  std::string concatenate_path(std::string dir, std::string base)
67  {
68    if (dir.empty() || dir==".")
69      return base;
70    if (dir[dir.size()-1]!='/')
71      dir.append("/");
72    return dir+base;
73  }
74
75
76  void copy_file(const std::string& source, const std::string& target)
77  {
78    std::ofstream o(target.c_str());
79    std::ifstream i(source.c_str());
80    while (i.good()) {
81      char ch=i.get();
82      if (i.good())
83        o.put(ch);
84      if (!o.good())
85        throw std::runtime_error(std::string("copy_file: ") +
86                                 "writing target file failed '" + target + "'");
87    }
88    if (!i.eof() && (i.bad() || i.fail()))  // fail on everything except eof
89      throw std::runtime_error(std::string("copy_file: ") +
90                               "error reading source file '" + source + "'");
91    i.close(); o.close();
92  }
93
94
95  std::string directory_name(std::string path)
96  {
97    size_t pos = path.find_last_of("/");
98    if (pos==std::string::npos)
99      return ".";
100    if (pos==path.size()-1)
101      return directory_name(path.substr(0,path.size()-2));
102    return path.substr(0,pos+1);
103  }
104
105
106  bool equal(std::string::const_iterator first1, 
107             std::string::const_iterator end1,
108             std::string::const_iterator first2,
109             std::string::const_iterator end2)
110  {
111    if (first1==end1 && first2==end2)
112      return true;
113    if (first1!=end1 && first2!=end2 && 
114        (*first1==*first2 || *first1=='*' || *first2=='*' ||
115         *first1=='?' || *first2=='?') && 
116        equal(first1+1, end1, first2+1, end2) )
117      return true;
118    if ( (first1!=end1 && first2!=end2 && (*first1=='*'|| *first2=='*') ) && 
119         (equal(first1+1, end1, first2, end2) || 
120          equal(first1, end1, first2+1, end2))
121         )
122      return true;
123    return false;
124  }
125
126
127  std::string file_name(const std::string& full_path)
128  {
129    std::stringstream ss(full_path);
130    std::string name;
131    while (getline(ss,name,'/')) {}
132    return name;
133  }
134
135
136  std::string getenv(const std::string& var)
137  {
138    char* buffer=std::getenv(var.c_str());
139    if (!buffer)
140      throw std::runtime_error("Environment variable "+var+" is not set");
141    return std::string(buffer);
142  }
143
144
145  std::string hex(int x, unsigned int width)
146  {
147    std::stringstream ss;
148    ss << std::hex << x;
149    if (!width)
150      return ss.str();
151    if (ss.str().size()<width) 
152      return std::string(width-ss.str().size(), '0') + ss.str();
153    return ss.str().substr(0, width);
154  }
155
156
157  std::string htrim(std::string str)
158  {
159    size_t length=str.size();
160    while(length && isspace(str[length-1]))
161      --length;
162    return str.substr(0,length);
163  }
164
165
166  bool is_int(std::string s)
167  {
168    std::stringstream ss(s);
169    int a;
170    ss >> a;
171    if(ss.fail()) 
172      return false;
173    // Check that nothing is left on stream
174    std::string b;
175    ss >> b;
176    return b.empty();
177  }
178
179
180  std::string ltrim(std::string str)
181  {
182    size_t i = 0;
183    while(i<str.size() && isspace(str[i]))
184      ++i;
185    return str.substr(i);
186  }
187
188  void mkdir(const std::string& dir)
189  { 
190    int code = ::mkdir(dir.c_str(),0777);
191    if (code){
192      std::stringstream ss;
193      ss << "mkdir(" << dir << "): failed with error code: errno=" << errno;
194      throw std::runtime_error(ss.str());
195    }
196  }
197
198
199  bool node_exist(const std::string& path)
200  {
201    struct stat buf;
202    return !stat(path.c_str(),&buf);
203  }
204
205
206  int percent(int a, int b)
207  {
208    if (b)
209      return (100*a)/b;
210    return 0;
211  }
212
213
214  std::string pwd(void)
215  {
216    char buffer[MAXPATHLEN];
217    if (!getcwd(buffer, MAXPATHLEN))
218      throw std::runtime_error("Failed to get current working directory");
219    return std::string(buffer);
220  }
221
222
223  bool regexp(std::string::const_iterator first1, 
224              std::string::const_iterator last1,
225              std::string::const_iterator first2,
226              std::string::const_iterator last2,
227              std::vector<std::string>& vec)
228  {
229    if (vec.empty())
230      vec.push_back("");
231
232    // first two cases when ranges are empty
233    if (first1==last1 && first2==last2){
234      vec.pop_back();
235      return true;
236    }
237    if (first1==last1 || first2==last2)
238      return false;
239
240    // then we take care of the real stuff
241    if (*first2 == '*'){
242      // trying '*' to consume another character
243      vec.back().append(1, *first1);
244      if (regexp(first1+1, last1, first2, last2, vec) )
245        return true;
246      assert(vec.back().size());
247      vec.back().resize(vec.back().size()-1);
248
249      // stepping away from the '*'
250      vec.push_back("");
251      if (regexp(first1, last1, first2+1, last2, vec)) 
252        return true;
253      vec.pop_back();
254      return false;
255    }
256    else if (*first2 == '?'){
257      // eating a character
258      vec.back() = std::string(first1, first1+1);
259      vec.push_back("");
260      if (regexp(first1+1, last1, first2+1, last2, vec) )
261        return true;
262      vec.pop_back();
263      // ? interpreted as zero characters
264      vec.back() = "";
265      vec.push_back("");
266      if (regexp(first1, last1, first2+1, last2, vec) )
267        return true;
268      vec.pop_back();
269      return false;
270    }
271    if (*first1 != *first2)
272      return false;
273    return regexp(++first1, last1, ++first2, last2, vec);
274  }
275
276
277  void replace(std::string& str, std::string old_str, std::string new_str)
278  {
279    std::string::iterator iter(str.begin());
280    while ((iter=search(iter, str.end(), old_str)) != str.end()) {
281      size_t i = iter-str.begin();
282      str = std::string(str.begin(), iter) + new_str + 
283        std::string(iter+old_str.size(), str.end());
284      // pointing to char after substr we just inserted
285      iter = str.begin() + (i+new_str.size()); 
286    }
287  }
288
289
290  void touch(std::string str)
291  {
292    if (!node_exist(str)) {
293      std::ofstream os(str.c_str());
294      os.close();
295    }
296  }
297
298  time_t str2time(const std::string& str)
299  {
300    //  str in format 2006-09-09T10:55:52.132733Z
301    std::stringstream sstream(str);
302    time_t rawtime;
303    struct tm * timeinfo;
304    time ( &rawtime );
305    timeinfo =  gmtime ( &rawtime );
306
307    unsigned int year, month, day, hour, minute, second;
308    std::string tmp;
309    getline(sstream,tmp,'-');
310    year=atoi(tmp.c_str());
311    timeinfo->tm_year = year - 1900;
312
313    getline(sstream,tmp,'-');
314    month=atoi(tmp.c_str());
315    timeinfo->tm_mon = month - 1;
316
317    getline(sstream,tmp,'T');
318    day=atoi(tmp.c_str());
319    timeinfo->tm_mday = day;
320
321    getline(sstream,tmp,':');
322    hour=atoi(tmp.c_str());
323    timeinfo->tm_hour = hour;
324
325    getline(sstream,tmp,':');
326    minute=atoi(tmp.c_str());
327    timeinfo->tm_min = minute;
328
329    getline(sstream,tmp,'.');
330    second=atoi(tmp.c_str());
331    timeinfo->tm_sec = second;
332
333    return mktime(timeinfo);
334  }
335
336
337  std::string match(std::string::const_iterator& first,
338                    const std::string::const_iterator& last,
339                    std::string str)
340  {
341    if (match_begin(first, last, str)){
342      first+=str.size();
343      return str;
344    }
345    return std::string();
346  }
347
348}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.