20 #include "kmp_debug.h" 31 #include "kmp_i18n_default.inc" 33 #include "kmp_environment.h" 37 #define get_section( id ) ( (id) >> 16 ) 38 #define get_number( id ) ( (id) & 0xFFFF ) 40 kmp_msg_t __kmp_msg_empty = { kmp_mt_dummy, 0,
"", 0 };
41 kmp_msg_t __kmp_msg_null = { kmp_mt_dummy, 0, NULL, 0 };
42 static char const * no_message_available =
"(No message available)";
44 enum kmp_i18n_cat_status {
49 typedef enum kmp_i18n_cat_status kmp_i18n_cat_status_t;
50 static volatile kmp_i18n_cat_status_t status = KMP_I18N_CLOSED;
60 static void __kmp_i18n_do_catopen();
61 static kmp_bootstrap_lock_t lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( lock );
69 if ( status == KMP_I18N_CLOSED ) {
70 __kmp_acquire_bootstrap_lock( & lock );
71 if ( status == KMP_I18N_CLOSED ) {
72 __kmp_i18n_do_catopen();
74 __kmp_release_bootstrap_lock( & lock );
90 #define KMP_I18N_NULLCAT ((nl_catd)( -1 )) 91 static nl_catd cat = KMP_I18N_NULLCAT;
92 static char const * name = ( KMP_VERSION_MAJOR == 4 ?
"libguide.cat" :
"libomp.cat" );
102 __kmp_i18n_do_catopen(
105 char * lang = __kmp_env_get(
"LANG" );
108 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
109 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
113 strcmp( lang,
"" ) == 0 ||
114 strcmp( lang,
" " ) == 0 ||
117 strcmp( lang,
"C" ) == 0 ||
118 strcmp( lang,
"POSIX" ) == 0;
124 __kmp_str_split( lang,
'@', & lang, & tail );
125 __kmp_str_split( lang,
'.', & lang, & tail );
126 __kmp_str_split( lang,
'_', & lang, & tail );
127 english = ( strcmp( lang,
"en" ) == 0 );
130 KMP_INTERNAL_FREE( lang );
135 status = KMP_I18N_ABSENT;
139 cat = catopen( name, 0 );
141 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
143 if ( status == KMP_I18N_ABSENT ) {
144 if (__kmp_generate_warnings > kmp_warnings_low) {
146 char * nlspath = __kmp_env_get(
"NLSPATH" );
147 char * lang = __kmp_env_get(
"LANG" );
153 KMP_MSG( CantOpenMessageCatalog, name ),
155 KMP_HNT( CheckEnvVar,
"NLSPATH", nlspath ),
156 KMP_HNT( CheckEnvVar,
"LANG", lang ),
159 KMP_INFORM( WillUseDefaultMessages );
160 KMP_INTERNAL_FREE( nlspath );
161 KMP_INTERNAL_FREE( lang );
165 int section = get_section( kmp_i18n_prp_Version );
166 int number = get_number( kmp_i18n_prp_Version );
167 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
169 kmp_str_buf_t version;
170 __kmp_str_buf_init( & version );
171 __kmp_str_buf_print( & version,
"%s", catgets( cat, section, number, NULL ) );
174 if ( strcmp( version.str, expected ) != 0 ) {
175 __kmp_i18n_catclose();
176 status = KMP_I18N_ABSENT;
177 if (__kmp_generate_warnings > kmp_warnings_low) {
179 char const * name =
"NLSPATH";
180 char const * nlspath = __kmp_env_get( name );
183 KMP_MSG( WrongMessageCatalog, name, version.str, expected ),
184 KMP_HNT( CheckEnvVar, name, nlspath ),
187 KMP_INFORM( WillUseDefaultMessages );
188 KMP_INTERNAL_FREE( (
void *) nlspath );
191 __kmp_str_buf_free( & version );
201 if ( status == KMP_I18N_OPENED ) {
202 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
204 cat = KMP_I18N_NULLCAT;
206 status = KMP_I18N_CLOSED;
215 int section = get_section(
id );
216 int number = get_number(
id );
217 char const * message = NULL;
219 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
220 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
221 if ( status == KMP_I18N_CLOSED ) {
222 __kmp_i18n_catopen();
224 if ( status == KMP_I18N_OPENED ) {
229 __kmp_i18n_default_table.sect[ section ].str[ number ]
232 if ( message == NULL ) {
233 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
237 if ( message == NULL ) {
238 message = no_message_available;
245 #endif // KMP_OS_UNIX 256 #include "kmp_environment.h" 259 #define KMP_I18N_NULLCAT NULL 260 static HMODULE cat = KMP_I18N_NULLCAT;
261 static char const * name = ( KMP_VERSION_MAJOR == 4 ?
"libguide40ui.dll" :
"libompui.dll" );
263 static kmp_i18n_table_t table = { 0, NULL };
267 static UINT
const default_code_page = CP_OEMCP;
268 static UINT code_page = default_code_page;
270 static char const * ___catgets( kmp_i18n_id_t
id );
271 static UINT get_code_page();
272 static void kmp_i18n_table_free( kmp_i18n_table_t * table );
279 UINT cp = default_code_page;
280 char const * value = __kmp_env_get(
"KMP_CODEPAGE" );
281 if ( value != NULL ) {
282 if ( _stricmp( value,
"ANSI" ) == 0 ) {
284 }
else if ( _stricmp( value,
"OEM" ) == 0 ) {
286 }
else if ( _stricmp( value,
"UTF-8" ) == 0 || _stricmp( value,
"UTF8" ) == 0 ) {
288 }
else if ( _stricmp( value,
"UTF-7" ) == 0 || _stricmp( value,
"UTF7" ) == 0 ) {
294 KMP_INTERNAL_FREE( (
void *) value );
302 kmp_i18n_table_t * table
306 for ( s = 0; s < table->size; ++ s ) {
307 for ( m = 0; m < table->sect[ s ].size; ++ m ) {
309 KMP_INTERNAL_FREE( (
void *) table->sect[ s ].str[ m ] );
310 table->sect[ s ].str[ m ] = NULL;
312 table->sect[ s ].size = 0;
314 KMP_INTERNAL_FREE ( (
void *) table->sect[ s ].str );
315 table->sect[ s ].str = NULL;
318 KMP_INTERNAL_FREE( (
void *) table->sect );
324 __kmp_i18n_do_catopen(
327 LCID locale_id = GetThreadLocale();
328 WORD lang_id = LANGIDFROMLCID( locale_id );
329 WORD primary_lang_id = PRIMARYLANGID( lang_id );
332 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
333 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
335 __kmp_str_buf_init( & path );
339 if ( primary_lang_id == LANG_ENGLISH ) {
340 status = KMP_I18N_ABSENT;
358 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
359 reinterpret_cast< LPCSTR >( & __kmp_i18n_do_catopen ),
363 status = KMP_I18N_ABSENT;
371 DWORD drc = GetModuleFileName( handle, path.str, path.size );
373 status = KMP_I18N_ABSENT;
376 if ( drc < path.size ) {
380 __kmp_str_buf_reserve( & path, path.size * 2 );
385 __kmp_str_fname_init( & fname, path.str );
386 __kmp_str_buf_clear( & path );
387 __kmp_str_buf_print( & path,
"%s%lu/%s", fname.dir, (
unsigned long)( locale_id ), name );
388 __kmp_str_fname_free( & fname );
393 cat = LoadLibraryEx( path.str, NULL, LOAD_LIBRARY_AS_DATAFILE );
394 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
396 if ( status == KMP_I18N_ABSENT ) {
397 if (__kmp_generate_warnings > kmp_warnings_low) {
398 DWORD error = GetLastError();
416 KMP_MSG( CantOpenMessageCatalog, path.str ),
417 KMP_SYSERRCODE( error ),
418 ( error == ERROR_BAD_EXE_FORMAT ? KMP_HNT( BadExeFormat, path.str, KMP_ARCH_STR ) : __kmp_msg_null ),
421 KMP_INFORM( WillUseDefaultMessages );
425 int section = get_section( kmp_i18n_prp_Version );
426 int number = get_number( kmp_i18n_prp_Version );
427 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
428 kmp_str_buf_t version;
429 __kmp_str_buf_init( & version );
430 __kmp_str_buf_print( & version,
"%s", ___catgets( kmp_i18n_prp_Version ) );
432 if ( strcmp( version.str, expected ) != 0 ) {
434 __kmp_i18n_catclose();
435 status = KMP_I18N_ABSENT;
436 if (__kmp_generate_warnings > kmp_warnings_low) {
440 KMP_MSG( WrongMessageCatalog, path.str, version.str, expected ),
443 KMP_INFORM( WillUseDefaultMessages );
446 __kmp_str_buf_free( & version );
449 code_page = get_code_page();
452 __kmp_str_buf_free( & path );
461 if ( status == KMP_I18N_OPENED ) {
462 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
463 kmp_i18n_table_free( & table );
465 cat = KMP_I18N_NULLCAT;
467 code_page = default_code_page;
468 status = KMP_I18N_CLOSED;
504 if ( str[ in ] !=
'\r' ) {
505 str[ out ] = str[ in ];
508 if ( str[ in ] == 0 ) {
523 char * result = NULL;
525 wchar_t * wmsg = NULL;
531 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
534 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
535 FORMAT_MESSAGE_IGNORE_INSERTS,
546 wmsg = (
wchar_t *) addr;
562 msg = (
char *) KMP_INTERNAL_MALLOC( len + 1 );
573 if ( rc <= 0 || rc > len ) {
576 KMP_DEBUG_ASSERT( rc == len );
581 len = ___strip_crs( msg );
584 if ( len >= 1 && msg[ len - 1 ] ==
'\n' ) {
596 KMP_INTERNAL_FREE( msg );
598 if ( wmsg != NULL ) {
612 int section = get_section(
id );
613 int number = get_number(
id );
614 char const * message = NULL;
616 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
617 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
618 if ( status == KMP_I18N_CLOSED ) {
619 __kmp_i18n_catopen();
621 if ( cat != KMP_I18N_NULLCAT ) {
622 if ( table.size == 0 ) {
623 table.sect = (kmp_i18n_section_t *)
625 ( __kmp_i18n_default_table.size + 2 ),
626 sizeof( kmp_i18n_section_t )
628 table.size = __kmp_i18n_default_table.size;
630 if ( table.sect[ section ].size == 0 ) {
631 table.sect[ section ].str = (
const char **)
633 __kmp_i18n_default_table.sect[ section ].size + 2,
634 sizeof(
char const * )
636 table.sect[ section ].size = __kmp_i18n_default_table.sect[ section ].size;
638 if ( table.sect[ section ].str[ number ] == NULL ) {
639 table.sect[ section ].str[ number ] = ___catgets(
id );
641 message = table.sect[ section ].str[ number ];
643 if ( message == NULL ) {
645 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
649 if ( message == NULL ) {
650 message = no_message_available;
657 #endif // KMP_OS_WINDOWS 662 #error I18n support is not implemented for this OS. 663 #endif // KMP_I18N_OK 668 __kmp_i18n_dump_catalog(
669 kmp_str_buf_t * buffer
672 struct kmp_i18n_id_range_t {
677 static struct kmp_i18n_id_range_t ranges[] = {
678 { kmp_i18n_prp_first, kmp_i18n_prp_last },
679 { kmp_i18n_str_first, kmp_i18n_str_last },
680 { kmp_i18n_fmt_first, kmp_i18n_fmt_last },
681 { kmp_i18n_msg_first, kmp_i18n_msg_last },
682 { kmp_i18n_hnt_first, kmp_i18n_hnt_last }
685 int num_of_ranges =
sizeof( ranges ) /
sizeof(
struct kmp_i18n_id_range_t );
689 for ( range = 0; range < num_of_ranges; ++ range ) {
690 __kmp_str_buf_print( buffer,
"*** Set #%d ***\n", range + 1 );
691 for (
id = (kmp_i18n_id_t)( ranges[ range ].first + 1 );
692 id < ranges[ range ].last;
693 id = (kmp_i18n_id_t)(
id + 1 ) ) {
694 __kmp_str_buf_print( buffer,
"%d: <<%s>>\n",
id, __kmp_i18n_catgets(
id ) );
698 __kmp_printf(
"%s", buffer->str );
712 kmp_str_buf_t buffer;
713 __kmp_str_buf_init( & buffer );
715 va_start( args,
id );
719 __kmp_str_buf_vprint( & buffer, __kmp_i18n_catgets(
id ), args );
728 FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
729 __kmp_i18n_catgets(
id ),
735 len = ___strip_crs( str );
736 __kmp_str_buf_cat( & buffer, str, len );
743 __kmp_str_buf_detach( & buffer );
745 msg.type = (kmp_msg_type_t)(
id >> 16 );
746 msg.num =
id & 0xFFFF;
747 msg.str = buffer.str;
748 msg.len = buffer.used;
762 char * message = NULL;
766 LPVOID buffer = NULL;
771 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
774 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
781 message = __kmp_str_format(
"%s", (
char *) buffer );
782 len = ___strip_crs( message );
784 while ( len > 0 && message[ len - 1 ] ==
'\n' ) {
793 if ( buffer != NULL ) {
797 #else // Non-Windows* OS: Linux* OS or OS X* 811 char *
const err_msg = strerror_r( err, buffer,
sizeof( buffer ) );
814 message = __kmp_str_format(
"%s", err_msg );
816 #else // OS X*, FreeBSD* etc. 822 char * buffer = (
char *) KMP_INTERNAL_MALLOC( size );
824 rc = strerror_r( err, buffer, size );
828 while ( rc == ERANGE ) {
829 KMP_INTERNAL_FREE( buffer );
831 buffer = (
char *) KMP_INTERNAL_MALLOC( size );
832 rc = strerror_r( err, buffer, size );
841 KMP_INTERNAL_FREE( buffer );
848 if ( message == NULL ) {
850 message = __kmp_str_format(
"%s",
"(No system error message available)" );
859 __kmp_msg_error_code(
864 msg.type = kmp_mt_syserr;
866 msg.str = sys_error( code );
867 msg.len = KMP_STRLEN( msg.str );
875 __kmp_msg_error_mesg(
880 msg.type = kmp_mt_syserr;
882 msg.str = __kmp_str_format(
"%s", mesg );
883 msg.len = KMP_STRLEN( msg.str );
892 kmp_msg_severity_t severity,
898 kmp_i18n_id_t format;
900 kmp_str_buf_t buffer;
902 if ( severity != kmp_ms_fatal && __kmp_generate_warnings == kmp_warnings_off )
905 __kmp_str_buf_init( & buffer );
908 switch ( severity ) {
909 case kmp_ms_inform : {
910 format = kmp_i18n_fmt_Info;
912 case kmp_ms_warning : {
913 format = kmp_i18n_fmt_Warning;
915 case kmp_ms_fatal : {
916 format = kmp_i18n_fmt_Fatal;
919 KMP_DEBUG_ASSERT( 0 );
922 fmsg = __kmp_msg_format( format, message.num, message.str );
923 KMP_INTERNAL_FREE( (
void *) message.str );
924 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
925 KMP_INTERNAL_FREE( (
void *) fmsg.str );
928 va_start( args, message );
930 message = va_arg( args, kmp_msg_t );
931 if ( message.type == kmp_mt_dummy && message.str == NULL ) {
934 if ( message.type == kmp_mt_dummy && message.str == __kmp_msg_empty.str ) {
937 switch ( message.type ) {
939 format = kmp_i18n_fmt_Hint;
941 case kmp_mt_syserr : {
942 format = kmp_i18n_fmt_SysErr;
945 KMP_DEBUG_ASSERT( 0 );
948 fmsg = __kmp_msg_format( format, message.num, message.str );
949 KMP_INTERNAL_FREE( (
void *) message.str );
950 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
951 KMP_INTERNAL_FREE( (
void *) fmsg.str );
958 __kmp_printf(
"%s", buffer.str );
959 __kmp_str_buf_free( & buffer );
961 if ( severity == kmp_ms_fatal ) {
963 __kmp_thread_sleep( 500 );
965 __kmp_abort_process();