icuinfo.cpp (9396B)
1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * 6 * Copyright (C) 1999-2016, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 * 9 ******************************************************************************* 10 * file name: icuinfo.cpp 11 * encoding: UTF-8 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, 45 /*4*/ UOPTION_DEF("list-plugins", 'L', UOPT_NO_ARG), // may be a no-op if disabled 46 /*5*/ UOPTION_DEF("milisecond-time", 'm', UOPT_NO_ARG), 47 /*6*/ UOPTION_DEF("cleanup", 'K', UOPT_NO_ARG), 48 /*7*/ UOPTION_DEF("xml", 'x', UOPT_REQUIRES_ARG), 49 }; 50 51 static UErrorCode initStatus = U_ZERO_ERROR; 52 static UBool icuInitted = false; 53 54 static void do_init() { 55 if(!icuInitted) { 56 u_init(&initStatus); 57 icuInitted = true; 58 } 59 } 60 61 static void do_cleanup() { 62 if (icuInitted) { 63 u_cleanup(); 64 icuInitted = false; 65 } 66 } 67 68 void cmd_millis() 69 { 70 printf("Milliseconds since Epoch: %.0f\n", uprv_getUTCtime()); 71 } 72 73 void cmd_version(UBool /* noLoad */, UErrorCode &errorCode) 74 { 75 76 do_init(); 77 78 udbg_writeIcuInfo(stdout); /* print the XML format */ 79 80 union { 81 uint8_t byte; 82 uint16_t word; 83 } u; 84 u.word=0x0100; 85 if(U_IS_BIG_ENDIAN==u.byte) { 86 //printf("U_IS_BIG_ENDIAN: %d\n", U_IS_BIG_ENDIAN); 87 } else { 88 fprintf(stderr, " error: U_IS_BIG_ENDIAN=%d != %d=actual 'is big endian'\n", 89 U_IS_BIG_ENDIAN, u.byte); 90 errorCode=U_INTERNAL_PROGRAM_ERROR; 91 } 92 93 #if defined(_MSC_VER) 94 // Ignore warning 4127, conditional expression is constant. This is intentional below. 95 #pragma warning(push) 96 #pragma warning(disable: 4127) 97 #endif 98 99 if(U_SIZEOF_WCHAR_T==sizeof(wchar_t)) { 100 //printf("U_SIZEOF_WCHAR_T: %d\n", U_SIZEOF_WCHAR_T); 101 } else { 102 fprintf(stderr, " error: U_SIZEOF_WCHAR_T=%d != %d=sizeof(wchar_t)\n", 103 U_SIZEOF_WCHAR_T, static_cast<int>(sizeof(wchar_t))); 104 errorCode=U_INTERNAL_PROGRAM_ERROR; 105 } 106 107 int charsetFamily; 108 if('A'==0x41) { 109 charsetFamily=U_ASCII_FAMILY; 110 } else if('A'==0xc1) { 111 charsetFamily=U_EBCDIC_FAMILY; 112 } else { 113 charsetFamily=-1; // unknown 114 } 115 if(U_CHARSET_FAMILY==charsetFamily) { 116 //printf("U_CHARSET_FAMILY: %d\n", U_CHARSET_FAMILY); 117 } else { 118 fprintf(stderr, " error: U_CHARSET_FAMILY=%d != %d=actual charset family\n", 119 U_CHARSET_FAMILY, charsetFamily); 120 errorCode=U_INTERNAL_PROGRAM_ERROR; 121 } 122 123 #if defined(_MSC_VER) 124 #pragma warning(pop) 125 #endif 126 127 printf("\n\nICU Initialization returned: %s\n", u_errorName(initStatus)); 128 129 130 #if UCONFIG_ENABLE_PLUGINS 131 #if U_ENABLE_DYLOAD 132 const char *pluginFile = uplug_getPluginFile(); 133 printf("Plugin file is: %s\n", (pluginFile&&*pluginFile)?pluginFile:"(not set. try setting ICU_PLUGINS to a directory.)"); 134 #else 135 fprintf(stderr, "Dynamic Loading: is disabled. No plugins will be loaded at start-up.\n"); 136 #endif 137 #else 138 fprintf(stderr, "Plugins are disabled.\n"); 139 #endif 140 } 141 142 void cmd_cleanup() 143 { 144 u_cleanup(); 145 fprintf(stdout, "ICU u_cleanup() called.\n"); 146 } 147 148 149 void cmd_listplugins() { 150 #if UCONFIG_ENABLE_PLUGINS 151 int32_t i; 152 UPlugData *plug; 153 154 do_init(); 155 printf("ICU Initialized: u_init() returned %s\n", u_errorName(initStatus)); 156 157 printf("Plugins: \n"); 158 printf( "# %6s %s \n", 159 "Level", 160 "Name" ); 161 printf( " %10s:%-10s\n", 162 "Library", 163 "Symbol" 164 ); 165 166 167 printf( " config| (configuration string)\n"); 168 printf( " >>> Error | Explanation \n"); 169 printf( "-----------------------------------\n"); 170 171 for(i=0;(plug=uplug_getPlugInternal(i))!=nullptr;i++) { 172 UErrorCode libStatus = U_ZERO_ERROR; 173 const char *name = uplug_getPlugName(plug); 174 const char *sym = uplug_getSymbolName(plug); 175 const char *lib = uplug_getLibraryName(plug, &libStatus); 176 const char *config = uplug_getConfiguration(plug); 177 UErrorCode loadStatus = uplug_getPlugLoadStatus(plug); 178 const char *message = nullptr; 179 180 printf("\n#%d %-6s %s \n", 181 i+1, 182 udbg_enumName(UDBG_UPlugLevel,(int32_t)uplug_getPlugLevel(plug)), 183 name!=nullptr?(*name?name:"this plugin did not call uplug_setPlugName()"):"(null)" 184 ); 185 printf(" plugin| %10s:%-10s\n", 186 (U_SUCCESS(libStatus)?(lib!=nullptr?lib:"(null)"):u_errorName(libStatus)), 187 sym!=nullptr?sym:"(null)" 188 ); 189 190 if(config!=nullptr&&*config) { 191 printf(" config| %s\n", config); 192 } 193 194 switch(loadStatus) { 195 case U_PLUGIN_CHANGED_LEVEL_WARNING: 196 message = "Note: This plugin changed the system level (by allocating memory or calling something which does). Later plugins may not load."; 197 break; 198 199 case U_PLUGIN_DIDNT_SET_LEVEL: 200 message = "Error: This plugin did not call uplug_setPlugLevel during QUERY."; 201 break; 202 203 case U_PLUGIN_TOO_HIGH: 204 message = "Error: This plugin couldn't load because the system level was too high. Try loading this plugin earlier."; 205 break; 206 207 case U_ZERO_ERROR: 208 message = nullptr; /* no message */ 209 break; 210 default: 211 if(U_FAILURE(loadStatus)) { 212 message = "error loading:"; 213 } else { 214 message = "warning during load:"; 215 } 216 } 217 218 if(message!=nullptr) { 219 printf("\\\\\\ status| %s\n" 220 "/// %s\n", u_errorName(loadStatus), message); 221 } 222 223 } 224 if(i==0) { 225 printf("No plugins loaded.\n"); 226 } 227 #endif 228 } 229 230 231 232 extern int 233 main(int argc, char* argv[]) { 234 UErrorCode errorCode = U_ZERO_ERROR; 235 UBool didSomething = false; 236 237 /* preset then read command line options */ 238 argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); 239 240 /* error handling, printing usage message */ 241 if(argc<0) { 242 fprintf(stderr, 243 "error in command line argument \"%s\"\n", 244 argv[-argc]); 245 } 246 if( options[0].doesOccur || options[1].doesOccur) { 247 fprintf(stderr, "%s: Output information about the current ICU\n", argv[0]); 248 fprintf(stderr, "Options:\n" 249 " -h or --help - Print this help message.\n" 250 " -m or --millisecond-time - Print the current UTC time in milliseconds.\n" 251 " -d <dir> or --icudatadir <dir> - Set the ICU Data Directory\n" 252 " -v - Print version and configuration information about ICU\n" 253 #if UCONFIG_ENABLE_PLUGINS 254 " -L or --list-plugins - List and diagnose issues with ICU Plugins\n" 255 #endif 256 " -K or --cleanup - Call u_cleanup() before exiting (will attempt to unload plugins)\n" 257 "\n" 258 "If no arguments are given, the tool will print ICU version and configuration information.\n" 259 ); 260 fprintf(stderr, "International Components for Unicode %s\n%s\n", U_ICU_VERSION, U_COPYRIGHT_STRING ); 261 return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; 262 } 263 264 if(options[2].doesOccur) { 265 u_setDataDirectory(options[2].value); 266 } 267 268 if(options[5].doesOccur) { 269 cmd_millis(); 270 didSomething=true; 271 } 272 if(options[4].doesOccur) { 273 cmd_listplugins(); 274 didSomething = true; 275 } 276 277 if(options[3].doesOccur) { 278 cmd_version(false, errorCode); 279 didSomething = true; 280 } 281 282 if(options[7].doesOccur) { /* 2nd part of version: cleanup */ 283 FILE *out = fopen(options[7].value, "w"); 284 if(out==nullptr) { 285 fprintf(stderr,"ERR: can't write to XML file %s\n", options[7].value); 286 return 1; 287 } 288 /* todo: API for writing DTD? */ 289 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); 290 udbg_writeIcuInfo(out); 291 fclose(out); 292 didSomething = true; 293 } 294 295 if(options[6].doesOccur) { /* 2nd part of version: cleanup */ 296 cmd_cleanup(); 297 didSomething = true; 298 } 299 300 if(!didSomething) { 301 cmd_version(false, errorCode); /* at least print the version # */ 302 } 303 304 do_cleanup(); 305 306 return U_FAILURE(errorCode); 307 }