Blame view

stim/parser/filename.h 13.1 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
  

1c994463   David Mayerich   fixed root direct...
113
114
115
116
117
118
119
120
121
122
  		if(drive.size() != 0){

  			relative = false;

  		}

  		if(unix_dir.size() > 0){										//if there is a directory specified, remove surrounding slashes

  			if(unix_dir[0] == '/'){						//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[unix_dir.size()-1] == '/')

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

25d8d20b   David Mayerich   added FFT support...
123
  		}

8157c392   David Mayerich   added parser and ...
124
  

25d8d20b   David Mayerich   added FFT support...
125
126
127
128
129
130
  		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 ...
131
132
  	}

  

25d8d20b   David Mayerich   added FFT support...
133
  	

8157c392   David Mayerich   added parser and ...
134
  

25d8d20b   David Mayerich   added FFT support...
135
136
137
  public:

  	filepath(){

  		_drive = "";

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

  

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

  		*this = p;

8157c392   David Mayerich   added parser and ...
142
143
  	}

  

25d8d20b   David Mayerich   added FFT support...
144
145
146
  	filepath(const std::string s){

  		parse_path(_drive, _path, s);

  	}

8157c392   David Mayerich   added parser and ...
147
  

25d8d20b   David Mayerich   added FFT support...
148
149
150
  	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 ...
151
152
  	}

  

25d8d20b   David Mayerich   added FFT support...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  	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 ...
177
178
  	}

  

25d8d20b   David Mayerich   added FFT support...
179
180
181
182
183
  public:

  	filename(){}

  

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

  		set_filename(fname);

8157c392   David Mayerich   added parser and ...
184
185
  	}

  

25d8d20b   David Mayerich   added FFT support...
186
187
188
  	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 ...
189
  

25d8d20b   David Mayerich   added FFT support...
190
191
192
  		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...
193
  		}

8157c392   David Mayerich   added parser and ...
194
  

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

8157c392   David Mayerich   added parser and ...
196
  

8157c392   David Mayerich   added parser and ...
197
  

25d8d20b   David Mayerich   added FFT support...
198
199
200
201
202
203
204
  		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 ...
205
206
  	}

  

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

  		operator=(s);

6422f96a   Pavel Govyadinov   minor bug fixes a...
209
210
  	}

  

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
211
212
213
  	bool is_relative(){

  		return false;

  	}

25d8d20b   David Mayerich   added FFT support...
214
215
  

  

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

25d8d20b   David Mayerich   added FFT support...
217
218
219
220
221
  		std::stringstream ss;

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

  		if(_extension.size() != 0)

  			ss<<"."<<_extension;

  		return ss.str();

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

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

ec722ff9   David Mayerich   added spero mosai...
224
225
226
227
228
229
230
  	//return a string for the filename without an extension

  	std::string str_noext(){

  		std::stringstream ss;

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

  		return ss.str();

  	}

  

25d8d20b   David Mayerich   added FFT support...
231
232
233
234
235
236
  	/// 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 ...
237
  

25d8d20b   David Mayerich   added FFT support...
238
239
240
  	std::string prefix(){

  		return _prefix;

  	}

8157c392   David Mayerich   added parser and ...
241
  

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

  		return _prefix;

  	}

eb5dfb2b   David Mayerich   fixed linux compa...
245
  

25d8d20b   David Mayerich   added FFT support...
246
247
248
249
250
251
  	/// 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 ...
252
  

25d8d20b   David Mayerich   added FFT support...
253
254
255
  	std::string extension(){

  		return _extension;

  	}

8157c392   David Mayerich   added parser and ...
256
  

25d8d20b   David Mayerich   added FFT support...
257
258
259
260
261
262
263
264
265
266
  	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...
267
  	}

eb5dfb2b   David Mayerich   fixed linux compa...
268
  

25d8d20b   David Mayerich   added FFT support...
269
270
271
272
273
274
  	/// 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 ...
275
  

25d8d20b   David Mayerich   added FFT support...
276
277
278
  	std::string path(){

  		return filepath::str();

  	}

8157c392   David Mayerich   added parser and ...
279
  

25d8d20b   David Mayerich   added FFT support...
280
281
282
283
  	/// Casting operator, casts to a string

  	operator std::string(){

  		return str();

  	}

8157c392   David Mayerich   added parser and ...
284
  

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

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

8157c392   David Mayerich   added parser and ...
287
  

25d8d20b   David Mayerich   added FFT support...
288
289
290
291
292
293
294
295
296
297
298
  		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 ...
299
  

25d8d20b   David Mayerich   added FFT support...
300
301
302
  		std::stringstream ss;

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

  		return insert(ss.str());

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

8157c392   David Mayerich   added parser and ...
304
  

cfcf8619   David Mayerich   changes to filena...
305
306
307
308
309
310
311
312
313
  	///This method returns true if any characters in the filename contain '*' or '?'

  	bool wildcards() {

  		if (_prefix.find('*') != std::string::npos) return true;

  		if (_prefix.find('?') != std::string::npos) return true;

  		if (_extension.find('*') != std::string::npos) return true;

  		if (_extension.find('?') != std::string::npos) return true;

  		return false;

  	}

  

25d8d20b   David Mayerich   added FFT support...
314
  	

4f007f77   David Mayerich   added better comm...
315
316
317
318
  	/// 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...
319
  	std::vector<stim::filename> get_list(){

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

  		//the Unix version requires Boost

8157c392   David Mayerich   added parser and ...
322
  

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

f28202b1   David Mayerich   fixed OS interop ...
324
  

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

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

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

eb5dfb2b   David Mayerich   fixed linux compa...
328
  

25d8d20b   David Mayerich   added FFT support...
329
330
  		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...
331
  

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

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

  			return file_list;

eb5dfb2b   David Mayerich   fixed linux compa...
335
  		}

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

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

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

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

25d8d20b   David Mayerich   added FFT support...
340
341
342
  			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...
343
344
  

  			// List all the other files in the directory.

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

25d8d20b   David Mayerich   added FFT support...
346
347
348
349
350
  				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 ...
351
  			}

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

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

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

4e2809fa   David Mayerich   fixed an error pr...
355
356
  

  #elif BOOST_PRECOMPILED

9b766f1f   Pavel Govyadinov   completed merge f...
357
  

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

9b766f1f   Pavel Govyadinov   completed merge f...
359
360
361
362
363
364
365
366
367
368
369
370
  		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...
371
  					if( _prefix == "*" || _prefix == (*it).filename().stem().string()){

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

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

9b766f1f   Pavel Govyadinov   completed merge f...
374
375
376
377
378
379
380
381
382
383
384
  							file_list.push_back((*it).string());	//include it in the final list

  						}

  

  					}

  

  

  

  				}

  

  			}

  

84bae1ab   David Mayerich   fixed an error pr...
385
386
  		}

  		return file_list;

4e2809fa   David Mayerich   fixed an error pr...
387
388
389
  #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...
390
  #endif

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

eb5dfb2b   David Mayerich   fixed linux compa...
392
  	}

25d8d20b   David Mayerich   added FFT support...
393
394
  };				//end filename

  }				//end namespace stim

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