source: branches/0.10-stable/yat/utility/utility.cc @ 3093

Last change on this file since 3093 was 3093, checked in by Peter, 8 years ago

implement replace(3), which fixes #768

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1// $Id: utility.cc 3093 2013-10-21 04:07:37Z peter $
2
3/*
4  Copyright (C) 2005, 2006 Jari Häkkinen, Markus Ringnér
5  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
6  Copyright (C) 2010 Peter Johansson
7  Copyright (C) 2012 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2013 Peter Johansson
9
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include <config.h>
27
28#include "utility.h"
29
30#include "Exception.h"
31#include "FileUtil.h"
32#include "stl_utility.h"
33
34#include <cassert>
35#include <fnmatch.h>
36#include <fstream>
37#include <sstream>
38#include <string>
39#include <sys/stat.h>
40
41namespace theplu {
42namespace yat {
43namespace utility {
44
45  std::string basename(const std::string& path)
46  {
47    if (path.size()==1)
48      return path;
49    size_t pos = path.find_last_of('/');
50    if (pos==std::string::npos)
51      return path;
52    if (pos==path.size()-1)
53      return basename(path.substr(0, path.size()-1));
54    return path.substr(pos+1);
55  }
56
57
58  void chdir(const std::string& dir)
59  {
60    if (::chdir(dir.c_str()) )
61      throw errno_error("chdir: " + dir + ":");
62  }
63
64
65  void chmod(const std::string& filename, mode_t mode)
66  {
67    if (::chmod(filename.c_str(), mode))
68      throw errno_error("chmod: ");
69  }
70
71
72  void copy_file(const std::string& source, const std::string& target)
73  {
74    std::ifstream is;
75    std::ofstream os;
76
77    is.open(source.c_str(), std::ios::in | std::ios::binary);
78    os.open(target.c_str(), std::ios::out | std::ios::binary);
79    os << is.rdbuf();
80    if (!os.good()) {
81      std::ostringstream ss;
82      ss << "copy_file failed writing to '" << target << "'\n";
83      throw runtime_error(ss.str());
84    }
85    if (is.bad() || is.fail()) {
86      std::ostringstream ss;
87      ss << "copy_file failed reading from '" << source << "'\n";
88      throw runtime_error(ss.str());
89    }
90    is.close();
91    os.close();
92
93    // copy permissions
94    struct stat nodestat;
95    stat(source.c_str(), &nodestat);
96    chmod(target.c_str(), nodestat.st_mode);
97  }
98
99
100  std::string dirname(const std::string& path)
101  {
102    if (path.size()==1) {
103      if (path=="/")
104        return path;
105      else
106        return ".";
107    }
108    assert(path.size()>=2);
109    size_t pos = path.find_last_of('/', path.size()-2);
110    if (pos==std::string::npos)
111      return ".";
112    if (pos==0)
113      return "/";
114    return path.substr(0,pos);
115  }
116
117
118  bool fnmatch(const std::string& pattern, const std::string& str, int flags)
119  {
120    int res = ::fnmatch(pattern.c_str(), str.c_str(), flags);
121    if (res==0)
122      return true;
123    if (res!=FNM_NOMATCH) {
124      std::stringstream ss;
125      ss << "fnmatch(" << pattern << ", " << str << ")";
126      throw runtime_error(ss.str());
127    }
128    return false;
129  }
130
131
132  bool is_double(const std::string& s)
133  {
134    return is<double>(s);
135  }
136 
137
138  bool is_equal(std::string s, std::string other)
139  {
140    std::stringstream ss(s);
141    std::string s2;
142    ss >> s2; // to trim surrounding whitespaces
143    to_lower(s2);
144    if (s2!=other)
145      return false;
146    // Check that nothing is left on stream
147    std::string s3;
148    ss >> s3;
149    return s3.empty();
150  }
151
152
153  bool is_float(const std::string& s)
154  {
155    return is<float>(s);
156  }
157
158
159  bool is_int(const std::string& s)
160  {
161    return is<int>(s);
162  }
163
164  bool is_nan(const std::string& s)
165  {
166    return is_equal(s, "nan");
167  }
168
169
170  void mkdir(const std::string& dir, mode_t mode)
171  {
172    int code = ::mkdir(dir.c_str(), mode);
173    if (code){
174      std::stringstream ss;
175      ss << "mkdir: '" << dir << "': ";
176      throw yat::utility::errno_error(ss.str());
177    }
178  }
179
180
181  void mkdir_p(const std::string& dir, mode_t mode)
182  {
183    if (FileUtil(dir).exists())
184      return;
185    mkdir_p(dirname(dir), mode);
186    mkdir(dir, mode);
187  }
188
189
190  void replace(std::string& str, std::string old_value, std::string new_value)
191  {
192    assert(old_value.size());
193    std::string result;
194    std::back_insert_iterator<std::string> out(result);
195    std::string::iterator c = str.begin();
196    while (c!=str.end()) {
197      if (str.end() - c >= static_cast<int>(old_value.size()) &&
198          std::equal(old_value.begin(), old_value.end(), c)) {
199        std::copy(new_value.begin(), new_value.end(), out);
200        c += old_value.size();
201      }
202      else {
203        *out = *c;
204        ++c;
205      }
206    }
207    str.swap(result);
208  }
209
210
211}}} // end of namespace utility, yat and thep
Note: See TracBrowser for help on using the repository browser.