| 1 | /* |
| 2 | * kmp_i18n.h |
| 3 | */ |
| 4 | |
| 5 | //===----------------------------------------------------------------------===// |
| 6 | // |
| 7 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 8 | // See https://llvm.org/LICENSE.txt for license information. |
| 9 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #ifndef KMP_I18N_H |
| 14 | #define KMP_I18N_H |
| 15 | |
| 16 | #include "kmp_str.h" |
| 17 | |
| 18 | #ifdef __cplusplus |
| 19 | extern "C" { |
| 20 | #endif // __cplusplus |
| 21 | |
| 22 | /* kmp_i18n_id.inc defines kmp_i18n_id_t type. It is an enumeration with |
| 23 | identifiers of all the messages in the catalog. There is one special |
| 24 | identifier: kmp_i18n_null, which denotes absence of message. */ |
| 25 | #include "kmp_i18n_id.inc" // Generated file. Do not edit it manually. |
| 26 | |
| 27 | /* Low-level functions handling message catalog. __kmp_i18n_open() opens message |
| 28 | catalog, __kmp_i18n_closes() it. Explicit opening is not required: if message |
| 29 | catalog is not yet open, __kmp_i18n_catgets() will open it implicitly. |
| 30 | However, catalog should be explicitly closed, otherwise resources (mamory, |
| 31 | handles) may leak. |
| 32 | |
| 33 | __kmp_i18n_catgets() returns read-only string. It should not be freed. |
| 34 | |
| 35 | KMP_I18N_STR macro simplifies access to strings in message catalog a bit. |
| 36 | Following two lines are equivalent: |
| 37 | |
| 38 | __kmp_i18n_catgets( kmp_i18n_str_Warning ) |
| 39 | KMP_I18N_STR( Warning ) |
| 40 | */ |
| 41 | |
| 42 | void __kmp_i18n_catopen(); |
| 43 | void __kmp_i18n_catclose(); |
| 44 | char const *__kmp_i18n_catgets(kmp_i18n_id_t id); |
| 45 | |
| 46 | #define KMP_I18N_STR(id) __kmp_i18n_catgets(kmp_i18n_str_##id) |
| 47 | |
| 48 | /* High-level interface for printing strings targeted to the user. |
| 49 | |
| 50 | All the strings are divided into 3 types: |
| 51 | * messages, |
| 52 | * hints, |
| 53 | * system errors. |
| 54 | |
| 55 | There are 3 kind of message severities: |
| 56 | * informational messages, |
| 57 | * warnings (non-fatal errors), |
| 58 | * fatal errors. |
| 59 | |
| 60 | For example: |
| 61 | OMP: Warning #2: Cannot open message catalog "libguide.cat": (1) |
| 62 | OMP: System error #2: No such file or directory (2) |
| 63 | OMP: Hint: Please check NLSPATH environment variable. (3) |
| 64 | OMP: Info #3: Default messages will be used. (4) |
| 65 | |
| 66 | where |
| 67 | (1) is a message of warning severity, |
| 68 | (2) is a system error caused the previous warning, |
| 69 | (3) is a hint for the user how to fix the problem, |
| 70 | (4) is a message of informational severity. |
| 71 | |
| 72 | Usage in complex cases (message is accompanied with hints and system errors): |
| 73 | |
| 74 | int error = errno; // We need save errno immediately, because it may |
| 75 | // be changed. |
| 76 | __kmp_msg( |
| 77 | kmp_ms_warning, // Severity |
| 78 | KMP_MSG( CantOpenMessageCatalog, name ), // Primary message |
| 79 | KMP_ERR( error ), // System error |
| 80 | KMP_HNT( CheckNLSPATH ), // Hint |
| 81 | __kmp_msg_null // Variadic argument list finisher |
| 82 | ); |
| 83 | |
| 84 | Usage in simple cases (just a message, no system errors or hints): |
| 85 | KMP_INFORM( WillUseDefaultMessages ); |
| 86 | KMP_WARNING( CantOpenMessageCatalog, name ); |
| 87 | KMP_FATAL( StackOverlap ); |
| 88 | KMP_SYSFAIL( "pthread_create", status ); |
| 89 | KMP_CHECK_SYSFAIL( "pthread_create", status ); |
| 90 | KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status ); |
| 91 | */ |
| 92 | |
| 93 | enum kmp_msg_type { |
| 94 | kmp_mt_dummy = 0, // Special type for internal purposes. |
| 95 | kmp_mt_mesg = |
| 96 | 4, // Primary OpenMP message, could be information, warning, or fatal. |
| 97 | kmp_mt_hint = 5, // Hint to the user. |
| 98 | kmp_mt_syserr = -1 // System error message. |
| 99 | }; // enum kmp_msg_type |
| 100 | typedef enum kmp_msg_type kmp_msg_type_t; |
| 101 | |
| 102 | struct kmp_msg { |
| 103 | kmp_msg_type_t type; |
| 104 | int num; |
| 105 | char *str; |
| 106 | size_t len; |
| 107 | }; // struct kmp_message |
| 108 | typedef struct kmp_msg kmp_msg_t; |
| 109 | |
| 110 | // Special message to denote the end of variadic list of arguments. |
| 111 | extern kmp_msg_t __kmp_msg_null; |
| 112 | |
| 113 | // Helper functions. Creates messages either from message catalog or from |
| 114 | // system. Note: these functions allocate memory. You should pass created |
| 115 | // messages to __kmp_msg() function, it will print messages and destroy them. |
| 116 | kmp_msg_t __kmp_msg_format(unsigned id_arg, ...); |
| 117 | kmp_msg_t __kmp_msg_error_code(int code); |
| 118 | kmp_msg_t __kmp_msg_error_mesg(char const *mesg); |
| 119 | |
| 120 | // Helper macros to make calls shorter. |
| 121 | #define KMP_MSG(...) __kmp_msg_format(kmp_i18n_msg_##__VA_ARGS__) |
| 122 | #define KMP_HNT(...) __kmp_msg_format(kmp_i18n_hnt_##__VA_ARGS__) |
| 123 | #define KMP_SYSERRCODE(code) __kmp_msg_error_code(code) |
| 124 | #define KMP_SYSERRMESG(mesg) __kmp_msg_error_mesg(mesg) |
| 125 | #define KMP_ERR KMP_SYSERRCODE |
| 126 | |
| 127 | // Message severity. |
| 128 | enum kmp_msg_severity { |
| 129 | kmp_ms_inform, // Just information for the user. |
| 130 | kmp_ms_warning, // Non-fatal error, execution continues. |
| 131 | kmp_ms_fatal // Fatal error, program aborts. |
| 132 | }; // enum kmp_msg_severity |
| 133 | typedef enum kmp_msg_severity kmp_msg_severity_t; |
| 134 | |
| 135 | // Primary function for printing messages for the user. The first message is |
| 136 | // mandatory. Any number of system errors and hints may be specified. Argument |
| 137 | // list must be finished with __kmp_msg_null. |
| 138 | void __kmp_msg(kmp_msg_severity_t severity, kmp_msg_t message, ...); |
| 139 | KMP_NORETURN void __kmp_fatal(kmp_msg_t message, ...); |
| 140 | |
| 141 | // Helper macros to make calls shorter in simple cases. |
| 142 | #define KMP_INFORM(...) \ |
| 143 | __kmp_msg(kmp_ms_inform, KMP_MSG(__VA_ARGS__), __kmp_msg_null) |
| 144 | #define KMP_WARNING(...) \ |
| 145 | __kmp_msg(kmp_ms_warning, KMP_MSG(__VA_ARGS__), __kmp_msg_null) |
| 146 | #define KMP_FATAL(...) __kmp_fatal(KMP_MSG(__VA_ARGS__), __kmp_msg_null) |
| 147 | #define KMP_SYSFAIL(func, error) \ |
| 148 | __kmp_fatal(KMP_MSG(FunctionError, func), KMP_SYSERRCODE(error), \ |
| 149 | __kmp_msg_null) |
| 150 | |
| 151 | // Check error, if not zero, generate fatal error message. |
| 152 | #define KMP_CHECK_SYSFAIL(func, error) \ |
| 153 | { \ |
| 154 | if (error) { \ |
| 155 | KMP_SYSFAIL(func, error); \ |
| 156 | } \ |
| 157 | } |
| 158 | |
| 159 | // Check status, if not zero, generate fatal error message using errno. |
| 160 | #define KMP_CHECK_SYSFAIL_ERRNO(func, status) \ |
| 161 | { \ |
| 162 | if (status != 0) { \ |
| 163 | int error = errno; \ |
| 164 | KMP_SYSFAIL(func, error); \ |
| 165 | } \ |
| 166 | } |
| 167 | |
| 168 | #ifdef KMP_DEBUG |
| 169 | void __kmp_i18n_dump_catalog(kmp_str_buf_t *buffer); |
| 170 | #endif // KMP_DEBUG |
| 171 | |
| 172 | #ifdef __cplusplus |
| 173 | } // extern "C" |
| 174 | #endif // __cplusplus |
| 175 | |
| 176 | #endif // KMP_I18N_H |
| 177 | |
| 178 | // end of file // |
| 179 | |