1/*
2*******************************************************************************
3*
4*   Copyright (C) 1999-2010, International Business Machines
5*   Corporation and others.  All Rights Reserved.
6*
7*******************************************************************************
8*   file name:  icuinfo.cpp
9*   encoding:   US-ASCII
10*   tab size:   8 (not used)
11*   indentation:4
12*
13*   created on: 2009-2010
14*   created by: Steven R. Loomis
15*
16*   This program shows some basic info about the current ICU.
17*/
18
19#include <stdio.h>
20#include <stdlib.h>
21#include "unicode/utypes.h"
22#include "unicode/putil.h"
23#include "unicode/uclean.h"
24#include "udbgutil.h"
25#include "unewdata.h"
26#include "cmemory.h"
27#include "cstring.h"
28#include "uoptions.h"
29#include "toolutil.h"
30#include "icuplugimp.h"
31#include <unicode/uloc.h>
32#include <unicode/ucnv.h>
33#include "unicode/ucal.h"
34#include <unicode/ulocdata.h>
35#include "putilimp.h"
36#include "unicode/uchar.h"
37
38static UOption options[]={
39  /*0*/ UOPTION_HELP_H,
40  /*1*/ UOPTION_HELP_QUESTION_MARK,
41  /*2*/ UOPTION_ICUDATADIR,
42  /*3*/ UOPTION_VERBOSE,
43  /*4*/ UOPTION_DEF("list-plugins", 'L', UOPT_NO_ARG),
44  /*5*/ UOPTION_DEF("milisecond-time", 'm', UOPT_NO_ARG),
45  /*6*/ UOPTION_DEF("cleanup", 'K', UOPT_NO_ARG),
46};
47
48static UErrorCode initStatus = U_ZERO_ERROR;
49static UBool icuInitted = FALSE;
50
51static void do_init() {
52    if(!icuInitted) {
53      u_init(&initStatus);
54      icuInitted = TRUE;
55    }
56}
57
58/**
59 * Print the current platform
60 */
61static const char *getPlatform()
62{
63#if defined(U_PLATFORM)
64	return U_PLATFORM;
65#elif defined(U_WINDOWS)
66	return "Windows";
67#elif defined(U_PALMOS)
68	return "PalmOS";
69#elif defined(_PLATFORM_H)
70	return "Other (POSIX-like)";
71#else
72	return "unknown"
73#endif
74}
75
76void cmd_millis()
77{
78  printf("Milliseconds since Epoch: %.0f\n", uprv_getUTCtime());
79}
80
81void cmd_version(UBool noLoad)
82{
83    UVersionInfo icu;
84    char str[200];
85    printf("<ICUINFO>\n");
86    printf("International Components for Unicode for C/C++\n");
87    printf("%s\n", U_COPYRIGHT_STRING);
88    printf("Compiled-Version: %s\n", U_ICU_VERSION);
89    u_getVersion(icu);
90    u_versionToString(icu, str);
91    printf("Runtime-Version: %s\n", str);
92    printf("Compiled-Unicode-Version: %s\n", U_UNICODE_VERSION);
93    u_getUnicodeVersion(icu);
94    u_versionToString(icu, str);
95    printf("Runtime-Unicode-Version: %s\n", U_UNICODE_VERSION);
96    printf("Platform: %s\n", getPlatform());
97#if defined(U_BUILD)
98    printf("Build: %s\n", U_BUILD);
99#if defined(U_HOST)
100    if(strcmp(U_BUILD,U_HOST)) {
101      printf("Host: %s\n", U_HOST);
102    }
103#endif
104#endif
105#if defined(U_CC)
106    printf("C compiler: %s\n", U_CC);
107#endif
108#if defined(U_CXX)
109    printf("C++ compiler: %s\n", U_CXX);
110#endif
111#if defined(CYGWINMSVC)
112    printf("Cygwin: CYGWINMSVC\n");
113#endif
114    printf("ICUDATA: %s\n", U_ICUDATA_NAME);
115    do_init();
116    printf("Data Directory: %s\n", u_getDataDirectory());
117    printf("ICU Initialization returned: %s\n", u_errorName(initStatus));
118    printf( "Default locale: %s\n", uloc_getDefault());
119    {
120      UErrorCode subStatus = U_ZERO_ERROR;
121      ulocdata_getCLDRVersion(icu, &subStatus);
122      if(U_SUCCESS(subStatus)) {
123	u_versionToString(icu, str);
124	printf("CLDR-Version: %s\n", str);
125      } else {
126	printf("CLDR-Version: %s\n", u_errorName(subStatus));
127      }
128    }
129
130#if !UCONFIG_NO_CONVERSION
131    if(noLoad == FALSE)
132    {
133      printf("Default converter: %s\n", ucnv_getDefaultName());
134    }
135#endif
136#if !UCONFIG_NO_FORMATTING
137    {
138      UChar buf[100];
139      char buf2[100];
140      UErrorCode subsubStatus= U_ZERO_ERROR;
141      int32_t len;
142
143      len = ucal_getDefaultTimeZone(buf, 100, &subsubStatus);
144      if(U_SUCCESS(subsubStatus)&&len>0) {
145	u_UCharsToChars(buf, buf2, len+1);
146	printf("Default TZ: %s\n", buf2);
147      } else {
148	printf("Default TZ: %s\n", u_errorName(subsubStatus));
149      }
150    }
151    {
152      UErrorCode subStatus = U_ZERO_ERROR;
153      const char *tzVer = ucal_getTZDataVersion(&subStatus);
154      if(U_FAILURE(subStatus)) {
155	tzVer = u_errorName(subStatus);
156      }
157      printf("TZ data version: %s\n", tzVer);
158    }
159#endif
160
161#if U_ENABLE_DYLOAD
162    const char *pluginFile = uplug_getPluginFile();
163    printf("Plugin file is: %s\n", (pluginFile&&*pluginFile)?pluginFile:"(not set. try setting ICU_PLUGINS to a directory.)");
164#else
165    fprintf(stderr, "Dynamic Loading: is disabled. No plugins will be loaded at start-up.\n");
166#endif
167    printf("</ICUINFO>\n\n");
168}
169
170void cmd_cleanup()
171{
172    u_cleanup();
173    fprintf(stderr,"ICU u_cleanup() called.\n");
174}
175
176
177void cmd_listplugins() {
178    int32_t i;
179    UPlugData *plug;
180
181    do_init();
182    printf("ICU Initialized: u_init() returned %s\n", u_errorName(initStatus));
183
184    printf("Plugins: \n");
185    printf(    "# %6s   %s \n",
186                       "Level",
187                       "Name" );
188    printf(    "    %10s:%-10s\n",
189                       "Library",
190                       "Symbol"
191            );
192
193
194    printf(    "       config| (configuration string)\n");
195    printf(    " >>>   Error          | Explanation \n");
196    printf(    "-----------------------------------\n");
197
198    for(i=0;(plug=uplug_getPlugInternal(i))!=NULL;i++) {
199        UErrorCode libStatus = U_ZERO_ERROR;
200        const char *name = uplug_getPlugName(plug);
201        const char *sym = uplug_getSymbolName(plug);
202        const char *lib = uplug_getLibraryName(plug, &libStatus);
203        const char *config = uplug_getConfiguration(plug);
204        UErrorCode loadStatus = uplug_getPlugLoadStatus(plug);
205        const char *message = NULL;
206
207        printf("\n#%d  %-6s %s \n",
208            i+1,
209            udbg_enumName(UDBG_UPlugLevel,(int32_t)uplug_getPlugLevel(plug)),
210            name!=NULL?(*name?name:"this plugin did not call uplug_setPlugName()"):"(null)"
211        );
212        printf("    plugin| %10s:%-10s\n",
213            (U_SUCCESS(libStatus)?(lib!=NULL?lib:"(null)"):u_errorName(libStatus)),
214            sym!=NULL?sym:"(null)"
215        );
216
217        if(config!=NULL&&*config) {
218            printf("    config| %s\n", config);
219        }
220
221        switch(loadStatus) {
222            case U_PLUGIN_CHANGED_LEVEL_WARNING:
223                message = "Note: This plugin changed the system level (by allocating memory or calling something which does). Later plugins may not load.";
224                break;
225
226            case U_PLUGIN_DIDNT_SET_LEVEL:
227                message = "Error: This plugin did not call uplug_setPlugLevel during QUERY.";
228                break;
229
230            case U_PLUGIN_TOO_HIGH:
231                message = "Error: This plugin couldn't load because the system level was too high. Try loading this plugin earlier.";
232                break;
233
234            case U_ZERO_ERROR:
235                message = NULL; /* no message */
236                break;
237            default:
238                if(U_FAILURE(loadStatus)) {
239                    message = "error loading:";
240                } else {
241                    message = "warning during load:";
242                }
243        }
244
245        if(message!=NULL) {
246            printf("\\\\\\ status| %s\n"
247                   "/// %s\n", u_errorName(loadStatus), message);
248        }
249
250    }
251	if(i==0) {
252		printf("No plugins loaded.\n");
253	}
254
255}
256
257
258
259extern int
260main(int argc, char* argv[]) {
261    UErrorCode errorCode = U_ZERO_ERROR;
262    UBool didSomething = FALSE;
263
264    /* preset then read command line options */
265    argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
266
267    /* error handling, printing usage message */
268    if(argc<0) {
269        fprintf(stderr,
270            "error in command line argument \"%s\"\n",
271            argv[-argc]);
272    }
273    if( options[0].doesOccur || options[1].doesOccur) {
274      fprintf(stderr, "%s: Output information about the current ICU\n", argv[0]);
275      fprintf(stderr, "Options:\n"
276              " -h     or  --help                 - Print this help message.\n"
277              " -m     or  --millisecond-time     - Print the current UTC time in milliseconds.\n"
278              " -d <dir>   or  --icudatadir <dir> - Set the ICU Data Directory\n"
279              " -v                                - Print version and configuration information about ICU\n"
280              " -L         or  --list-plugins     - List and diagnose issues with ICU Plugins\n"
281              " -K         or  --cleanup          - Call u_cleanup() before exitting (will attempt to unload plugins)\n"
282              "\n"
283              "If no arguments are given, the tool will print ICU version and configuration information.\n"
284              );
285      fprintf(stderr, "International Components for Unicode %s\n%s\n", U_ICU_VERSION, U_COPYRIGHT_STRING );
286      return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
287    }
288
289    if(options[2].doesOccur) {
290      u_setDataDirectory(options[2].value);
291    }
292
293    if(options[5].doesOccur) {
294      cmd_millis();
295      didSomething=TRUE;
296    }
297    if(options[4].doesOccur) {
298      cmd_listplugins();
299      didSomething = TRUE;
300    }
301
302    if(options[3].doesOccur) {
303      cmd_version(FALSE);
304      didSomething = TRUE;
305    }
306
307    if(options[6].doesOccur) {  /* 2nd part of version: cleanup */
308      cmd_cleanup();
309      didSomething = TRUE;
310    }
311
312    if(!didSomething) {
313      cmd_version(FALSE);  /* at least print the version # */
314    }
315
316    return U_FAILURE(errorCode);
317}
318