41 #include "kmp_debug.h"
52 #include "kmp_i18n_default.inc"
54 #include "kmp_environment.h"
58 #define get_section( id ) ( (id) >> 16 )
59 #define get_number( id ) ( (id) & 0xFFFF )
61 kmp_msg_t __kmp_msg_empty = { kmp_mt_dummy, 0,
"", 0 };
62 kmp_msg_t __kmp_msg_null = { kmp_mt_dummy, 0, NULL, 0 };
63 static char const * no_message_available =
"(No message available)";
65 enum kmp_i18n_cat_status {
70 typedef enum kmp_i18n_cat_status kmp_i18n_cat_status_t;
71 static volatile kmp_i18n_cat_status_t status = KMP_I18N_CLOSED;
81 static void __kmp_i18n_do_catopen();
82 static kmp_bootstrap_lock_t lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( lock );
90 if ( status == KMP_I18N_CLOSED ) {
91 __kmp_acquire_bootstrap_lock( & lock );
92 if ( status == KMP_I18N_CLOSED ) {
93 __kmp_i18n_do_catopen();
95 __kmp_release_bootstrap_lock( & lock );
109 #include <nl_types.h>
111 #define KMP_I18N_NULLCAT ((nl_catd)( -1 ))
112 static nl_catd cat = KMP_I18N_NULLCAT;
113 static char const * name = ( KMP_VERSION_MAJOR == 4 ?
"libguide.cat" :
"libiomp5.cat" );
123 __kmp_i18n_do_catopen(
126 char * lang = __kmp_env_get(
"LANG" );
129 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
130 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
134 strcmp( lang,
"" ) == 0 ||
135 strcmp( lang,
" " ) == 0 ||
138 strcmp( lang,
"C" ) == 0 ||
139 strcmp( lang,
"POSIX" ) == 0;
145 __kmp_str_split( lang,
'@', & lang, & tail );
146 __kmp_str_split( lang,
'.', & lang, & tail );
147 __kmp_str_split( lang,
'_', & lang, & tail );
148 english = ( strcmp( lang,
"en" ) == 0 );
151 KMP_INTERNAL_FREE( lang );
156 status = KMP_I18N_ABSENT;
160 cat = catopen( name, 0 );
162 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
164 if ( status == KMP_I18N_ABSENT ) {
165 if (__kmp_generate_warnings > kmp_warnings_low) {
167 char * nlspath = __kmp_env_get(
"NLSPATH" );
168 char * lang = __kmp_env_get(
"LANG" );
174 KMP_MSG( CantOpenMessageCatalog, name ),
176 KMP_HNT( CheckEnvVar,
"NLSPATH", nlspath ),
177 KMP_HNT( CheckEnvVar,
"LANG", lang ),
180 KMP_INFORM( WillUseDefaultMessages );
181 KMP_INTERNAL_FREE( nlspath );
182 KMP_INTERNAL_FREE( lang );
186 int section = get_section( kmp_i18n_prp_Version );
187 int number = get_number( kmp_i18n_prp_Version );
188 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
190 kmp_str_buf_t version;
191 __kmp_str_buf_init( & version );
192 __kmp_str_buf_print( & version,
"%s", catgets( cat, section, number, NULL ) );
195 if ( strcmp( version.str, expected ) != 0 ) {
196 __kmp_i18n_catclose();
197 status = KMP_I18N_ABSENT;
198 if (__kmp_generate_warnings > kmp_warnings_low) {
200 char const * name =
"NLSPATH";
201 char const * nlspath = __kmp_env_get( name );
204 KMP_MSG( WrongMessageCatalog, name, version.str, expected ),
205 KMP_HNT( CheckEnvVar, name, nlspath ),
208 KMP_INFORM( WillUseDefaultMessages );
209 KMP_INTERNAL_FREE( (
void *) nlspath );
212 __kmp_str_buf_free( & version );
222 if ( status == KMP_I18N_OPENED ) {
223 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
225 cat = KMP_I18N_NULLCAT;
227 status = KMP_I18N_CLOSED;
236 int section = get_section(
id );
237 int number = get_number(
id );
238 char const * message = NULL;
240 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
241 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
242 if ( status == KMP_I18N_CLOSED ) {
243 __kmp_i18n_catopen();
245 if ( status == KMP_I18N_OPENED ) {
250 __kmp_i18n_default_table.sect[ section ].str[ number ]
253 if ( message == NULL ) {
254 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
258 if ( message == NULL ) {
259 message = no_message_available;
266 #endif // KMP_OS_UNIX
277 #include "kmp_environment.h"
280 #define KMP_I18N_NULLCAT NULL
281 static HMODULE cat = KMP_I18N_NULLCAT;
282 static char const * name = ( KMP_VERSION_MAJOR == 4 ?
"libguide40ui.dll" :
"libiomp5ui.dll" );
284 static kmp_i18n_table_t table = { 0, NULL };
288 static UINT
const default_code_page = CP_OEMCP;
289 static UINT code_page = default_code_page;
291 static char const * ___catgets( kmp_i18n_id_t
id );
292 static UINT get_code_page();
293 static void kmp_i18n_table_free( kmp_i18n_table_t * table );
300 UINT cp = default_code_page;
301 char const * value = __kmp_env_get(
"KMP_CODEPAGE" );
302 if ( value != NULL ) {
303 if ( _stricmp( value,
"ANSI" ) == 0 ) {
305 }
else if ( _stricmp( value,
"OEM" ) == 0 ) {
307 }
else if ( _stricmp( value,
"UTF-8" ) == 0 || _stricmp( value,
"UTF8" ) == 0 ) {
309 }
else if ( _stricmp( value,
"UTF-7" ) == 0 || _stricmp( value,
"UTF7" ) == 0 ) {
315 KMP_INTERNAL_FREE( (
void *) value );
323 kmp_i18n_table_t * table
327 for ( s = 0; s < table->size; ++ s ) {
328 for ( m = 0; m < table->sect[ s ].size; ++ m ) {
330 KMP_INTERNAL_FREE( (
void *) table->sect[ s ].str[ m ] );
331 table->sect[ s ].str[ m ] = NULL;
333 table->sect[ s ].size = 0;
335 KMP_INTERNAL_FREE ( (
void *) table->sect[ s ].str );
336 table->sect[ s ].str = NULL;
339 KMP_INTERNAL_FREE( (
void *) table->sect );
345 __kmp_i18n_do_catopen(
348 LCID locale_id = GetThreadLocale();
349 WORD lang_id = LANGIDFROMLCID( locale_id );
350 WORD primary_lang_id = PRIMARYLANGID( lang_id );
353 KMP_DEBUG_ASSERT( status == KMP_I18N_CLOSED );
354 KMP_DEBUG_ASSERT( cat == KMP_I18N_NULLCAT );
356 __kmp_str_buf_init( & path );
360 if ( primary_lang_id == LANG_ENGLISH ) {
361 status = KMP_I18N_ABSENT;
379 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
380 reinterpret_cast< LPCSTR >( & __kmp_i18n_do_catopen ),
384 status = KMP_I18N_ABSENT;
392 DWORD drc = GetModuleFileName( handle, path.str, path.size );
394 status = KMP_I18N_ABSENT;
397 if ( drc < path.size ) {
401 __kmp_str_buf_reserve( & path, path.size * 2 );
406 __kmp_str_fname_init( & fname, path.str );
407 __kmp_str_buf_clear( & path );
408 __kmp_str_buf_print( & path,
"%s%lu/%s", fname.dir, (
unsigned long)( locale_id ), name );
409 __kmp_str_fname_free( & fname );
414 cat = LoadLibraryEx( path.str, NULL, LOAD_LIBRARY_AS_DATAFILE );
415 status = ( cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED );
417 if ( status == KMP_I18N_ABSENT ) {
418 if (__kmp_generate_warnings > kmp_warnings_low) {
419 DWORD error = GetLastError();
437 KMP_MSG( CantOpenMessageCatalog, path.str ),
438 KMP_SYSERRCODE( error ),
439 ( error == ERROR_BAD_EXE_FORMAT ? KMP_HNT( BadExeFormat, path.str, KMP_ARCH_STR ) : __kmp_msg_null ),
442 KMP_INFORM( WillUseDefaultMessages );
446 int section = get_section( kmp_i18n_prp_Version );
447 int number = get_number( kmp_i18n_prp_Version );
448 char const * expected = __kmp_i18n_default_table.sect[ section ].str[ number ];
449 kmp_str_buf_t version;
450 __kmp_str_buf_init( & version );
451 __kmp_str_buf_print( & version,
"%s", ___catgets( kmp_i18n_prp_Version ) );
453 if ( strcmp( version.str, expected ) != 0 ) {
455 __kmp_i18n_catclose();
456 status = KMP_I18N_ABSENT;
457 if (__kmp_generate_warnings > kmp_warnings_low) {
461 KMP_MSG( WrongMessageCatalog, path.str, version.str, expected ),
464 KMP_INFORM( WillUseDefaultMessages );
467 __kmp_str_buf_free( & version );
470 code_page = get_code_page();
473 __kmp_str_buf_free( & path );
482 if ( status == KMP_I18N_OPENED ) {
483 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
484 kmp_i18n_table_free( & table );
486 cat = KMP_I18N_NULLCAT;
488 code_page = default_code_page;
489 status = KMP_I18N_CLOSED;
525 if ( str[ in ] !=
'\r' ) {
526 str[ out ] = str[ in ];
529 if ( str[ in ] == 0 ) {
544 char * result = NULL;
546 wchar_t * wmsg = NULL;
552 KMP_DEBUG_ASSERT( cat != KMP_I18N_NULLCAT );
555 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
556 FORMAT_MESSAGE_IGNORE_INSERTS,
567 wmsg = (
wchar_t *) addr;
583 msg = (
char *) KMP_INTERNAL_MALLOC( len + 1 );
594 if ( rc <= 0 || rc > len ) {
597 KMP_DEBUG_ASSERT( rc == len );
602 len = ___strip_crs( msg );
605 if ( len >= 1 && msg[ len - 1 ] ==
'\n' ) {
617 KMP_INTERNAL_FREE( msg );
619 if ( wmsg != NULL ) {
633 int section = get_section(
id );
634 int number = get_number(
id );
635 char const * message = NULL;
637 if ( 1 <= section && section <= __kmp_i18n_default_table.size ) {
638 if ( 1 <= number && number <= __kmp_i18n_default_table.sect[ section ].size ) {
639 if ( status == KMP_I18N_CLOSED ) {
640 __kmp_i18n_catopen();
642 if ( cat != KMP_I18N_NULLCAT ) {
643 if ( table.size == 0 ) {
644 table.sect = (kmp_i18n_section_t *)
646 ( __kmp_i18n_default_table.size + 2 ),
647 sizeof( kmp_i18n_section_t )
649 table.size = __kmp_i18n_default_table.size;
651 if ( table.sect[ section ].size == 0 ) {
652 table.sect[ section ].str = (
const char **)
654 __kmp_i18n_default_table.sect[ section ].size + 2,
655 sizeof(
char const * )
657 table.sect[ section ].size = __kmp_i18n_default_table.sect[ section ].size;
659 if ( table.sect[ section ].str[ number ] == NULL ) {
660 table.sect[ section ].str[ number ] = ___catgets(
id );
662 message = table.sect[ section ].str[ number ];
664 if ( message == NULL ) {
666 message = __kmp_i18n_default_table.sect[ section ].str[ number ];
670 if ( message == NULL ) {
671 message = no_message_available;
678 #endif // KMP_OS_WINDOWS
683 #error I18n support is not implemented for this OS.
684 #endif // KMP_I18N_OK
689 __kmp_i18n_dump_catalog(
690 kmp_str_buf_t * buffer
693 struct kmp_i18n_id_range_t {
698 static struct kmp_i18n_id_range_t ranges[] = {
699 { kmp_i18n_prp_first, kmp_i18n_prp_last },
700 { kmp_i18n_str_first, kmp_i18n_str_last },
701 { kmp_i18n_fmt_first, kmp_i18n_fmt_last },
702 { kmp_i18n_msg_first, kmp_i18n_msg_last },
703 { kmp_i18n_hnt_first, kmp_i18n_hnt_last }
706 int num_of_ranges =
sizeof( ranges ) /
sizeof(
struct kmp_i18n_id_range_t );
710 for ( range = 0; range < num_of_ranges; ++ range ) {
711 __kmp_str_buf_print( buffer,
"*** Set #%d ***\n", range + 1 );
712 for (
id = (kmp_i18n_id_t)( ranges[ range ].first + 1 );
713 id < ranges[ range ].last;
714 id = (kmp_i18n_id_t)(
id + 1 ) ) {
715 __kmp_str_buf_print( buffer,
"%d: <<%s>>\n",
id, __kmp_i18n_catgets(
id ) );
719 __kmp_printf(
"%s", buffer->str );
733 kmp_str_buf_t buffer;
734 __kmp_str_buf_init( & buffer );
736 va_start( args,
id );
740 __kmp_str_buf_vprint( & buffer, __kmp_i18n_catgets(
id ), args );
749 FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
750 __kmp_i18n_catgets(
id ),
756 len = ___strip_crs( str );
757 __kmp_str_buf_cat( & buffer, str, len );
764 __kmp_str_buf_detach( & buffer );
766 msg.type = (kmp_msg_type_t)(
id >> 16 );
767 msg.num =
id & 0xFFFF;
768 msg.str = buffer.str;
769 msg.len = buffer.used;
783 char * message = NULL;
787 LPVOID buffer = NULL;
792 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
795 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
802 message = __kmp_str_format(
"%s", (
char *) buffer );
803 len = ___strip_crs( message );
805 while ( len > 0 && message[ len - 1 ] ==
'\n' ) {
814 if ( buffer != NULL ) {
818 #else // Non-Windows* OS: Linux* OS or OS X*
832 char *
const err_msg = strerror_r( err, buffer,
sizeof( buffer ) );
835 message = __kmp_str_format(
"%s", err_msg );
837 #else // OS X*, FreeBSD* etc.
843 char * buffer = (
char *) KMP_INTERNAL_MALLOC( size );
845 rc = strerror_r( err, buffer, size );
849 while ( rc == ERANGE ) {
850 KMP_INTERNAL_FREE( buffer );
852 buffer = (
char *) KMP_INTERNAL_MALLOC( size );
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 = 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 = 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_INTERNAL_FREE( (
void *) message.str );
945 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
946 KMP_INTERNAL_FREE( (
void *) 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_INTERNAL_FREE( (
void *) message.str );
971 __kmp_str_buf_cat( & buffer, fmsg.str, fmsg.len );
972 KMP_INTERNAL_FREE( (
void *) 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();