cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : CubitUtil.cc 00003 // 00004 // Purpose : This file contains utility functions that can be used 00005 // throughout Cubit. 00006 // 00007 // Special Notes : This is a pure virtual class, to prevent instantiation. 00008 // All functions are static, called like this: 00009 // CubitUtil::function_name(); 00010 // 00011 // Creator : Darryl Melander 00012 // 00013 // Date : 06/08/98 00014 // 00015 // Owner : Darryl Melander 00016 //------------------------------------------------------------------------- 00017 00018 #include "CubitUtil.hpp" 00019 #include "CubitString.hpp" 00020 #include "CubitEntity.hpp" 00021 #include "CubitMessage.hpp" 00022 00023 #include "AppUtil.hpp" 00024 #include <ctype.h> 00025 #include <time.h> 00026 #include <sstream> 00027 00028 00029 #ifdef _WIN32 00030 #include "windows.h" 00031 #else 00032 #include <unistd.h> 00033 #include <sys/utsname.h> 00034 #endif 00035 00036 FILE *CubitUtil::fp = NULL; 00037 static int displayDigits = -1; 00038 00039 00040 int CubitUtil::get_digits() 00041 { 00042 return displayDigits; 00043 } 00044 00045 void CubitUtil::set_digits(int new_digits) 00046 { 00047 displayDigits = new_digits; 00048 } 00049 00050 00051 void CubitUtil::convert_string_to_lowercase(char *string) 00052 { 00053 register char *p = string; 00054 while (*p) 00055 { 00056 if (isascii(*p) && isupper(*p)) 00057 *p = tolower(*p); 00058 p++; 00059 } 00060 } 00061 00062 int CubitUtil::strcmp_case_insensitive (const char *s1, const char *s2) 00063 { 00064 char c1, c2; 00065 00066 do 00067 { 00068 c1 = *s1++; 00069 if(isupper(c1)) 00070 c1 = tolower(c1); 00071 00072 c2 = *s2++; 00073 if(isupper(c2)) 00074 c2 = tolower(c2); 00075 00076 if(c1 != c2) 00077 return c1 - c2; 00078 00079 } while(c1 != '\0'); 00080 00081 return 0; 00082 } 00083 00084 int CubitUtil::strncmp_case_insensitive (const char *s1, const char *s2, 00085 int n) 00086 { 00087 char c1, c2; 00088 00089 do 00090 { 00091 c1 = *s1++; 00092 if(isupper(c1)) 00093 c1 = tolower(c1); 00094 00095 c2 = *s2++; 00096 if(isupper(c2)) 00097 c2 = tolower(c2); 00098 00099 if(c1 != c2) 00100 return c1 - c2; 00101 00102 n--; 00103 } while(c1 && n > 0); 00104 00105 return 0; 00106 } 00107 00108 void CubitUtil::list_ids( const char *const heading, 00109 const DLIList<CubitEntity*> &entity_list, 00110 int should_sort, int report_once, 00111 int wrap ) 00112 { 00113 if ( entity_list.size() == 0 ) 00114 { 00115 PRINT_INFO(" No %s.\n", heading ); 00116 return; 00117 } 00118 DLIList <int> id_list( entity_list.size() ); 00119 for ( int j = 0; j < entity_list.size(); j++ ) 00120 { 00121 id_list.append( entity_list[j]->id() ); 00122 } 00123 00124 if ( id_list.size() == 1 ) 00125 { 00126 PRINT_INFO(" The 1 %s id is %d.\n", heading, id_list[0]); 00127 return; 00128 } 00129 sort_and_print_ids( heading, id_list, should_sort, report_once, wrap ); 00130 } 00131 00132 void CubitUtil::sort_and_print_ids( const char *const heading, 00133 DLIList<int> &id_list, 00134 int should_sort, int report_once, 00135 int wrap ) 00136 { 00137 // sort, if desired 00138 if ( should_sort ) { 00139 id_list.sort(); 00140 } 00141 00142 if ( report_once ) { 00143 DLIList <int> id_list_2( id_list ); 00144 id_list_2.reset(); 00145 id_list.clean_out(); 00146 id_list.append( id_list_2.get_and_step() ); 00147 for ( int j = id_list_2.size()-1; j--; ) 00148 { 00149 if ( id_list_2.get() != id_list_2.prev() ) 00150 id_list.append( id_list_2.get() ); 00151 id_list_2.step(); 00152 } 00153 } 00154 00155 if( wrap == -1 ) 00156 { 00157 // print out ranges 00158 int begin = id_list.get_and_step(); 00159 int end = begin; 00160 int current = -1; 00161 PRINT_INFO(" The %d %s ids are %d", id_list.size(), heading, begin); 00162 for (int i=id_list.size()-1; i > 0; i--) { 00163 current = id_list.get_and_step(); 00164 if (current == end+1) { 00165 end++; 00166 } 00167 else { 00168 if (end == begin) { 00169 PRINT_INFO(", %d", current); 00170 } 00171 else if (end == begin+1) { 00172 PRINT_INFO(", %d, %d", end, current); 00173 } 00174 else { 00175 PRINT_INFO(" to %d, %d", end, current); 00176 } 00177 begin = current; 00178 end = begin; 00179 } 00180 } 00181 if (current == begin + 1) { 00182 PRINT_INFO(", %d", current); 00183 } 00184 else if (current != begin) { 00185 PRINT_INFO(" to %d", current); 00186 } 00187 PRINT_INFO(".\n"); 00188 } 00189 else 00190 { 00191 char pre_string[67]; 00192 sprintf( pre_string, " The %d %s ids are: ", id_list.size(),heading ); 00193 CubitUtil::list_entity_ids( pre_string, id_list, wrap, ".\n", CUBIT_FALSE, 00194 CUBIT_FALSE ); 00195 } 00196 } 00197 00198 void CubitUtil::list_entity_ids( const char *pre_string, 00199 const DLIList<CubitEntity*> &entity_list, 00200 int width, const char *post_string, 00201 int sort, int unique, 00202 int tab, const char *sep_string, 00203 const char *post_string_none ) 00204 { 00205 DLIList <int> id_list( entity_list.size() ); 00206 for ( int i=0; i<entity_list.size(); i++ ) 00207 id_list.append( entity_list.next(i)->id() ); 00208 00209 list_entity_ids( pre_string, id_list, width, post_string, sort, 00210 unique, tab, sep_string, post_string_none ); 00211 } 00212 00213 void CubitUtil::list_entity_ids( const char *pre_string, 00214 DLIList<int> &id_list, 00215 int width, 00216 const char *post_string, 00217 int sort, int unique, 00218 int tab_len, const char *sep_string, 00219 const char *post_string_none ) 00220 { 00221 CubitString ret_str; 00222 process_entity_ids( 1, ret_str, pre_string, id_list, width, post_string, 00223 sort, unique, tab_len, sep_string, post_string_none ); 00224 } 00225 00226 CubitString CubitUtil::get_entity_ids_str( const char *pre_string, 00227 DLIList<int> &id_list, 00228 int width, const char *post_string, 00229 int sort, int unique, int tab_len, 00230 const char *sep_string, 00231 const char *post_string_none ) 00232 { 00233 CubitString ret_str; 00234 00235 process_entity_ids( 0, ret_str, pre_string, id_list, width, post_string, 00236 sort, unique, tab_len, sep_string, post_string_none ); 00237 return ret_str; 00238 } 00239 00240 void CubitUtil::process_entity_ids( int method, 00241 CubitString &ret_str, 00242 const char *pre_string, 00243 DLIList<int> &id_list, 00244 int max_len, 00245 const char *post_string, 00246 int sort, int unique, 00247 int tab_len, const char *sep_string, 00248 const char* post_string_none ) 00249 { 00250 // Method: 0 - to a string 00251 // 1 - to PRINT_INFO 00252 char temp[200]; 00253 00254 if ( id_list.size() == 0 ) { 00255 if( method ) 00256 PRINT_INFO("%s%s", pre_string, post_string_none ); 00257 else 00258 { 00259 sprintf( temp, "%s%s", pre_string, post_string_none ); 00260 ret_str = temp; 00261 } 00262 if( fp ) 00263 fprintf( fp, "%s%s", pre_string, post_string_none ); 00264 return; 00265 } 00266 00267 // sort 00268 if( sort ) 00269 { 00270 id_list.sort(); 00271 00272 // make unique 00273 if( unique ) 00274 { 00275 int i; 00276 DLIList <int> id_list_2( id_list ); 00277 id_list_2.reset(); 00278 id_list.clean_out(); 00279 id_list.append( id_list_2.get_and_step() ); 00280 for ( i=id_list_2.size()-1; i--; ) 00281 { 00282 if ( id_list_2.get() != id_list_2.prev() ) 00283 id_list.append( id_list_2.get() ); 00284 id_list_2.step(); 00285 } 00286 } 00287 } 00288 00289 if( max_len < 0 ) 00290 max_len = CUBIT_INT_MAX/2; 00291 00292 // TODO: wrap prestring, if necessary 00293 if( method ) 00294 PRINT_INFO( "%s", pre_string ); 00295 else 00296 ret_str = pre_string; 00297 if( fp ) 00298 fprintf( fp, "%s", pre_string ); 00299 00300 // Keep track of length printed 00301 int curr_len = strlen(pre_string); 00302 00303 int num = 0; 00304 int begin = id_list.get(); 00305 int previous = begin; 00306 int current; 00307 int comma = 0; // Is comma needed 00308 int beg_len, prev_len; 00309 int sep_len = strlen( sep_string ); 00310 00311 // Setup the tab 00312 char* tab = new char[tab_len+1]; 00313 for( int i=0; i<tab_len; i++ ) 00314 tab[i] = ' '; 00315 tab[tab_len] = '\0'; 00316 00317 // Loop until all the ids are printed. Use ranges if possible. 00318 while( num < id_list.size()+1 ) 00319 { 00320 current = id_list.get_and_step(); 00321 num++; 00322 00323 // Handle last entity 00324 if( num <= id_list.size() ) 00325 { 00326 if( num==1 ) // Handle 1st time in loop 00327 continue; 00328 00329 if( current==previous+1 ) 00330 { 00331 previous = current; 00332 continue; 00333 } 00334 } 00335 00336 // If we are here, we are no longer tracking a range and 00337 // need to print the range or a number. 00338 if( comma ) 00339 { 00340 if( method ) 00341 PRINT_INFO("%s", sep_string ); 00342 else 00343 ret_str += sep_string; 00344 if( fp ) 00345 fprintf( fp, "%s", sep_string ); 00346 curr_len += sep_len; 00347 } 00348 00349 if( begin==previous ) 00350 { 00351 // a single number 00352 prev_len = int_len(previous); 00353 00354 if( curr_len+1+prev_len+sep_len > max_len ) 00355 { 00356 if( method ) 00357 { 00358 PRINT_INFO( "\n" ); 00359 PRINT_INFO( "%s%d", tab, previous ); 00360 } 00361 else 00362 { 00363 sprintf( temp, "\n%s%d", tab, previous ); 00364 ret_str += temp; 00365 } 00366 if( fp ) 00367 fprintf( fp, "\n%s%d", tab, previous ); 00368 curr_len = tab_len + prev_len; 00369 } 00370 else 00371 { 00372 if( comma ) // Don't print space before first item 00373 { 00374 if( method ) 00375 PRINT_INFO( " " ); 00376 else 00377 ret_str += " "; 00378 if( fp ) 00379 fprintf( fp, " " ); 00380 curr_len++; 00381 } 00382 00383 if( method ) 00384 PRINT_INFO( "%d", previous ); 00385 else 00386 { 00387 sprintf( temp, "%d", previous ); 00388 ret_str += temp; 00389 } 00390 if( fp ) 00391 fprintf( fp, "%d", previous ); 00392 curr_len = curr_len + prev_len; 00393 } 00394 } 00395 else if( previous==begin+1 ) 00396 { 00397 // a range, but only 2 consecutive numbers 00398 prev_len = int_len(previous); 00399 beg_len = int_len(begin); 00400 00401 // Print 1st 00402 if( curr_len+1+beg_len+sep_len > max_len ) 00403 { 00404 if( method ) 00405 { 00406 PRINT_INFO( "\n" ); 00407 PRINT_INFO( "%s%d%s", tab, begin, sep_string ); 00408 } 00409 else 00410 { 00411 sprintf( temp, "\n%s%d%s", tab, begin, sep_string ); 00412 ret_str += temp; 00413 } 00414 if( fp ) 00415 fprintf( fp, "\n%s%d%s", tab, begin, sep_string ); 00416 curr_len = tab_len + beg_len + sep_len; 00417 } 00418 else 00419 { 00420 if( comma ) // Don't print space before first item 00421 { 00422 if( method ) 00423 PRINT_INFO( " " ); 00424 else 00425 ret_str += " "; 00426 if( fp ) 00427 fprintf( fp, " " ); 00428 curr_len++; 00429 } 00430 00431 if( method ) 00432 PRINT_INFO( "%d%s", begin, sep_string ); 00433 else 00434 { 00435 sprintf( temp, "%d%s", begin, sep_string ); 00436 ret_str += temp; 00437 } 00438 if( fp ) 00439 fprintf( fp, "%d%s", begin, sep_string ); 00440 curr_len = curr_len + beg_len + sep_len; 00441 } 00442 00443 // Print 2nd 00444 if( curr_len+1+prev_len+sep_len > max_len ) 00445 { 00446 if( method ) 00447 { 00448 PRINT_INFO( "\n" ); 00449 PRINT_INFO( "%s%d", tab, previous ); 00450 } 00451 else 00452 { 00453 sprintf( temp, "\n%s%d", tab, previous ); 00454 ret_str += temp; 00455 } 00456 if( fp ) 00457 fprintf( fp, "\n%s%d", tab, previous ); 00458 curr_len = tab_len + prev_len; 00459 } 00460 else 00461 { 00462 if( method ) 00463 PRINT_INFO( " %d", previous ); 00464 else 00465 { 00466 sprintf( temp, " %d", previous ); 00467 ret_str += temp; 00468 } 00469 if( fp ) 00470 fprintf( fp, " %d", previous ); 00471 curr_len = curr_len + 1+prev_len; 00472 } 00473 } 00474 else 00475 { 00476 // a range of 3 or more consecutive numbers 00477 prev_len = int_len(previous); 00478 beg_len = int_len(begin); 00479 00480 if( curr_len+beg_len+prev_len+5+sep_len > max_len ) 00481 { 00482 if( method ) 00483 { 00484 PRINT_INFO( "\n" ); 00485 PRINT_INFO( "%s%d to %d", tab, begin, previous ); 00486 } 00487 else 00488 { 00489 sprintf( temp, "\n%s%d to %d", tab, begin, previous ); 00490 ret_str += temp; 00491 } 00492 if( fp ) 00493 fprintf( fp, "\n%s%d to %d", tab, begin, previous ); 00494 curr_len = tab_len + beg_len+prev_len+4; 00495 } 00496 else 00497 { 00498 if( comma ) // Don't print space before first item 00499 { 00500 if( method ) 00501 PRINT_INFO( " " ); 00502 else 00503 ret_str += " "; 00504 if( fp ) 00505 fprintf( fp, " " ); 00506 curr_len++; 00507 } 00508 00509 if( method ) 00510 PRINT_INFO( "%d to %d", begin, previous ); 00511 else 00512 { 00513 sprintf( temp, "%d to %d", begin, previous ); 00514 ret_str += temp; 00515 } 00516 if( fp ) 00517 fprintf( fp, "%d to %d", begin, previous ); 00518 curr_len = curr_len + beg_len+4+prev_len; 00519 } 00520 } 00521 00522 begin = current; 00523 previous = current; 00524 comma = 1; 00525 00526 } 00527 00528 //TODO: wrap poststring, if required 00529 if (post_string) { 00530 00531 if( method ) 00532 PRINT_INFO( "%s", post_string ); 00533 else 00534 ret_str += post_string; 00535 if( fp ) 00536 fprintf( fp, "%s", post_string ); 00537 } 00538 00539 delete [] tab; 00540 } 00541 00542 #define INTABS(n) ((n) >= 0 ? (n) : (-(n))) 00543 int CubitUtil::int_len( int num ) 00544 { 00545 int len = 0; // length of the string to hold the integer number 00546 unsigned long n; // absolute value of the integer value 00547 00548 // If the number is negative, add 1 for the negative sign 00549 if (num < 0) len++; 00550 00551 // Loop until the absolute value of the number reaches 0 00552 n = INTABS(num); 00553 do { 00554 // Increment the length and divide the number by 10 00555 len++; 00556 n /= 10; 00557 } while (n); 00558 00559 return len; 00560 } 00561 00562 namespace 00563 { 00564 // Unix: Returns the TEMPDIR, TMP, or TEMP directory, whichever is set to a 00565 // writeable directory. If neither is set, return /tmp. 00566 // Windows: Return path returned by GetTempPath() windows function. 00567 // If it doesn't return a writeable directory, use current directory. 00568 CubitString get_temp_directory() 00569 { 00570 #ifdef _WIN32 00571 00572 //get a place to put the temporary file 00573 const DWORD buf_size = MAX_PATH; 00574 wchar_t temp_path[buf_size]; 00575 GetTempPathW(buf_size, temp_path); 00576 00577 // If the path is not writeable, use the current directory instead 00578 DWORD atts = GetFileAttributesW(temp_path); 00579 #if _MSC_VER > 1200 // after VC6.0 00580 if (atts == INVALID_FILE_ATTRIBUTES || // File doesn't exist 00581 (atts & FILE_ATTRIBUTE_DIRECTORY) == 0 || // File isn't a directory 00582 atts & FILE_ATTRIBUTE_READONLY) // File is read only 00583 #else 00584 if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0 || // File isn't a directory 00585 atts & FILE_ATTRIBUTE_READONLY) // File is read only 00586 #endif 00587 { 00588 if (DEBUG_FLAG(141)) 00589 { 00590 PRINT_DEBUG_141("\nUsing cwd because "); 00591 #if _MSC_VER > 1200 00592 if (atts == INVALID_FILE_ATTRIBUTES) 00593 { 00594 PRINT_DEBUG_141("directory doesn't exist: %s\n", CubitString::toUtf8(temp_path).c_str()); 00595 } 00596 else if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0) 00597 { 00598 PRINT_DEBUG_141("file isn't a directory: %s\n", CubitString::toUtf8(temp_path).c_str()); 00599 } 00600 else if (atts & FILE_ATTRIBUTE_READONLY) 00601 { 00602 PRINT_DEBUG_141("directory is read only: %s\n", CubitString::toUtf8(temp_path).c_str()); 00603 } 00604 #else 00605 if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0) 00606 { 00607 PRINT_DEBUG_141("file isn't a directory: %s\n", CubitString::toUtf8(temp_path).c_str()); 00608 } 00609 else if (atts & FILE_ATTRIBUTE_READONLY) 00610 { 00611 PRINT_DEBUG_141("directory is read only: %s\n", CubitString::toUtf8(temp_path).c_str()); 00612 } 00613 #endif 00614 } 00615 temp_path[0] = '.'; 00616 temp_path[1] = '\0'; 00617 } 00618 else 00619 { 00620 PRINT_DEBUG_141("\nUsing GetTempPath: %s\n", CubitString::toUtf8(temp_path).c_str()); 00621 } 00622 return CubitString::toUtf8(temp_path); 00623 00624 #else 00625 00626 const char* tmpdir = "/tmp"; 00627 const char* env_tmpdir = getenv("TMPDIR"); 00628 if (!env_tmpdir) 00629 env_tmpdir = getenv("TMP"); 00630 if (!env_tmpdir) 00631 env_tmpdir = getenv("TEMP"); 00632 if(env_tmpdir) 00633 tmpdir = env_tmpdir; 00634 00635 return tmpdir; 00636 00637 #endif 00638 } 00639 } 00640 00641 CubitString CubitUtil::get_temporary_filename() 00642 { 00643 00644 CubitString ret_str; 00645 00646 #ifdef _WIN32 00647 00648 //get a place to put the temporary file 00649 CubitString temp_path = get_temp_directory(); 00650 00651 // make an empty temporary and return the name for it 00652 wchar_t temp_file_name[MAX_PATH]; 00653 if( GetTempFileNameW(CubitString::toUtf16(temp_path.c_str()).c_str(), L"CBT", 0, temp_file_name) != 0 ) 00654 ret_str = CubitString::toUtf8(temp_file_name); 00655 00656 #else 00657 00658 CubitString tmpdir = get_temp_directory(); 00659 const char* filepattern = "CBT.XXXXXX"; 00660 //needs to be two longer because of the "/"? 00661 char *temp_file_name = new char[tmpdir.length() + strlen(filepattern) + 2]; 00662 sprintf(temp_file_name, "%s/%s", tmpdir.c_str(), filepattern); 00663 00664 // make an empty file and return the name for it 00665 int fd = mkstemp(temp_file_name); 00666 if( fd != -1 ) 00667 { 00668 ret_str = temp_file_name; 00669 // release the open done by mkstemp, 00670 // temporary file still exists 00671 close(fd); 00672 } 00673 delete [] temp_file_name; 00674 00675 #endif 00676 00677 return ret_str; 00678 } 00679 00680 void CubitUtil::print_columns( const std::vector<CubitString>& array, 00681 const CubitString& indent) 00682 { 00683 int term_height, term_width; 00684 00685 if( ! AppUtil::instance()->get_terminal_size( term_height, term_width ) ) 00686 { 00687 for( size_t i = 0; i < array.size(); i++ ) 00688 { 00689 PRINT_INFO("%s%s\n", indent.c_str(), array[i].c_str() ); 00690 } 00691 return; 00692 } 00693 00694 // find lenth of longest string 00695 int maxlen = 0; 00696 for( size_t i = 0; i < array.size(); i++ ) 00697 { 00698 int len = CubitUtil::string_length(array[i].c_str()); 00699 if( len > maxlen ) 00700 maxlen = len; 00701 } 00702 00703 char* const line = new char[CUBIT_MAX(maxlen,term_width)+2]; 00704 00705 // calculate number of columns of output 00706 term_width -= string_length(indent.c_str()); 00707 int width = maxlen + 1; 00708 int columns = term_width > width ? term_width / width : 1; 00709 00710 // calculate number of rows of output 00711 int rows = array.size() / columns; 00712 if( array.size() % columns ) 00713 rows++; 00714 00715 // calculate the width of one column 00716 if (columns > 1) 00717 width = maxlen + (term_width - columns * maxlen) / (columns - 1); 00718 else 00719 width = term_width; 00720 00721 // now write output 00722 for( int i = 0; i < rows; i++ ) 00723 { 00724 size_t idx; 00725 const char* str; 00726 char* ptr = line + sprintf( line, "%s", indent.c_str() ); 00727 for(int j = 0; j < columns - 1; j++ ) 00728 { 00729 idx = j * rows + i; 00730 if (idx < array.size() ) 00731 str = array[idx].c_str(); 00732 else 00733 str = ""; 00734 00735 ptr += sprintf( ptr, "%-*s", width, str); 00736 } 00737 00738 idx = (columns - 1) * rows + i; 00739 if (idx < array.size() ) 00740 sprintf(ptr, "%s\n", array[idx].c_str()); 00741 else 00742 sprintf(ptr, "\n"); 00743 00744 PRINT_INFO( "%s", line ); 00745 } 00746 00747 delete [] line; 00748 } 00749 00750 int CubitUtil::string_length( const char* string, int tabsize ) 00751 { 00752 int result = 0; 00753 for( ; *string ; string++ ) 00754 { 00755 if( *string == '\t' ) 00756 result += tabsize; 00757 else if( *string >= ' ' ) 00758 result ++; 00759 } 00760 return result; 00761 } 00762 00763 //does the same thing as strdup... strdup is not supported by some 00764 // compilers 00765 char* CubitUtil::util_strdup(const char *s1) 00766 { 00767 #ifdef CUBIT_NO_STRDUP 00768 int len = strlen(s1)+1; 00769 char* ret_char = (char*) malloc ( (unsigned long) len * sizeof(char)); 00770 strcpy(ret_char, s1); 00771 return ret_char; 00772 #else 00773 #ifdef _WIN32 00774 return _strdup(s1); 00775 #else 00776 return strdup(s1); 00777 #endif 00778 #endif 00779 } 00780 00781 void CubitUtil::cubit_sleep(int duration_in_seconds) 00782 { 00783 #ifdef _WIN32 00784 ::Sleep(duration_in_seconds*1000); 00785 #else 00786 sleep(duration_in_seconds); 00787 #endif 00788 } 00789 00790 CubitString CubitUtil::getenv(const CubitString& var) 00791 { 00792 #ifdef _WIN32 00793 return CubitString::toUtf8(_wgetenv(CubitString::toUtf16(var).c_str())); 00794 #else 00795 return CubitString(::getenv(var.c_str())); 00796 #endif 00797 } 00798 00799 void CubitUtil::setenv(const CubitString& var, const CubitString& value) 00800 { 00801 #ifdef _WIN32 00802 CubitString tmp = var + "=" + value; 00803 _wputenv(CubitString::toUtf16(tmp).c_str()); 00804 #else 00805 ::setenv(var.c_str(), value.c_str(), 1); 00806 #endif 00807 } 00808 00809 00810 CubitString CubitUtil::get_computer_name() 00811 { 00812 CubitString name = "unknown"; 00813 #ifdef _WIN32 00814 wchar_t machine_buf[MAX_COMPUTERNAME_LENGTH + 1]; 00815 DWORD machine_buf_length = MAX_COMPUTERNAME_LENGTH + 1; 00816 if (::GetComputerNameW(machine_buf, &machine_buf_length)) 00817 name = CubitString::toUtf8(machine_buf); 00818 #else 00819 struct utsname uname_data; 00820 if( uname( &uname_data ) >= 0 ) 00821 { 00822 name = uname_data.nodename; 00823 } 00824 #endif 00825 return name; 00826 } 00827 00828 CubitString CubitUtil::get_os() 00829 { 00830 #ifdef _WIN32 00831 CubitString os = "Microsoft Windows"; 00832 OSVERSIONINFO osvi; 00833 00834 ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); 00835 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00836 00837 if(GetVersionEx(&osvi)) 00838 { 00839 std::stringstream str; 00840 str << " "; 00841 str << osvi.dwMajorVersion << "." << osvi.dwMinorVersion; 00842 str << " "; 00843 str << osvi.szCSDVersion; 00844 DWORD build = osvi.dwBuildNumber & 0xFFFF; 00845 str << " (Build " << build << ")"; 00846 os += str.str().c_str(); 00847 } 00848 #else 00849 CubitString os = "unknown"; 00850 struct utsname uname_data; 00851 if( uname( &uname_data ) >= 0 ) 00852 { 00853 os = uname_data.sysname; 00854 os += " "; 00855 os += uname_data.release; 00856 } 00857 #endif 00858 return os; 00859 } 00860 00861 int CubitUtil::num_cpu() 00862 { 00863 int num_cpu = 0; 00864 00865 #ifdef _WIN32 00866 SYSTEM_INFO sysinfo; 00867 GetSystemInfo( &sysinfo ); 00868 num_cpu = sysinfo.dwNumberOfProcessors; 00869 #else 00870 num_cpu = sysconf( _SC_NPROCESSORS_ONLN ); 00871 #endif 00872 00873 return num_cpu; 00874 }