Blame view

stim/parser/filename.h 12.4 KB
8157c392   David Mayerich   added parser and ...
1
2
3
4
  #ifndef STIM_FILENAME_H

  #define STIM_FILENAME_H

  

  #include <stdio.h>  /* defines FILENAME_MAX */

25d8d20b   David Mayerich   added FFT support...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  #include <sstream>

  #include <vector>

  #include <algorithm>

  #include <iostream>

  #include <iomanip>

  

  #include <stim/parser/parser.h>

  

  // set OS dependent defines, including:

  //	1) path division character ('/' or '\') used for output only

  //	2) command for getting the current working directory

  //	3) header files for getting the current working directory

  //	4) include BOOST filesystem class if compiling on GCC

  #define STIM_DIV '/'

5cda84ab   David Mayerich   putting pranathi ...
19
  #ifdef _WIN32

f92397d2   David Mayerich   fixed a Win32 bug...
20
  	#include <windows.h>

25d8d20b   David Mayerich   added FFT support...
21
22
23
  	#include <direct.h>

  	#define GetCurrentDir _getcwd

  	#define STIM_FILENAME_DIV '\\'

8157c392   David Mayerich   added parser and ...
24
  #else

25d8d20b   David Mayerich   added FFT support...
25
26
27
28
29
  	#ifdef BOOST_PRECOMPILED

  		#include <boost/filesystem.hpp>

  	#endif

  	#include <unistd.h>

  	#define GetCurrentDir getcwd

8157c392   David Mayerich   added parser and ...
30
31
32
  	#define STIM_FILENAME_DIV '/'

   #endif

  

8157c392   David Mayerich   added parser and ...
33
34
  namespace stim{

  

25d8d20b   David Mayerich   added FFT support...
35
36
37
38
  class filepath{

  protected:

  	std::string _drive;					//drive on which the file is located (used for Windows)

  	std::vector<std::string> _path;		//path for the specified file (list of hierarchical directories)

8157c392   David Mayerich   added parser and ...
39
  

25d8d20b   David Mayerich   added FFT support...
40
41
42
43
44
  	/// replaces win32 dividers with the Linux standard (used internally by default)

  	std::string unix_div(std::string s) {

  		std::replace( s.begin(), s.end(), '\\', '/');

  		return s;

  	}

8157c392   David Mayerich   added parser and ...
45
  

25d8d20b   David Mayerich   added FFT support...
46
47
48
  	/// gets the directory hierarchy for the current working directory

  	static std::string cwd(){

  		char cCurrentPath[FILENAME_MAX];

8157c392   David Mayerich   added parser and ...
49
  

25d8d20b   David Mayerich   added FFT support...
50
51
52
53
  		 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath))){

  			 std::cout<<"ERROR getting current working directory."<<std::endl;

  			 exit(1);

  		 }

8157c392   David Mayerich   added parser and ...
54
  

25d8d20b   David Mayerich   added FFT support...
55
56
57
  		 std::stringstream ss;

  		 ss<<cCurrentPath;

  		 return ss.str();

8157c392   David Mayerich   added parser and ...
58
59
  	}

  

25d8d20b   David Mayerich   added FFT support...
60
61
  	/// convert a relative path to an absolute path

  	void get_absolute(std::string &drive, std::vector<std::string> &absolute, std::vector<std::string> relative){

8157c392   David Mayerich   added parser and ...
62
  

25d8d20b   David Mayerich   added FFT support...
63
  		std::string current = cwd();						//get the current directory as a string

8157c392   David Mayerich   added parser and ...
64
  

25d8d20b   David Mayerich   added FFT support...
65
66
67
  		std::string current_drive;

  		std::vector<std::string> current_dir;

  		parse_path(current_drive, current_dir, current);			//get the current drive and directories

8b7be670   David Mayerich   implemented savin...
68
  

25d8d20b   David Mayerich   added FFT support...
69
70
71
72
73
74
75
76
77
78
79
80
  		// step through each directory in the relative path, adjusting the current directory

  		//		index depending on whether the relative path is specified with '.' or '..'

  		int current_i = (int)current_dir.size() - 1;

  		int relative_i;

  		for(relative_i = 0; relative_i < relative.size(); relative_i++){

  			if(relative[relative_i] == "..") current_i--;

  			else if(relative[relative_i] != ".") break;

  		}

  		if(current_i < 0){

  			std::cerr<<"ERROR stim::filepath - relative path is incompatible with working directory"<<std::endl;

  			exit(1);

  		}

8157c392   David Mayerich   added parser and ...
81
  

25d8d20b   David Mayerich   added FFT support...
82
83
84
85
86
87
  		absolute.clear();

  		for(size_t i = 0; i <= current_i; i++){

  			absolute.push_back(current_dir[i]);

  		}

  		for(size_t i = relative_i; i < relative.size(); i++){

  			absolute.push_back(relative[i]);

8157c392   David Mayerich   added parser and ...
88
  		}

8157c392   David Mayerich   added parser and ...
89
90
  	}

  

