source: trunk/lib/utility.cc @ 693

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

Fixes #339. Change to GPLv3.

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