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" );
151 kmp_msg_t err_code = KMP_ERR( error );
154 KMP_MSG( CantOpenMessageCatalog, name ),
156 KMP_HNT( CheckEnvVar,
"NLSPATH", nlspath ),
157 KMP_HNT( CheckEnvVar,
"LANG", lang ),
160 if (__kmp_generate_warnings == kmp_warnings_off) {
161 __kmp_str_free(&err_code.str);
164 KMP_INFORM( WillUseDefaultMessages );
165 KMP_INTERNAL_FREE( nlspath );
166 KMP_INTERNAL_FREE( lang );
170 int section = get_section( kmp_i18n_prp_Version );
171 int number = get_number( kmp_i18n_prp_Version );
172 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
174 kmp_str_buf_t version;
175 __kmp_str_buf_init( & version );
176 __kmp_str_buf_print( & version,
"%s", catgets( cat, section, number, NULL ) );
179 if ( strcmp( version.str, expected ) != 0 ) {
180 __kmp_i18n_catclose();
181 status = KMP_I18N_ABSENT;
182 if (__kmp_generate_warnings > kmp_warnings_low) {
184 char const * name =
"NLSPATH";
185 char const * nlspath = __kmp_env_get( name );
188 KMP_MSG( WrongMessageCatalog, name, version.str, expected ),
189 KMP_HNT( CheckEnvVar, name, nlspath ),
192 KMP_INFORM( WillUseDefaultMessages );
193 KMP_INTERNAL_FREE( (
void *) nlspath );
196 __kmp_str_buf_free( & version );
206 if ( status == KMP_I18N_OPENED ) {
207 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
209 cat = KMP_I18N_NULLCAT;
211 status = KMP_I18N_CLOSED;
220 int section = get_section(
id );
221 int number = get_number(
id );
222 char const * message = NULL;
224 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
225 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
226 if ( status == KMP_I18N_CLOSED ) {
227 __kmp_i18n_catopen();
229 if ( status == KMP_I18N_OPENED ) {
234 __kmp_i18n_default_table.sect[ section ].str[ number ]
237 if ( message == NULL ) {
238 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
242 if ( message == NULL ) {
243 message = no_message_available;
250 #endif // KMP_OS_UNIX 261 #include "kmp_environment.h" 264 #define KMP_I18N_NULLCAT NULL 265 static HMODULE cat = KMP_I18N_NULLCAT;
266 static char const * name = ( KMP_VERSION_MAJOR == 4 ?
"libguide40ui.dll" :
"libompui.dll" );
268 static kmp_i18n_table_t table = { 0, NULL };
272 static UINT
const default_code_page = CP_OEMCP;
273 static UINT code_page = default_code_page;
275 static char const * ___catgets( kmp_i18n_id_t
id );
276 static UINT get_code_page();
277 static void kmp_i18n_table_free( kmp_i18n_table_t * table );
284 UINT cp = default_code_page;
285 char const * value = __kmp_env_get(
"KMP_CODEPAGE" );
286 if ( value != NULL ) {
287 if ( _stricmp( value,
"ANSI" ) == 0 ) {
289 }
else if ( _stricmp( value,
"OEM" ) == 0 ) {
291 }
else if ( _stricmp( value,
"UTF-8" ) == 0 || _stricmp( value,
"UTF8" ) == 0 ) {
293 }
else if ( _stricmp( value,
"UTF-7" ) == 0 || _stricmp( value,
"UTF7" ) == 0 ) {
299 KMP_INTERNAL_FREE( (
void *) value );
307 kmp_i18n_table_t * table
311 for ( s = 0; s < table->size; ++ s ) {
312 for ( m = 0; m < table->sect[ s ].size; ++ m ) {
314 KMP_INTERNAL_FREE( (
void *) table->sect[ s ].str[ m ] );
315 table->sect[ s ].str[ m ] = NULL;
317 table->sect[ s ].size = 0;
319 KMP_INTERNAL_FREE ( (
void *) table->sect[ s ].str );
320 table->sect[ s ].str = NULL;
323 KMP_INTERNAL_FREE( (
void *) table->sect );
329 __kmp_i18n_do_catopen(
332 LCID locale_id = GetThreadLocale();
333 WORD lang_id = LANGIDFROMLCID( locale_id );
334 WORD primary_lang_id = PRIMARYLANGID( lang_id );
337 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
338 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
340 __kmp_str_buf_init( & path );
344 if ( primary_lang_id == LANG_ENGLISH ) {
345 status = KMP_I18N_ABSENT;
363 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
364 reinterpret_cast< LPCSTR >( & __kmp_i18n_do_catopen ),
368 status = KMP_I18N_ABSENT;
376 DWORD drc = GetModuleFileName( handle, path.str, path.size );
378 status = KMP_I18N_ABSENT;
381 if ( drc < path.size ) {
385 __kmp_str_buf_reserve( & path, path.size * 2 );
390 __kmp_str_fname_init( & fname, path.str );
391 __kmp_str_buf_clear( & path );
392 __kmp_str_buf_print( & path,
"%s%lu/%s", fname.dir, (
unsigned long)( locale_id ), name );
393 __kmp_str_fname_free( & fname );
398 cat = LoadLibraryEx( path.str, NULL, LOAD_LIBRARY_AS_DATAFILE );
399 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
401 if ( status == KMP_I18N_ABSENT ) {
402 if (__kmp_generate_warnings > kmp_warnings_low) {
403 DWORD error = GetLastError();
419 kmp_msg_t err_code = KMP_SYSERRCODE(error);
422 KMP_MSG( CantOpenMessageCatalog, path.str ),
424 ( error == ERROR_BAD_EXE_FORMAT ? KMP_HNT( BadExeFormat, path.str, KMP_ARCH_STR ) : __kmp_msg_null ),
427 if (__kmp_generate_warnings == kmp_warnings_off) {
428 __kmp_str_free(&err_code.str);
431 KMP_INFORM( WillUseDefaultMessages );
435 int section = get_section( kmp_i18n_prp_Version );
436 int number = get_number( kmp_i18n_prp_Version );
437 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
438 kmp_str_buf_t version;
439 __kmp_str_buf_init( & version );
440 __kmp_str_buf_print( & version,
"%s", ___catgets( kmp_i18n_prp_Version ) );
442 if ( strcmp( version.str, expected ) != 0 ) {
444 __kmp_i18n_catclose();
445 status = KMP_I18N_ABSENT;
446 if (__kmp_generate_warnings > kmp_warnings_low) {
450 KMP_MSG( WrongMessageCatalog, path.str, version.str, expected ),
453 KMP_INFORM( WillUseDefaultMessages );
456 __kmp_str_buf_free( & version );
459 code_page = get_code_page();
462 __kmp_str_buf_free( & path );
471 if ( status == KMP_I18N_OPENED ) {
472 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
473 kmp_i18n_table_free( & table );
475 cat = KMP_I18N_NULLCAT;
477 code_page = default_code_page;
478 status = KMP_I18N_CLOSED;
514 if ( str[ in ] !=
'\r' ) {
515 str[ out ] = str[ in ];
518 if ( str[ in ] == 0 ) {
533 char * result = NULL;
535 wchar_t * wmsg = NULL;
541 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
544 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
545 FORMAT_MESSAGE_IGNORE_INSERTS,
556 wmsg = (
wchar_t *) addr;
572 msg = (
char *) KMP_INTERNAL_MALLOC( len + 1 );
583 if ( rc <= 0 || rc > len ) {
586 KMP_DEBUG_ASSERT( rc == len );
591 len = ___strip_crs( msg );
594 if ( len >= 1 && msg[ len - 1 ] ==
'\n' ) {
606 KMP_INTERNAL_FREE( msg );
608 if ( wmsg != NULL ) {
622 int section = get_section(
id );
623 int number = get_number(
id );
624 char const * message = NULL;
626 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
627 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
628 if ( status == KMP_I18N_CLOSED ) {
629 __kmp_i18n_catopen();
631 if ( cat != KMP_I18N_NULLCAT ) {
632 if ( table.size == 0 ) {
633 table.sect = (kmp_i18n_section_t *)
635 ( __kmp_i18n_default_table.size + 2 ),
636 sizeof( kmp_i18n_section_t )
638 table.size = __kmp_i18n_default_table.size;
640 if ( table.sect[ section ].size == 0 ) {
641 table.sect[ section ].str = (
const char **)
643 __kmp_i18n_default_table.sect[ section ].size + 2,
644 sizeof(
char const * )
646 table.sect[ section ].size = __kmp_i18n_default_table.sect[ section ].size;
648 if ( table.sect[ section ].str[ number ] == NULL ) {
649 table.sect[ section ].str[ number ] = ___catgets(
id );
651 message = table.sect[ section ].str[ number ];
653 if ( message == NULL ) {
655 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
659 if ( message == NULL ) {
660 message = no_message_available;
667 #endif // KMP_OS_WINDOWS 672 #error I18n support is not implemented for this OS. 673 #endif // KMP_I18N_OK 678 __kmp_i18n_dump_catalog(
679 kmp_str_buf_t * buffer
682 struct kmp_i18n_id_range_t {
687 static struct kmp_i18n_id_range_t ranges[] = {
688 { kmp_i18n_prp_first, kmp_i18n_prp_last },
689 { kmp_i18n_str_first, kmp_i18n_str_last },
690 { kmp_i18n_fmt_first, kmp_i18n_fmt_last },
691 { kmp_i18n_msg_first, kmp_i18n_msg_last },
692 { kmp_i18n_hnt_first, kmp_i18n_hnt_last }
695 int num_of_ranges =
sizeof( ranges ) /
sizeof(
struct kmp_i18n_id_range_t );
699 for ( range = 0; range < num_of_ranges; ++ range ) {
700 __kmp_str_buf_print( buffer,
"*** Set #%d ***\n", range + 1 );
701 for (
id = (kmp_i18n_id_t)( ranges[ range ].first + 1 );
702 id < ranges[ range ].last;
703 id = (kmp_i18n_id_t)(
id + 1 ) ) {
704 __kmp_str_buf_print( buffer,
"%d: <<%s>>\n",
id, __kmp_i18n_catgets(
id ) );
708 __kmp_printf(
"%s", buffer->str );
722 kmp_str_buf_t buffer;
723 __kmp_str_buf_init( & buffer );
725 va_start( args, id_arg );
730 kmp_i18n_id_t
id = (kmp_i18n_id_t)id_arg;
735 __kmp_str_buf_vprint( & buffer, __kmp_i18n_catgets(
id ), args );
744 FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
745 __kmp_i18n_catgets(
id ),
751 len = ___strip_crs( str );
752 __kmp_str_buf_cat( & buffer, str, len );
759 __kmp_str_buf_detach( & buffer );
761 msg.type = (kmp_msg_type_t)(
id >> 16 );
762 msg.num =
id & 0xFFFF;
763 msg.str = buffer.str;
764 msg.len = buffer.used;
778 char * message = NULL;
782 LPVOID buffer = NULL;
787 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
790 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
797 message = __kmp_str_format(
"%s", (
char *) buffer );
798 len = ___strip_crs( message );
800 while ( len > 0 && message[ len - 1 ] ==
'\n' ) {
809 if ( buffer != NULL ) {
813 #else // Non-Windows* OS: Linux* OS or OS X* 822 #if defined(__GLIBC__) && defined(_GNU_SOURCE) 827 char *
const err_msg = strerror_r( err, buffer,
sizeof( buffer ) );
830 message = __kmp_str_format(
"%s", err_msg );
832 #else // OS X*, FreeBSD* etc. 837 char * buffer = (
char *) KMP_INTERNAL_MALLOC( size );
839 if (buffer == NULL) {
840 KMP_FATAL(MemoryAllocFailed);
842 rc = strerror_r( err, buffer, size );
846 while ( rc == ERANGE ) {
847 KMP_INTERNAL_FREE( buffer );
849 buffer = (
char *) KMP_INTERNAL_MALLOC( size );
850 if (buffer == NULL) {
851 KMP_FATAL(MemoryAllocFailed);
853 rc = strerror_r( err, buffer, size );
862 KMP_INTERNAL_FREE( buffer );
869 if ( message == NULL ) {
871 message = __kmp_str_format(
"%s",
"(No system error message available)" );
880 __kmp_msg_error_code(
885 msg.type = kmp_mt_syserr;
887 msg.str = sys_error( code );
888 msg.len = KMP_STRLEN( msg.str );
896 __kmp_msg_error_mesg(
901 msg.type = kmp_mt_syserr;
903 msg.str = __kmp_str_format(
"%s", mesg );
904 msg.len = KMP_STRLEN( msg.str );
913 kmp_msg_severity_t severity,
919 kmp_i18n_id_t format;
921 kmp_str_buf_t buffer;
923 if ( severity != kmp_ms_fatal && __kmp_generate_warnings == kmp_warnings_off )
926 __kmp_str_buf_init( & buffer );
929 switch ( severity ) {
930 case kmp_ms_inform : {
931 format = kmp_i18n_fmt_Info;
933 case kmp_ms_warning : {
934 format = kmp_i18n_fmt_Warning;
936 case kmp_ms_fatal : {
937 format = kmp_i18n_fmt_Fatal;
940 KMP_DEBUG_ASSERT( 0 );
943 fmsg = __kmp_msg_format( format, message.num, message.str );
944 __kmp_str_free(&message.str);
945 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
946 __kmp_str_free(&fmsg.str);
949 va_start( args, message );
951 message = va_arg( args, kmp_msg_t );
952 if ( message.type == kmp_mt_dummy && message.str == NULL ) {
955 if ( message.type == kmp_mt_dummy && message.str == __kmp_msg_empty.str ) {
958 switch ( message.type ) {
960 format = kmp_i18n_fmt_Hint;
962 case kmp_mt_syserr : {
963 format = kmp_i18n_fmt_SysErr;
966 KMP_DEBUG_ASSERT( 0 );
969 fmsg = __kmp_msg_format( format, message.num, message.str );
970 __kmp_str_free(&message.str);
971 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
972 __kmp_str_free(&fmsg.str);
979 __kmp_printf(
"%s", buffer.str );
980 __kmp_str_buf_free( & buffer );
982 if ( severity == kmp_ms_fatal ) {
984 __kmp_thread_sleep( 500 );
986 __kmp_abort_process();