source: trunk/lib/utility.cc @ 750

Last change on this file since 750 was 750, checked in by Peter Johansson, 14 years ago

fixes #358

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