portability/file_system.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#ifndef STLPLUS_FILE_SYSTEM
#define STLPLUS_FILE_SYSTEM
////////////////////////////////////////////////////////////////////////////////
 
//   Author:    Andy Rushton
//   Copyright: (c) Southampton University 1999-2004
//              (c) Andy Rushton           2004 onwards
//   License:   BSD License, see ../docs/license.html
 
//   Simplified access to the File system
 
//   All file system access and filename manipulation should be done
//   with this package. Then it is only necessary to port this package
//   to port all file handling.
 
////////////////////////////////////////////////////////////////////////////////
#include "portability_fixes.hpp"
#include <string>
#include <vector>
#include <time.h>
////////////////////////////////////////////////////////////////////////////////
 
namespace stlplus
{
 
  ////////////////////////////////////////////////////////////////////////////////
  // implement string comparison of paths - Unix is case-sensitive, Windows is case-insensitive
 
  bool path_compare(const std::string& l, const std::string& r);
 
  ////////////////////////////////////////////////////////////////////////////////
  // classifying functions
 
  // test for whether there's something (i.e. folder or file) with this name
  bool is_present(const std::string& thing);
  // test for whether there's something present and its a folder
  bool is_folder(const std::string& thing);
  // test for whether there's something present and its a file
  // a file can be a regular file, a symbolic link, a FIFO or a socket, but not a device
  bool is_file(const std::string& thing);
 
  ////////////////////////////////////////////////////////////////////////////////
  // file functions
 
  // tests whether there's a file of this name
  bool file_exists(const std::string& filespec);
  // tests whether the file is readable - i.e. exists and has read mode set
  bool file_readable(const std::string& filespec);
  // tests whether file is writable - either it exists and is writable or doesn't exist but is in a writable folder
  bool file_writable(const std::string& filespec);
  // the size of the file in bytes - 0 if doesn't exist
  size_t file_size(const std::string& filespec);
  // delete the file - returns true if the delete succeeded
  bool file_delete(const std::string& filespec);
  // rename the file - returns true if the rename succeeded
  bool file_rename (const std::string& old_filespec, const std::string& new_filespec);
  // make an exact copy of the file - returns true if it succeeded
  bool file_copy (const std::string& old_filespec, const std::string& new_filespec);
  // move the file - tries to rename, if that fails, tries to copy - returns true if either of these succeeded
  bool file_move (const std::string& old_filespec, const std::string& new_filespec);
 
  // get the file's time stamps as a time_t - see the stlplus time.hpp package
 
  // time the file was originally created
  time_t file_created(const std::string& filespec);
  // time the file was last modified
  time_t file_modified(const std::string& filespec);
  // time the file was accessed
  time_t file_accessed(const std::string& filespec);
 
  // platform-specific string handling to combine a directory and filename into a path
 
  // combine a folder with a filename (basename.extension)
  std::string create_filespec(const std::string& folder, const std::string& filename);
  // combine a folder, a basename and an extension - extension does not need the .
  std::string create_filespec(const std::string& folder, const std::string& basename, const std::string& extension);
  // combine a basename and an extension - extension does not need the .
  std::string create_filename(const std::string& basename, const std::string& extension);
 
  ////////////////////////////////////////////////////////////////////////////////
  // folder functions
 
  // craete a folder - returns true if successful
  bool folder_create(const std::string& folder);
  // tests for whether the folder exists, i.e. there is something of that name and its a folder
  bool folder_exists(const std::string& folder);
  // test whether the folder contents are readable
  bool folder_readable(const std::string& folder);
  // tests whether the folder can be written to - for example to create a new file
  bool folder_writable(const std::string& folder);
  // delete the folder, optionally deleting the contents first - only succeeds if everything could be deleted
  bool folder_delete(const std::string& folder, bool recurse = false);
  // rename the folder - this probably only works within a disk/partition
  bool folder_rename (const std::string& old_directory, const std::string& new_directory);
  // test whether the folder is empty (of files)
  bool folder_empty(const std::string& folder);
 
  // set the current folder
  bool folder_set_current(const std::string& folder);
 
