source: trunk/lib/utility.cc @ 1090

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

update copyrights

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1// $Id: utility.cc 1090 2010-06-12 17:27:00Z peter $
2
3/*
4  Copyright (C) 2006, 2007, 2008, 2009 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2010 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 "yat/Exception.h"
29
30#include <cassert>
31#include <cerrno> 
32#include <cstdio>
33#include <cstdlib>
34#include <cstring>
35#include <fnmatch.h>
36#include <fstream>
37#include <sstream>
38#include <stdexcept>
39#include <string>
40#include <sys/param.h>
41#include <sys/stat.h>
42#include <unistd.h>
43
44#include <iostream>
45
46namespace theplu{
47namespace svndigest{
48
49  int access_rights(const std::string& path, const std::string& bits)
50  {
51    if (access(path.c_str(),F_OK)) {
52      throw std::runtime_error(std::string("access_rights: ") + path +
53                               "' does not exist.");
54    }
55    int mode=0;
56    for (unsigned int i=0; i<bits.length(); ++i)
57      switch (bits[i]) {
58          case 'r':
59            mode|=R_OK;
60            break;
61          case 'w':
62            mode|=W_OK;
63            break;
64          case 'x':
65            mode|=X_OK;
66            break;
67      }
68    return access(path.c_str(),mode);
69  }
70
71
72  void chdir(const std::string& dir)
73  {
74    if (::chdir(dir.c_str()) )
75      throw yat::utility::errno_error("chdir: " + dir + ":");
76  }
77
78
79  std::string concatenate_path(std::string dir, std::string base)
80  {
81    if (dir.empty() || dir==".")
82      return base;
83    if (dir[dir.size()-1]!='/')
84      dir.append("/");
85    return dir+base;
86  }
87
88
89  void copy_file(const std::string& source, const std::string& target)
90  {
91    std::ofstream o(target.c_str());
92    std::ifstream i(source.c_str());
93    while (i.good()) {
94      char ch=i.get();
95      if (i.good())
96        o.put(ch);
97      if (!o.good())
98        throw std::runtime_error(std::string("copy_file: ") +
99                                 "writing target file failed '" + target + "'");
100    }
101    if (!i.eof() && (i.bad() || i.fail()))  // fail on everything except eof
102      throw std::runtime_error(std::string("copy_file: ") +
103                               "error reading source file '" + source + "'");
104    i.close(); o.close();
105  }
106
107
108  std::string directory_name(std::string path)
109  {
110    size_t pos = path.find_last_of("/");
111    if (pos==std::string::npos)
112      return ".";
113    if (pos==path.size()-1)
114      return directory_name(path.substr(0,path.size()-2));
115    return path.substr(0,pos+1);
116  }
117
118
119  std::string file_name(const std::string& full_path)
120  {
121    std::stringstream ss(full_path);
122    std::string name;
123    while (getline(ss,name,'/')) {}
124    return name;
125  }
126
127
128  std::string getenv(const std::string& var)
129  {
130    char* buffer=std::getenv(var.c_str());
131    if (!buffer)
132      throw std::runtime_error("Environment variable "+var+" is not set");
133    return std::string(buffer);
134  }
135
136
137  std::string hex(int x, unsigned int width)
138  {
139    std::stringstream ss;
140    ss << std::hex << x;
141    if (!width)
142      return ss.str();
143    if (ss.str().size()<width) 
144      return std::string(width-ss.str().size(), '0') + ss.str();
145    return ss.str().substr(0, width);
146  }
147
148
149  std::string htrim(std::string str)
150  {
151    size_t length=str.size();
152    while(length && isspace(str[length-1]))
153      --length;
154    return str.substr(0,length);
155  }
156
157
158  bool fnmatch(const std::string& pattern, const std::string& str)
159  {
160    int res = ::fnmatch(pattern.c_str(), str.c_str(), FNM_PERIOD);
161    if (res==0)
162      return true;
163    if (res!=FNM_NOMATCH) {
164      std::stringstream ss;
165      ss << "svndigest: fnmatch with args: " << pattern << ", " << str;
166      throw std::runtime_error(ss.str());
167    }                     
168    return false;
169  }
170
171
172  std::string ltrim(std::string str)
173  {
174    size_t i = 0;
175    while(i<str.size() && isspace(str[i]))
176      ++i;
177    return str.substr(i);
178  }
179
180  void mkdir(const std::string& dir)
181  { 
182    int code = ::mkdir(dir.c_str(),0777);
183    if (code){
184      std::stringstream ss;
185      ss << "mkdir(" << dir << "): failed\n" << strerror(errno);
186      throw std::runtime_error(ss.str());
187    }
188  }
189
190
191  void mkdir_p(const std::string& dir)
192  { 
193    if (node_exist(dir))
194      return;
195    std::string mother = directory_name(dir);
196    mkdir_p(mother);
197    mkdir(dir);
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.