source: trunk/lib/utility.cc @ 687

Last change on this file since 687 was 687, checked in by Peter Johansson, 13 years ago

Merged patch release 0.6.6 to trunk. Delta 0.6.6 - 0.6.5

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