25d8d20b   David Mayerich   added FFT support...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  	/// Parses a directory string into a drive (NULL if not Windows) and list of hierarchical directories

  	/// Returns true if the path is relative, false if it is absolute

  	void parse_path(std::string &drive, std::vector<std::string> &absolute, std::string dir){

  		drive = "";						//initialize the drive to NULL (it will stay that way for Windows)

  		std::vector<std::string> path;

  		bool relative = true;			//the default path is relative

  

  		if(dir.length() == 0) return;					//return if the file locator is empty

  		std::string unix_dir = unix_div(dir);				//replace any Windows division characters with Unix

  

  		if(unix_dir.length() > 1 && unix_dir[1] == ':'){	//if a drive identifier is given

  			if(unix_dir[0] > 64 && unix_dir[0] < 91)		//if the drive letter is upper case

  				_drive = unix_dir[0] + 32;					//convert it to lower case

  			else if(unix_dir[0] > 96 && unix_dir[0] < 123)	//if the drive character is lower case

  					_drive = unix_dir[0];					//store it as-is

  			else{											//otherwise throw an error

  				std::cerr<<"ERROR stim::filename - drive letter is invalid: "<<unix_dir[0]<<std::endl;

  				exit(1);

8b7be670   David Mayerich   implemented savin...
109
  			}

25d8d20b   David Mayerich   added FFT support...
110
111
  			unix_dir = unix_dir.substr(2, unix_dir.length()-2);	//extract the directory structure

  		}

8157c392   David Mayerich   added parser and ...
112
  

25d8d20b   David Mayerich   added FFT support...
113
114
115
116
117
118
  		if(unix_dir.front() == '/'){						//if there is a leading slash

  			relative = false;								//the path is not relative

  			unix_dir = unix_dir.substr(1, unix_dir.length() - 1);	//remove the slash

  		}

  		if(unix_dir.back() == '/')

  			unix_dir = unix_dir.substr(0, unix_dir.length() - 1);

8157c392   David Mayerich   added parser and ...
119
  

25d8d20b   David Mayerich   added FFT support...
120
121
122
123
124
125
  		path = stim::parser::split(unix_dir, '/');					//split up the directory structure

  		

  		if(relative)

  			get_absolute(drive, absolute, path);

  		else

  			absolute = path;

8157c392   David Mayerich   added parser and ...
126
127
  	}

  

25d8d20b   David Mayerich   added FFT support...
128
  	

8157c392   David Mayerich   added parser and ...
129
  

25d8d20b   David Mayerich   added FFT support...
130
131
132
  public:

  	filepath(){

  		_drive = "";

8157c392   David Mayerich   added parser and ...
133
134
  	}

  

25d8d20b   David Mayerich   added FFT support...
135
136
  	filepath(const stim::filepath& p){

  		*this = p;

8157c392   David Mayerich   added parser and ...
137
138
  	}

  

25d8d20b   David Mayerich   added FFT support...
139
140
141
  	filepath(const std::string s){

  		parse_path(_drive, _path, s);

  	}

8157c392   David Mayerich   added parser and ...
142
  

25d8d20b   David Mayerich   added FFT support...
143
144
145
  	stim::filepath& operator=(const std::string s){

  		parse_path(_drive, _path, s);		//parse the string to get the drive and relative path

  		return *this;

8157c392   David Mayerich   added parser and ...
146
147
  	}

  

