source: trunk/lib/utility.cc @ 755

Last change on this file since 755 was 755, checked in by Jari Häkkinen, 12 years ago

Addresses #358. Added by strerror() required include statements (mac, SuSE)

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