]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
729e4ab9 A |
3 | /* |
4 | ******************************************************************************* | |
5 | * | |
2ca993e8 | 6 | * Copyright (C) 1999-2016, International Business Machines |
729e4ab9 A |
7 | * Corporation and others. All Rights Reserved. |
8 | * | |
9 | ******************************************************************************* | |
10 | * file name: icuinfo.cpp | |
f3c0d7a5 | 11 | * encoding: UTF-8 |
729e4ab9 A |
12 | * tab size: 8 (not used) |
13 | * indentation:4 | |
14 | * | |
15 | * created on: 2009-2010 | |
16 | * created by: Steven R. Loomis | |
17 | * | |
18 | * This program shows some basic info about the current ICU. | |
19 | */ | |
20 | ||
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include "unicode/utypes.h" | |
24 | #include "unicode/putil.h" | |
25 | #include "unicode/uclean.h" | |
26 | #include "udbgutil.h" | |
27 | #include "unewdata.h" | |
28 | #include "cmemory.h" | |
29 | #include "cstring.h" | |
30 | #include "uoptions.h" | |
31 | #include "toolutil.h" | |
32 | #include "icuplugimp.h" | |
33 | #include <unicode/uloc.h> | |
34 | #include <unicode/ucnv.h> | |
35 | #include "unicode/ucal.h" | |
36 | #include <unicode/ulocdata.h> | |
37 | #include "putilimp.h" | |
38 | #include "unicode/uchar.h" | |
39 | ||
40 | static UOption options[]={ | |
41 | /*0*/ UOPTION_HELP_H, | |
42 | /*1*/ UOPTION_HELP_QUESTION_MARK, | |
43 | /*2*/ UOPTION_ICUDATADIR, | |
44 | /*3*/ UOPTION_VERBOSE, | |
2ca993e8 | 45 | /*4*/ UOPTION_DEF("list-plugins", 'L', UOPT_NO_ARG), // may be a no-op if disabled |
729e4ab9 A |
46 | /*5*/ UOPTION_DEF("milisecond-time", 'm', UOPT_NO_ARG), |
47 | /*6*/ UOPTION_DEF("cleanup", 'K', UOPT_NO_ARG), | |
4388f060 | 48 | /*7*/ UOPTION_DEF("xml", 'x', UOPT_REQUIRES_ARG), |
c5116b9f | 49 | /*8*/ UOPTION_DEF("perf", 'p', UOPT_NO_ARG), // Apple |
729e4ab9 A |
50 | }; |
51 | ||
52 | static UErrorCode initStatus = U_ZERO_ERROR; | |
53 | static UBool icuInitted = FALSE; | |
54 | ||
55 | static void do_init() { | |
56 | if(!icuInitted) { | |
57 | u_init(&initStatus); | |
58 | icuInitted = TRUE; | |
59 | } | |
60 | } | |
61 | ||
c5116b9f | 62 | static void cmd_perf(); // Apple |
729e4ab9 A |
63 | |
64 | void cmd_millis() | |
65 | { | |
66 | printf("Milliseconds since Epoch: %.0f\n", uprv_getUTCtime()); | |
67 | } | |
68 | ||
4388f060 | 69 | void cmd_version(UBool /* noLoad */, UErrorCode &errorCode) |
729e4ab9 | 70 | { |
4388f060 | 71 | |
729e4ab9 | 72 | do_init(); |
4388f060 A |
73 | |
74 | udbg_writeIcuInfo(stdout); /* print the XML format */ | |
729e4ab9 | 75 | |
4388f060 A |
76 | union { |
77 | uint8_t byte; | |
78 | uint16_t word; | |
79 | } u; | |
80 | u.word=0x0100; | |
81 | if(U_IS_BIG_ENDIAN==u.byte) { | |
82 | //printf("U_IS_BIG_ENDIAN: %d\n", U_IS_BIG_ENDIAN); | |
83 | } else { | |
84 | fprintf(stderr, " error: U_IS_BIG_ENDIAN=%d != %d=actual 'is big endian'\n", | |
85 | U_IS_BIG_ENDIAN, u.byte); | |
86 | errorCode=U_INTERNAL_PROGRAM_ERROR; | |
729e4ab9 | 87 | } |
729e4ab9 | 88 | |
3d1f044b A |
89 | #if defined(_MSC_VER) |
90 | // Ignore warning 4127, conditional expression is constant. This is intentional below. | |
91 | #pragma warning(push) | |
92 | #pragma warning(disable: 4127) | |
93 | #endif | |
94 | ||
4388f060 A |
95 | if(U_SIZEOF_WCHAR_T==sizeof(wchar_t)) { |
96 | //printf("U_SIZEOF_WCHAR_T: %d\n", U_SIZEOF_WCHAR_T); | |
97 | } else { | |
98 | fprintf(stderr, " error: U_SIZEOF_WCHAR_T=%d != %d=sizeof(wchar_t)\n", | |
99 | U_SIZEOF_WCHAR_T, (int)sizeof(wchar_t)); | |
100 | errorCode=U_INTERNAL_PROGRAM_ERROR; | |
729e4ab9 | 101 | } |
4388f060 A |
102 | |
103 | int charsetFamily; | |
104 | if('A'==0x41) { | |
105 | charsetFamily=U_ASCII_FAMILY; | |
106 | } else if('A'==0xc1) { | |
107 | charsetFamily=U_EBCDIC_FAMILY; | |
108 | } else { | |
109 | charsetFamily=-1; // unknown | |
729e4ab9 | 110 | } |
4388f060 A |
111 | if(U_CHARSET_FAMILY==charsetFamily) { |
112 | //printf("U_CHARSET_FAMILY: %d\n", U_CHARSET_FAMILY); | |
113 | } else { | |
114 | fprintf(stderr, " error: U_CHARSET_FAMILY=%d != %d=actual charset family\n", | |
115 | U_CHARSET_FAMILY, charsetFamily); | |
116 | errorCode=U_INTERNAL_PROGRAM_ERROR; | |
117 | } | |
118 | ||
3d1f044b A |
119 | #if defined(_MSC_VER) |
120 | #pragma warning(pop) | |
121 | #endif | |
122 | ||
4388f060 A |
123 | printf("\n\nICU Initialization returned: %s\n", u_errorName(initStatus)); |
124 | ||
2ca993e8 A |
125 | |
126 | #if UCONFIG_ENABLE_PLUGINS | |
729e4ab9 A |
127 | #if U_ENABLE_DYLOAD |
128 | const char *pluginFile = uplug_getPluginFile(); | |
129 | printf("Plugin file is: %s\n", (pluginFile&&*pluginFile)?pluginFile:"(not set. try setting ICU_PLUGINS to a directory.)"); | |
130 | #else | |
131 | fprintf(stderr, "Dynamic Loading: is disabled. No plugins will be loaded at start-up.\n"); | |
132 | #endif | |
2ca993e8 A |
133 | #else |
134 | fprintf(stderr, "Plugins are disabled.\n"); | |
c5116b9f | 135 | #endif |
729e4ab9 A |
136 | } |
137 | ||
138 | void cmd_cleanup() | |
139 | { | |
140 | u_cleanup(); | |
51004dcb | 141 | fprintf(stdout, "ICU u_cleanup() called.\n"); |
729e4ab9 A |
142 | } |
143 | ||
144 | ||
145 | void cmd_listplugins() { | |
2ca993e8 | 146 | #if UCONFIG_ENABLE_PLUGINS |
729e4ab9 A |
147 | int32_t i; |
148 | UPlugData *plug; | |
149 | ||
150 | do_init(); | |
151 | printf("ICU Initialized: u_init() returned %s\n", u_errorName(initStatus)); | |
152 | ||
153 | printf("Plugins: \n"); | |
154 | printf( "# %6s %s \n", | |
155 | "Level", | |
156 | "Name" ); | |
157 | printf( " %10s:%-10s\n", | |
158 | "Library", | |
159 | "Symbol" | |
160 | ); | |
161 | ||
162 | ||
163 | printf( " config| (configuration string)\n"); | |
164 | printf( " >>> Error | Explanation \n"); | |
165 | printf( "-----------------------------------\n"); | |
166 | ||
167 | for(i=0;(plug=uplug_getPlugInternal(i))!=NULL;i++) { | |
168 | UErrorCode libStatus = U_ZERO_ERROR; | |
169 | const char *name = uplug_getPlugName(plug); | |
170 | const char *sym = uplug_getSymbolName(plug); | |
171 | const char *lib = uplug_getLibraryName(plug, &libStatus); | |
172 | const char *config = uplug_getConfiguration(plug); | |
173 | UErrorCode loadStatus = uplug_getPlugLoadStatus(plug); | |
174 | const char *message = NULL; | |
175 | ||
176 | printf("\n#%d %-6s %s \n", | |
177 | i+1, | |
178 | udbg_enumName(UDBG_UPlugLevel,(int32_t)uplug_getPlugLevel(plug)), | |
179 | name!=NULL?(*name?name:"this plugin did not call uplug_setPlugName()"):"(null)" | |
180 | ); | |
181 | printf(" plugin| %10s:%-10s\n", | |
182 | (U_SUCCESS(libStatus)?(lib!=NULL?lib:"(null)"):u_errorName(libStatus)), | |
183 | sym!=NULL?sym:"(null)" | |
184 | ); | |
185 | ||
186 | if(config!=NULL&&*config) { | |
187 | printf(" config| %s\n", config); | |
188 | } | |
189 | ||
190 | switch(loadStatus) { | |
191 | case U_PLUGIN_CHANGED_LEVEL_WARNING: | |
192 | message = "Note: This plugin changed the system level (by allocating memory or calling something which does). Later plugins may not load."; | |
193 | break; | |
194 | ||
195 | case U_PLUGIN_DIDNT_SET_LEVEL: | |
196 | message = "Error: This plugin did not call uplug_setPlugLevel during QUERY."; | |
197 | break; | |
198 | ||
199 | case U_PLUGIN_TOO_HIGH: | |
200 | message = "Error: This plugin couldn't load because the system level was too high. Try loading this plugin earlier."; | |
201 | break; | |
202 | ||
203 | case U_ZERO_ERROR: | |
204 | message = NULL; /* no message */ | |
205 | break; | |
206 | default: | |
207 | if(U_FAILURE(loadStatus)) { | |
208 | message = "error loading:"; | |
209 | } else { | |
210 | message = "warning during load:"; | |
211 | } | |
212 | } | |
213 | ||
214 | if(message!=NULL) { | |
215 | printf("\\\\\\ status| %s\n" | |
216 | "/// %s\n", u_errorName(loadStatus), message); | |
217 | } | |
218 | ||
219 | } | |
220 | if(i==0) { | |
221 | printf("No plugins loaded.\n"); | |
222 | } | |
2ca993e8 | 223 | #endif |
729e4ab9 A |
224 | } |
225 | ||
226 | ||
227 | ||
228 | extern int | |
229 | main(int argc, char* argv[]) { | |
230 | UErrorCode errorCode = U_ZERO_ERROR; | |
231 | UBool didSomething = FALSE; | |
232 | ||
233 | /* preset then read command line options */ | |
2ca993e8 | 234 | argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); |
729e4ab9 A |
235 | |
236 | /* error handling, printing usage message */ | |
237 | if(argc<0) { | |
238 | fprintf(stderr, | |
239 | "error in command line argument \"%s\"\n", | |
240 | argv[-argc]); | |
241 | } | |
242 | if( options[0].doesOccur || options[1].doesOccur) { | |
243 | fprintf(stderr, "%s: Output information about the current ICU\n", argv[0]); | |
244 | fprintf(stderr, "Options:\n" | |
245 | " -h or --help - Print this help message.\n" | |
246 | " -m or --millisecond-time - Print the current UTC time in milliseconds.\n" | |
247 | " -d <dir> or --icudatadir <dir> - Set the ICU Data Directory\n" | |
248 | " -v - Print version and configuration information about ICU\n" | |
2ca993e8 | 249 | #if UCONFIG_ENABLE_PLUGINS |
729e4ab9 | 250 | " -L or --list-plugins - List and diagnose issues with ICU Plugins\n" |
2ca993e8 | 251 | #endif |
729e4ab9 | 252 | " -K or --cleanup - Call u_cleanup() before exitting (will attempt to unload plugins)\n" |
c5116b9f A |
253 | " -p or --perf - Perf tests (Apple)\n" |
254 | "\n" | |
729e4ab9 A |
255 | "If no arguments are given, the tool will print ICU version and configuration information.\n" |
256 | ); | |
257 | fprintf(stderr, "International Components for Unicode %s\n%s\n", U_ICU_VERSION, U_COPYRIGHT_STRING ); | |
258 | return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; | |
259 | } | |
260 | ||
261 | if(options[2].doesOccur) { | |
262 | u_setDataDirectory(options[2].value); | |
263 | } | |
264 | ||
265 | if(options[5].doesOccur) { | |
266 | cmd_millis(); | |
267 | didSomething=TRUE; | |
268 | } | |
269 | if(options[4].doesOccur) { | |
270 | cmd_listplugins(); | |
271 | didSomething = TRUE; | |
272 | } | |
4388f060 | 273 | |
729e4ab9 | 274 | if(options[3].doesOccur) { |
4388f060 | 275 | cmd_version(FALSE, errorCode); |
729e4ab9 A |
276 | didSomething = TRUE; |
277 | } | |
4388f060 A |
278 | |
279 | if(options[7].doesOccur) { /* 2nd part of version: cleanup */ | |
280 | FILE *out = fopen(options[7].value, "w"); | |
281 | if(out==NULL) { | |
282 | fprintf(stderr,"ERR: can't write to XML file %s\n", options[7].value); | |
283 | return 1; | |
284 | } | |
285 | /* todo: API for writing DTD? */ | |
286 | fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); | |
287 | udbg_writeIcuInfo(out); | |
288 | fclose(out); | |
289 | didSomething = TRUE; | |
290 | } | |
291 | ||
729e4ab9 A |
292 | if(options[6].doesOccur) { /* 2nd part of version: cleanup */ |
293 | cmd_cleanup(); | |
294 | didSomething = TRUE; | |
295 | } | |
4388f060 | 296 | |
c5116b9f A |
297 | if(options[8].doesOccur) { // Apple |
298 | cmd_perf(); | |
299 | didSomething=TRUE; | |
300 | } | |
301 | ||
729e4ab9 | 302 | if(!didSomething) { |
4388f060 | 303 | cmd_version(FALSE, errorCode); /* at least print the version # */ |
729e4ab9 A |
304 | } |
305 | ||
306 | return U_FAILURE(errorCode); | |
307 | } | |
c5116b9f A |
308 | |
309 | // Apple addition | |
310 | #include <unistd.h> | |
311 | #include <mach/mach_time.h> | |
312 | #include <unicode/ustring.h> | |
313 | #include <unicode/udat.h> | |
314 | enum { kUCharsOutMax = 128, kBytesOutMax = 256 }; | |
315 | ||
316 | static void cmd_perf() { | |
317 | static const char* locale = "en_US"; | |
318 | static const UChar* tzName = (const UChar*)u"America/Los_Angeles"; | |
319 | static const UDate udatTry1 = 1290714600000.0; // 2010 Nov. 25 (Thurs) 11:50:00 AM PT | |
320 | static const UDate udatTry2 = 1451736016000.0; // 2016 Jan. 02 ... | |
321 | int remaining = 2; | |
322 | mach_timebase_info_data_t info; | |
323 | mach_timebase_info(&info); | |
324 | while (remaining-- > 0) { | |
325 | uint64_t start, durationOpen, durationUse1, durationUse2; | |
326 | UDateFormat *udatfmt; | |
327 | int32_t datlen1, datlen2; | |
328 | UChar outUChars[kUCharsOutMax]; | |
329 | UErrorCode status = U_ZERO_ERROR; | |
330 | ||
331 | start = mach_absolute_time(); | |
332 | udatfmt = udat_open(UDAT_MEDIUM, UDAT_FULL, locale, tzName, -1, NULL, 0, &status); | |
333 | durationOpen = ((mach_absolute_time() - start) * info.numer)/info.denom; | |
334 | if ( U_SUCCESS(status) ) { | |
335 | start = mach_absolute_time(); | |
336 | datlen1 = udat_format(udatfmt, udatTry1, outUChars, kUCharsOutMax, NULL, &status); | |
337 | durationUse1 = ((mach_absolute_time() - start) * info.numer)/info.denom; | |
338 | ||
339 | start = mach_absolute_time(); | |
340 | datlen2 = udat_format(udatfmt, udatTry2, outUChars, kUCharsOutMax, NULL, &status); | |
341 | durationUse2 = ((mach_absolute_time() - start) * info.numer)/info.denom; | |
342 | ||
343 | if ( U_SUCCESS(status) ) { | |
344 | printf("first time %d udat open, fmt1(len %d), fmt2(len %d) nsec:\t%llu\t%llu\t%llu\n", remaining, datlen1, datlen2, durationOpen, durationUse1, durationUse2); | |
345 | } else { | |
346 | printf("first time %d udat_format failed\n", remaining); | |
347 | } | |
348 | udat_close(udatfmt); | |
349 | } else { | |
350 | printf("first time %d udat_open failed\n", remaining); | |
351 | } | |
352 | } | |
353 | } | |
354 |