25d8d20b   David Mayerich   added FFT support...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  	std::string str(){

  		std::stringstream ss;

  		if(_drive != "")							//if a drive letter is specified

  			ss<<_drive<<":";						//add it to the string

  		for(size_t i = 0; i < _path.size(); i++)

  			ss<<STIM_FILENAME_DIV<<_path[i];

  		ss<<STIM_FILENAME_DIV;

  		return ss.str();

  	}	

  };				//end filepath

  

  class filename : public filepath{

  protected:

  	std::string _prefix;				//filename prefix

  	std::string _extension;				//filename extension

  

  	void set_filename(std::string fname){

  		size_t ext_i = fname.find_last_of('.');								//calculate the index of the '.'

  		if(ext_i != std::string::npos){											//if there is an extension

  			_prefix = fname.substr(0, ext_i);				//store the prefix

  			_extension = fname.substr(ext_i + 1, fname.size() - ext_i - 1);	//store the extension

  		}

  		else												//otherwise just store the prefix

  			_prefix = fname;

8157c392   David Mayerich   added parser and ...
172
173
  	}

  

25d8d20b   David Mayerich   added FFT support...
174
175
176
177
178
  public:

  	filename(){}

  

  	filename(stim::filepath p, std::string fname) : stim::filepath(p){

  		set_filename(fname);

8157c392   David Mayerich   added parser and ...
179
180
  	}

  

25d8d20b   David Mayerich   added FFT support...
181
182
183
  	stim::filename& operator=(const std::string s){

  		std::string unix_s = unix_div(s);					//convert dividers to unix

  		size_t name_i = unix_s.find_last_of('/');		//find the index of the last divider

8157c392   David Mayerich   added parser and ...
184
  

25d8d20b   David Mayerich   added FFT support...
185
186
187
  		if(name_i == std::string::npos){					//if there is no divider, this is just a filename

  			unix_s = "./" + unix_s;							//append a ./ to the beginning so that the working directory is used

  			name_i = 1;

8b7be670   David Mayerich   implemented savin...
188
  		}

8157c392   David Mayerich   added parser and ...
189
  

25d8d20b   David Mayerich   added FFT support...
190
  		name_i++;

8157c392   David Mayerich   added parser and ...
191
  

8157c392   David Mayerich   added parser and ...
192
  

25d8d20b   David Mayerich   added FFT support...
193
194
195
196
197
198
199
  		std::string filename = unix_s.substr(name_i, unix_s.size() - name_i);	//extract the filename

  		std::string filepath = unix_s.substr(0, name_i-1);						//extract the filepath

  

  		filepath::operator=(filepath);						//parse and store the file path

  

  		set_filename(filename);

  		return *this;

8157c392   David Mayerich   added parser and ...
200
201
  	}

  

25d8d20b   David Mayerich   added FFT support...
202
203
  	filename(std::string s){

  		operator=(s);

6422f96a   Pavel Govyadinov   minor bug fixes a...
204
205
  	}

  

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
206
207
208
  	bool is_relative(){

  		return false;

  	}

25d8d20b   David Mayerich   added FFT support...
209
210
  

  

8157c392   David Mayerich   added parser and ...
211
  	std::string str(){

25d8d20b   David Mayerich   added FFT support...
212
213
214
215
216
  		std::stringstream ss;

  		ss<<filepath::str()<<_prefix;

  		if(_extension.size() != 0)

  			ss<<"."<<_extension;

  		return ss.str();

8157c392   David Mayerich   added parser and ...
217
  	}

4191c034   Pavel Govyadinov   minor:bug fixes. ...
218
  

25d8d20b   David Mayerich   added FFT support...
219
220
221
222
223
224
  	/// Create a matching file locator with a prefix s

  	stim::filename prefix(std::string s){

  		stim::filename result = *this;

  		result._prefix = s;

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
225
  

25d8d20b   David Mayerich   added FFT support...
226
227
228
  	std::string prefix(){

  		return _prefix;

  	}

8157c392   David Mayerich   added parser and ...
229
  

25d8d20b   David Mayerich   added FFT support...
230
231
232
  	std::string get_prefix(){

  		return _prefix;

  	}

eb5dfb2b   David Mayerich   fixed linux compa...
233
  

25d8d20b   David Mayerich   added FFT support...
234
235
236
237
238
239
  	/// Create a matching file locator with the extension changed to s

  	stim::filename extension(std::string s){

  		stim::filename result = *this;

  		result._extension = s;

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
240
  

25d8d20b   David Mayerich   added FFT support...
241
242
243
  	std::string extension(){

  		return _extension;

  	}

8157c392   David Mayerich   added parser and ...
244
  

25d8d20b   David Mayerich   added FFT support...
245
246
247
248
249
250
251
252
253
254
  	stim::filename fname(std::string s){

  		stim::filename result = *this;

  		size_t ext_i = s.find_last_of('.');								//calculate the index of the '.'

  		if(ext_i != std::string::npos){											//if there is an extension

  			result._prefix = s.substr(0, ext_i);				//store the prefix

  			result._extension = s.substr(ext_i + 1, s.size() - ext_i - 1);	//store the extension

  		}

  		else												//otherwise just store the prefix

  			result._prefix = s;

  		return result;

945ee13c   Laila Saadatifard   the get_list func...
255
  	}

eb5dfb2b   David Mayerich   fixed linux compa...
256
  

25d8d20b   David Mayerich   added FFT support...
257
258
259
260
261
262
  	/// create a matching file locator with the path changed to s

  	stim::filename path(std::string s){

  		stim::filename result = *this;

  		result.parse_path(result._drive, result._path, s);

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
263
  

25d8d20b   David Mayerich   added FFT support...
264
265
266
  	std::string path(){

  		return filepath::str();

  	}

8157c392   David Mayerich   added parser and ...
267
  

25d8d20b   David Mayerich   added FFT support...
268
269
270
271
  	/// Casting operator, casts to a string

  	operator std::string(){

  		return str();

  	}

8157c392   David Mayerich   added parser and ...
272
  

25d8d20b   David Mayerich   added FFT support...
273
274
  	/// This function replaces a wildcard in the prefix with the specified string

  	stim::filename insert(std::string str){

8157c392   David Mayerich   added parser and ...
275
  

25d8d20b   David Mayerich   added FFT support...
276
277
278
279
280
281
282
283
284
285
286
  		stim::filename result = *this;				//initialize the result filename to the current filename

  		size_t loc = result._prefix.find('*');		//find a wild card in the string

  		if(loc == std::string::npos)						//if a wildcard isn't found

  			result._prefix += str;							//append the value to the prefix

  		else

  			result._prefix.replace(loc, 1, str);			//replace the wildcard with the string

  		return result;								//return the result

  	}

  

  	/// This function replaces a wildcard in the prefix with the specified integer (with a padding of n)

  	stim::filename insert(size_t i, size_t n = 2){

8157c392   David Mayerich   added parser and ...
287
  

25d8d20b   David Mayerich   added FFT support...
288
289
290
  		std::stringstream ss;

  		ss << std::setw(n) << std::setfill('0') << i;

  		return insert(ss.str());

945ee13c   Laila Saadatifard   the get_list func...
291
  	}

8157c392   David Mayerich   added parser and ...
292
  

25d8d20b   David Mayerich   added FFT support...
293
  	

4f007f77   David Mayerich   added better comm...
294
295
296
297
  	/// Returns a list of files using the current filename as a template.

  	/// For example:

  	///			C:\this\is\a\path\file*.txt

  	///		can be used as a template to find a series of files file001.txt, file002.txt, file003.txt, etc.

eb5dfb2b   David Mayerich   fixed linux compa...
298
  	std::vector<stim::filename> get_list(){

4f007f77   David Mayerich   added better comm...
299
300
  		//this is OS dependent, so we're starting with Windows

  		//the Unix version requires Boost

8157c392   David Mayerich   added parser and ...
301
  

6d242237   David Mayerich   added comments an...
302
  #ifdef _WIN32

f28202b1   David Mayerich   fixed OS interop ...
303
  

4f007f77   David Mayerich   added better comm...
304
  		HANDLE            hFind = INVALID_HANDLE_VALUE;							//allocate data structures for looping through files

945ee13c   Laila Saadatifard   the get_list func...
305
  		WIN32_FIND_DATAA   FindFileData;

4f007f77   David Mayerich   added better comm...
306
  		std::vector<stim::filename> file_list;									//initialize a list to hold all matching filenames

eb5dfb2b   David Mayerich   fixed linux compa...
307
  

25d8d20b   David Mayerich   added FFT support...
308
309
  		std::string path_string = str();

  		hFind = FindFirstFileA(path_string.c_str(), &FindFileData);		//find the first file that matches the specified file path

945ee13c   Laila Saadatifard   the get_list func...
310
  

4f007f77   David Mayerich   added better comm...
311
  		if (hFind == INVALID_HANDLE_VALUE) { 									//if there are no matching files

25d8d20b   David Mayerich   added FFT support...
312
313
  			//printf ("Invalid file handle. Error is %u.\n", GetLastError());		//print an error

  			return file_list;

eb5dfb2b   David Mayerich   fixed linux compa...
314
  		}

945ee13c   Laila Saadatifard   the get_list func...
315
  		else {

4f007f77   David Mayerich   added better comm...
316
  			std::string file_name = FindFileData.cFileName;						//save the file name

25d8d20b   David Mayerich   added FFT support...
317
  			std::string file_path = path();										//the file is in the specified directory, so save it

4f007f77   David Mayerich   added better comm...
318
  			stim::filename current_file(file_path + file_name);					//create a stim::filename structure representing this file

25d8d20b   David Mayerich   added FFT support...
319
320
321
  			if(!(FindFileData.cFileName[0] == '.' && FindFileData.cFileName[1] == '\0'))

  				file_list.push_back(current_file);									//push the new stim::filename to the file list

  

945ee13c   Laila Saadatifard   the get_list func...
322
323
  

  			// List all the other files in the directory.

4f007f77   David Mayerich   added better comm...
324
  			while (FindNextFileA(hFind, &FindFileData) != 0){ 					//iterate until there are no more matching files

25d8d20b   David Mayerich   added FFT support...
325
326
327
328
329
  				if(!(FindFileData.cFileName[0] == '.' && FindFileData.cFileName[1] == '.' && FindFileData.cFileName[2] == '\0')){	//account for the possibility of the '..' filename

  					file_name = FindFileData.cFileName;								//save the next file

  					current_file = fname(file_name);								//append the directory

  					file_list.push_back(current_file);								//push it to the list

  				}

8157c392   David Mayerich   added parser and ...
330
  			}

4f007f77   David Mayerich   added better comm...
331
  			FindClose(hFind);													//close the file data structure

43dec788   David Mayerich   added code for si...
332
  		}

4f007f77   David Mayerich   added better comm...
333
  		return file_list;														//return the list of files

4e2809fa   David Mayerich   fixed an error pr...
334
335
  

  #elif BOOST_PRECOMPILED

9b766f1f   Pavel Govyadinov   completed merge f...
336
  

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
337
  		boost::filesystem::path p(path());	//create a path from the current filename

9b766f1f   Pavel Govyadinov   completed merge f...
338
339
340
341
342
343
344
345
346
347
348
349
  		std::vector<stim::filename> file_list;

  		if(boost::filesystem::exists(p)){

  			if(boost::filesystem::is_directory(p)){

  				typedef std::vector<boost::filesystem::path> vec;             // store paths,

  				vec v;                                // so we can sort them later

  				std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(v));

  				std::sort(v.begin(), v.end());             // sort, since directory iteration

  				  // is not ordered on some file systems

  				//compare file names to the current template (look for wild cards)

  				for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it)

  				{

  					//if the filename is a wild card *or* it matches the read file name

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
350
  					if( _prefix == "*" || _prefix == (*it).filename().stem().string()){

9b766f1f   Pavel Govyadinov   completed merge f...
351
  						//if the extension is a wild card *or* it matches the read file extension

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
352
  						if( _extension == "*" || "." + _extension == (*it).filename().extension().string()){

9b766f1f   Pavel Govyadinov   completed merge f...
353
354
355
356
357
358
359
360
361
362
363
  							file_list.push_back((*it).string());	//include it in the final list

  						}

  

  					}

  

  

  

  				}

  

  			}

  

84bae1ab   David Mayerich   fixed an error pr...
364
365
  		}

  		return file_list;

4e2809fa   David Mayerich   fixed an error pr...
366
367
368
  #else

  		std::cout<<"ERROR: UNIX systems don't support file lists without the Boost precompiled libraries."<<std::endl;

  		exit(1);

788862df   Tianshu Cheng   added a BOOST_PRE...
369
  #endif

84bae1ab   David Mayerich   fixed an error pr...
370
  		

eb5dfb2b   David Mayerich   fixed linux compa...
371
  	}

25d8d20b   David Mayerich   added FFT support...
372
373
  };				//end filename

  }				//end namespace stim

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
374
  #endif