Branch data Line data Source code
1 : : //- Class: CubitFileUtil
2 : : //- Description: Class with functions to get files from a directory, etc.
3 : : //- Owner: Steve Storm
4 : :
5 : : #define NOMINMAX
6 : :
7 : : #include "CubitFileUtil.hpp"
8 : : #include "CubitUtil.hpp"
9 : : #include "CubitString.hpp"
10 : : #include "CubitMessage.hpp"
11 : : #include "CubitDirIterator.hpp"
12 : :
13 : : #ifdef _WIN32
14 : : #include <sys/types.h>
15 : : #include <sys/stat.h>
16 : : #include <windows.h>
17 : : #ifndef PATH_MAX
18 : : #define PATH_MAX _MAX_PATH
19 : : #endif
20 : : #include "shlwapi.h"
21 : : #else
22 : : #include <sys/types.h>
23 : : #include <sys/stat.h>
24 : : #include <dirent.h>
25 : : #include <cstdlib>
26 : : #include <sys/param.h>
27 : : #include <unistd.h>
28 : : #include <pwd.h>
29 : : #include <fnmatch.h>
30 : : #endif
31 : : #include <errno.h>
32 : : #include <string.h>
33 : :
34 : : #include <algorithm>
35 : :
36 : :
37 : : #ifdef _WIN32
38 : : static const char* DIR_SEP_STR = "\\";
39 : : static const char DIR_SEP_CHAR = '\\';
40 : : #else
41 : : static const char* DIR_SEP_STR = "/";
42 : : static const char DIR_SEP_CHAR = '/';
43 : : #endif
44 : :
45 : 0 : const char* CubitFileUtil::separator()
46 : : {
47 : 0 : return DIR_SEP_STR;
48 : : }
49 : :
50 : : CubitStatus
51 : 0 : CubitFileUtil::get_current_working_directory( CubitString& wd )
52 : : {
53 : : #ifdef _WIN32
54 : : wchar_t* buffer = _wgetcwd( NULL, 0 );
55 : : #else
56 : 0 : char* buffer = getcwd( NULL, 0 );
57 : : #endif
58 [ # # ]: 0 : if (!buffer)
59 : : {
60 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to get new working directory\n" );
61 : 0 : return CUBIT_FAILURE;
62 : : }
63 : : else
64 : : {
65 : : // convert to string
66 : : #ifdef _WIN32
67 : : wd = CubitString::toUtf8(buffer);
68 : : #else
69 [ # # ]: 0 : wd = buffer;
70 : : #endif
71 : :
72 : : // Add a slash at the end, if not already there
73 : 0 : int wd_len = wd.length();
74 [ # # ]: 0 : if( wd.c_str()[wd_len-1] != DIR_SEP_CHAR )
75 : : {
76 [ # # ]: 0 : wd += DIR_SEP_STR;
77 : :
78 : 0 : free(buffer);
79 : : }
80 : :
81 : : // TODO: need to figure out the right way to do this. This assumes
82 : : // variables of length PATH_MAX which is bad!
83 : : //#ifdef _WIN32
84 : : // // Make sure format is compatible with full path format
85 : : // CubitString full_path_str;
86 : : // if( get_full_path_str( wd, full_path_str ) == CUBIT_SUCCESS )
87 : : // strcpy( wd, full_path_str.c_str() );
88 : : //#endif
89 : :
90 : 0 : return CUBIT_SUCCESS;
91 : : }
92 : : }
93 : :
94 : 0 : CubitStatus CubitFileUtil::set_current_working_directory( const CubitString& wd )
95 : : {
96 : : #ifdef _WIN32
97 : : int ret = _wchdir(CubitString::toUtf16(wd).c_str());
98 : : #else
99 : 0 : int ret = chdir(wd.c_str());
100 : : #endif
101 [ # # ]: 0 : return ret == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
102 : : }
103 : :
104 : 0 : CubitString CubitFileUtil::add_name_to_path( const CubitString& path, const CubitString& name )
105 : : {
106 : 0 : CubitString result = path;
107 : : // Add a slash at the end of the path, if not already there
108 [ # # ]: 0 : int path_len = result.length();
109 [ # # ][ # # ]: 0 : if( result.c_str()[path_len-1] != DIR_SEP_CHAR )
110 : : {
111 [ # # ][ # # ]: 0 : result += DIR_SEP_STR;
[ # # ]
112 : : }
113 : : // append the name to the end of the path
114 [ # # ]: 0 : result += name;
115 : :
116 : 0 : return result;
117 : : }
118 : :
119 : 0 : CubitString CubitFileUtil::find_home_path(const CubitString& which_user)
120 : : {
121 : 0 : CubitString home_dir;
122 : :
123 : : #ifdef _WIN32
124 : : home_dir = CubitUtil::getenv("USERPROFILE");
125 : : #else
126 [ # # ][ # # ]: 0 : if(which_user.length() == 0)
127 : : {
128 [ # # ][ # # ]: 0 : home_dir = CubitUtil::getenv("HOME");
[ # # ][ # # ]
[ # # ]
129 [ # # ][ # # ]: 0 : if( home_dir.length() == 0 )
130 : : {
131 [ # # ]: 0 : struct passwd* userdata = getpwuid( getuid() );
132 [ # # ]: 0 : if( userdata )
133 [ # # ][ # # ]: 0 : home_dir = userdata->pw_dir;
[ # # ]
134 : : }
135 : : }
136 : : else
137 : : {
138 [ # # ][ # # ]: 0 : struct passwd* userdata = getpwnam( which_user.c_str() );
139 [ # # ]: 0 : if(userdata)
140 [ # # ][ # # ]: 0 : home_dir = userdata->pw_dir;
[ # # ]
141 : : }
142 : : #endif
143 : :
144 : 0 : return home_dir;
145 : : }
146 : :
147 : : CubitStatus
148 : 0 : CubitFileUtil::create_directory( const CubitString& wd )
149 : : {
150 : : // Create the directory
151 : : #ifdef _WIN32
152 : : if (_wmkdir(CubitString::toUtf16(wd).c_str()) == -1)
153 : : {
154 : : PRINT_WARNING( "Unable to create new directory\n" );
155 : : return CUBIT_FAILURE;
156 : : }
157 : : #else
158 [ # # ]: 0 : if (mkdir(wd.c_str(), 0777) == -1)
159 : : {
160 [ # # ][ # # ]: 0 : PRINT_WARNING( "Unable to create new directory\n" );
161 : 0 : return CUBIT_FAILURE;
162 : : }
163 : : #endif
164 : 0 : return CUBIT_SUCCESS;
165 : : }
166 : :
167 : :
168 : 0 : CubitStatus CubitFileUtil::remove_file( const CubitString& file )
169 : : {
170 : : #ifdef _WIN32
171 : : int status = _wremove(CubitString::toUtf16(file).c_str());
172 : : #else
173 : 0 : int status = remove(file.c_str());
174 : : #endif
175 [ # # ]: 0 : return status == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
176 : : }
177 : :
178 : 0 : CubitStatus CubitFileUtil::rename_file( const CubitString& old_file, const CubitString& new_file )
179 : : {
180 : : #ifdef _WIN32
181 : : int status = _wrename(CubitString::toUtf16(old_file).c_str(), CubitString::toUtf16(new_file).c_str());
182 : : #else
183 : 0 : int status = rename(old_file.c_str(), new_file.c_str());
184 : : #endif
185 [ # # ]: 0 : return status == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
186 : : }
187 : :
188 : : CubitStatus
189 : 0 : CubitFileUtil::get_full_path_str( const CubitString& part,
190 : : CubitString &full_path_str )
191 : : {
192 [ # # ]: 0 : CubitString my_part = CubitFileUtil::make_path_platform_compatible(part);
193 : :
194 : : #ifdef _WIN32
195 : :
196 : : wchar_t* full = _wfullpath(NULL, CubitString::toUtf16(my_part).c_str(), 0);
197 : : if(!full)
198 : : {
199 : : PRINT_ERROR( "problem getting full path to %s\n", part.c_str() );
200 : : return CUBIT_FAILURE;
201 : : }
202 : : full_path_str = CubitString::toUtf8(full);
203 : : free(full);
204 : :
205 : : #else
206 : :
207 : : // we loop removing parts until realpath can resolve an existing path,
208 : : // then add the non-existing parts back on.
209 : :
210 [ # # ][ # # ]: 0 : std::vector<CubitString> split_parts;
211 [ # # ][ # # ]: 0 : CubitString trypart = part;
212 : :
213 [ # # ][ # # ]: 0 : if(!CubitFileUtil::is_absolute(trypart))
214 : : {
215 [ # # ]: 0 : CubitString cwd;
216 [ # # ]: 0 : CubitFileUtil::get_current_working_directory(cwd);
217 [ # # ][ # # ]: 0 : trypart = CubitFileUtil::add_name_to_path(cwd, trypart);
[ # # ][ # # ]
218 : : }
219 : :
220 : : char full[PATH_MAX];
221 [ # # ][ # # ]: 0 : while(trypart.length() && !realpath(trypart.c_str(), full))
[ # # ][ # # ]
[ # # ]
222 : : {
223 [ # # ][ # # ]: 0 : CubitString split_part1, split_part2;
[ # # ][ # # ]
224 [ # # ]: 0 : CubitFileUtil::split_path(trypart, split_part1, split_part2);
225 [ # # ]: 0 : split_parts.push_back(split_part2);
226 [ # # ][ # # ]: 0 : if(split_part1.length() == 0)
227 : : {
228 [ # # ][ # # ]: 0 : PRINT_ERROR( "problem getting full path to %s\n", part.c_str() );
[ # # ][ # # ]
[ # # ]
229 : 0 : return CUBIT_FAILURE;
230 : : }
231 [ # # ][ # # ]: 0 : trypart = split_part1;
[ # # ]
232 : 0 : }
233 : :
234 [ # # ][ # # ]: 0 : full_path_str = full;
[ # # ]
235 [ # # ][ # # ]: 0 : for(size_t i=0; i<split_parts.size(); i++)
236 : : {
237 [ # # ][ # # ]: 0 : full_path_str += CubitString("/") + split_parts[split_parts.size() - i - 1];
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
238 : : }
239 : :
240 : : #endif
241 : :
242 [ # # ]: 0 : return CUBIT_SUCCESS;
243 : : }
244 : :
245 : : CubitString
246 : 0 : CubitFileUtil::make_path_platform_compatible( const CubitString& path)
247 : : {
248 : 0 : CubitString ret = path;
249 [ # # ][ # # ]: 0 : for(size_t i=0; i<ret.length(); i++)
250 : : {
251 : : #ifdef _WIN32
252 : : // Replace '/' with '\\'
253 : : if(ret.get_at(i) == '/' )
254 : : ret.put_at(i, '\\');
255 : : #else
256 : : // Replace '\\' with '/'
257 [ # # ][ # # ]: 0 : if(ret.get_at(i) == '\\' )
258 [ # # ]: 0 : ret.put_at(i, '/');
259 : : #endif
260 : : }
261 : 0 : return ret;
262 : : }
263 : :
264 : : CubitString
265 : 0 : CubitFileUtil::get_nice_filename( const CubitString& path )
266 : : {
267 [ # # ]: 0 : CubitString ret_str;
268 : :
269 [ # # ][ # # ]: 0 : CubitString dpart_in, fpart_in;
[ # # ][ # # ]
270 [ # # ]: 0 : split_path( path, dpart_in, fpart_in );
271 : :
272 [ # # ][ # # ]: 0 : CubitString wd;
273 [ # # ]: 0 : get_current_working_directory( wd );
274 : :
275 [ # # ][ # # ]: 0 : if( dpart_in == wd )
276 [ # # ]: 0 : ret_str = fpart_in;
277 : : else
278 [ # # ]: 0 : ret_str = path;
279 : :
280 : 0 : return ret_str;
281 : : }
282 : :
283 : : void
284 : 0 : CubitFileUtil::split_path( const CubitString& path, CubitString& dirpart, CubitString& filepart )
285 : : {
286 [ # # ]: 0 : CubitString mypath = path;
287 [ # # ][ # # ]: 0 : while(mypath.length() && mypath.get_at(mypath.length()-1) == DIR_SEP_CHAR)
[ # # ][ # # ]
[ # # ][ # # ]
288 : : {
289 [ # # ][ # # ]: 0 : mypath = mypath.substr(0, mypath.length()-1);
[ # # ][ # # ]
290 : : }
291 [ # # ]: 0 : size_t pos = mypath.find_last(DIR_SEP_CHAR);
292 : :
293 : : // No separator - could be filename or directory. We assume
294 : : // it's a directory.
295 [ # # ]: 0 : if(pos == CubitString::npos)
296 : : {
297 [ # # ][ # # ]: 0 : filepart = ".";
[ # # ]
298 [ # # ]: 0 : dirpart = mypath;
299 : : }
300 : : else
301 : : {
302 [ # # ][ # # ]: 0 : filepart = mypath.substr(pos+1);
[ # # ]
303 [ # # ][ # # ]: 0 : dirpart = mypath.substr(0, pos);
[ # # ]
304 : : }
305 : :
306 : : // Add slash on end of dirpart if not already there
307 [ # # ][ # # ]: 0 : if(dirpart.length() && dirpart.get_at(dirpart.length()-1) != DIR_SEP_CHAR)
[ # # ][ # # ]
[ # # ][ # # ]
308 [ # # ][ # # ]: 0 : dirpart += DIR_SEP_STR;
[ # # ]
309 : :
310 [ # # ]: 0 : return;
311 : : }
312 : :
313 : :
314 : : CubitString
315 : 0 : CubitFileUtil::get_file_extension(
316 : : const CubitString& file,
317 : : bool remove_version /* remove .1, .2, ...*/ )
318 : : {
319 [ # # ]: 0 : size_t dot_pos = file.find_last('.');
320 : 0 : size_t dot_pos2 = 0;
321 : :
322 [ # # ]: 0 : if ( dot_pos == CubitString::npos )
323 [ # # ]: 0 : return "";
324 : :
325 [ # # ]: 0 : if(remove_version)
326 : : {
327 [ # # ]: 0 : dot_pos2 = file.find_last('.',dot_pos);
328 [ # # ]: 0 : if ( dot_pos2 == CubitString::npos )
329 : 0 : remove_version = false;
330 [ # # ][ # # ]: 0 : else if(!is_int_number( file.substr(dot_pos+1).c_str() ))
[ # # ][ # # ]
[ # # ]
331 : 0 : remove_version = false;
332 : : }
333 : :
334 [ # # ]: 0 : CubitString extension;
335 [ # # ]: 0 : if(!remove_version)
336 [ # # ][ # # ]: 0 : extension = file.substr(dot_pos);
[ # # ]
337 : : else
338 [ # # ][ # # ]: 0 : extension = file.substr(dot_pos2,dot_pos-dot_pos2);
[ # # ]
339 : :
340 [ # # ][ # # ]: 0 : for ( size_t i = 0; i < extension.length(); i++ )
341 [ # # ][ # # ]: 0 : extension.put_at(i, tolower( extension.get_at(i) ) );
342 : :
343 [ # # ][ # # ]: 0 : return extension;
344 : :
345 : : } // get_file_extension()
346 : :
347 : : CubitBoolean
348 : 0 : CubitFileUtil::all_chars_are( char ch, const char *str )
349 : : {
350 [ # # ]: 0 : while( *str )
351 [ # # ]: 0 : if( *str++ != ch )
352 : 0 : return CUBIT_FALSE;
353 : 0 : return CUBIT_TRUE;
354 : : }
355 : :
356 : : CubitBoolean
357 : 0 : CubitFileUtil::is_int_number( const char *str )
358 : : {
359 [ # # ]: 0 : while( *str )
360 [ # # ]: 0 : if( !isdigit(*str++) )
361 : 0 : return CUBIT_FALSE;
362 : 0 : return CUBIT_TRUE;
363 : : }
364 : :
365 : : CubitBoolean
366 : 0 : CubitFileUtil::contains_char( char ch, const char *str )
367 : : {
368 [ # # ]: 0 : while( *str )
369 [ # # ]: 0 : if( *str++ == ch )
370 : 0 : return CUBIT_TRUE;
371 : 0 : return CUBIT_FALSE;
372 : : }
373 : :
374 : : //CubitString
375 : : //CubitFileUtil::get_default_cubit_file_name()
376 : : //{
377 : : // // Get a list of all files matching 'cubit*.cub', in current directory
378 : :
379 : : // CubitDirIterator dir_iter(".", "cubit*.cub");
380 : :
381 : : // int max_number = 0;
382 : :
383 : : // while(dir_iter.has_next())
384 : : // {
385 : : // CubitString f = dir_iter.next();
386 : :
387 : : // // cut off the "cubit" at the start and the ".cub" at the end
388 : : // f = f.substr(5, f.length()-9);
389 : : // if( is_int_number(f.c_str()) )
390 : : // {
391 : : // int num = atoi(f.c_str());
392 : : // max_number = std::max(num, max_number);
393 : : // }
394 : : // }
395 : :
396 : : // max_number++;
397 : :
398 : : // CubitString num_str = CubitString::number(max_number);
399 : : // if(max_number < 10)
400 : : // num_str = CubitString("0") + num_str;
401 : :
402 : : // return CubitString("cubit") + num_str + CubitString(".cub");
403 : : //}
404 : :
405 : : int
406 : 0 : CubitFileUtil::get_next_filenumber( const CubitString& file_pattern,
407 : : int &num_matches,
408 : : int &first_id )
409 : : {
410 : : // TODO: check this bug?
411 : : // Continue if nothing after dot. Also, I noticed the _WIN32 will match
412 : : // file.cub against wildcard file.cub.*
413 : :
414 : 0 : int max_number = 0;
415 : 0 : int min_number = CUBIT_INT_MAX;
416 : 0 : num_matches = 0;
417 : :
418 : : // get directory and file parts
419 [ # # ][ # # ]: 0 : CubitString dir, file, full_file_pattern;
[ # # ][ # # ]
[ # # ]
420 [ # # ]: 0 : CubitFileUtil::get_full_path_str(file_pattern, full_file_pattern);
421 [ # # ]: 0 : CubitFileUtil::split_path(full_file_pattern, dir, file);
422 : :
423 [ # # ][ # # ]: 0 : size_t wildcard_location = file.find("*");
[ # # ]
424 [ # # ]: 0 : if(wildcard_location == CubitString::npos)
425 : 0 : return 1;
426 : :
427 [ # # ][ # # ]: 0 : CubitDirIterator dir_iter(dir, file);
428 : :
429 [ # # ][ # # ]: 0 : while(dir_iter.has_next())
430 : : {
431 [ # # ]: 0 : CubitString f = dir_iter.next();
432 : :
433 : : // cut off the matched part
434 [ # # ][ # # ]: 0 : f = f.substr(wildcard_location, 1 + f.length() - file.length());
[ # # ][ # # ]
[ # # ]
435 [ # # ][ # # ]: 0 : if( is_int_number(f.c_str()) )
[ # # ]
436 : : {
437 [ # # ]: 0 : int num = atoi(f.c_str());
438 [ # # ]: 0 : max_number = std::max(num, max_number);
439 [ # # ]: 0 : min_number = std::min(num, min_number);
440 : : }
441 : 0 : num_matches++;
442 [ # # ]: 0 : }
443 : :
444 [ # # ]: 0 : if( min_number != CUBIT_INT_MAX )
445 : 0 : first_id = min_number;
446 : :
447 [ # # ]: 0 : return max_number+1;
448 : : }
449 : :
450 : 0 : bool CubitFileUtil::is_directory(const CubitString& path)
451 : : {
452 : : off_t size;
453 : : time_t time;
454 : 0 : int mode = 0;
455 [ # # ][ # # ]: 0 : if(0 == file_info(path, size, time, mode))
456 : : {
457 : : #ifdef _WIN32
458 : : if( (_S_IFDIR & mode) )
459 : : #else
460 [ # # ]: 0 : if( S_ISDIR( mode ) )
461 : : #endif
462 : : {
463 : 0 : return true;
464 : : }
465 : : }
466 : 0 : return false;
467 : : }
468 : :
469 : 0 : bool CubitFileUtil::path_exists(const CubitString& path)
470 : : {
471 : : off_t size;
472 : : time_t time;
473 : : int mode;
474 [ # # ]: 0 : return 0 == file_info(path, size, time, mode);
475 : : }
476 : :
477 : 0 : bool CubitFileUtil::is_absolute(const CubitString& path)
478 : : {
479 : : #ifdef _WIN32
480 : : return !PathIsRelativeW(CubitString::toUtf16(path).c_str());
481 : : #else
482 : 0 : return path.c_str()[0] == '/' ? true : false;
483 : : #endif
484 : : }
485 : :
486 : 0 : int CubitFileUtil::file_info(const CubitString& path, off_t& size, time_t& time, int& mode)
487 : : {
488 : : #ifdef _WIN32
489 : : // remove trailing separators
490 : : CubitString mypath = path;
491 : : if(mypath.length() >= 1 && mypath.get_at(mypath.length()-1) == DIR_SEP_CHAR)
492 : : mypath = mypath.substr(0, mypath.length()-1);
493 : : struct _stati64 file_info;
494 : : int stat_result = _wstati64( CubitString::toUtf16(mypath).c_str(), &file_info );
495 : : #else
496 : : struct stat file_info;
497 [ # # ]: 0 : int stat_result = lstat( path.c_str(), &file_info );
498 : : #endif
499 : :
500 [ # # ]: 0 : if(stat_result == 0)
501 : : {
502 : 0 : size = file_info.st_size;
503 : 0 : time = file_info.st_mtime;
504 : 0 : mode = file_info.st_mode;
505 : 0 : return 0;
506 : : }
507 [ # # ]: 0 : return errno ? errno : ENOENT;
508 : : }
509 : :
510 : 0 : int CubitFileUtil::complete_filename(CubitString& line, int& num_additional_chars, bool& found_quote)
511 : : {
512 : : // save the original length
513 [ # # ]: 0 : num_additional_chars = line.length();
514 [ # # ]: 0 : char* buffer = (char*) line.c_str();
515 : :
516 : : char *ptr_from;
517 [ # # ][ # # ]: 0 : if ( (ptr_from = strrchr(buffer, '\'')) == NULL &&
[ # # ]
518 : : (ptr_from = strrchr(buffer, '\"')) == NULL)
519 : : {
520 : 0 : return -1;
521 : : }
522 : :
523 : 0 : ptr_from++; // skip past the single/double quote
524 : :
525 : : // Separate the directory portion from the filename portion (if any)
526 : : char *file;
527 : : char *path;
528 : :
529 : : #ifndef _WIN32
530 [ # # ]: 0 : if ((file = strrchr(ptr_from, '/')) == NULL) // No path
531 : : {
532 : 0 : path = strdup(".");
533 : 0 : file = strdup(ptr_from);
534 : : }
535 [ # # ]: 0 : else if (file == ptr_from)
536 : : {
537 : 0 : path = strdup("/");
538 : 0 : file = strdup(ptr_from + 1);
539 : : }
540 : : else
541 : : {
542 : 0 : path = strdup(ptr_from);
543 : 0 : char *end = strrchr(path, '/');
544 : 0 : *end = '\0';
545 : 0 : ++file;
546 : 0 : file = strdup(file);
547 : :
548 [ # # ]: 0 : if ( *path == '~' )
549 : : {
550 : 0 : const char *home = getenv("HOME");
551 [ # # ]: 0 : if( !home )
552 : : {
553 [ # # ]: 0 : struct passwd* userdata = getpwuid( getuid() );
554 [ # # ]: 0 : if( userdata )
555 : 0 : home = userdata->pw_dir;
556 : : }
557 : 0 : char *after_tilde = path;
558 : 0 : after_tilde++;
559 [ # # ]: 0 : std::string new_path = home;
560 [ # # ]: 0 : new_path += after_tilde;
561 : 0 : free(path);
562 [ # # ][ # # ]: 0 : path = strdup( new_path.c_str() );
563 : : }
564 : :
565 : : }
566 : : #else
567 : : file = strrchr(ptr_from, '\\');
568 : : bool slash = 0;
569 : : if(file == NULL)
570 : : {
571 : : slash = 1;
572 : : file = strrchr(ptr_from, '/');
573 : : }
574 : : if(file == NULL)
575 : : // if ((file = strrchr(ptr_from, '\\')) == NULL
576 : : // && file = strrchr(ptr_from, '/') == NULL) // No path
577 : : {
578 : : path = strdup(".");
579 : : file = strdup(ptr_from);
580 : : }
581 : : else if (file == ptr_from)
582 : : {
583 : : path = strdup("\\");
584 : : file = strdup(ptr_from + 1);
585 : : }
586 : : else
587 : : {
588 : : path = strdup(ptr_from);
589 : : char *end;
590 : : if(slash)
591 : : end = strrchr(path, '/');
592 : : else
593 : : end = strrchr(path, '\\');
594 : :
595 : : *end = '\0';
596 : : ++file;
597 : : file = strdup(file);
598 : : }
599 : : #endif
600 : : // Determine what type of files to match (suffix_strings)
601 : : // Need to lowercase keyword and identifier.....
602 : 0 : char *tmp_str = strdup(buffer);
603 : 0 : char *keyword = strtok(tmp_str, " \t");
604 [ # # ]: 0 : CubitUtil::convert_string_to_lowercase(keyword);
605 : 0 : int lenkey = strlen(keyword);
606 [ # # ]: 0 : std::vector<std::string> suffix_strings;
607 : :
608 [ # # ][ # # ]: 0 : if ((strncmp("import", keyword, lenkey) == 0) ||
609 : 0 : (strncmp("export", keyword, lenkey) == 0))
610 : : {
611 : 0 : char *identifier = strtok(NULL, " \t");
612 [ # # ]: 0 : CubitUtil::convert_string_to_lowercase(identifier);
613 : 0 : int lenid = strlen(identifier);
614 : :
615 : : //Let's set up a vector of strings
616 [ # # ][ # # ]: 0 : std::vector<std::string> acis_strings, cubfile_strings,iges_strings,
[ # # ][ # # ]
[ # # ]
617 [ # # ][ # # ]: 0 : catia_strings,proe_strings,step_strings,fastq_strings, mesh_strings,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
618 [ # # ][ # # ]: 0 : facet_strings, avs_strings, stl_strings, ideas_strings, abaqus_strings,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
619 [ # # ][ # # ]: 0 : nastran_strings, presto_strings;
[ # # ][ # # ]
620 : :
621 [ # # ][ # # ]: 0 : iges_strings.push_back(".igs");
[ # # ]
622 [ # # ][ # # ]: 0 : iges_strings.push_back(".iges");
[ # # ]
623 : :
624 : :
625 : : #ifdef GRANITE
626 : : proe_strings.push_back(".prt");
627 : : proe_strings.push_back(".asm");
628 : : proe_strings.push_back(".prt.");
629 : : proe_strings.push_back(".asm.");
630 : : proe_strings.push_back(".g");
631 : : #endif
632 : : #ifdef CATIA
633 : : catia_strings.push_back(".catpart");
634 : : catia_strings.push_back(".catproduct");
635 : : catia_strings.push_back(".ncgm");
636 : : #endif
637 : :
638 [ # # ][ # # ]: 0 : step_strings.push_back(".stp");
[ # # ]
639 [ # # ][ # # ]: 0 : step_strings.push_back(".step");
[ # # ]
640 : :
641 [ # # ][ # # ]: 0 : fastq_strings.push_back(".fsq");
[ # # ]
642 : :
643 [ # # ][ # # ]: 0 : mesh_strings.push_back(".g");
[ # # ]
644 [ # # ][ # # ]: 0 : mesh_strings.push_back(".e");
[ # # ]
645 [ # # ][ # # ]: 0 : mesh_strings.push_back(".exo");
[ # # ]
646 [ # # ][ # # ]: 0 : mesh_strings.push_back(".exoII");
[ # # ]
647 [ # # ][ # # ]: 0 : mesh_strings.push_back(".gen");
[ # # ]
648 : :
649 [ # # ][ # # ]: 0 : facet_strings.push_back(".facets");
[ # # ]
650 [ # # ][ # # ]: 0 : facet_strings.push_back(".facet");
[ # # ]
651 [ # # ][ # # ]: 0 : facet_strings.push_back(".fac");
[ # # ]
652 [ # # ][ # # ]: 0 : facet_strings.push_back(".off");
[ # # ]
653 [ # # ][ # # ]: 0 : facet_strings.push_back(".OFF");
[ # # ]
654 : :
655 [ # # ][ # # ]: 0 : avs_strings.push_back(".avs");
[ # # ]
656 : :
657 [ # # ][ # # ]: 0 : stl_strings.push_back(".stl");
[ # # ]
658 : :
659 [ # # ][ # # ]: 0 : ideas_strings.push_back(".unv");
[ # # ]
660 : :
661 [ # # ][ # # ]: 0 : abaqus_strings.push_back(".inp");
[ # # ]
662 : :
663 [ # # ][ # # ]: 0 : nastran_strings.push_back(".bdf");
[ # # ]
664 : :
665 [ # # ][ # # ]: 0 : presto_strings.push_back(".i");
[ # # ]
666 : :
667 [ # # ]: 0 : if (strncmp("iges", identifier, lenid) == 0)
668 : : {
669 [ # # ][ # # ]: 0 : suffix_strings.assign(iges_strings.begin(), iges_strings.end());
[ # # ]
670 : : }
671 : :
672 : :
673 : : #ifdef CATIA
674 : : else if (strncmp("catia", identifier, lenid) == 0)
675 : : {
676 : : suffix_strings.assign(catia_strings.begin(), catia_strings.end());
677 : : }
678 : : #endif
679 : :
680 : : #ifdef GRANITE
681 : : else if (strncmp("proe", identifier, lenid) == 0)
682 : : {
683 : : suffix_strings.assign(proe_strings.begin(), proe_strings.end());
684 : : }
685 : : #endif
686 [ # # ]: 0 : else if (strncmp("step", identifier, lenid) == 0)
687 : : {
688 [ # # ][ # # ]: 0 : suffix_strings.assign(step_strings.begin(), step_strings.end());
[ # # ]
689 : : }
690 [ # # ]: 0 : else if (strncmp("fastq", identifier, lenid) == 0)
691 : : {
692 [ # # ][ # # ]: 0 : suffix_strings.assign(fastq_strings.begin(), fastq_strings.end());
[ # # ]
693 : : }
694 [ # # ][ # # ]: 0 : else if ( strncmp("mesh", identifier, lenid) == 0 ||
695 : 0 : strncmp("free", identifier, lenid) == 0 )
696 : : {
697 [ # # ][ # # ]: 0 : suffix_strings.assign(mesh_strings.begin(), mesh_strings.end());
[ # # ]
698 : : }
699 [ # # ]: 0 : else if (strncmp("facets", identifier, lenid) == 0)
700 : : {
701 [ # # ][ # # ]: 0 : suffix_strings.assign(facet_strings.begin(), facet_strings.end());
[ # # ]
702 : : }
703 [ # # ]: 0 : else if (strncmp("avs", identifier, lenid) == 0)
704 : : {
705 [ # # ][ # # ]: 0 : suffix_strings.assign(avs_strings.begin(), avs_strings.end());
[ # # ]
706 : : }
707 [ # # ]: 0 : else if (strncmp("stl", identifier, lenid) == 0)
708 : : {
709 [ # # ][ # # ]: 0 : suffix_strings.assign(stl_strings.begin(), stl_strings.end());
[ # # ]
710 : : }
711 [ # # ]: 0 : else if (strncmp("ideas", identifier, lenid) == 0)
712 : : {
713 [ # # ][ # # ]: 0 : suffix_strings.assign(ideas_strings.begin(), ideas_strings.end());
[ # # ]
714 : : }
715 [ # # ]: 0 : else if (strncmp("abaqus", identifier, lenid) == 0)
716 : : {
717 [ # # ][ # # ]: 0 : suffix_strings.assign(abaqus_strings.begin(), abaqus_strings.end());
[ # # ]
718 : : }
719 [ # # ]: 0 : else if (strncmp("nastran", identifier, lenid) == 0)
720 : : {
721 [ # # ][ # # ]: 0 : suffix_strings.assign(nastran_strings.begin(), nastran_strings.end());
[ # # ]
722 : : }
723 [ # # ]: 0 : else if (strncmp("presto", identifier, lenid) == 0)
724 : : {
725 [ # # ][ # # ]: 0 : suffix_strings.assign(presto_strings.begin(), presto_strings.end());
[ # # ]
726 : : }
727 : : else //user didn't specify anything, so let's add them all
728 : : {
729 [ # # ][ # # ]: 0 : suffix_strings.assign(acis_strings.begin(),acis_strings.end());
[ # # ]
730 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),cubfile_strings.begin(), cubfile_strings.end());
[ # # ][ # # ]
731 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),iges_strings.begin(), iges_strings.end());
[ # # ][ # # ]
732 : :
733 : :
734 : : #ifdef CATIA
735 : : suffix_strings.insert(suffix_strings.end(),catia_strings.begin(), catia_strings.end());
736 : : #endif
737 : :
738 : : #ifdef GRANITE
739 : : suffix_strings.insert(suffix_strings.end(),proe_strings.begin(), proe_strings.end());
740 : : #endif
741 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),step_strings.begin(), step_strings.end());
[ # # ][ # # ]
742 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),fastq_strings.begin(), fastq_strings.end());
[ # # ][ # # ]
743 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),mesh_strings.begin(), mesh_strings.end());
[ # # ][ # # ]
744 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),facet_strings.begin(), facet_strings.end());
[ # # ][ # # ]
745 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),avs_strings.begin(), avs_strings.end());
[ # # ][ # # ]
746 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),stl_strings.begin(), stl_strings.end());
[ # # ][ # # ]
747 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),ideas_strings.begin(), ideas_strings.end());
[ # # ][ # # ]
748 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),abaqus_strings.begin(), abaqus_strings.end());
[ # # ][ # # ]
749 [ # # ][ # # ]: 0 : suffix_strings.insert(suffix_strings.end(),nastran_strings.begin(), nastran_strings.end());
[ # # ][ # # ]
750 [ # # ]: 0 : }
751 : : }
752 [ # # ]: 0 : else if (strncmp("open", keyword, lenkey) == 0)
753 : : {
754 [ # # ][ # # ]: 0 : suffix_strings.push_back(".cub"); // Not an actual suffix, just an indicator
[ # # ]
755 : : }
756 [ # # ][ # # ]: 0 : else if (strncmp("playback", keyword, lenkey) == 0 ||
757 : 0 : strncmp("record", keyword, lenkey) == 0)
758 : : {
759 [ # # ][ # # ]: 0 : suffix_strings.push_back(".jou");
[ # # ]
760 [ # # ][ # # ]: 0 : suffix_strings.push_back(".test");
[ # # ]
761 [ # # ][ # # ]: 0 : suffix_strings.push_back(".cubit");
[ # # ]
762 : : }
763 [ # # ]: 0 : else if (strncmp("hardcopy", keyword, lenkey) == 0)
764 : : {
765 [ # # ][ # # ]: 0 : suffix_strings.push_back(".ps");
[ # # ]
766 : : }
767 [ # # ]: 0 : else if (strncmp("cd", keyword, lenkey) == 0)
768 : : {
769 [ # # ][ # # ]: 0 : suffix_strings.push_back("/"); // Not an actual suffix, just an indicator
[ # # ]
770 : : }
771 : : else
772 : : {
773 [ # # ][ # # ]: 0 : suffix_strings.push_back("\0");
[ # # ]
774 : : }
775 : :
776 : 0 : free(tmp_str);
777 : :
778 [ # # ][ # # ]: 0 : CubitString tmp_line(buffer);
779 [ # # ][ # # ]: 0 : CubitString match = CubitFileUtil::list_matching_files(path, file, suffix_strings, tmp_line);
[ # # ][ # # ]
780 : :
781 [ # # ][ # # ]: 0 : if (match.length())
782 : : {
783 : 0 : int file_length = strlen(file);
784 [ # # ][ # # ]: 0 : match = match.c_str() + file_length;
[ # # ][ # # ]
785 [ # # ]: 0 : tmp_line += match;
786 [ # # ][ # # ]: 0 : if (tmp_line.find("\'") != CubitString::npos)
[ # # ][ # # ]
787 [ # # ][ # # ]: 0 : tmp_line += "\'";
[ # # ]
788 [ # # ][ # # ]: 0 : else if (tmp_line.find("\"") != CubitString::npos)
[ # # ][ # # ]
789 [ # # ][ # # ]: 0 : tmp_line += "\" ";
[ # # ]
790 : : else
791 : : {
792 [ # # ][ # # ]: 0 : PRINT_ERROR("INTERNAL ERROR: CubitFileUtil::complete_file -- Could not find "
[ # # ]
793 [ # # ]: 0 : "quote type.");
794 [ # # ][ # # ]: 0 : tmp_line += "\' ";
[ # # ]
795 : : }
796 : : //gl_in_quoted_string = !gl_in_quoted_string;
797 : : //gl_fixup(gl_pos, gl_pos+additional_char);
798 : 0 : found_quote = !found_quote;
799 : : }
800 [ # # ]: 0 : line = tmp_line;
801 : 0 : free(path);
802 : 0 : free(file);
803 : : //gl_redraw();
804 [ # # ]: 0 : num_additional_chars = line.length() - num_additional_chars;
805 : :
806 [ # # ]: 0 : return 1;
807 : : }
808 : :
809 : 0 : CubitString CubitFileUtil::list_matching_files(const char *path, const char *file, std::vector<std::string> suffixes, CubitString& line)
810 : : {
811 [ # # ]: 0 : CubitString filename;
812 : : size_t len;
813 : 0 : int match = 0;
814 : 0 : int width = 0;
815 [ # # ][ # # ]: 0 : CubitString match_file;
816 [ # # ][ # # ]: 0 : CubitString char_match;
817 : 0 : CubitBoolean list_files = CUBIT_FALSE;
818 : 0 : CubitBoolean dir_only = CUBIT_FALSE;
819 : 0 : CubitBoolean is_dir = CUBIT_FALSE;
820 : :
821 [ # # ][ # # ]: 0 : CubitDirIterator dirp(path);
[ # # ][ # # ]
[ # # ][ # # ]
822 : :
823 [ # # ][ # # ]: 0 : if (!dirp.has_next())
824 : : {
825 [ # # ][ # # ]: 0 : PRINT_INFO("\n");
[ # # ][ # # ]
826 [ # # ][ # # ]: 0 : PRINT_ERROR("Invalid Directory: '%s'\n",
[ # # ]
827 [ # # ]: 0 : path);
828 [ # # ]: 0 : return "";
829 : : }
830 : :
831 : : // If we're looking for directories only, indicate it
832 [ # # ][ # # ]: 0 : if (suffixes.size() > 0 && suffixes.front() == "/")
[ # # ][ # # ]
[ # # ][ # # ]
833 : : {
834 : 0 : dir_only = CUBIT_TRUE;
835 : : }
836 : :
837 : 0 : len = strlen(file);
838 [ # # ][ # # ]: 0 : while (dirp.has_next())
839 : : {
840 [ # # ][ # # ]: 0 : filename = dirp.next();
[ # # ]
841 : :
842 : : // Skip the . and .. entries in the directory
843 [ # # ][ # # ]: 0 : if (filename.c_str()[0] == '.' &&
[ # # ][ # # ]
844 [ # # ]: 0 : (filename.c_str()[1] == '\0'))
845 : 0 : continue;
846 : : // Skip files if we only want directories
847 : :
848 [ # # ][ # # ]: 0 : is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename));
[ # # ][ # # ]
[ # # ]
849 : :
850 [ # # ][ # # ]: 0 : if (dir_only && !is_dir)
851 : 0 : continue;
852 : :
853 : : // Skip what doesn't match
854 [ # # ][ # # ]: 0 : if (len && strncmp(filename.c_str(), file, len) != 0)
[ # # ][ # # ]
855 : 0 : continue;
856 : :
857 : : // We have a match, see if the suffix (if any) matches
858 : 0 : int sat_number_found = 0;
859 : :
860 : : // Only match ".prt.", or ".asm." if they are followed by just digits.
861 [ # # ]: 0 : std::vector<std::string>::iterator suff;
862 [ # # ][ # # ]: 0 : for(suff = suffixes.begin(); suff != suffixes.end(); suff++)
[ # # ][ # # ]
[ # # ]
863 : : {
864 : :
865 [ # # ][ # # ]: 0 : if(*suff == ".prt." || *suff == ".asm.")
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
866 : : {
867 [ # # ][ # # ]: 0 : const char* c_ptr = strstr(filename.c_str(), suff->c_str());
[ # # ]
868 [ # # ]: 0 : if(c_ptr)
869 : : {
870 : 0 : c_ptr += 5;
871 : : // Make sure the rest of the filename is just digits
872 : 0 : sat_number_found = 1;
873 [ # # ]: 0 : while(*c_ptr != '\0')
874 : : {
875 [ # # ]: 0 : if (!isdigit(*c_ptr))
876 : 0 : sat_number_found = 0;
877 : 0 : c_ptr++;
878 : : }
879 : : }
880 : : }
881 : : }
882 : :
883 : 0 : int found = 0;
884 [ # # ]: 0 : const char* dot = strrchr(filename.c_str(), '.');
885 [ # # ][ # # ]: 0 : if(dot != NULL && !is_dir)
886 : : {
887 [ # # ][ # # ]: 0 : for(suff = suffixes.begin(); suff != suffixes.end(); suff++)
[ # # ][ # # ]
[ # # ]
888 : : {
889 : : #ifdef _WIN32
890 : : if(stricmp(suff->c_str(), dot) == 0)
891 : : #else
892 [ # # ][ # # ]: 0 : if(strcasecmp(suff->c_str(), dot) == 0)
[ # # ]
893 : : #endif
894 : : {
895 : 0 : found = 1; //if the suffix matches
896 : 0 : break;
897 : : }
898 : : }
899 : : }
900 : : else //If the filename has no suffix, then we'll add it
901 : 0 : found = 1;
902 : :
903 : :
904 [ # # ][ # # ]: 0 : if(suffixes.begin()->size() == 0 || // If no suffix was sent in
[ # # ][ # # ]
[ # # ]
[ # # # # ]
905 [ # # ][ # # ]: 0 : found == 1 || //or suffix matches or the filename has no suffix
906 : : sat_number_found == 1) //or if the suffix is something like ".sat."
907 : : {
908 : : // Save the filename of the first match
909 [ # # ]: 0 : if (++match == 1)
910 : : {
911 [ # # ]: 0 : match_file = filename;
912 [ # # ]: 0 : if (list_files == CUBIT_FALSE)
913 [ # # ][ # # ]: 0 : char_match = filename.c_str()+len;
[ # # ][ # # ]
914 : : }
915 : : // list_files is FALSE until we have found 2 or more matches
916 : : // that have no initial characters in common
917 [ # # ]: 0 : else if (list_files == CUBIT_FALSE)
918 : : {
919 : : // If the initial character doesn't match, list instead.
920 [ # # ][ # # ]: 0 : if (char_match.c_str()[0] != filename.c_str()[len])
[ # # ]
921 : : {
922 : : // Indicate that we are listing
923 : 0 : list_files = CUBIT_TRUE;
924 : : // Indicate that we are starting over
925 [ # # ][ # # ]: 0 : dirp.open(path);
[ # # ][ # # ]
[ # # ]
926 : 0 : match = 0;
927 : : // Undo what has already been done
928 : 0 : continue;
929 : : }
930 : :
931 : : // If there is a match, see how many characters match.
932 [ # # ][ # # ]: 0 : for (unsigned int i = 0; i < char_match.length(); i++)
933 : : {
934 [ # # ][ # # ]: 0 : if (char_match.c_str()[i] != filename.c_str()[i+len])
[ # # ]
935 : : {
936 : : // Chop off end of char_match
937 [ # # ]: 0 : char_match.put_at(i, '\0');
938 : 0 : break;
939 : : }
940 : : }
941 : : }
942 : : // If two or more matches, we want to
943 : : // output a list, so put out header and first two matches.
944 [ # # ]: 0 : else if (match == 2)
945 : : {
946 [ # # ][ # # ]: 0 : width = match_file.length() + filename.length() + 6;
947 : : // See if we need to add a '/' to the first name
948 : : char first_str[2];
949 : 0 : first_str[0] = first_str[1] = '\0';
950 [ # # ][ # # ]: 0 : if(CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, match_file)))
[ # # ][ # # ]
[ # # ][ # # ]
951 : 0 : first_str[0] = '/';
952 : :
953 : : // Get ready to test second file
954 [ # # ][ # # ]: 0 : bool tmp_is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename));
[ # # ][ # # ]
[ # # ]
955 : :
956 [ # # ][ # # ]: 0 : PRINT_INFO("\n\nPossible filename matches:\n %s%s %s%s",
[ # # ][ # # ]
[ # # ][ # # ]
957 : : match_file.c_str(), first_str, filename.c_str(),
958 [ # # ]: 0 : tmp_is_dir ? "/" : "");
959 : : }
960 : : else // This is at least the third match, and we
961 : : // need to list the file names
962 : : {
963 [ # # ][ # # ]: 0 : bool tmp_is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename));
[ # # ][ # # ]
[ # # ]
964 [ # # ]: 0 : int dir_adjust = tmp_is_dir ? 1 : 0;
965 [ # # ]: 0 : width += filename.length() + 2 + dir_adjust;
966 [ # # ]: 0 : if (width > 79)
967 : : {
968 [ # # ][ # # ]: 0 : PRINT_INFO(" \n" );
[ # # ][ # # ]
969 [ # # ]: 0 : width = filename.length() + 2 + dir_adjust;
970 : : }
971 [ # # ][ # # ]: 0 : PRINT_INFO(" %s%s", filename.c_str(),
[ # # ][ # # ]
[ # # ]
972 [ # # ]: 0 : dir_adjust ? "/" : "");
973 : : }
974 : : }
975 : : }
976 : :
977 [ # # ]: 0 : if (match == 1)
978 : : {
979 : : // See if match_file is a directory
980 : :
981 [ # # ][ # # ]: 0 : if(CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, match_file)))
[ # # ][ # # ]
[ # # ][ # # ]
982 : : {
983 : : // If our only match is a directory,
984 : : // Add the directory name to the buffer, but
985 : : // return NULL.
986 : : // Otherwise, return match_file.
987 : :
988 : : // Look at 'line'. Find the first occurance of a '\'. Use that as
989 : : // the suffix for the line if found. Otherwise use '/'.
990 : :
991 [ # # ]: 0 : CubitString suffix = "/";
992 [ # # ][ # # ]: 0 : if (line.find_first('\\') != CubitString::npos)
993 [ # # ][ # # ]: 0 : suffix = "\\";
[ # # ]
994 : :
995 [ # # ][ # # ]: 0 : line += match_file.substr(len) + suffix;
[ # # ][ # # ]
[ # # ]
996 : :
997 [ # # ][ # # ]: 0 : match_file = "";
[ # # ][ # # ]
998 : : }
999 : : }
1000 [ # # ]: 0 : else if (match > 1)
1001 : : {
1002 : : // If we didn't list files,
1003 : : // add the common chars to the buffer
1004 [ # # ]: 0 : if (!list_files)
1005 [ # # ]: 0 : line += char_match;
1006 [ # # ][ # # ]: 0 : PRINT_INFO(" \n" );
[ # # ][ # # ]
1007 [ # # ][ # # ]: 0 : match_file = "";
[ # # ]
1008 : : }
1009 : :
1010 : : // Return the file name.
1011 : : // If it was a directory or there was more than one match, it returns an empty string.
1012 [ # # ][ # # ]: 0 : return match_file;
1013 : : }
1014 : :
|