source: trunk/lib/utility.cc @ 795

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

refs #388

Create a sub-directory 'lib/yat' in which files from yat are
placed. The files may be updated via 'make fetch', see file README for
more details on how to change which files are updated/copied through
this mechanism.

The reason we do not use subversion's external mechanism is that we
don't want the files to be synchronised with yat automatically. We
want the update to be moderated by some developer.

I chose to fetch files using the svn client rather than wget because
the svn allows us to get an Id string with information from the yat
repository. 'wget' would just download the file as it appears on the
server that is the string is not expanded.

The file 'config_public.h' is created by configure just as in
yat. This implies that automake adds $(top_builddir)/lib/yat to the
include path so unless in a VPATH build $(top_srcdir)/lib/yat is in
the include path. As we have already added $(top_srcdir)/lib to the
include path, and there are both a lib/utility.h and a
lib/yat/utility.h it is not obvious which file is included when having
'include "utility.h"'. For this reason, when being in bin/ and test/
it is needed to include "../lib/utility.h" rather than "utility.h"
when we want to include 'lib/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 795 2009-06-30 03:57:27Z peter $
2
3/*
4  Copyright (C) 2006, 2007, 2009 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2008 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 <cassert>
29#include <cerrno> 
30#include <cstdio>
31#include <cstdlib>
32#include <cstring>
33#include <fstream>
34#include <sstream>
35#include <stdexcept>
36#include <string>
37#include <sys/param.h>
38#include <sys/stat.h>
39#include <unistd.h>
40
41#include <iostream>
42
43namespace theplu{
44namespace svndigest{
45
46  int access_rights(const std::string& path, const std::string& bits)
47  {
48    if (access(path.c_str(),F_OK)) {
49      throw std::runtime_error(std::string("access_rights: ") + path +
50                               "' does not exist.");
51    }
52    int mode=0;
53    for (unsigned int i=0; i<bits.length(); ++i)
54      switch (bits[i]) {
55          case 'r':
56            mode|=R_OK;
57            break;
58          case 'w':
59            mode|=W_OK;
60            break;
61          case 'x':
62            mode|=X_OK;
63            break;
64      }
65    return access(path.c_str(),mode);
66  }
67
68
69  std::string concatenate_path(std::string dir, std::string base)
70  {
71    if (dir.empty() || dir==".")
72      return base;
73    if (dir[dir.size()-1]!='/')
74      dir.append("/");
75    return dir+base;
76  }
77
78
79  void copy_file(const std::string& source, const std::string& target)
80  {
81    std::ofstream o(target.c_str());
82    std::ifstream i(source.c_str());
83    while (i.good()) {
84      char ch=i.get();
85      if (i.good())
86        o.put(ch);
87      if (!o.good())
88        throw std::runtime_error(std::string("copy_file: ") +
89                                 "writing target file failed '" + target + "'");
90    }
91    if (!i.eof() && (i.bad() || i.fail()))  // fail on everything except eof
92      throw std::runtime_error(std::string("copy_file: ") +
93                               "error reading source file '" + source + "'");
94    i.close(); o.close();
95  }
96
97
98  std::string directory_name(std::string path)
99  {
100    size_t pos = path.find_last_of("/");
101    if (pos==std::string::npos)
102      return ".";
103    if (pos==path.size()-1)
104      return directory_name(path.substr(0,path.size()-2));
105    return path.substr(0,pos+1);
106  }
107
108
109  bool equal(std::string::const_iterator first1, 
110             std::string::const_iterator end1,
111             std::string::const_iterator first2,
112             std::string::const_iterator end2)
113  {
114    if (first1==end1 && first2==end2)
115      return true;
116    if (first1!=end1 && first2!=end2 && 
117        (*first1==*first2 || *first1=='*' || *first2=='*' ||
118         *first1=='?' || *first2=='?') && 
119        equal(first1+1, end1, first2+1, end2) )
120      return true;
121    if ( (first1!=end1 && first2!=end2 && (*first1=='*'|| *first2=='*') ) && 
122         (equal(first1+1, end1, first2, end2) || 
123          equal(first1, end1, first2+1, end2))
124         )
125      return true;
126    return false;
127  }
128
129
130  std::string file_name(const std::string& full_path)
131  {
132    std::stringstream ss(full_path);
133    std::string name;
134    while (getline(ss,name,'/')) {}
135    return name;
136  }
137
138
139  std::string getenv(const std::string& var)
140  {
141    char* buffer=std::getenv(var.c_str());
142    if (!buffer)
143      throw std::runtime_error("Environment variable "+var+" is not set");
144    return std::string(buffer);
145  }
146
147
148  std::string hex(int x, unsigned int width)
149  {
150    std::stringstream ss;
151    ss << std::hex << x;
152    if (!width)
153      return ss.str();
154    if (ss.str().size()<width) 
155      return std::string(width-ss.str().size(), '0') + ss.str();
156    return ss.str().substr(0, width);
157  }
158
159
160  std::string htrim(std::string str)
161  {
162    size_t length=str.size();
163    while(length && isspace(str[length-1]))
164      --length;
165    return str.substr(0,length);
166  }
167
168
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
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\n" << strerror(errno);
183      throw std::runtime_error(ss.str());
184    }
185  }
186
187
188  bool node_exist(const std::string& path)
189  {
190    struct stat buf;
191    return !stat(path.c_str(),&buf);
192  }
193
194
195  int percent(int a, int b)
196  {
197    if (b)
198      return (100*a)/b;
199    return 0;
200  }
201
202
203  std::string pwd(void)
204  {
205    char buffer[MAXPATHLEN];
206    if (!getcwd(buffer, MAXPATHLEN))
207      throw std::runtime_error("Failed to get current working directory");
208    return std::string(buffer);
209  }
210
211
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
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
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
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
296    unsigned int year, month, day, hour, minute, second;
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
326  std::string match(std::string::const_iterator& first,
327                    const std::string::const_iterator& last,
328                    std::string str)
329  {
330    if (match_begin(first, last, str)){
331      first+=str.size();
332      return str;
333    }
334    return std::string();
335  }
336
337}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.