source: trunk/yat/utility/utility.cc

Last change on this file was 4207, checked in by Peter, 3 months ago

update copyright statements

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1// $Id: utility.cc 4207 2022-08-26 04:36:28Z 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, 2012, 2013, 2014, 2017, 2018, 2019, 2020, 2021 Peter Johansson
7
8  This file is part of the yat library, http://dev.thep.lu.se/yat
9
10  The yat library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License as
12  published by the Free Software Foundation; either version 3 of the
13  License, or (at your option) any later version.
14
15  The yat library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with yat. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include <config.h>
25
26#include "utility.h"
27
28#include "Exception.h"
29#include "FileUtil.h"
30#include "stl_utility.h"
31
32#include <boost/algorithm/string/replace.hpp>
33
34#include <cassert>
35#include <cerrno>
36#include <fnmatch.h>
37#include <fstream>
38#include <sstream>
39#include <string>
40#include <sys/stat.h>
41
42namespace theplu {
43namespace yat {
44namespace utility {
45
46  std::string basename(const std::string& path)
47  {
48    if (path.empty())
49      return ".";
50    if (path.size()==1)
51      return path;
52    size_t pos = path.find_last_of('/');
53    if (pos==std::string::npos)
54      return path;
55    if (pos==path.size()-1)
56      return basename(path.substr(0, path.size()-1));
57    return path.substr(pos+1);
58  }
59
60
61  void chdir(const std::string& dir)
62  {
63    if (::chdir(dir.c_str()) )
64      throw errno_error("chdir: '" + dir + "': ");
65  }
66
67
68  void chmod(const std::string& filename, mode_t mode)
69  {
70    if (::chmod(filename.c_str(), mode))
71      throw errno_error("chmod: '" + filename + "': ");
72  }
73
74
75  void copy_file(const std::string& source, const std::string& target)
76  {
77    std::ifstream is;
78    std::ofstream os;
79
80    is.open(source.c_str(), std::ios::in | std::ios::binary);
81    os.open(target.c_str(), std::ios::out | std::ios::binary);
82    os << is.rdbuf();
83    if (!os.good()) {
84      std::ostringstream ss;
85      ss << "copy_file failed writing to '" << target << "'\n";
86      throw runtime_error(ss.str());
87    }
88    if (is.bad() || is.fail()) {
89      std::ostringstream ss;
90      ss << "copy_file failed reading from '" << source << "'\n";
91      throw runtime_error(ss.str());
92    }
93    is.close();
94    os.close();
95
96    // copy permissions
97    struct stat nodestat;
98    stat(source.c_str(), &nodestat);
99    chmod(target.c_str(), nodestat.st_mode);
100  }
101
102
103  std::string dirname(const std::string& path)
104  {
105    if (path.size()<=1) {
106      if (path=="/")
107        return path;
108      else
109        return ".";
110    }
111    assert(path.size()>=2);
112    size_t pos = path.find_last_of('/', path.size()-2);
113    if (pos==std::string::npos)
114      return ".";
115    if (pos==0)
116      return "/";
117    return path.substr(0,pos);
118  }
119
120
121  bool fnmatch(const std::string& pattern, const std::string& str, int flags)
122  {
123    int res = ::fnmatch(pattern.c_str(), str.c_str(), flags);
124    if (res==0)
125      return true;
126    if (res!=FNM_NOMATCH) {
127      std::stringstream ss;
128      ss << "fnmatch(" << pattern << ", " << str << ")";
129      throw runtime_error(ss.str());
130    }
131    return false;
132  }
133
134
135  std::string getcwd(void)
136  {
137    char buffer[256];
138    if (::getcwd(buffer, 256))
139      return std::string(buffer);
140    if (errno == ERANGE) {
141      char buffer2[4096];
142      if (::getcwd(buffer2, 4096))
143        return std::string(buffer2);
144    }
145    throw errno_error("getcwd failed: ");
146    return "";
147  }
148
149
150  void gsl_error_handler(const char* reason, const char* file,
151                         int line, int gsl_errno)
152  {
153    std::ostringstream msg;
154    msg << file << ":" << line << ": " << reason << ": ";
155    throw GSL_error(msg.str(), gsl_errno);
156  }
157
158
159  bool is_double(const std::string& s)
160  {
161    return is<double>(s);
162  }
163
164
165  bool is_equal(std::string s, std::string other)
166  {
167    std::stringstream ss(s);
168    std::string s2;
169    ss >> s2; // to trim surrounding whitespaces
170    to_lower(s2);
171    if (s2!=other)
172      return false;
173    // Check that nothing is left on stream
174    std::string s3;
175    ss >> s3;
176    return s3.empty();
177  }
178
179
180  bool is_float(const std::string& s)
181  {
182    return is<float>(s);
183  }
184
185
186  bool is_int(const std::string& s)
187  {
188    return is<int>(s);
189  }
190
191  bool is_nan(const std::string& s)
192  {
193    return is_equal(s, "nan");
194  }
195
196
197  void mkdir(const std::string& dir, mode_t mode)
198  {
199    int code = ::mkdir(dir.c_str(), mode);
200    if (code){
201      std::stringstream ss;
202      ss << "mkdir: '" << dir << "': ";
203      throw errno_error(ss.str());
204    }
205  }
206
207
208  void mkdir_p(const std::string& dir, mode_t mode)
209  {
210    if (FileUtil(dir).exists())
211      return;
212    mkdir_p(dirname(dir), mode);
213    mkdir(dir, mode);
214  }
215
216
217  void print_what(const std::exception& error, std::ostream& out)
218  {
219    // implemented as example at
220    // http://www.cplusplus.com/reference/exception/rethrow_if_nested/
221    out << error.what() << "\n";
222    try {
223      std::rethrow_if_nested(error);
224    }
225    catch (const std::exception& nested) {
226      print_what(nested, out);
227    }
228  }
229
230
231  void remove(const std::string& fn)
232  {
233    if (::remove(fn.c_str())) {
234      std::string msg("remove: '");
235      msg += fn;
236      msg += "': ";
237      throw errno_error(msg);
238    }
239  }
240
241
242  void rename(const std::string& from, const std::string& to)
243  {
244    if (::rename(from.c_str(), to.c_str())) {
245      std::stringstream ss;
246      ss << "rename '" << from << "' to '" << to << "': ";
247      throw errno_error(ss.str());
248    }
249  }
250
251
252  void replace(std::string& str, const std::string& old_value,
253               const std::string& new_value)
254  {
255    assert(old_value.size());
256    boost::algorithm::replace_all(str, old_value, new_value);
257  }
258
259
260  void symlink(const std::string& path1, const std::string& path2)
261  {
262    if (::symlink(path1.c_str(), path2.c_str())) {
263      std::string msg("symlink: '");
264      msg += path1;
265      msg += "' -> '";
266      msg += path2;
267      msg += "': ";
268      throw errno_error(msg);
269    }
270  }
271
272
273}}} // end of namespace utility, yat and thep
Note: See TracBrowser for help on using the repository browser.