source: trunk/lib/utility.cc @ 516

Last change on this file since 516 was 516, checked in by Peter Johansson, 14 years ago

adding filename translations in Configuration class. Before checking what type parsing to use, filename is translated according to rules set in config file. Default rule (as before) is to remove trailing .in from filenames. To solve the parsing I added a simple regexp function - see utility.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1// $Id: utility.cc 516 2007-12-09 07:58:54Z peter $
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/trac/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.