source: trunk/lib/utility.cc @ 768

Last change on this file since 768 was 768, checked in by Peter Johansson, 12 years ago

Merged patch release 0.6.7 to trunk. Delta 0.6.7 - 0.6.6

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