cgma
|
00001 //- Class: CubitFileUtil 00002 //- Description: Class with functions to get files from a directory, etc. 00003 //- Owner: Steve Storm 00004 00005 #define NOMINMAX 00006 00007 #include "CubitFileUtil.hpp" 00008 #include "CubitUtil.hpp" 00009 #include "CubitString.hpp" 00010 #include "CubitMessage.hpp" 00011 #include "CubitDirIterator.hpp" 00012 00013 #ifdef _WIN32 00014 #include <sys/types.h> 00015 #include <sys/stat.h> 00016 #include <windows.h> 00017 #ifndef PATH_MAX 00018 #define PATH_MAX _MAX_PATH 00019 #endif 00020 #include "shlwapi.h" 00021 #else 00022 #include <sys/types.h> 00023 #include <sys/stat.h> 00024 #include <dirent.h> 00025 #include <cstdlib> 00026 #include <sys/param.h> 00027 #include <unistd.h> 00028 #include <pwd.h> 00029 #include <fnmatch.h> 00030 #endif 00031 #include <errno.h> 00032 #include <string.h> 00033 00034 #include <algorithm> 00035 00036 00037 #ifdef _WIN32 00038 static const char* DIR_SEP_STR = "\\"; 00039 static const char DIR_SEP_CHAR = '\\'; 00040 #else 00041 static const char* DIR_SEP_STR = "/"; 00042 static const char DIR_SEP_CHAR = '/'; 00043 #endif 00044 00045 const char* CubitFileUtil::separator() 00046 { 00047 return DIR_SEP_STR; 00048 } 00049 00050 CubitStatus 00051 CubitFileUtil::get_current_working_directory( CubitString& wd ) 00052 { 00053 #ifdef _WIN32 00054 wchar_t* buffer = _wgetcwd( NULL, 0 ); 00055 #else 00056 char* buffer = getcwd( NULL, 0 ); 00057 #endif 00058 if (!buffer) 00059 { 00060 PRINT_WARNING( "Unable to get new working directory\n" ); 00061 return CUBIT_FAILURE; 00062 } 00063 else 00064 { 00065 // convert to string 00066 #ifdef _WIN32 00067 wd = CubitString::toUtf8(buffer); 00068 #else 00069 wd = buffer; 00070 #endif 00071 00072 // Add a slash at the end, if not already there 00073 int wd_len = wd.length(); 00074 if( wd.c_str()[wd_len-1] != DIR_SEP_CHAR ) 00075 { 00076 wd += DIR_SEP_STR; 00077 00078 free(buffer); 00079 } 00080 00081 // TODO: need to figure out the right way to do this. This assumes 00082 // variables of length PATH_MAX which is bad! 00083 //#ifdef _WIN32 00084 // // Make sure format is compatible with full path format 00085 // CubitString full_path_str; 00086 // if( get_full_path_str( wd, full_path_str ) == CUBIT_SUCCESS ) 00087 // strcpy( wd, full_path_str.c_str() ); 00088 //#endif 00089 00090 return CUBIT_SUCCESS; 00091 } 00092 } 00093 00094 CubitStatus CubitFileUtil::set_current_working_directory( const CubitString& wd ) 00095 { 00096 #ifdef _WIN32 00097 int ret = _wchdir(CubitString::toUtf16(wd).c_str()); 00098 #else 00099 int ret = chdir(wd.c_str()); 00100 #endif 00101 return ret == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE; 00102 } 00103 00104 CubitString CubitFileUtil::add_name_to_path( const CubitString& path, const CubitString& name ) 00105 { 00106 CubitString result = path; 00107 // Add a slash at the end of the path, if not already there 00108 int path_len = result.length(); 00109 if( result.c_str()[path_len-1] != DIR_SEP_CHAR ) 00110 { 00111 result += DIR_SEP_STR; 00112 } 00113 // append the name to the end of the path 00114 result += name; 00115 00116 return result; 00117 } 00118 00119 CubitString CubitFileUtil::find_home_path(const CubitString& which_user) 00120 { 00121 CubitString home_dir; 00122 00123 #ifdef _WIN32 00124 home_dir = CubitUtil::getenv("USERPROFILE"); 00125 #else 00126 if(which_user.length() == 0) 00127 { 00128 home_dir = CubitUtil::getenv("HOME"); 00129 if( home_dir.length() == 0 ) 00130 { 00131 struct passwd* userdata = getpwuid( getuid() ); 00132 if( userdata ) 00133 home_dir = userdata->pw_dir; 00134 } 00135 } 00136 else 00137 { 00138 struct passwd* userdata = getpwnam( which_user.c_str() ); 00139 if(userdata) 00140 home_dir = userdata->pw_dir; 00141 } 00142 #endif 00143 00144 return home_dir; 00145 } 00146 00147 CubitStatus 00148 CubitFileUtil::create_directory( const CubitString& wd ) 00149 { 00150 // Create the directory 00151 #ifdef _WIN32 00152 if (_wmkdir(CubitString::toUtf16(wd).c_str()) == -1) 00153 { 00154 PRINT_WARNING( "Unable to create new directory\n" ); 00155 return CUBIT_FAILURE; 00156 } 00157 #else 00158 if (mkdir(wd.c_str(), 0777) == -1) 00159 { 00160 PRINT_WARNING( "Unable to create new directory\n" ); 00161 return CUBIT_FAILURE; 00162 } 00163 #endif 00164 return CUBIT_SUCCESS; 00165 } 00166 00167 00168 CubitStatus CubitFileUtil::remove_file( const CubitString& file ) 00169 { 00170 #ifdef _WIN32 00171 int status = _wremove(CubitString::toUtf16(file).c_str()); 00172 #else 00173 int status = remove(file.c_str()); 00174 #endif 00175 return status == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE; 00176 } 00177 00178 CubitStatus CubitFileUtil::rename_file( const CubitString& old_file, const CubitString& new_file ) 00179 { 00180 #ifdef _WIN32 00181 int status = _wrename(CubitString::toUtf16(old_file).c_str(), CubitString::toUtf16(new_file).c_str()); 00182 #else 00183 int status = rename(old_file.c_str(), new_file.c_str()); 00184 #endif 00185 return status == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE; 00186 } 00187 00188 CubitStatus 00189 CubitFileUtil::get_full_path_str( const CubitString& part, 00190 CubitString &full_path_str ) 00191 { 00192 CubitString my_part = CubitFileUtil::make_path_platform_compatible(part); 00193 00194 #ifdef _WIN32 00195 00196 wchar_t* full = _wfullpath(NULL, CubitString::toUtf16(my_part).c_str(), 0); 00197 if(!full) 00198 { 00199 PRINT_ERROR( "problem getting full path to %s\n", part.c_str() ); 00200 return CUBIT_FAILURE; 00201 } 00202 full_path_str = CubitString::toUtf8(full); 00203 free(full); 00204 00205 #else 00206 00207 // we loop removing parts until realpath can resolve an existing path, 00208 // then add the non-existing parts back on. 00209 00210 std::vector<CubitString> split_parts; 00211 CubitString trypart = part; 00212 00213 if(!CubitFileUtil::is_absolute(trypart)) 00214 { 00215 CubitString cwd; 00216 CubitFileUtil::get_current_working_directory(cwd); 00217 trypart = CubitFileUtil::add_name_to_path(cwd, trypart); 00218 } 00219 00220 char full[PATH_MAX]; 00221 while(trypart.length() && !realpath(trypart.c_str(), full)) 00222 { 00223 CubitString split_part1, split_part2; 00224 CubitFileUtil::split_path(trypart, split_part1, split_part2); 00225 split_parts.push_back(split_part2); 00226 if(split_part1.length() == 0) 00227 { 00228 PRINT_ERROR( "problem getting full path to %s\n", part.c_str() ); 00229 return CUBIT_FAILURE; 00230 } 00231 trypart = split_part1; 00232 } 00233 00234 full_path_str = full; 00235 for(size_t i=0; i<split_parts.size(); i++) 00236 { 00237 full_path_str += CubitString("/") + split_parts[split_parts.size() - i - 1]; 00238 } 00239 00240 #endif 00241 00242 return CUBIT_SUCCESS; 00243 } 00244 00245 CubitString 00246 CubitFileUtil::make_path_platform_compatible( const CubitString& path) 00247 { 00248 CubitString ret = path; 00249 for(size_t i=0; i<ret.length(); i++) 00250 { 00251 #ifdef _WIN32 00252 // Replace '/' with '\\' 00253 if(ret.get_at(i) == '/' ) 00254 ret.put_at(i, '\\'); 00255 #else 00256 // Replace '\\' with '/' 00257 if(ret.get_at(i) == '\\' ) 00258 ret.put_at(i, '/'); 00259 #endif 00260 } 00261 return ret; 00262 } 00263 00264 CubitString 00265 CubitFileUtil::get_nice_filename( const CubitString& path ) 00266 { 00267 CubitString ret_str; 00268 00269 CubitString dpart_in, fpart_in; 00270 split_path( path, dpart_in, fpart_in ); 00271 00272 CubitString wd; 00273 get_current_working_directory( wd ); 00274 00275 if( dpart_in == wd ) 00276 ret_str = fpart_in; 00277 else 00278 ret_str = path; 00279 00280 return ret_str; 00281 } 00282 00283 void 00284 CubitFileUtil::split_path( const CubitString& path, CubitString& dirpart, CubitString& filepart ) 00285 { 00286 CubitString mypath = path; 00287 while(mypath.length() && mypath.get_at(mypath.length()-1) == DIR_SEP_CHAR) 00288 { 00289 mypath = mypath.substr(0, mypath.length()-1); 00290 } 00291 size_t pos = mypath.find_last(DIR_SEP_CHAR); 00292 00293 // No separator - could be filename or directory. We assume 00294 // it's a directory. 00295 if(pos == CubitString::npos) 00296 { 00297 filepart = "."; 00298 dirpart = mypath; 00299 } 00300 else 00301 { 00302 filepart = mypath.substr(pos+1); 00303 dirpart = mypath.substr(0, pos); 00304 } 00305 00306 // Add slash on end of dirpart if not already there 00307 if(dirpart.length() && dirpart.get_at(dirpart.length()-1) != DIR_SEP_CHAR) 00308 dirpart += DIR_SEP_STR; 00309 00310 return; 00311 } 00312 00313 00314 CubitString 00315 CubitFileUtil::get_file_extension( 00316 const CubitString& file, 00317 bool remove_version /* remove .1, .2, ...*/ ) 00318 { 00319 size_t dot_pos = file.find_last('.'); 00320 size_t dot_pos2 = 0; 00321 00322 if ( dot_pos == CubitString::npos ) 00323 return ""; 00324 00325 if(remove_version) 00326 { 00327 dot_pos2 = file.find_last('.',dot_pos); 00328 if ( dot_pos2 == CubitString::npos ) 00329 remove_version = false; 00330 else if(!is_int_number( file.substr(dot_pos+1).c_str() )) 00331 remove_version = false; 00332 } 00333 00334 CubitString extension; 00335 if(!remove_version) 00336 extension = file.substr(dot_pos); 00337 else 00338 extension = file.substr(dot_pos2,dot_pos-dot_pos2); 00339 00340 for ( size_t i = 0; i < extension.length(); i++ ) 00341 extension.put_at(i, tolower( extension.get_at(i) ) ); 00342 00343 return extension; 00344 00345 } // get_file_extension() 00346 00347 CubitBoolean 00348 CubitFileUtil::all_chars_are( char ch, const char *str ) 00349 { 00350 while( *str ) 00351 if( *str++ != ch ) 00352 return CUBIT_FALSE; 00353 return CUBIT_TRUE; 00354 } 00355 00356 CubitBoolean 00357 CubitFileUtil::is_int_number( const char *str ) 00358 { 00359 while( *str ) 00360 if( !isdigit(*str++) ) 00361 return CUBIT_FALSE; 00362 return CUBIT_TRUE; 00363 } 00364 00365 CubitBoolean 00366 CubitFileUtil::contains_char( char ch, const char *str ) 00367 { 00368 while( *str ) 00369 if( *str++ == ch ) 00370 return CUBIT_TRUE; 00371 return CUBIT_FALSE; 00372 } 00373 00374 //CubitString 00375 //CubitFileUtil::get_default_cubit_file_name() 00376 //{ 00377 // // Get a list of all files matching 'cubit*.cub', in current directory 00378 00379 // CubitDirIterator dir_iter(".", "cubit*.cub"); 00380 00381 // int max_number = 0; 00382 00383 // while(dir_iter.has_next()) 00384 // { 00385 // CubitString f = dir_iter.next(); 00386 00387 // // cut off the "cubit" at the start and the ".cub" at the end 00388 // f = f.substr(5, f.length()-9); 00389 // if( is_int_number(f.c_str()) ) 00390 // { 00391 // int num = atoi(f.c_str()); 00392 // max_number = std::max(num, max_number); 00393 // } 00394 // } 00395 00396 // max_number++; 00397 00398 // CubitString num_str = CubitString::number(max_number); 00399 // if(max_number < 10) 00400 // num_str = CubitString("0") + num_str; 00401 00402 // return CubitString("cubit") + num_str + CubitString(".cub"); 00403 //} 00404 00405 int 00406 CubitFileUtil::get_next_filenumber( const CubitString& file_pattern, 00407 int &num_matches, 00408 int &first_id ) 00409 { 00410 // TODO: check this bug? 00411 // Continue if nothing after dot. Also, I noticed the _WIN32 will match 00412 // file.cub against wildcard file.cub.* 00413 00414 int max_number = 0; 00415 int min_number = CUBIT_INT_MAX; 00416 num_matches = 0; 00417 00418 // get directory and file parts 00419 CubitString dir, file, full_file_pattern; 00420 CubitFileUtil::get_full_path_str(file_pattern, full_file_pattern); 00421 CubitFileUtil::split_path(full_file_pattern, dir, file); 00422 00423 size_t wildcard_location = file.find("*"); 00424 if(wildcard_location == CubitString::npos) 00425 return 1; 00426 00427 CubitDirIterator dir_iter(dir, file); 00428 00429 while(dir_iter.has_next()) 00430 { 00431 CubitString f = dir_iter.next(); 00432 00433 // cut off the matched part 00434 f = f.substr(wildcard_location, 1 + f.length() - file.length()); 00435 if( is_int_number(f.c_str()) ) 00436 { 00437 int num = atoi(f.c_str()); 00438 max_number = std::max(num, max_number); 00439 min_number = std::min(num, min_number); 00440 } 00441 num_matches++; 00442 } 00443 00444 if( min_number != CUBIT_INT_MAX ) 00445 first_id = min_number; 00446 00447 return max_number+1; 00448 } 00449 00450 bool CubitFileUtil::is_directory(const CubitString& path) 00451 { 00452 off_t size; 00453 time_t time; 00454 int mode = 0; 00455 if(0 == file_info(path, size, time, mode)) 00456 { 00457 #ifdef _WIN32 00458 if( (_S_IFDIR & mode) ) 00459 #else 00460 if( S_ISDIR( mode ) ) 00461 #endif 00462 { 00463 return true; 00464 } 00465 } 00466 return false; 00467 } 00468 00469 bool CubitFileUtil::path_exists(const CubitString& path) 00470 { 00471 off_t size; 00472 time_t time; 00473 int mode; 00474 return 0 == file_info(path, size, time, mode); 00475 } 00476 00477 bool CubitFileUtil::is_absolute(const CubitString& path) 00478 { 00479 #ifdef _WIN32 00480 return !PathIsRelativeW(CubitString::toUtf16(path).c_str()); 00481 #else 00482 return path.c_str()[0] == '/' ? true : false; 00483 #endif 00484 } 00485 00486 int CubitFileUtil::file_info(const CubitString& path, off_t& size, time_t& time, int& mode) 00487 { 00488 #ifdef _WIN32 00489 // remove trailing separators 00490 CubitString mypath = path; 00491 if(mypath.length() >= 1 && mypath.get_at(mypath.length()-1) == DIR_SEP_CHAR) 00492 mypath = mypath.substr(0, mypath.length()-1); 00493 struct _stati64 file_info; 00494 int stat_result = _wstati64( CubitString::toUtf16(mypath).c_str(), &file_info ); 00495 #else 00496 struct stat file_info; 00497 int stat_result = lstat( path.c_str(), &file_info ); 00498 #endif 00499 00500 if(stat_result == 0) 00501 { 00502 size = file_info.st_size; 00503 time = file_info.st_mtime; 00504 mode = file_info.st_mode; 00505 return 0; 00506 } 00507 return errno ? errno : ENOENT; 00508 } 00509 00510 int CubitFileUtil::complete_filename(CubitString& line, int& num_additional_chars, bool& found_quote) 00511 { 00512 // save the original length 00513 num_additional_chars = line.length(); 00514 char* buffer = (char*) line.c_str(); 00515 00516 char *ptr_from; 00517 if ( (ptr_from = strrchr(buffer, '\'')) == NULL && 00518 (ptr_from = strrchr(buffer, '\"')) == NULL) 00519 { 00520 return -1; 00521 } 00522 00523 ptr_from++; // skip past the single/double quote 00524 00525 // Separate the directory portion from the filename portion (if any) 00526 char *file; 00527 char *path; 00528 00529 #ifndef _WIN32 00530 if ((file = strrchr(ptr_from, '/')) == NULL) // No path 00531 { 00532 path = strdup("."); 00533 file = strdup(ptr_from); 00534 } 00535 else if (file == ptr_from) 00536 { 00537 path = strdup("/"); 00538 file = strdup(ptr_from + 1); 00539 } 00540 else 00541 { 00542 path = strdup(ptr_from); 00543 char *end = strrchr(path, '/'); 00544 *end = '\0'; 00545 ++file; 00546 file = strdup(file); 00547 00548 if ( *path == '~' ) 00549 { 00550 const char *home = getenv("HOME"); 00551 if( !home ) 00552 { 00553 struct passwd* userdata = getpwuid( getuid() ); 00554 if( userdata ) 00555 home = userdata->pw_dir; 00556 } 00557 char *after_tilde = path; 00558 after_tilde++; 00559 std::string new_path = home; 00560 new_path += after_tilde; 00561 free(path); 00562 path = strdup( new_path.c_str() ); 00563 } 00564 00565 } 00566 #else 00567 file = strrchr(ptr_from, '\\'); 00568 bool slash = 0; 00569 if(file == NULL) 00570 { 00571 slash = 1; 00572 file = strrchr(ptr_from, '/'); 00573 } 00574 if(file == NULL) 00575 // if ((file = strrchr(ptr_from, '\\')) == NULL 00576 // && file = strrchr(ptr_from, '/') == NULL) // No path 00577 { 00578 path = strdup("."); 00579 file = strdup(ptr_from); 00580 } 00581 else if (file == ptr_from) 00582 { 00583 path = strdup("\\"); 00584 file = strdup(ptr_from + 1); 00585 } 00586 else 00587 { 00588 path = strdup(ptr_from); 00589 char *end; 00590 if(slash) 00591 end = strrchr(path, '/'); 00592 else 00593 end = strrchr(path, '\\'); 00594 00595 *end = '\0'; 00596 ++file; 00597 file = strdup(file); 00598 } 00599 #endif 00600 // Determine what type of files to match (suffix_strings) 00601 // Need to lowercase keyword and identifier..... 00602 char *tmp_str = strdup(buffer); 00603 char *keyword = strtok(tmp_str, " \t"); 00604 CubitUtil::convert_string_to_lowercase(keyword); 00605 int lenkey = strlen(keyword); 00606 std::vector<std::string> suffix_strings; 00607 00608 if ((strncmp("import", keyword, lenkey) == 0) || 00609 (strncmp("export", keyword, lenkey) == 0)) 00610 { 00611 char *identifier = strtok(NULL, " \t"); 00612 CubitUtil::convert_string_to_lowercase(identifier); 00613 int lenid = strlen(identifier); 00614 00615 //Let's set up a vector of strings 00616 std::vector<std::string> acis_strings, cubfile_strings,iges_strings, 00617 catia_strings,proe_strings,step_strings,fastq_strings, mesh_strings, 00618 facet_strings, avs_strings, stl_strings, ideas_strings, abaqus_strings, 00619 nastran_strings, presto_strings; 00620 00621 iges_strings.push_back(".igs"); 00622 iges_strings.push_back(".iges"); 00623 00624 00625 #ifdef GRANITE 00626 proe_strings.push_back(".prt"); 00627 proe_strings.push_back(".asm"); 00628 proe_strings.push_back(".prt."); 00629 proe_strings.push_back(".asm."); 00630 proe_strings.push_back(".g"); 00631 #endif 00632 #ifdef CATIA 00633 catia_strings.push_back(".catpart"); 00634 catia_strings.push_back(".catproduct"); 00635 catia_strings.push_back(".ncgm"); 00636 #endif 00637 00638 step_strings.push_back(".stp"); 00639 step_strings.push_back(".step"); 00640 00641 fastq_strings.push_back(".fsq"); 00642 00643 mesh_strings.push_back(".g"); 00644 mesh_strings.push_back(".e"); 00645 mesh_strings.push_back(".exo"); 00646 mesh_strings.push_back(".exoII"); 00647 mesh_strings.push_back(".gen"); 00648 00649 facet_strings.push_back(".facets"); 00650 facet_strings.push_back(".facet"); 00651 facet_strings.push_back(".fac"); 00652 facet_strings.push_back(".off"); 00653 facet_strings.push_back(".OFF"); 00654 00655 avs_strings.push_back(".avs"); 00656 00657 stl_strings.push_back(".stl"); 00658 00659 ideas_strings.push_back(".unv"); 00660 00661 abaqus_strings.push_back(".inp"); 00662 00663 nastran_strings.push_back(".bdf"); 00664 00665 presto_strings.push_back(".i"); 00666 00667 if (strncmp("iges", identifier, lenid) == 0) 00668 { 00669 suffix_strings.assign(iges_strings.begin(), iges_strings.end()); 00670 } 00671 00672 00673 #ifdef CATIA 00674 else if (strncmp("catia", identifier, lenid) == 0) 00675 { 00676 suffix_strings.assign(catia_strings.begin(), catia_strings.end()); 00677 } 00678 #endif 00679 00680 #ifdef GRANITE 00681 else if (strncmp("proe", identifier, lenid) == 0) 00682 { 00683 suffix_strings.assign(proe_strings.begin(), proe_strings.end()); 00684 } 00685 #endif 00686 else if (strncmp("step", identifier, lenid) == 0) 00687 { 00688 suffix_strings.assign(step_strings.begin(), step_strings.end()); 00689 } 00690 else if (strncmp("fastq", identifier, lenid) == 0) 00691 { 00692 suffix_strings.assign(fastq_strings.begin(), fastq_strings.end()); 00693 } 00694 else if ( strncmp("mesh", identifier, lenid) == 0 || 00695 strncmp("free", identifier, lenid) == 0 ) 00696 { 00697 suffix_strings.assign(mesh_strings.begin(), mesh_strings.end()); 00698 } 00699 else if (strncmp("facets", identifier, lenid) == 0) 00700 { 00701 suffix_strings.assign(facet_strings.begin(), facet_strings.end()); 00702 } 00703 else if (strncmp("avs", identifier, lenid) == 0) 00704 { 00705 suffix_strings.assign(avs_strings.begin(), avs_strings.end()); 00706 } 00707 else if (strncmp("stl", identifier, lenid) == 0) 00708 { 00709 suffix_strings.assign(stl_strings.begin(), stl_strings.end()); 00710 } 00711 else if (strncmp("ideas", identifier, lenid) == 0) 00712 { 00713 suffix_strings.assign(ideas_strings.begin(), ideas_strings.end()); 00714 } 00715 else if (strncmp("abaqus", identifier, lenid) == 0) 00716 { 00717 suffix_strings.assign(abaqus_strings.begin(), abaqus_strings.end()); 00718 } 00719 else if (strncmp("nastran", identifier, lenid) == 0) 00720 { 00721 suffix_strings.assign(nastran_strings.begin(), nastran_strings.end()); 00722 } 00723 else if (strncmp("presto", identifier, lenid) == 0) 00724 { 00725 suffix_strings.assign(presto_strings.begin(), presto_strings.end()); 00726 } 00727 else //user didn't specify anything, so let's add them all 00728 { 00729 suffix_strings.assign(acis_strings.begin(),acis_strings.end()); 00730 suffix_strings.insert(suffix_strings.end(),cubfile_strings.begin(), cubfile_strings.end()); 00731 suffix_strings.insert(suffix_strings.end(),iges_strings.begin(), iges_strings.end()); 00732 00733 00734 #ifdef CATIA 00735 suffix_strings.insert(suffix_strings.end(),catia_strings.begin(), catia_strings.end()); 00736 #endif 00737 00738 #ifdef GRANITE 00739 suffix_strings.insert(suffix_strings.end(),proe_strings.begin(), proe_strings.end()); 00740 #endif 00741 suffix_strings.insert(suffix_strings.end(),step_strings.begin(), step_strings.end()); 00742 suffix_strings.insert(suffix_strings.end(),fastq_strings.begin(), fastq_strings.end()); 00743 suffix_strings.insert(suffix_strings.end(),mesh_strings.begin(), mesh_strings.end()); 00744 suffix_strings.insert(suffix_strings.end(),facet_strings.begin(), facet_strings.end()); 00745 suffix_strings.insert(suffix_strings.end(),avs_strings.begin(), avs_strings.end()); 00746 suffix_strings.insert(suffix_strings.end(),stl_strings.begin(), stl_strings.end()); 00747 suffix_strings.insert(suffix_strings.end(),ideas_strings.begin(), ideas_strings.end()); 00748 suffix_strings.insert(suffix_strings.end(),abaqus_strings.begin(), abaqus_strings.end()); 00749 suffix_strings.insert(suffix_strings.end(),nastran_strings.begin(), nastran_strings.end()); 00750 } 00751 } 00752 else if (strncmp("open", keyword, lenkey) == 0) 00753 { 00754 suffix_strings.push_back(".cub"); // Not an actual suffix, just an indicator 00755 } 00756 else if (strncmp("playback", keyword, lenkey) == 0 || 00757 strncmp("record", keyword, lenkey) == 0) 00758 { 00759 suffix_strings.push_back(".jou"); 00760 suffix_strings.push_back(".test"); 00761 suffix_strings.push_back(".cubit"); 00762 } 00763 else if (strncmp("hardcopy", keyword, lenkey) == 0) 00764 { 00765 suffix_strings.push_back(".ps"); 00766 } 00767 else if (strncmp("cd", keyword, lenkey) == 0) 00768 { 00769 suffix_strings.push_back("/"); // Not an actual suffix, just an indicator 00770 } 00771 else 00772 { 00773 suffix_strings.push_back("\0"); 00774 } 00775 00776 free(tmp_str); 00777 00778 CubitString tmp_line(buffer); 00779 CubitString match = CubitFileUtil::list_matching_files(path, file, suffix_strings, tmp_line); 00780 00781 if (match.length()) 00782 { 00783 int file_length = strlen(file); 00784 match = match.c_str() + file_length; 00785 tmp_line += match; 00786 if (tmp_line.find("\'") != CubitString::npos) 00787 tmp_line += "\'"; 00788 else if (tmp_line.find("\"") != CubitString::npos) 00789 tmp_line += "\" "; 00790 else 00791 { 00792 PRINT_ERROR("INTERNAL ERROR: CubitFileUtil::complete_file -- Could not find " 00793 "quote type."); 00794 tmp_line += "\' "; 00795 } 00796 //gl_in_quoted_string = !gl_in_quoted_string; 00797 //gl_fixup(gl_pos, gl_pos+additional_char); 00798 found_quote = !found_quote; 00799 } 00800 line = tmp_line; 00801 free(path); 00802 free(file); 00803 //gl_redraw(); 00804 num_additional_chars = line.length() - num_additional_chars; 00805 00806 return 1; 00807 } 00808 00809 CubitString CubitFileUtil::list_matching_files(const char *path, const char *file, std::vector<std::string> suffixes, CubitString& line) 00810 { 00811 CubitString filename; 00812 size_t len; 00813 int match = 0; 00814 int width = 0; 00815 CubitString match_file; 00816 CubitString char_match; 00817 CubitBoolean list_files = CUBIT_FALSE; 00818 CubitBoolean dir_only = CUBIT_FALSE; 00819 CubitBoolean is_dir = CUBIT_FALSE; 00820 00821 CubitDirIterator dirp(path); 00822 00823 if (!dirp.has_next()) 00824 { 00825 PRINT_INFO("\n"); 00826 PRINT_ERROR("Invalid Directory: '%s'\n", 00827 path); 00828 return ""; 00829 } 00830 00831 // If we're looking for directories only, indicate it 00832 if (suffixes.size() > 0 && suffixes.front() == "/") 00833 { 00834 dir_only = CUBIT_TRUE; 00835 } 00836 00837 len = strlen(file); 00838 while (dirp.has_next()) 00839 { 00840 filename = dirp.next(); 00841 00842 // Skip the . and .. entries in the directory 00843 if (filename.c_str()[0] == '.' && 00844 (filename.c_str()[1] == '\0')) 00845 continue; 00846 // Skip files if we only want directories 00847 00848 is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename)); 00849 00850 if (dir_only && !is_dir) 00851 continue; 00852 00853 // Skip what doesn't match 00854 if (len && strncmp(filename.c_str(), file, len) != 0) 00855 continue; 00856 00857 // We have a match, see if the suffix (if any) matches 00858 int sat_number_found = 0; 00859 00860 // Only match ".prt.", or ".asm." if they are followed by just digits. 00861 std::vector<std::string>::iterator suff; 00862 for(suff = suffixes.begin(); suff != suffixes.end(); suff++) 00863 { 00864 00865 if(*suff == ".prt." || *suff == ".asm.") 00866 { 00867 const char* c_ptr = strstr(filename.c_str(), suff->c_str()); 00868 if(c_ptr) 00869 { 00870 c_ptr += 5; 00871 // Make sure the rest of the filename is just digits 00872 sat_number_found = 1; 00873 while(*c_ptr != '\0') 00874 { 00875 if (!isdigit(*c_ptr)) 00876 sat_number_found = 0; 00877 c_ptr++; 00878 } 00879 } 00880 } 00881 } 00882 00883 int found = 0; 00884 const char* dot = strrchr(filename.c_str(), '.'); 00885 if(dot != NULL && !is_dir) 00886 { 00887 for(suff = suffixes.begin(); suff != suffixes.end(); suff++) 00888 { 00889 #ifdef _WIN32 00890 if(stricmp(suff->c_str(), dot) == 0) 00891 #else 00892 if(strcasecmp(suff->c_str(), dot) == 0) 00893 #endif 00894 { 00895 found = 1; //if the suffix matches 00896 break; 00897 } 00898 } 00899 } 00900 else //If the filename has no suffix, then we'll add it 00901 found = 1; 00902 00903 00904 if(suffixes.begin()->size() == 0 || // If no suffix was sent in 00905 found == 1 || //or suffix matches or the filename has no suffix 00906 sat_number_found == 1) //or if the suffix is something like ".sat." 00907 { 00908 // Save the filename of the first match 00909 if (++match == 1) 00910 { 00911 match_file = filename; 00912 if (list_files == CUBIT_FALSE) 00913 char_match = filename.c_str()+len; 00914 } 00915 // list_files is FALSE until we have found 2 or more matches 00916 // that have no initial characters in common 00917 else if (list_files == CUBIT_FALSE) 00918 { 00919 // If the initial character doesn't match, list instead. 00920 if (char_match.c_str()[0] != filename.c_str()[len]) 00921 { 00922 // Indicate that we are listing 00923 list_files = CUBIT_TRUE; 00924 // Indicate that we are starting over 00925 dirp.open(path); 00926 match = 0; 00927 // Undo what has already been done 00928 continue; 00929 } 00930 00931 // If there is a match, see how many characters match. 00932 for (unsigned int i = 0; i < char_match.length(); i++) 00933 { 00934 if (char_match.c_str()[i] != filename.c_str()[i+len]) 00935 { 00936 // Chop off end of char_match 00937 char_match.put_at(i, '\0'); 00938 break; 00939 } 00940 } 00941 } 00942 // If two or more matches, we want to 00943 // output a list, so put out header and first two matches. 00944 else if (match == 2) 00945 { 00946 width = match_file.length() + filename.length() + 6; 00947 // See if we need to add a '/' to the first name 00948 char first_str[2]; 00949 first_str[0] = first_str[1] = '\0'; 00950 if(CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, match_file))) 00951 first_str[0] = '/'; 00952 00953 // Get ready to test second file 00954 bool tmp_is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename)); 00955 00956 PRINT_INFO("\n\nPossible filename matches:\n %s%s %s%s", 00957 match_file.c_str(), first_str, filename.c_str(), 00958 tmp_is_dir ? "/" : ""); 00959 } 00960 else // This is at least the third match, and we 00961 // need to list the file names 00962 { 00963 bool tmp_is_dir = CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, filename)); 00964 int dir_adjust = tmp_is_dir ? 1 : 0; 00965 width += filename.length() + 2 + dir_adjust; 00966 if (width > 79) 00967 { 00968 PRINT_INFO(" \n" ); 00969 width = filename.length() + 2 + dir_adjust; 00970 } 00971 PRINT_INFO(" %s%s", filename.c_str(), 00972 dir_adjust ? "/" : ""); 00973 } 00974 } 00975 } 00976 00977 if (match == 1) 00978 { 00979 // See if match_file is a directory 00980 00981 if(CubitFileUtil::is_directory(CubitFileUtil::add_name_to_path(path, match_file))) 00982 { 00983 // If our only match is a directory, 00984 // Add the directory name to the buffer, but 00985 // return NULL. 00986 // Otherwise, return match_file. 00987 00988 // Look at 'line'. Find the first occurance of a '\'. Use that as 00989 // the suffix for the line if found. Otherwise use '/'. 00990 00991 CubitString suffix = "/"; 00992 if (line.find_first('\\') != CubitString::npos) 00993 suffix = "\\"; 00994 00995 line += match_file.substr(len) + suffix; 00996 00997 match_file = ""; 00998 } 00999 } 01000 else if (match > 1) 01001 { 01002 // If we didn't list files, 01003 // add the common chars to the buffer 01004 if (!list_files) 01005 line += char_match; 01006 PRINT_INFO(" \n" ); 01007 match_file = ""; 01008 } 01009 01010 // Return the file name. 01011 // If it was a directory or there was more than one match, it returns an empty string. 01012 return match_file; 01013 } 01014