w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rtools.cpp
Go to the documentation of this file.
1// $Id: Rtools.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2011-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2018-12-18 1089 1.0.9 use c++ style casts
8// 2018-10-26 1059 1.0.8 add Catch2Cerr()
9// 2017-02-18 852 1.0.7 remove TimeOfDayAsDouble()
10// 2014-11-23 606 1.0.6 add TimeOfDayAsDouble()
11// 2014-11-08 602 1.0.5 add (int) cast in snprintf to match %d type
12// 2014-08-22 584 1.0.4 use nullptr
13// 2013-05-04 516 1.0.3 add CreateBackupFile()
14// 2013-02-13 481 1.0.2 remove Throw(Logic|Runtime)(); use Rexception
15// 2011-04-10 376 1.0.1 add ThrowLogic(), ThrowRuntime()
16// 2011-03-12 368 1.0 Initial version
17// ---------------------------------------------------------------------------
18
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <unistd.h>
26
27#include <iostream>
28#include <vector>
29
30#include "Rexception.hpp"
31
32#include "Rtools.hpp"
33
34using namespace std;
35
41// all method definitions in namespace Retro
42namespace Retro {
43namespace Rtools {
44
45//------------------------------------------+-----------------------------------
47
48std::string Flags2String(uint32_t flags, const RflagName* fnam, char delim)
49{
50 if (fnam == nullptr)
51 throw Rexception("Rtools::Flags2String()","Bad args: fnam==nullptr");
52
53 string rval;
54 while (fnam->mask) {
55 if (flags & fnam->mask) {
56 if (!rval.empty()) rval += delim;
57 rval += fnam->name;
58 }
59 fnam++;
60 }
61 return rval;
62}
63
64//------------------------------------------+-----------------------------------
66
67bool String2Long(const std::string& str, long& res, RerrMsg& emsg, int base)
68{
69 char* endptr;
70 res = ::strtol(str.c_str(), &endptr, base);
71 if (*endptr == 0) return true;
72
73 emsg.Init("Rtools::String2Long",
74 string("conversion error in '") + str +"'");
75 res = 0;
76 return false;
77}
78
79//------------------------------------------+-----------------------------------
81
82bool String2Long(const std::string& str, unsigned long& res,
83 RerrMsg& emsg, int base)
84{
85 char* endptr;
86 res = ::strtoul(str.c_str(), &endptr, base);
87 if (*endptr == 0) return true;
88
89 emsg.Init("Rtools::String2Long",
90 string("conversion error in '") + str +"'");
91 res = 0;
92 return false;
93}
94
95//------------------------------------------+-----------------------------------
97
98bool CreateBackupFile(const std::string& fname, size_t nbackup, RerrMsg& emsg)
99{
100 if (nbackup == 0) return true;
101
102 size_t dotpos = fname.find_last_of('.');
103 string fbase = fname.substr(0,dotpos);
104 string fext = fname.substr(dotpos);
105
106 if (nbackup > 99) {
107 emsg.Init("Rtools::CreateBackupFile",
108 "only up to 99 backup levels supported");
109 return false;
110 }
111
112 vector<string> fnames;
113 fnames.push_back(fname);
114 for (size_t i=1; i<=nbackup; i++) {
115 char fnum[4];
116 ::snprintf(fnum, sizeof(fnum), "%d", int(i));
117 fnames.push_back(fbase + "_" + fnum + fext);
118 }
119
120 for (size_t i=nbackup; i>0; i--) {
121 string fnam_new = fnames[i];
122 string fnam_old = fnames[i-1];
123
124 struct stat sbuf;
125 int irc = ::stat(fnam_old.c_str(), &sbuf);
126 if (irc < 0) {
127 if (errno == ENOENT) continue;
128 emsg.InitErrno("Rtools::CreateBackupFile",
129 string("stat() for '") + fnam_old + "'failed: ", errno);
130 return false;
131 }
132 if (S_ISREG(sbuf.st_mode) == 0) {
133 emsg.Init("Rtools::CreateBackupFile",
134 "backups only supported for regular files");
135 return false;
136 }
137 // here we know old file exists and is a regular file
138 /* coverity[toctou] */
139 irc = ::rename(fnam_old.c_str(), fnam_new.c_str());
140 if (irc < 0) {
141 emsg.InitErrno("Rtools::CreateBackupFile",
142 string("rename() for '") + fnam_old + "' -> '" +
143 fnam_new + "'failed: ", errno);
144 return false;
145 }
146 }
147
148 return true;
149}
150
151//------------------------------------------+-----------------------------------
153
154bool CreateBackupFile(const RparseUrl& purl, RerrMsg& emsg)
155{
156 string bck;
157 if (!purl.FindOpt("app") && purl.FindOpt("bck", bck)) {
158 unsigned long nbck;
159 if (!Rtools::String2Long(bck, nbck, emsg)) return false;
160 if (nbck > 0) {
161 if (!Rtools::CreateBackupFile(purl.Path(), nbck, emsg)) return false;
162 }
163 }
164 return true;
165}
166
167//------------------------------------------+-----------------------------------
169
170void Catch2Cerr(const char* msg, std::function<void()> func)
171{
172 try {
173 func();
174 } catch (Rexception& e) {
175 cerr << "Catch2Cerr-E: exception '" << e.ErrMsg().Text()
176 << "' thrown in " << e.ErrMsg().Meth()
177 << " caught and dropped in " << msg << endl;
178 } catch (exception& e) {
179 cerr << "Catch2Cerr-E: exception '" << e.what()
180 << "' caught and dropped in " << msg << endl;
181 } catch(...) {
182 cerr << "Catch2Cerr-E: non std::exception"
183 << " caught and dropped in " << msg << endl;
184 }
185 return;
186}
187
188} // end namespace Rtools
189} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
const std::string & Meth() const
FIXME_docs.
Definition: RerrMsg.ipp:39
void Init(const std::string &meth, const std::string &text)
FIXME_docs.
Definition: RerrMsg.cpp:74
const std::string & Text() const
FIXME_docs.
Definition: RerrMsg.ipp:47
void InitErrno(const std::string &meth, const std::string &text, int errnum)
FIXME_docs.
Definition: RerrMsg.cpp:84
FIXME_docs.
Definition: Rexception.hpp:29
virtual const char * what() const noexcept
FIXME_docs.
Definition: Rexception.cpp:81
const RerrMsg & ErrMsg() const
FIXME_docs.
Definition: Rexception.ipp:20
FIXME_docs.
Definition: RparseUrl.hpp:27
bool FindOpt(const std::string &name) const
FIXME_docs.
Definition: RparseUrl.cpp:196
const std::string & Path() const
FIXME_docs.
Definition: RparseUrl.ipp:45
std::string Flags2String(uint32_t flags, const RflagName *fnam, char delim)
FIXME_docs.
Definition: Rtools.cpp:48
bool String2Long(const std::string &str, long &res, RerrMsg &emsg, int base)
FIXME_docs.
Definition: Rtools.cpp:67
void Catch2Cerr(const char *msg, std::function< void()> func)
FIXME_docs.
Definition: Rtools.cpp:170
bool CreateBackupFile(const std::string &fname, size_t nbackup, RerrMsg &emsg)
FIXME_docs.
Definition: Rtools.cpp:98
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47
uint32_t mask
Definition: Rtools.hpp:34
const char * name
Definition: Rtools.hpp:35