16 #include "kmp_debug.h" 27 #include "kmp_environment.h" 28 #include "kmp_i18n_default.inc" 33 #define get_section(id) ((id) >> 16) 34 #define get_number(id) ((id)&0xFFFF) 36 kmp_msg_t __kmp_msg_null = {kmp_mt_dummy, 0, NULL, 0};
37 static char const *no_message_available =
"(No message available)";
39 static void __kmp_msg(kmp_msg_severity_t severity, kmp_msg_t message,
42 enum kmp_i18n_cat_status {
47 typedef enum kmp_i18n_cat_status kmp_i18n_cat_status_t;
48 static volatile kmp_i18n_cat_status_t status = KMP_I18N_CLOSED;
56 static void __kmp_i18n_do_catopen();
57 static kmp_bootstrap_lock_t lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(lock);
62 void __kmp_i18n_catopen() {
63 if (status == KMP_I18N_CLOSED) {
64 __kmp_acquire_bootstrap_lock(&lock);
65 if (status == KMP_I18N_CLOSED) {
66 __kmp_i18n_do_catopen();
68 __kmp_release_bootstrap_lock(&lock);
78 #define KMP_I18N_NULLCAT ((nl_catd)(-1)) 79 static nl_catd cat = KMP_I18N_NULLCAT;
80 static char const *name =
81 (KMP_VERSION_MAJOR == 4 ?
"libguide.cat" :
"libomp.cat");
89 void __kmp_i18n_do_catopen() {
91 char *lang = __kmp_env_get(
"LANG");
94 KMP_DEBUG_ASSERT(status == KMP_I18N_CLOSED);
95 KMP_DEBUG_ASSERT(cat == KMP_I18N_NULLCAT);
97 english = lang == NULL ||
98 strcmp(lang,
"") == 0 || strcmp(lang,
" ") == 0 ||
101 strcmp(lang,
"C") == 0 || strcmp(lang,
"POSIX") == 0;
107 __kmp_str_split(lang,
'@', &lang, &tail);
108 __kmp_str_split(lang,
'.', &lang, &tail);
109 __kmp_str_split(lang,
'_', &lang, &tail);
110 english = (strcmp(lang,
"en") == 0);
113 KMP_INTERNAL_FREE(lang);
118 status = KMP_I18N_ABSENT;
123 cat = catopen(name, 0);
125 status = (cat == KMP_I18N_NULLCAT ? KMP_I18N_ABSENT : KMP_I18N_OPENED);
127 if (status == KMP_I18N_ABSENT) {
128 if (__kmp_generate_warnings > kmp_warnings_low) {
131 char *nlspath = __kmp_env_get(
"NLSPATH");
132 char *lang = __kmp_env_get(
"LANG");
137 kmp_msg_t err_code = KMP_ERR(error);
138 __kmp_msg(kmp_ms_warning, KMP_MSG(CantOpenMessageCatalog, name), err_code,
139 KMP_HNT(CheckEnvVar,
"NLSPATH", nlspath),
140 KMP_HNT(CheckEnvVar,
"LANG", lang), __kmp_msg_null);
141 if (__kmp_generate_warnings == kmp_warnings_off) {
142 __kmp_str_free(&err_code.str);
145 KMP_INFORM(WillUseDefaultMessages);
146 KMP_INTERNAL_FREE(nlspath);
147 KMP_INTERNAL_FREE(lang);
150 int section = get_section(kmp_i18n_prp_Version);
151 int number = get_number(kmp_i18n_prp_Version);
152 char const *expected = __kmp_i18n_default_table.sect[section].str[number];
154 kmp_str_buf_t version;
155 __kmp_str_buf_init(&version);
156 __kmp_str_buf_print(&version,
"%s", catgets(cat, section, number, NULL));
159 if (strcmp(version.str, expected) != 0) {
160 __kmp_i18n_catclose();
161 status = KMP_I18N_ABSENT;
162 if (__kmp_generate_warnings > kmp_warnings_low) {
165 char const *name =
"NLSPATH";
166 char const *nlspath = __kmp_env_get(name);
167 __kmp_msg(kmp_ms_warning,
168 KMP_MSG(WrongMessageCatalog, name, version.str, expected),
169 KMP_HNT(CheckEnvVar, name, nlspath), __kmp_msg_null);
170 KMP_INFORM(WillUseDefaultMessages);
171 KMP_INTERNAL_FREE(CCAST(
char *, nlspath));
174 __kmp_str_buf_free(&version);
178 void __kmp_i18n_catclose() {
179 if (status == KMP_I18N_OPENED) {
180 KMP_DEBUG_ASSERT(cat != KMP_I18N_NULLCAT);
182 cat = KMP_I18N_NULLCAT;
184 status = KMP_I18N_CLOSED;
187 char const *__kmp_i18n_catgets(kmp_i18n_id_t
id) {
189 int section = get_section(
id);
190 int number = get_number(
id);
191 char const *message = NULL;
193 if (1 <= section && section <= __kmp_i18n_default_table.size) {
194 if (1 <= number && number <= __kmp_i18n_default_table.sect[section].size) {
195 if (status == KMP_I18N_CLOSED) {
196 __kmp_i18n_catopen();
198 if (status == KMP_I18N_OPENED) {
199 message = catgets(cat, section, number,
200 __kmp_i18n_default_table.sect[section].str[number]);
202 if (message == NULL) {
203 message = __kmp_i18n_default_table.sect[section].str[number];
207 if (message == NULL) {
208 message = no_message_available;
214 #endif // KMP_OS_UNIX