source: trunk/lib/utility.cc @ 519

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

trac moved to new location.

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