Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
LUPI_file.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include <errno.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/stat.h>
14#include <iostream>
15#include <iomanip>
16
17#include <LUPI.hpp>
18
19#ifdef _WIN32
20#include <windows.h>
21#include <direct.h>
22#include <filesystem>
23char *realpath( char const *a_path, char *a_resolved ) {
24
25 char resolvedPath[LUPI_PATH_MAX+1], *p1 = nullptr;
26
27 DWORD length = GetFullPathName( a_path, LUPI_PATH_MAX, resolvedPath, nullptr );
28 // MSVC requires explicitly casting malloc result
29 if( ( p1 = (char *)malloc( length + 1 ) ) == nullptr ) return( nullptr );
30 strcpy( p1, resolvedPath );
31 if( length == 0 ) return( nullptr );
32 return( p1 );
33}
34
35std::string dirname( char const *a_path ) {
36 std::filesystem::path filePath( a_path );
37 return filePath.parent_path().string();
38}
39
40std::string basename( char const *a_path ) {
41 // don't strip the extension for compatibility with <unistd> version
42 std::filesystem::path filePath( a_path );
43 return filePath.filename().string();
44}
45#else
46// FIXME: once all users are on C++17 or later, switch to using std::filesystem for all systems
47#include <unistd.h>
48#include <libgen.h>
49#endif
50
51namespace LUPI {
52
53namespace FileInfo {
54
55/* *********************************************************************************************************//**
56 * This function takes a file path and returns its real path. On a Unix system, the system function realpath is called.
57 *
58 * @param a_path [in] The path whose real path is to be determined.
59 *
60 * @return The real path.
61 ***********************************************************************************************************/
62
63std::string realPath( std::string const &a_path ) {
64
65 char *p1 = realpath( a_path.c_str( ), nullptr );
66
67 if( p1 == nullptr ) {
68 std::string errMsg( "realPath: file does not exist: " );
69 throw Exception( errMsg + a_path );
70 }
71 std::string basePath( p1 );
72 free( p1 );
73 return( basePath );
74}
75
76/* *********************************************************************************************************//**
77 * Returns the base name of a path.
78 *
79 * @param a_path [in] The path whose base name is returned.
80 ***********************************************************************************************************/
81
82std::string _basename( std::string const &a_path ) {
83
84 char *path = new char[a_path.size( ) + 1];
85 strcpy( path, a_path.c_str( ) );
86 std::string basename1( basename( path ) );
87
88 delete[] path;
89
90 return( basename1 );
91}
92
93/* *********************************************************************************************************//**
94 * Same as **basename** but removes, if a *period* (i.e., ".") exists in the string, the last "." and all following characters.
95 *
96 * @param a_path [in] The path whose base name is returned without its extension.
97 ***********************************************************************************************************/
98
99std::string basenameWithoutExtension( std::string const &a_path ) {
100
101 std::size_t found = a_path.rfind( '.' );
102
103 return( a_path.substr( 0, found ) );
104}
105
106/* *********************************************************************************************************//**
107 * Returns the directory name of a path. This is, it removes the base name.
108 *
109 * @param a_path [in] The path whose base name is returned.
110 ***********************************************************************************************************/
111
112std::string _dirname( std::string const &a_path ) {
113
114 char *path = new char[a_path.size( ) + 1];
115 strcpy( path, a_path.c_str( ) );
116 std::string dirname1( dirname( (char *) path ) );
117
118 delete[] path;
119
120 return( dirname1 );
121}
122
123/* *********************************************************************************************************//**
124 * Returns *true* if the path exists and *false* otherwise.
125 *
126 * @param a_path [in] The path that is checked for existence.
127 ***********************************************************************************************************/
128
129bool exists( std::string const &a_path ) {
130
131#ifdef _WIN32
132 return std::filesystem::exists( std::filesystem::path( a_path ) );
133#else
134 return( access( a_path.c_str( ), F_OK ) == 0 );
135#endif
136}
137
138/* *********************************************************************************************************//**
139 * Returns *true* if path is a direction that exists and *false* otherwise.
140 *
141 * @param a_path [in] The path that is checked for existence and is it a directory.
142 *
143 * @return Returns *true* if the path exists (e.g., created if it does not exists) and *false* otherwise.
144 ***********************************************************************************************************/
145
146bool isDirectory( std::string const &a_path ) {
147
148 try {
149 FileStat fileStat( a_path );
150 return( fileStat.isDirectory( ) ); }
151 catch (...) {
152 }
153
154 return( false );
155}
156
157/* *********************************************************************************************************//**
158 * Adds all needed directories to complete *a_path*.
159 *
160 * @param a_path [in] The path that is checked for existence.
161 *
162 * @return Returns *true* if the path exists (e.g., created if it does not exists) and *false* otherwise.
163 ***********************************************************************************************************/
164
165bool createDirectories( std::string const &a_path ) {
166
167 if( isDirectory( a_path ) ) return( true );
168 if( ( a_path == LUPI_FILE_SEPARATOR ) || ( a_path == "." ) || ( a_path == "" ) ) return( true );
169
170 std::string dirname1( _dirname( a_path ) );
171 if( createDirectories( dirname1 ) ) {
172#ifdef _WIN32
173 int status = _mkdir( a_path.c_str( ) );
174#else
175 int status = mkdir( a_path.c_str( ), S_IRWXU | S_IRWXG | S_IRWXG );
176#endif
177 if( status == 0 ) return( true );
178 switch( errno ) {
179 case EEXIST :
180 return( true );
181 default :
182 return( false );
183 }
184 }
185
186 return( false );
187}
188
189/* *********************************************************************************************************//**
190 * Calls the C stat function and stores its information.
191 *
192 * @param a_path [in] The path (e.g., file, directory) whose stat is determined.
193 ***********************************************************************************************************/
194
195FileStat::FileStat( std::string const &a_path ) :
196 m_path( a_path ) {
197
198 int error = stat( a_path.c_str( ), &m_stat );
199
200 if( error != 0 ) {
201 switch( error ) {
202 case EACCES :
203 throw Exception( "FileStat::FileStat: Permission denied for file '" + a_path + "'.." );
204 case EIO :
205 throw Exception( "FileStat::FileStat: An error occurred while stat-ing file '" + a_path + "'.." );
206 case ELOOP :
207 throw Exception( "FileStat::FileStat: A loop exists in symbolic links for file '" + a_path + "'.." );
208 case ENAMETOOLONG :
209 throw Exception( "FileStat::FileStat: Path name too long '" + a_path + "'." );
210 case ENOENT :
211 throw Exception( "FileStat::FileStat: No such path '" + a_path + "'." );
212 case ENOTDIR :
213 throw Exception( "FileStat::FileStat: A component of the path prefix is not a directory '" + a_path + "'." );
214 case EOVERFLOW :
215 throw Exception( "FileStat::FileStat: File too big: '" + a_path + "'." );
216 default :
217 throw Exception( "FileStat::FileStat: Unknown error from C function 'stat' for file '" + a_path + "'." );
218 }
219 }
220}
221
222} // End of namespace FileInfo.
223
224} // End of namespace LUPI.
#define LUPI_FILE_SEPARATOR
Definition LUPI.hpp:45
#define LUPI_PATH_MAX
Definition LUPI.hpp:31
FileStat(std::string const &a_path)
Definition LUPI_file.cc:195
bool isDirectory() const
Definition LUPI.hpp:421
void free(voidpf ptr)
voidp malloc(uInt size)
std::string basenameWithoutExtension(std::string const &a_path)
Definition LUPI_file.cc:99
std::string _basename(std::string const &a_path)
Definition LUPI_file.cc:82
bool exists(std::string const &a_path)
Definition LUPI_file.cc:129
std::string realPath(std::string const &a_path)
Definition LUPI_file.cc:63
bool createDirectories(std::string const &a_path)
Definition LUPI_file.cc:165
std::string _dirname(std::string const &a_path)
Definition LUPI_file.cc:112
bool isDirectory(std::string const &a_path)
Definition LUPI_file.cc:146
Definition LUPI.hpp:40