00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "kmp_i18n.h"
00049
00050 #include "kmp_os.h"
00051 #include "kmp_debug.h"
00052 #include "kmp.h"
00053 #include "kmp_lock.h"
00054 #include "kmp_io.h"
00055
00056 #include <stdio.h>
00057 #include <errno.h>
00058 #include <string.h>
00059 #include <locale.h>
00060 #include <stdarg.h>
00061
00062 #include "kmp_i18n_default.inc"
00063 #include "kmp_str.h"
00064 #include "kmp_environment.h"
00065
00066 #undef KMP_I18N_OK
00067
00068 #define get_section( id ) ( (id) >> 16 )
00069 #define get_number( id ) ( (id) & 0xFFFF )
00070
00071 kmp_msg_t __kmp_msg_empty = { kmp_mt_dummy, 0, "", 0 };
00072 kmp_msg_t __kmp_msg_null = { kmp_mt_dummy, 0, NULL, 0 };
00073 static char const * no_message_available = "(No message available)";
00074
00075 enum kmp_i18n_cat_status {
00076 KMP_I18N_CLOSED,
00077 KMP_I18N_OPENED,
00078 KMP_I18N_ABSENT
00079 };
00080 typedef enum kmp_i18n_cat_status kmp_i18n_cat_status_t;
00081 static volatile kmp_i18n_cat_status_t status = KMP_I18N_CLOSED;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 static void __kmp_i18n_do_catopen();
00092 static kmp_bootstrap_lock_t lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( lock );
00093
00094
00095
00096
00097 void
00098 __kmp_i18n_catopen(
00099 ) {
00100 if ( status == KMP_I18N_CLOSED ) {
00101 __kmp_acquire_bootstrap_lock( & lock );
00102 if ( status == KMP_I18N_CLOSED ) {
00103 __kmp_i18n_do_catopen();
00104 };
00105 __kmp_release_bootstrap_lock( & lock );
00106 };
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 #if KMP_OS_UNIX
00117 #define KMP_I18N_OK
00118
00119 #include <nl_types.h>
00120
00121 #define KMP_I18N_NULLCAT ((nl_catd)( -1 ))
00122 static nl_catd cat = KMP_I18N_NULLCAT;
00123 static char const * name = ( KMP_VERSION_MAJOR == 4 ? "libguide.cat" : "libiomp5.cat" );
00124
00125
00126
00127
00128
00129
00130
00131
00132 void
00133 __kmp_i18n_do_catopen(
00134 ) {
00135 int english = 0;
00136 char * lang = __kmp_env_get( "LANG" );
00137
00138
00139 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
00140 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
00141
00142 english =
00143 lang == NULL ||
00144 strcmp( lang, "" ) == 0 ||
00145 strcmp( lang, " " ) == 0 ||
00146
00147
00148 strcmp( lang, "C" ) == 0 ||
00149 strcmp( lang, "POSIX" ) == 0;
00150
00151 if ( ! english ) {
00152
00153
00154 char * tail = NULL;
00155 __kmp_str_split( lang, '@', & lang, & tail );
00156 __kmp_str_split( lang, '.', & lang, & tail );
00157 __kmp_str_split( lang, '_', & lang, & tail );
00158 english = ( strcmp( lang, "en" ) == 0 );
00159 };
00160
00161 KMP_INTERNAL_FREE( lang );
00162
00163
00164
00165 if ( english ) {
00166 status = KMP_I18N_ABSENT;
00167 return;
00168 }
00169
00170 cat = catopen( name, 0 );
00171
00172 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
00173
00174 if ( status == KMP_I18N_ABSENT ) {
00175 if (__kmp_generate_warnings > kmp_warnings_low) {
00176 int error = errno;
00177 char * nlspath = __kmp_env_get( "NLSPATH" );
00178 char * lang = __kmp_env_get( "LANG" );
00179
00180
00181
00182 __kmp_msg(
00183 kmp_ms_warning,
00184 KMP_MSG( CantOpenMessageCatalog, name ),
00185 KMP_ERR( error ),
00186 KMP_HNT( CheckEnvVar, "NLSPATH", nlspath ),
00187 KMP_HNT( CheckEnvVar, "LANG", lang ),
00188 __kmp_msg_null
00189 );
00190 KMP_INFORM( WillUseDefaultMessages );
00191 KMP_INTERNAL_FREE( nlspath );
00192 KMP_INTERNAL_FREE( lang );
00193 }
00194 } else {
00195
00196 int section = get_section( kmp_i18n_prp_Version );
00197 int number = get_number( kmp_i18n_prp_Version );
00198 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
00199
00200 kmp_str_buf_t version;
00201 __kmp_str_buf_init( & version );
00202 __kmp_str_buf_print( & version, "%s", catgets( cat, section, number, NULL ) );
00203
00204
00205 if ( strcmp( version.str, expected ) != 0 ) {
00206 __kmp_i18n_catclose();
00207 status = KMP_I18N_ABSENT;
00208 if (__kmp_generate_warnings > kmp_warnings_low) {
00209
00210 char const * name = "NLSPATH";
00211 char const * nlspath = __kmp_env_get( name );
00212 __kmp_msg(
00213 kmp_ms_warning,
00214 KMP_MSG( WrongMessageCatalog, name, version.str, expected ),
00215 KMP_HNT( CheckEnvVar, name, nlspath ),
00216 __kmp_msg_null
00217 );
00218 KMP_INFORM( WillUseDefaultMessages );
00219 KMP_INTERNAL_FREE( (void *) nlspath );
00220 }
00221 };
00222 __kmp_str_buf_free( & version );
00223
00224 };
00225
00226 }
00227
00228
00229 void
00230 __kmp_i18n_catclose(
00231 ) {
00232 if ( status == KMP_I18N_OPENED ) {
00233 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
00234 catclose( cat );
00235 cat = KMP_I18N_NULLCAT;
00236 };
00237 status = KMP_I18N_CLOSED;
00238 }
00239
00240
00241 char const *
00242 __kmp_i18n_catgets(
00243 kmp_i18n_id_t id
00244 ) {
00245
00246 int section = get_section( id );
00247 int number = get_number( id );
00248 char const * message = NULL;
00249
00250 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
00251 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
00252 if ( status == KMP_I18N_CLOSED ) {
00253 __kmp_i18n_catopen();
00254 };
00255 if ( status == KMP_I18N_OPENED ) {
00256 message =
00257 catgets(
00258 cat,
00259 section, number,
00260 __kmp_i18n_default_table.sect[ section ].str[ number ]
00261 );
00262 };
00263 if ( message == NULL ) {
00264 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
00265 };
00266 };
00267 };
00268 if ( message == NULL ) {
00269 message = no_message_available;
00270 };
00271 return message;
00272
00273 }
00274
00275
00276 #endif // KMP_OS_UNIX
00277
00278
00279
00280
00281
00282
00283
00284 #if KMP_OS_WINDOWS
00285 #define KMP_I18N_OK
00286
00287 #include "kmp_environment.h"
00288 #include <windows.h>
00289
00290 #define KMP_I18N_NULLCAT NULL
00291 static HMODULE cat = KMP_I18N_NULLCAT;
00292 static char const * name = ( KMP_VERSION_MAJOR == 4 ? "libguide40ui.dll" : "libiomp5ui.dll" );
00293
00294 static kmp_i18n_table_t table = { 0, NULL };
00295
00296
00297
00298 static UINT const default_code_page = CP_OEMCP;
00299 static UINT code_page = default_code_page;
00300
00301 static char const * ___catgets( kmp_i18n_id_t id );
00302 static UINT get_code_page();
00303 static void kmp_i18n_table_free( kmp_i18n_table_t * table );
00304
00305
00306 static UINT
00307 get_code_page(
00308 ) {
00309
00310 UINT cp = default_code_page;
00311 char const * value = __kmp_env_get( "KMP_CODEPAGE" );
00312 if ( value != NULL ) {
00313 if ( _stricmp( value, "ANSI" ) == 0 ) {
00314 cp = CP_ACP;
00315 } else if ( _stricmp( value, "OEM" ) == 0 ) {
00316 cp = CP_OEMCP;
00317 } else if ( _stricmp( value, "UTF-8" ) == 0 || _stricmp( value, "UTF8" ) == 0 ) {
00318 cp = CP_UTF8;
00319 } else if ( _stricmp( value, "UTF-7" ) == 0 || _stricmp( value, "UTF7" ) == 0 ) {
00320 cp = CP_UTF7;
00321 } else {
00322
00323 };
00324 };
00325 KMP_INTERNAL_FREE( (void *) value );
00326 return cp;
00327
00328 }
00329
00330
00331 static void
00332 kmp_i18n_table_free(
00333 kmp_i18n_table_t * table
00334 ) {
00335 int s;
00336 int m;
00337 for ( s = 0; s < table->size; ++ s ) {
00338 for ( m = 0; m < table->sect[ s ].size; ++ m ) {
00339
00340 KMP_INTERNAL_FREE( (void *) table->sect[ s ].str[ m ] );
00341 table->sect[ s ].str[ m ] = NULL;
00342 };
00343 table->sect[ s ].size = 0;
00344
00345 KMP_INTERNAL_FREE ( (void *) table->sect[ s ].str );
00346 table->sect[ s ].str = NULL;
00347 };
00348 table->size = 0;
00349 KMP_INTERNAL_FREE( (void *) table->sect );
00350 table->sect = NULL;
00351 }
00352
00353
00354 void
00355 __kmp_i18n_do_catopen(
00356 ) {
00357
00358 LCID locale_id = GetThreadLocale();
00359 WORD lang_id = LANGIDFROMLCID( locale_id );
00360 WORD primary_lang_id = PRIMARYLANGID( lang_id );
00361 kmp_str_buf_t path;
00362
00363 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
00364 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
00365
00366 __kmp_str_buf_init( & path );
00367
00368
00369
00370 if ( primary_lang_id == LANG_ENGLISH ) {
00371 status = KMP_I18N_ABSENT;
00372 goto end;
00373 };
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 {
00384
00385
00386 HMODULE handle;
00387 BOOL brc =
00388 GetModuleHandleEx(
00389 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
00390 reinterpret_cast< LPCSTR >( & __kmp_i18n_do_catopen ),
00391 & handle
00392 );
00393 if ( ! brc ) {
00394 status = KMP_I18N_ABSENT;
00395 goto end;
00396
00397
00398 };
00399
00400
00401 for ( ; ; ) {
00402 DWORD drc = GetModuleFileName( handle, path.str, path.size );
00403 if ( drc == 0 ) {
00404 status = KMP_I18N_ABSENT;
00405 goto end;
00406 };
00407 if ( drc < path.size ) {
00408 path.used = drc;
00409 break;
00410 };
00411 __kmp_str_buf_reserve( & path, path.size * 2 );
00412 };
00413
00414
00415 kmp_str_fname fname;
00416 __kmp_str_fname_init( & fname, path.str );
00417 __kmp_str_buf_clear( & path );
00418 __kmp_str_buf_print( & path, "%s%lu/%s", fname.dir, (unsigned long)( locale_id ), name );
00419 __kmp_str_fname_free( & fname );
00420
00421 }
00422
00423
00424 cat = LoadLibraryEx( path.str, NULL, LOAD_LIBRARY_AS_DATAFILE );
00425 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
00426
00427 if ( status == KMP_I18N_ABSENT ) {
00428 if (__kmp_generate_warnings > kmp_warnings_low) {
00429 DWORD error = GetLastError();
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 __kmp_msg(
00446 kmp_ms_warning,
00447 KMP_MSG( CantOpenMessageCatalog, path.str ),
00448 KMP_SYSERRCODE( error ),
00449 ( error == ERROR_BAD_EXE_FORMAT ? KMP_HNT( BadExeFormat, path.str, KMP_ARCH_STR ) : __kmp_msg_null ),
00450 __kmp_msg_null
00451 );
00452 KMP_INFORM( WillUseDefaultMessages );
00453 }
00454 } else {
00455
00456 int section = get_section( kmp_i18n_prp_Version );
00457 int number = get_number( kmp_i18n_prp_Version );
00458 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
00459 kmp_str_buf_t version;
00460 __kmp_str_buf_init( & version );
00461 __kmp_str_buf_print( & version, "%s", ___catgets( kmp_i18n_prp_Version ) );
00462
00463 if ( strcmp( version.str, expected ) != 0 ) {
00464
00465 __kmp_i18n_catclose();
00466 status = KMP_I18N_ABSENT;
00467 if (__kmp_generate_warnings > kmp_warnings_low) {
00468
00469 __kmp_msg(
00470 kmp_ms_warning,
00471 KMP_MSG( WrongMessageCatalog, path.str, version.str, expected ),
00472 __kmp_msg_null
00473 );
00474 KMP_INFORM( WillUseDefaultMessages );
00475 }
00476 };
00477 __kmp_str_buf_free( & version );
00478
00479 };
00480 code_page = get_code_page();
00481
00482 end:
00483 __kmp_str_buf_free( & path );
00484 return;
00485
00486 }
00487
00488
00489 void
00490 __kmp_i18n_catclose(
00491 ) {
00492 if ( status == KMP_I18N_OPENED ) {
00493 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
00494 kmp_i18n_table_free( & table );
00495 FreeLibrary( cat );
00496 cat = KMP_I18N_NULLCAT;
00497 };
00498 code_page = default_code_page;
00499 status = KMP_I18N_CLOSED;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 static
00528 int
00529 ___strip_crs(
00530 char * str
00531 ) {
00532 int in = 0;
00533 int out = 0;
00534 for ( ; ; ) {
00535 if ( str[ in ] != '\r' ) {
00536 str[ out ] = str[ in ];
00537 ++ out;
00538 };
00539 if ( str[ in ] == 0 ) {
00540 break;
00541 };
00542 ++ in;
00543 };
00544 return out - 1;
00545 }
00546
00547
00548 static
00549 char const *
00550 ___catgets(
00551 kmp_i18n_id_t id
00552 ) {
00553
00554 char * result = NULL;
00555 PVOID addr = NULL;
00556 wchar_t * wmsg = NULL;
00557 DWORD wlen = 0;
00558 char * msg = NULL;
00559 int len = 0;
00560 int rc;
00561
00562 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
00563 wlen =
00564 FormatMessageW(
00565 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
00566 FORMAT_MESSAGE_IGNORE_INSERTS,
00567 cat,
00568 id,
00569 0,
00570 (LPWSTR) & addr,
00571 0,
00572 NULL
00573 );
00574 if ( wlen <= 0 ) {
00575 goto end;
00576 };
00577 wmsg = (wchar_t *) addr;
00578
00579
00580 len =
00581 WideCharToMultiByte(
00582 code_page,
00583 0,
00584 wmsg, wlen,
00585 NULL, 0,
00586 NULL, NULL
00587 );
00588 if ( len <= 0 ) {
00589 goto end;
00590 };
00591
00592
00593 msg = (char *) KMP_INTERNAL_MALLOC( len + 1 );
00594
00595
00596 rc =
00597 WideCharToMultiByte(
00598 code_page,
00599 0,
00600 wmsg, wlen,
00601 msg, len,
00602 NULL, NULL
00603 );
00604 if ( rc <= 0 || rc > len ) {
00605 goto end;
00606 };
00607 KMP_DEBUG_ASSERT( rc == len );
00608 len = rc;
00609 msg[ len ] = 0;
00610
00611
00612 len = ___strip_crs( msg );
00613
00614
00615 if ( len >= 1 && msg[ len - 1 ] == '\n' ) {
00616 -- len;
00617 msg[ len ] = 0;
00618 };
00619
00620
00621 result = msg;
00622 msg = NULL;
00623
00624 end:
00625
00626 if ( msg != NULL ) {
00627 KMP_INTERNAL_FREE( msg );
00628 };
00629 if ( wmsg != NULL ) {
00630 LocalFree( wmsg );
00631 };
00632
00633 return result;
00634
00635 }
00636
00637
00638 char const *
00639 __kmp_i18n_catgets(
00640 kmp_i18n_id_t id
00641 ) {
00642
00643 int section = get_section( id );
00644 int number = get_number( id );
00645 char const * message = NULL;
00646
00647 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
00648 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
00649 if ( status == KMP_I18N_CLOSED ) {
00650 __kmp_i18n_catopen();
00651 };
00652 if ( cat != KMP_I18N_NULLCAT ) {
00653 if ( table.size == 0 ) {
00654 table.sect = (kmp_i18n_section_t *)
00655 KMP_INTERNAL_CALLOC(
00656 ( __kmp_i18n_default_table.size + 2 ),
00657 sizeof( kmp_i18n_section_t )
00658 );
00659 table.size = __kmp_i18n_default_table.size;
00660 };
00661 if ( table.sect[ section ].size == 0 ) {
00662 table.sect[ section ].str = (const char **)
00663 KMP_INTERNAL_CALLOC(
00664 __kmp_i18n_default_table.sect[ section ].size + 2,
00665 sizeof( char const * )
00666 );
00667 table.sect[ section ].size = __kmp_i18n_default_table.sect[ section ].size;
00668 };
00669 if ( table.sect[ section ].str[ number ] == NULL ) {
00670 table.sect[ section ].str[ number ] = ___catgets( id );
00671 };
00672 message = table.sect[ section ].str[ number ];
00673 };
00674 if ( message == NULL ) {
00675
00676 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
00677 };
00678 };
00679 };
00680 if ( message == NULL ) {
00681 message = no_message_available;
00682 };
00683 return message;
00684
00685 }
00686
00687
00688 #endif // KMP_OS_WINDOWS
00689
00690
00691
00692 #ifndef KMP_I18N_OK
00693 #error I18n support is not implemented for this OS.
00694 #endif // KMP_I18N_OK
00695
00696
00697
00698 void
00699 __kmp_i18n_dump_catalog(
00700 kmp_str_buf_t & buffer
00701 ) {
00702
00703 struct kmp_i18n_id_range_t {
00704 kmp_i18n_id_t first;
00705 kmp_i18n_id_t last;
00706 };
00707
00708 static kmp_i18n_id_range_t ranges[] = {
00709 { kmp_i18n_prp_first, kmp_i18n_prp_last },
00710 { kmp_i18n_str_first, kmp_i18n_str_last },
00711 { kmp_i18n_fmt_first, kmp_i18n_fmt_last },
00712 { kmp_i18n_msg_first, kmp_i18n_msg_last },
00713 { kmp_i18n_hnt_first, kmp_i18n_hnt_last }
00714 };
00715
00716 int num_of_ranges = sizeof( ranges ) / sizeof( kmp_i18n_id_range_t );
00717 int range;
00718 kmp_i18n_id_t id;
00719
00720 for ( range = 0; range < num_of_ranges; ++ range ) {
00721 __kmp_str_buf_print( & buffer, "*** Set #%d ***\n", range + 1 );
00722 for ( id = kmp_i18n_id_t( ranges[ range ].first + 1 ); id < ranges[ range ].last; id = kmp_i18n_id_t( id + 1 ) ) {
00723 __kmp_str_buf_print( & buffer, "%d: <<%s>>\n", id, __kmp_i18n_catgets( id ) );
00724 };
00725 };
00726
00727 __kmp_printf( "%s", buffer.str );
00728
00729 }
00730
00731
00732
00733 kmp_msg_t
00734 __kmp_msg_format(
00735 kmp_i18n_id_t id,
00736 ...
00737 ) {
00738
00739 kmp_msg_t msg;
00740 va_list args;
00741 kmp_str_buf_t buffer;
00742 __kmp_str_buf_init( & buffer );
00743
00744 va_start( args, id );
00745 #if KMP_OS_UNIX
00746
00747
00748 __kmp_str_buf_vprint( & buffer, __kmp_i18n_catgets( id ), args );
00749 #elif KMP_OS_WINDOWS
00750
00751
00752
00753 {
00754 LPTSTR str = NULL;
00755 int len;
00756 FormatMessage(
00757 FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
00758 __kmp_i18n_catgets( id ),
00759 0, 0,
00760 (LPTSTR)( & str ),
00761 0,
00762 & args
00763 );
00764 len = ___strip_crs( str );
00765 __kmp_str_buf_cat( & buffer, str, len );
00766 LocalFree( str );
00767 }
00768 #else
00769 #error
00770 #endif
00771 va_end( args );
00772 __kmp_str_buf_detach( & buffer );
00773
00774 msg.type = (kmp_msg_type_t)( id >> 16 );
00775 msg.num = id & 0xFFFF;
00776 msg.str = buffer.str;
00777 msg.len = buffer.used;
00778
00779 return msg;
00780
00781 }
00782
00783
00784
00785 static
00786 char *
00787 sys_error(
00788 int err
00789 ) {
00790
00791 char * message = NULL;
00792
00793 #if KMP_OS_WINDOWS
00794
00795 LPVOID buffer = NULL;
00796 int len;
00797 DWORD rc;
00798 rc =
00799 FormatMessage(
00800 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00801 NULL,
00802 err,
00803 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
00804 (LPTSTR) & buffer,
00805 0,
00806 NULL
00807 );
00808 if ( rc > 0 ) {
00809
00810 message = __kmp_str_format( "%s", (char *) buffer );
00811 len = ___strip_crs( message );
00812
00813 while ( len > 0 && message[ len - 1 ] == '\n' ) {
00814 -- len;
00815 };
00816 message[ len ] = 0;
00817 } else {
00818
00819
00820
00821 };
00822 if ( buffer != NULL ) {
00823 LocalFree( buffer );
00824 };
00825
00826 #else // Non-Windows* OS: Linux* OS or OS X*
00827
00828
00829
00830
00831
00832
00833
00834
00835 #if KMP_OS_LINUX
00836
00837
00838
00839 char buffer[ 2048 ];
00840 char * const err_msg = strerror_r( err, buffer, sizeof( buffer ) );
00841
00842
00843 message = __kmp_str_format( "%s", err_msg );
00844
00845 #else // OS X*
00846
00847
00848
00849 int size = 2048;
00850
00851 char * buffer = (char *) KMP_INTERNAL_MALLOC( size );
00852 int rc;
00853 rc = strerror_r( err, buffer, size );
00854 if ( rc == -1 ) {
00855 rc = errno;
00856 };
00857 while ( rc == ERANGE ) {
00858 KMP_INTERNAL_FREE( buffer );
00859 size *= 2;
00860 buffer = (char *) KMP_INTERNAL_MALLOC( size );
00861 rc = strerror_r( err, buffer, size );
00862 if ( rc == -1 ) {
00863 rc = errno;
00864 };
00865 };
00866 if ( rc == 0 ) {
00867 message = buffer;
00868 } else {
00869
00870 KMP_INTERNAL_FREE( buffer );
00871 };
00872
00873 #endif
00874
00875 #endif
00876
00877 if ( message == NULL ) {
00878
00879 message = __kmp_str_format( "%s", "(No system error message available)" );
00880 };
00881 return message;
00882
00883 }
00884
00885
00886
00887 kmp_msg_t
00888 __kmp_msg_error_code(
00889 int code
00890 ) {
00891
00892 kmp_msg_t msg;
00893 msg.type = kmp_mt_syserr;
00894 msg.num = code;
00895 msg.str = sys_error( code );
00896 msg.len = strlen( msg.str );
00897 return msg;
00898
00899 }
00900
00901
00902
00903 kmp_msg_t
00904 __kmp_msg_error_mesg(
00905 char const * mesg
00906 ) {
00907
00908 kmp_msg_t msg;
00909 msg.type = kmp_mt_syserr;
00910 msg.num = 0;
00911 msg.str = __kmp_str_format( "%s", mesg );
00912 msg.len = strlen( msg.str );
00913 return msg;
00914
00915 }
00916
00917
00918
00919 void
00920 __kmp_msg(
00921 kmp_msg_severity_t severity,
00922 kmp_msg_t message,
00923 ...
00924 ) {
00925
00926 va_list args;
00927 kmp_i18n_id_t format;
00928 kmp_msg_t fmsg;
00929 kmp_str_buf_t buffer;
00930
00931 if ( severity != kmp_ms_fatal && __kmp_generate_warnings == kmp_warnings_off )
00932 return;
00933
00934 __kmp_str_buf_init( & buffer );
00935
00936
00937 switch ( severity ) {
00938 case kmp_ms_inform : {
00939 format = kmp_i18n_fmt_Info;
00940 } break;
00941 case kmp_ms_warning : {
00942 format = kmp_i18n_fmt_Warning;
00943 } break;
00944 case kmp_ms_fatal : {
00945 format = kmp_i18n_fmt_Fatal;
00946 } break;
00947 default : {
00948 KMP_DEBUG_ASSERT( 0 );
00949 };
00950 };
00951 fmsg = __kmp_msg_format( format, message.num, message.str );
00952 KMP_INTERNAL_FREE( (void *) message.str );
00953 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
00954 KMP_INTERNAL_FREE( (void *) fmsg.str );
00955
00956
00957 va_start( args, message );
00958 for ( ; ; ) {
00959 message = va_arg( args, kmp_msg_t );
00960 if ( message.type == kmp_mt_dummy && message.str == NULL ) {
00961 break;
00962 };
00963 if ( message.type == kmp_mt_dummy && message.str == __kmp_msg_empty.str ) {
00964 continue;
00965 };
00966 switch ( message.type ) {
00967 case kmp_mt_hint : {
00968 format = kmp_i18n_fmt_Hint;
00969 } break;
00970 case kmp_mt_syserr : {
00971 format = kmp_i18n_fmt_SysErr;
00972 } break;
00973 default : {
00974 KMP_DEBUG_ASSERT( 0 );
00975 };
00976 };
00977 fmsg = __kmp_msg_format( format, message.num, message.str );
00978 KMP_INTERNAL_FREE( (void *) message.str );
00979 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
00980 KMP_INTERNAL_FREE( (void *) fmsg.str );
00981 };
00982 va_end( args );
00983
00984
00985
00986
00987 __kmp_printf( "%s", buffer.str );
00988 __kmp_str_buf_free( & buffer );
00989
00990 if ( severity == kmp_ms_fatal ) {
00991 #if KMP_OS_WINDOWS
00992 __kmp_thread_sleep( 500 );
00993 #endif
00994 __kmp_abort_process();
00995 };
00996
00997
00998
00999 }
01000
01001
01002
01003