  // platform-specific string handling to retrieve some special locations
  // these do not check whether the folder exists, they just process strings
 
  // get the current folder
  std::string folder_current(void);
  // get the current folder as a full path
  std::string folder_current_full(void);
  // get the home folder - $HOME or %HOMEDRIVE%%HOMEPATH%
  std::string folder_home(void);
  // go down a level in the folder hierarchy
  std::string folder_down(const std::string& folder, const std::string& subfolder);
  // go up a level in the folder hierarchy
  std::string folder_up(const std::string& folder, unsigned levels = 1);
 
  // get folder contents
 
  // the set of all subdirectories
  std::vector<std::string> folder_subdirectories(const std::string& folder);
  // the set of all files
  std::vector<std::string> folder_files(const std::string& folder);
  // the set of all folders and files
  std::vector<std::string> folder_all(const std::string& folder);
  // the set of all folder contents matching a wildcard string
  // if folders is true, include folders; if files is true, include files
  std::vector<std::string> folder_wildcard(const std::string& folder,
                                           const std::string& wildcard,
                                           bool folders = true,
                                           bool files = true);
 
  ////////////////////////////////////////////////////////////////////////////////
  // path functions
 
  // string manipulations of paths
 
  // test whether a string represents a full path or a relative one
  bool is_full_path(const std::string& path);
  bool is_relative_path(const std::string& path);
 
  // convert to a full path relative to the root path
  std::string folder_to_path(const std::string& root, const std::string& folder);
  std::string filespec_to_path(const std::string& root, const std::string& filespec);
 
  // convert to a full path relative to the current working directory
  std::string folder_to_path(const std::string& folder);
  std::string filespec_to_path(const std::string& filespec);
 
  // convert to a relative path relative to the root path
  std::string folder_to_relative_path(const std::string& root, const std::string& folder);
  std::string filespec_to_relative_path(const std::string& root, const std::string& filespec);
 
  // convert to a relative path relative to the current working directory
  std::string folder_to_relative_path(const std::string& folder);
  std::string filespec_to_relative_path(const std::string& filespec);
 
  // append a folder separator to the path to make it absolutely clear that it is a folder
  std::string folder_append_separator(const std::string& folder);
  // undo the above to give a simplified folder with no trailing separator
  std::string folder_remove_end_separator(const std::string& folder);
 
  ////////////////////////////////////////////////////////////////////////////////
  // access functions split a filespec into its elements
 
  // get the basename - that is, the name of the file without folder or extension parts
  std::string basename_part(const std::string& filespec);
  // get the filename - that is, the name of the file without folder part but with extension
  std::string filename_part(const std::string& filespec);
  // get the extension - that is the part of the filename after the . (and excluding the .)
  std::string extension_part(const std::string& filespec);
  // get the folder part - that is the filespec with the filename removed
  std::string folder_part(const std::string& filespec);
 
  // split a path into a vector of elements - i.e. split at the folder separator
  std::vector<std::string> folder_elements(const std::string& folder);
  std::vector<std::string> filespec_elements(const std::string& filespec);
 
  ////////////////////////////////////////////////////////////////////////////////
  // Path lookup functions
 
#ifdef MSWINDOWS
#define PATH_SPLITTER ";"
#else
#define PATH_SPLITTER ":"
#endif
 
  // The lookup normally carried out by the shell to find a command in a
  // directory in the PATH. Give this function the name of a command and it
  // will return the full path. It returns an empty string on failure.
  std::string path_lookup (const std::string& command);
 
  // Generalised form of the above, takes a second argument
  // - the list to search. This can be used to do other path lookups,
  // such as LD_LIBRARY_PATH. The third argument specifies the splitter -
  // the default value of PATH_SPLITTER is appropriate for environment variables.
  std::string lookup (const std::string& file, const std::string& path, const std::string& splitter = PATH_SPLITTER);
 
  // utility function for finding the folder that contains the current executable
  // the argument is the argv[0] parameter passed to main
  std::string install_path(const std::string& argv0);
 
  ////////////////////////////////////////////////////////////////////////////////
 
} // end namespace stlplus
 
#endif