timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
filepath.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24//
25
26/** \file utility/filepath.hpp
27 * \headerfile utility/filepath.hpp "timemory/utility/filepath.hpp"
28 * Functions for converting OS filepaths
29 *
30 */
31
32#pragma once
33
37
38#include <cstring>
39#include <fstream>
40#include <iostream>
41#include <sstream>
42#include <string>
43
44#if defined(TIMEMORY_UNIX)
45# include <cxxabi.h>
46# include <execinfo.h>
47# include <sys/stat.h>
48# include <sys/types.h>
49#elif defined(TIMEMORY_WINDOWS)
50# include <direct.h>
51using pid_t = int;
52#endif
53
54#if !defined(TIMEMORY_DEFAULT_UMASK)
55# define TIMEMORY_DEFAULT_UMASK 0777
56#endif
57
58namespace tim
59{
60namespace filepath
61{
62int
64
65inline std::string&
66replace(std::string& _path, char _c, const char* _v)
67{
68 auto _pos = std::string::npos;
69 while((_pos = _path.find(_c)) != std::string::npos)
70 _path.replace(_pos, 1, _v);
71 return _path;
72}
73
74inline std::string&
75replace(std::string& _path, const char* _c, const char* _v)
76{
77 auto _pos = std::string::npos;
78 while((_pos = _path.find(_c)) != std::string::npos)
79 _path.replace(_pos, strlen(_c), _v);
80 return _path;
81}
82
83#if defined(TIMEMORY_WINDOWS)
84
85inline std::string
86os()
87{
88 return "\\";
89}
90
91inline std::string
92inverse()
93{
94 return "/";
95}
96
97inline std::string
98osrepr(std::string _path)
99{
100 // OS-dependent representation
101 while(_path.find('/') != std::string::npos)
102 _path.replace(_path.find('/'), 1, "\\");
103 return _path;
104}
105
106#elif defined(TIMEMORY_UNIX)
107
108inline std::string
109os()
110{
111 return "/";
112}
113
114inline std::string
115inverse()
116{
117 return "\\";
118}
119
120inline std::string
121osrepr(std::string _path)
122{
123 // OS-dependent representation
124 while(_path.find("\\\\") != std::string::npos)
125 _path.replace(_path.find("\\\\"), 2, "/");
126 while(_path.find('\\') != std::string::npos)
127 _path.replace(_path.find('\\'), 1, "/");
128 return _path;
129}
130
131#endif
132
133inline std::string
135{
136 replace(_path, '\\', "/");
137 replace(_path, "//", "/");
138 return _path;
139}
140
141inline int
143{
144#if defined(TIMEMORY_UNIX)
145 while(_dir.find("\\\\") != std::string::npos)
146 _dir.replace(_dir.find("\\\\"), 2, "/");
147 while(_dir.find('\\') != std::string::npos)
148 _dir.replace(_dir.find('\\'), 1, "/");
149
150 if(_dir.length() == 0)
151 return 0;
152
153 int ret = mkdir(_dir.c_str(), umask);
154 if(ret != 0)
155 {
156 int err = errno;
157 if(err != EEXIST)
158 {
159 std::stringstream _mdir{};
160 _mdir << "mkdir(" << _dir.c_str() << ", " << umask << ") returned: " << ret
161 << "\n";
162 std::stringstream _sdir{};
163 _sdir << "/bin/mkdir -p " << _dir;
164 ret = (launch_process(_sdir.str().c_str())) ? 0 : 1;
165 if(ret != 0)
166 {
167 std::cerr << _mdir.str() << _sdir.str() << " returned: " << ret
168 << std::endl;
169 }
170 return ret;
171 }
172 }
173#elif defined(TIMEMORY_WINDOWS)
174 consume_parameters(umask);
175 while(_dir.find('/') != std::string::npos)
176 _dir.replace(_dir.find('/'), 1, "\\");
177
178 if(_dir.length() == 0)
179 return 0;
180
181 int ret = _mkdir(_dir.c_str());
182 if(ret != 0)
183 {
184 int err = errno;
185 if(err != EEXIST)
186 {
187 std::stringstream _mdir{};
188 _mdir << "_mkdir(" << _dir.c_str() << ") returned: " << ret << "\n";
189 std::stringstream _sdir{};
190 _sdir << "mkdir " << _dir;
191 ret = (launch_process(_sdir.str().c_str())) ? 0 : 1;
192 if(ret != 0)
193 {
194 std::cerr << _mdir.str() << _sdir.str() << " returned: " << ret
195 << std::endl;
196 }
197 return ret;
198 }
199 }
200#endif
201 return 0;
202}
203
204//
205template <typename... Args>
206inline bool
207open(std::ofstream& _ofs, std::string _fpath, Args&&... _args)
208{
209 auto _path = canonical(_fpath);
210 auto _base = canonical(_fpath);
211 auto _pos = _path.find_last_of('/');
212 if(_pos != std::string::npos)
213 {
214 _path = _path.substr(0, _pos);
215 _base = _base.substr(_pos + 1);
216 }
217
218 if(!_path.empty())
219 {
220 auto ret = makedir(osrepr(_path));
221 if(ret != 0)
222 _fpath = std::string{ "./" } + _base;
223 }
224
225 _ofs.open(osrepr(_fpath), std::forward<Args>(_args)...);
226 return (_ofs && _ofs.is_open() && _ofs.good());
227}
228
229} // namespace filepath
230} // namespace tim
231
232//--------------------------------------------------------------------------------------//
#define TIMEMORY_DEFAULT_UMASK
Definition: filepath.hpp:55
int makedir(std::string _dir, int umask=0777)
Definition: filepath.hpp:142
bool open(std::ofstream &_ofs, std::string _fpath, Args &&... _args)
Definition: filepath.hpp:207
std::string & replace(std::string &_path, char _c, const char *_v)
Definition: filepath.hpp:66
std::string canonical(std::string _path)
Definition: filepath.hpp:134
const string_t const string_t & _dir
Definition: definition.hpp:52
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
const std::string std::ostream * os
bool launch_process(const char *cmd, const std::string &extra="", std::ostream *os=nullptr)
void consume_parameters(ArgsT &&...)
Definition: types.hpp:285