A tool to display MS-Windows locale information
Revision | 558e2a9d2b6f8e32c6051ad160dbaadfdb211e21 (tree) |
---|---|
Time | 2019-03-05 06:59:17 |
Author | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Segregate Windows version dependencies into a DLL.
* locale-info.c [BUILD_DLL] (query_locale_info): Compile it, and all
of its supporting static functions, as an exported function, which is
to be encapsulated within an arbitrarily named DLL.
[! BUILD_DLL] (main): Compile this function only; use LoadLibrary(),
and GetProcAddress(), to direct execution to the query_locale_info()
function, assuming that this has been compiled into a DLL named...
* locale-info.dll: ...thus.
@@ -55,6 +55,14 @@ | ||
55 | 55 | * Compile time options: |
56 | 56 | * In addition to the usual GCC options, users may choose to enable: |
57 | 57 | * |
58 | + * -D BUILD_DLL -shared Build the DLL component of the | |
59 | + * application. The application must | |
60 | + * be compiled and linked twice; once | |
61 | + * with BOTH of these options, and | |
62 | + * again with NEITHER, to build the | |
63 | + * DLL and main EXE components of | |
64 | + * the application respectively. | |
65 | + * | |
58 | 66 | * -D SETLOCALE Enables synchronization of the CRT |
59 | 67 | * locale with the specified Windows |
60 | 68 | * locale. |
@@ -76,6 +84,12 @@ static const char *error = "Error ***"; | ||
76 | 84 | #include <winbase.h> |
77 | 85 | #include <stdlib.h> |
78 | 86 | |
87 | +/* The primary duty of the application is served by a DLL component... | |
88 | + */ | |
89 | +#if BUILD_DLL | |
90 | +/* ...which is compiled in this case; (it is assumed that the -shared | |
91 | + * option is also specified, for the compile and link). | |
92 | + */ | |
79 | 93 | #include <limits.h> |
80 | 94 | #include <unistd.h> |
81 | 95 | #include <winnls.h> |
@@ -156,6 +170,7 @@ static int build_locale_string( wchar_t delim, int offset, int category ) | ||
156 | 170 | } |
157 | 171 | #endif |
158 | 172 | |
173 | +__declspec(dllexport) | |
159 | 174 | int query_locale_info( int argc, char **argv ) |
160 | 175 | { |
161 | 176 | unsigned int base = 0, span = UINT_MAX >> 4; |
@@ -261,7 +276,6 @@ int query_locale_info( int argc, char **argv ) | ||
261 | 276 | return EXIT_FAILURE; |
262 | 277 | } |
263 | 278 | } |
264 | - | |
265 | 279 | /* Finally, cycle over the specified key value range, performing |
266 | 280 | * the specified look-up action, ensuring that we do not wrap at |
267 | 281 | * UINT_MAX, into an interminable loop. |
@@ -272,8 +286,17 @@ int query_locale_info( int argc, char **argv ) | ||
272 | 286 | return EXIT_SUCCESS; |
273 | 287 | } |
274 | 288 | |
289 | +#else /* ! BUILD_DLL */ | |
290 | +/* When not building the DLL component, we simply furnish the main() | |
291 | + * function; this checks that the necessary GetLocaleInfoEx() function | |
292 | + * is actually present within kernel32.dll, (it isn't, on any Windows | |
293 | + * version pre-dating Vista), before delegating the actual query to | |
294 | + * the handler in the supporting DLL component. | |
295 | + */ | |
275 | 296 | int main( int argc, char **argv ) |
276 | 297 | { |
298 | + typedef int (*query)( int, char ** ); | |
299 | + | |
277 | 300 | HMODULE ref; const char *api = "kernel32.dll"; |
278 | 301 | if( (ref = GetModuleHandleA( api )) != NULL ) |
279 | 302 | { |
@@ -282,10 +305,22 @@ int main( int argc, char **argv ) | ||
282 | 305 | errprintf( "function '%s' is unsupported on this host\n", api ); |
283 | 306 | errprintf( "Windows-Vista (or later) is required\n" ); |
284 | 307 | } |
285 | - else return query_locale_info( argc, argv ); | |
308 | + else if( (ref = LoadLibraryA( api = "locale-info.dll" )) == NULL ) | |
309 | + errprintf( "cannot load '%s'\n", api ); | |
310 | + | |
311 | + else | |
312 | + { api = "query_locale_info"; | |
313 | + query locale_info = (query)(GetProcAddress( ref, api )); | |
314 | + if( locale_info == NULL ) | |
315 | + errprintf( "cannot access '%s()' API\n", api ); | |
316 | + | |
317 | + else return locale_info( argc, argv ); | |
318 | + } | |
286 | 319 | } |
287 | 320 | else errprintf( "'%s' was not mapped within this process\n", api ); |
288 | 321 | return EXIT_FAILURE; |
289 | 322 | } |
290 | 323 | |
324 | +#endif /* ! BUILD_DLL */ | |
325 | + | |
291 | 326 | /* $RCSfile$: end of file */ |