1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/toolutil/udbgutil.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,777 @@ 1.4 +/******************************************************************** 1.5 + * COPYRIGHT: 1.6 + * Copyright (c) 2007-2013, International Business Machines Corporation and 1.7 + * others. All Rights Reserved. 1.8 + ********************************************************************/ 1.9 + 1.10 +#include "udbgutil.h" 1.11 +#include <string.h> 1.12 +#include "ustr_imp.h" 1.13 +#include "cstring.h" 1.14 +#include "putilimp.h" 1.15 +#include "unicode/ulocdata.h" 1.16 +#include "unicode/ucnv.h" 1.17 +#include "unicode/unistr.h" 1.18 + 1.19 +/* 1.20 +To add a new enum type 1.21 + (For example: UShoeSize with values USHOE_WIDE=0, USHOE_REGULAR, USHOE_NARROW, USHOE_COUNT) 1.22 + 1.23 + 1. udbgutil.h: add UDBG_UShoeSize to the UDebugEnumType enum before UDBG_ENUM_COUNT 1.24 + ( The subsequent steps involve this file, udbgutil.cpp ) 1.25 + 2. Find the marker "Add new enum types above this line" 1.26 + 3. Before that marker, add a #include of any header file you need. 1.27 + 4. Each enum type has three things in this section: a #define, a count_, and an array of Fields. 1.28 + It may help to copy and paste a previous definition. 1.29 + 5. In the case of the USHOE_... strings above, "USHOE_" is common to all values- six characters 1.30 + " #define LEN_USHOE 6 " 1.31 + 6 characters will strip off "USHOE_" leaving enum values of WIDE, REGULAR, and NARROW. 1.32 + 6. Define the 'count_' variable, with the number of enum values. If the enum has a _MAX or _COUNT value, 1.33 + that can be helpful for automatically defining the count. Otherwise define it manually. 1.34 + " static const int32_t count_UShoeSize = USHOE_COUNT; " 1.35 + 7. Define the field names, in order. 1.36 + " static const Field names_UShoeSize[] = { 1.37 + " FIELD_NAME_STR( LEN_USHOE, USHOE_WIDE ), 1.38 + " FIELD_NAME_STR( LEN_USHOE, USHOE_REGULAR ), 1.39 + " FIELD_NAME_STR( LEN_USHOE, USHOE_NARROW ), 1.40 + " }; 1.41 + ( The following command was usedfor converting ucol.h into partially correct entities ) 1.42 + grep "^[ ]*UCOL" < unicode/ucol.h | 1.43 + sed -e 's%^[ ]*\([A-Z]*\)_\([A-Z_]*\).*% FIELD_NAME_STR( LEN_\1, \1_\2 ),%g' 1.44 + 8. Now, a bit farther down, add the name of the enum itself to the end of names_UDebugEnumType 1.45 + ( UDebugEnumType is an enum, too!) 1.46 + names_UDebugEnumType[] { ... 1.47 + " FIELD_NAME_STR( LEN_UDBG, UDBG_UShoeSize ), " 1.48 + 9. Find the function _udbg_enumCount and add the count macro: 1.49 + " COUNT_CASE(UShoeSize) 1.50 + 10. Find the function _udbg_enumFields and add the field macro: 1.51 + " FIELD_CASE(UShoeSize) 1.52 + 11. verify that your test code, and Java data generation, works properly. 1.53 +*/ 1.54 + 1.55 +/** 1.56 + * Structure representing an enum value 1.57 + */ 1.58 +struct Field { 1.59 + int32_t prefix; /**< how many characters to remove in the prefix - i.e. UCHAR_ = 5 */ 1.60 + const char *str; /**< The actual string value */ 1.61 + int32_t num; /**< The numeric value */ 1.62 +}; 1.63 + 1.64 +/** 1.65 + * Calculate the size of an array. 1.66 + */ 1.67 +#define DBG_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) 1.68 + 1.69 +/** 1.70 + * Define another field name. Used in an array of Field s 1.71 + * @param y the common prefix length (i.e. 6 for "USHOE_" ) 1.72 + * @param x the actual enum value - it will be copied in both string and symbolic form. 1.73 + * @see Field 1.74 + */ 1.75 +#define FIELD_NAME_STR(y,x) { y, #x, x } 1.76 + 1.77 + 1.78 +// TODO: Currently, this whole functionality goes away with UCONFIG_NO_FORMATTING. Should be split up. 1.79 +#if !UCONFIG_NO_FORMATTING 1.80 + 1.81 +// Calendar 1.82 +#include "unicode/ucal.h" 1.83 + 1.84 +// 'UCAL_' = 5 1.85 +#define LEN_UCAL 5 /* UCAL_ */ 1.86 +static const int32_t count_UCalendarDateFields = UCAL_FIELD_COUNT; 1.87 +static const Field names_UCalendarDateFields[] = 1.88 +{ 1.89 + FIELD_NAME_STR( LEN_UCAL, UCAL_ERA ), 1.90 + FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR ), 1.91 + FIELD_NAME_STR( LEN_UCAL, UCAL_MONTH ), 1.92 + FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_YEAR ), 1.93 + FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_MONTH ), 1.94 + FIELD_NAME_STR( LEN_UCAL, UCAL_DATE ), 1.95 + FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_YEAR ), 1.96 + FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK ), 1.97 + FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK_IN_MONTH ), 1.98 + FIELD_NAME_STR( LEN_UCAL, UCAL_AM_PM ), 1.99 + FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR ), 1.100 + FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR_OF_DAY ), 1.101 + FIELD_NAME_STR( LEN_UCAL, UCAL_MINUTE ), 1.102 + FIELD_NAME_STR( LEN_UCAL, UCAL_SECOND ), 1.103 + FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECOND ), 1.104 + FIELD_NAME_STR( LEN_UCAL, UCAL_ZONE_OFFSET ), 1.105 + FIELD_NAME_STR( LEN_UCAL, UCAL_DST_OFFSET ), 1.106 + FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR_WOY ), 1.107 + FIELD_NAME_STR( LEN_UCAL, UCAL_DOW_LOCAL ), 1.108 + FIELD_NAME_STR( LEN_UCAL, UCAL_EXTENDED_YEAR ), 1.109 + FIELD_NAME_STR( LEN_UCAL, UCAL_JULIAN_DAY ), 1.110 + FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECONDS_IN_DAY ), 1.111 + FIELD_NAME_STR( LEN_UCAL, UCAL_IS_LEAP_MONTH ), 1.112 +}; 1.113 + 1.114 + 1.115 +static const int32_t count_UCalendarMonths = UCAL_UNDECIMBER+1; 1.116 +static const Field names_UCalendarMonths[] = 1.117 +{ 1.118 + FIELD_NAME_STR( LEN_UCAL, UCAL_JANUARY ), 1.119 + FIELD_NAME_STR( LEN_UCAL, UCAL_FEBRUARY ), 1.120 + FIELD_NAME_STR( LEN_UCAL, UCAL_MARCH ), 1.121 + FIELD_NAME_STR( LEN_UCAL, UCAL_APRIL ), 1.122 + FIELD_NAME_STR( LEN_UCAL, UCAL_MAY ), 1.123 + FIELD_NAME_STR( LEN_UCAL, UCAL_JUNE ), 1.124 + FIELD_NAME_STR( LEN_UCAL, UCAL_JULY ), 1.125 + FIELD_NAME_STR( LEN_UCAL, UCAL_AUGUST ), 1.126 + FIELD_NAME_STR( LEN_UCAL, UCAL_SEPTEMBER ), 1.127 + FIELD_NAME_STR( LEN_UCAL, UCAL_OCTOBER ), 1.128 + FIELD_NAME_STR( LEN_UCAL, UCAL_NOVEMBER ), 1.129 + FIELD_NAME_STR( LEN_UCAL, UCAL_DECEMBER ), 1.130 + FIELD_NAME_STR( LEN_UCAL, UCAL_UNDECIMBER) 1.131 +}; 1.132 + 1.133 +#include "unicode/udat.h" 1.134 + 1.135 +#define LEN_UDAT 5 /* "UDAT_" */ 1.136 +static const int32_t count_UDateFormatStyle = UDAT_SHORT+1; 1.137 +static const Field names_UDateFormatStyle[] = 1.138 +{ 1.139 + FIELD_NAME_STR( LEN_UDAT, UDAT_FULL ), 1.140 + FIELD_NAME_STR( LEN_UDAT, UDAT_LONG ), 1.141 + FIELD_NAME_STR( LEN_UDAT, UDAT_MEDIUM ), 1.142 + FIELD_NAME_STR( LEN_UDAT, UDAT_SHORT ), 1.143 + /* end regular */ 1.144 + /* 1.145 + * negative enums.. leave out for now. 1.146 + FIELD_NAME_STR( LEN_UDAT, UDAT_NONE ), 1.147 + FIELD_NAME_STR( LEN_UDAT, UDAT_PATTERN ), 1.148 + */ 1.149 +}; 1.150 + 1.151 +#endif 1.152 + 1.153 +#include "unicode/uloc.h" 1.154 + 1.155 +#define LEN_UAR 12 /* "ULOC_ACCEPT_" */ 1.156 +static const int32_t count_UAcceptResult = 3; 1.157 +static const Field names_UAcceptResult[] = 1.158 +{ 1.159 + FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_FAILED ), 1.160 + FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_VALID ), 1.161 + FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_FALLBACK ), 1.162 +}; 1.163 + 1.164 +#if !UCONFIG_NO_COLLATION 1.165 +#include "unicode/ucol.h" 1.166 +#define LEN_UCOL 5 /* UCOL_ */ 1.167 +static const int32_t count_UColAttributeValue = UCOL_ATTRIBUTE_VALUE_COUNT; 1.168 +static const Field names_UColAttributeValue[] = { 1.169 + FIELD_NAME_STR( LEN_UCOL, UCOL_PRIMARY ), 1.170 + FIELD_NAME_STR( LEN_UCOL, UCOL_SECONDARY ), 1.171 + FIELD_NAME_STR( LEN_UCOL, UCOL_TERTIARY ), 1.172 +// FIELD_NAME_STR( LEN_UCOL, UCOL_CE_STRENGTH_LIMIT ), 1.173 + FIELD_NAME_STR( LEN_UCOL, UCOL_QUATERNARY ), 1.174 + // gap 1.175 + FIELD_NAME_STR( LEN_UCOL, UCOL_IDENTICAL ), 1.176 +// FIELD_NAME_STR( LEN_UCOL, UCOL_STRENGTH_LIMIT ), 1.177 + FIELD_NAME_STR( LEN_UCOL, UCOL_OFF ), 1.178 + FIELD_NAME_STR( LEN_UCOL, UCOL_ON ), 1.179 + // gap 1.180 + FIELD_NAME_STR( LEN_UCOL, UCOL_SHIFTED ), 1.181 + FIELD_NAME_STR( LEN_UCOL, UCOL_NON_IGNORABLE ), 1.182 + // gap 1.183 + FIELD_NAME_STR( LEN_UCOL, UCOL_LOWER_FIRST ), 1.184 + FIELD_NAME_STR( LEN_UCOL, UCOL_UPPER_FIRST ), 1.185 +}; 1.186 + 1.187 +#endif 1.188 + 1.189 + 1.190 +#include "unicode/icuplug.h" 1.191 + 1.192 +#define LEN_UPLUG_REASON 13 /* UPLUG_REASON_ */ 1.193 +static const int32_t count_UPlugReason = UPLUG_REASON_COUNT; 1.194 +static const Field names_UPlugReason[] = { 1.195 + FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_QUERY ), 1.196 + FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_LOAD ), 1.197 + FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_UNLOAD ), 1.198 +}; 1.199 + 1.200 +#define LEN_UPLUG_LEVEL 12 /* UPLUG_LEVEL_ */ 1.201 +static const int32_t count_UPlugLevel = UPLUG_LEVEL_COUNT; 1.202 +static const Field names_UPlugLevel[] = { 1.203 + FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_INVALID ), 1.204 + FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_UNKNOWN ), 1.205 + FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_LOW ), 1.206 + FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_HIGH ), 1.207 +}; 1.208 + 1.209 +#define LEN_UDBG 5 /* "UDBG_" */ 1.210 +static const int32_t count_UDebugEnumType = UDBG_ENUM_COUNT; 1.211 +static const Field names_UDebugEnumType[] = 1.212 +{ 1.213 + FIELD_NAME_STR( LEN_UDBG, UDBG_UDebugEnumType ), 1.214 +#if !UCONFIG_NO_FORMATTING 1.215 + FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarDateFields ), 1.216 + FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarMonths ), 1.217 + FIELD_NAME_STR( LEN_UDBG, UDBG_UDateFormatStyle ), 1.218 +#endif 1.219 + FIELD_NAME_STR( LEN_UDBG, UDBG_UPlugReason ), 1.220 + FIELD_NAME_STR( LEN_UDBG, UDBG_UPlugLevel ), 1.221 + FIELD_NAME_STR( LEN_UDBG, UDBG_UAcceptResult ), 1.222 +#if !UCONFIG_NO_COLLATION 1.223 + FIELD_NAME_STR( LEN_UDBG, UDBG_UColAttributeValue ), 1.224 +#endif 1.225 +}; 1.226 + 1.227 + 1.228 +// --- Add new enum types above this line --- 1.229 + 1.230 +#define COUNT_CASE(x) case UDBG_##x: return (actual?count_##x:DBG_ARRAY_COUNT(names_##x)); 1.231 +#define COUNT_FAIL_CASE(x) case UDBG_##x: return -1; 1.232 + 1.233 +#define FIELD_CASE(x) case UDBG_##x: return names_##x; 1.234 +#define FIELD_FAIL_CASE(x) case UDBG_##x: return NULL; 1.235 + 1.236 +// low level 1.237 + 1.238 +/** 1.239 + * @param type type of item 1.240 + * @param actual TRUE: for the actual enum's type (UCAL_FIELD_COUNT, etc), or FALSE for the string count 1.241 + */ 1.242 +static int32_t _udbg_enumCount(UDebugEnumType type, UBool actual) { 1.243 + switch(type) { 1.244 + COUNT_CASE(UDebugEnumType) 1.245 +#if !UCONFIG_NO_FORMATTING 1.246 + COUNT_CASE(UCalendarDateFields) 1.247 + COUNT_CASE(UCalendarMonths) 1.248 + COUNT_CASE(UDateFormatStyle) 1.249 +#endif 1.250 + COUNT_CASE(UPlugReason) 1.251 + COUNT_CASE(UPlugLevel) 1.252 + COUNT_CASE(UAcceptResult) 1.253 +#if !UCONFIG_NO_COLLATION 1.254 + COUNT_CASE(UColAttributeValue) 1.255 +#endif 1.256 + // COUNT_FAIL_CASE(UNonExistentEnum) 1.257 + default: 1.258 + return -1; 1.259 + } 1.260 +} 1.261 + 1.262 +static const Field* _udbg_enumFields(UDebugEnumType type) { 1.263 + switch(type) { 1.264 + FIELD_CASE(UDebugEnumType) 1.265 +#if !UCONFIG_NO_FORMATTING 1.266 + FIELD_CASE(UCalendarDateFields) 1.267 + FIELD_CASE(UCalendarMonths) 1.268 + FIELD_CASE(UDateFormatStyle) 1.269 +#endif 1.270 + FIELD_CASE(UPlugReason) 1.271 + FIELD_CASE(UPlugLevel) 1.272 + FIELD_CASE(UAcceptResult) 1.273 + // FIELD_FAIL_CASE(UNonExistentEnum) 1.274 +#if !UCONFIG_NO_COLLATION 1.275 + FIELD_CASE(UColAttributeValue) 1.276 +#endif 1.277 + default: 1.278 + return NULL; 1.279 + } 1.280 +} 1.281 + 1.282 +// implementation 1.283 + 1.284 +int32_t udbg_enumCount(UDebugEnumType type) { 1.285 + return _udbg_enumCount(type, FALSE); 1.286 +} 1.287 + 1.288 +int32_t udbg_enumExpectedCount(UDebugEnumType type) { 1.289 + return _udbg_enumCount(type, TRUE); 1.290 +} 1.291 + 1.292 +const char * udbg_enumName(UDebugEnumType type, int32_t field) { 1.293 + if(field<0 || 1.294 + field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items 1.295 + return NULL; 1.296 + } else { 1.297 + const Field *fields = _udbg_enumFields(type); 1.298 + if(fields == NULL) { 1.299 + return NULL; 1.300 + } else { 1.301 + return fields[field].str + fields[field].prefix; 1.302 + } 1.303 + } 1.304 +} 1.305 + 1.306 +int32_t udbg_enumArrayValue(UDebugEnumType type, int32_t field) { 1.307 + if(field<0 || 1.308 + field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items 1.309 + return -1; 1.310 + } else { 1.311 + const Field *fields = _udbg_enumFields(type); 1.312 + if(fields == NULL) { 1.313 + return -1; 1.314 + } else { 1.315 + return fields[field].num; 1.316 + } 1.317 + } 1.318 +} 1.319 + 1.320 +int32_t udbg_enumByName(UDebugEnumType type, const char *value) { 1.321 + if(type<0||type>=_udbg_enumCount(UDBG_UDebugEnumType, TRUE)) { 1.322 + return -1; // type out of range 1.323 + } 1.324 + const Field *fields = _udbg_enumFields(type); 1.325 + for(int32_t field = 0;field<_udbg_enumCount(type, FALSE);field++) { 1.326 + if(!strcmp(value, fields[field].str + fields[field].prefix)) { 1.327 + return fields[field].num; 1.328 + } 1.329 + } 1.330 + // try with the prefix 1.331 + for(int32_t field = 0;field<_udbg_enumCount(type, FALSE);field++) { 1.332 + if(!strcmp(value, fields[field].str)) { 1.333 + return fields[field].num; 1.334 + } 1.335 + } 1.336 + // fail 1.337 + return -1; 1.338 +} 1.339 + 1.340 +/* platform info */ 1.341 +/** 1.342 + * Print the current platform 1.343 + */ 1.344 +U_CAPI const char *udbg_getPlatform(void) 1.345 +{ 1.346 +#if U_PLATFORM_HAS_WIN32_API 1.347 + return "Windows"; 1.348 +#elif U_PLATFORM == U_PF_UNKNOWN 1.349 + return "unknown"; 1.350 +#elif U_PLATFORM == U_PF_DARWIN 1.351 + return "Darwin"; 1.352 +#elif U_PLATFORM == U_PF_BSD 1.353 + return "BSD"; 1.354 +#elif U_PLATFORM == U_PF_QNX 1.355 + return "QNX"; 1.356 +#elif U_PLATFORM == U_PF_LINUX 1.357 + return "Linux"; 1.358 +#elif U_PLATFORM == U_PF_ANDROID 1.359 + return "Android"; 1.360 +#elif U_PLATFORM == U_PF_CLASSIC_MACOS 1.361 + return "MacOS (Classic)"; 1.362 +#elif U_PLATFORM == U_PF_OS390 1.363 + return "IBM z"; 1.364 +#elif U_PLATFORM == U_PF_OS400 1.365 + return "IBM i"; 1.366 +#else 1.367 + return "Other (POSIX-like)"; 1.368 +#endif 1.369 +} 1.370 + 1.371 +struct USystemParams; 1.372 + 1.373 +typedef int32_t U_CALLCONV USystemParameterCallback(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status); 1.374 + 1.375 +struct USystemParams { 1.376 + const char *paramName; 1.377 + USystemParameterCallback *paramFunction; 1.378 + const char *paramStr; 1.379 + int32_t paramInt; 1.380 +}; 1.381 + 1.382 +/* parameter types */ 1.383 +U_CAPI int32_t 1.384 +paramEmpty(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) { 1.385 + if(U_FAILURE(*status))return 0; 1.386 + return u_terminateChars(target, targetCapacity, 0, status); 1.387 +} 1.388 + 1.389 +U_CAPI int32_t 1.390 +paramStatic(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) { 1.391 + if(param->paramStr==NULL) return paramEmpty(param,target,targetCapacity,status); 1.392 + if(U_FAILURE(*status))return 0; 1.393 + int32_t len = uprv_strlen(param->paramStr); 1.394 + if(target!=NULL) { 1.395 + uprv_strncpy(target,param->paramStr,uprv_min(len,targetCapacity)); 1.396 + } 1.397 + return u_terminateChars(target, targetCapacity, len, status); 1.398 +} 1.399 + 1.400 +static const char *nullString = "(null)"; 1.401 + 1.402 +static int32_t stringToStringBuffer(char *target, int32_t targetCapacity, const char *str, UErrorCode *status) { 1.403 + if(str==NULL) str=nullString; 1.404 + 1.405 + int32_t len = uprv_strlen(str); 1.406 + if (U_SUCCESS(*status)) { 1.407 + if(target!=NULL) { 1.408 + uprv_strncpy(target,str,uprv_min(len,targetCapacity)); 1.409 + } 1.410 + } else { 1.411 + const char *s = u_errorName(*status); 1.412 + len = uprv_strlen(s); 1.413 + if(target!=NULL) { 1.414 + uprv_strncpy(target,s,uprv_min(len,targetCapacity)); 1.415 + } 1.416 + } 1.417 + return u_terminateChars(target, targetCapacity, len, status); 1.418 +} 1.419 + 1.420 +static int32_t integerToStringBuffer(char *target, int32_t targetCapacity, int32_t n, int32_t radix, UErrorCode *status) { 1.421 + if(U_FAILURE(*status)) return 0; 1.422 + char str[300]; 1.423 + T_CString_integerToString(str,n,radix); 1.424 + return stringToStringBuffer(target,targetCapacity,str,status); 1.425 +} 1.426 + 1.427 +U_CAPI int32_t 1.428 +paramInteger(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) { 1.429 + if(U_FAILURE(*status))return 0; 1.430 + if(param->paramStr==NULL || param->paramStr[0]=='d') { 1.431 + return integerToStringBuffer(target,targetCapacity,param->paramInt, 10,status); 1.432 + } else if(param->paramStr[0]=='x') { 1.433 + return integerToStringBuffer(target,targetCapacity,param->paramInt, 16,status); 1.434 + } else if(param->paramStr[0]=='o') { 1.435 + return integerToStringBuffer(target,targetCapacity,param->paramInt, 8,status); 1.436 + } else if(param->paramStr[0]=='b') { 1.437 + return integerToStringBuffer(target,targetCapacity,param->paramInt, 2,status); 1.438 + } else { 1.439 + *status = U_INTERNAL_PROGRAM_ERROR; 1.440 + return 0; 1.441 + } 1.442 +} 1.443 + 1.444 + 1.445 +U_CAPI int32_t 1.446 +paramCldrVersion(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) { 1.447 + if(U_FAILURE(*status))return 0; 1.448 + char str[200]=""; 1.449 + UVersionInfo icu; 1.450 + 1.451 + ulocdata_getCLDRVersion(icu, status); 1.452 + if(U_SUCCESS(*status)) { 1.453 + u_versionToString(icu, str); 1.454 + return stringToStringBuffer(target,targetCapacity,str,status); 1.455 + } else { 1.456 + return 0; 1.457 + } 1.458 +} 1.459 + 1.460 + 1.461 +#if !UCONFIG_NO_FORMATTING 1.462 +U_CAPI int32_t 1.463 +paramTimezoneDefault(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) { 1.464 + if(U_FAILURE(*status))return 0; 1.465 + UChar buf[100]; 1.466 + char buf2[100]; 1.467 + int32_t len; 1.468 + 1.469 + len = ucal_getDefaultTimeZone(buf, 100, status); 1.470 + if(U_SUCCESS(*status)&&len>0) { 1.471 + u_UCharsToChars(buf, buf2, len+1); 1.472 + return stringToStringBuffer(target,targetCapacity, buf2,status); 1.473 + } else { 1.474 + return 0; 1.475 + } 1.476 +} 1.477 +#endif 1.478 + 1.479 +U_CAPI int32_t 1.480 +paramLocaleDefaultBcp47(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) { 1.481 + if(U_FAILURE(*status))return 0; 1.482 + const char *def = uloc_getDefault(); 1.483 + return uloc_toLanguageTag(def,target,targetCapacity,FALSE,status); 1.484 +} 1.485 + 1.486 + 1.487 +/* simple 1-liner param functions */ 1.488 +#define STRING_PARAM(func, str) U_CAPI int32_t \ 1.489 + func(const USystemParams *, char *target, int32_t targetCapacity, UErrorCode *status) \ 1.490 + { return stringToStringBuffer(target,targetCapacity,(str),status); } 1.491 + 1.492 +STRING_PARAM(paramIcudataPath, u_getDataDirectory()) 1.493 +STRING_PARAM(paramPlatform, udbg_getPlatform()) 1.494 +STRING_PARAM(paramLocaleDefault, uloc_getDefault()) 1.495 +#if !UCONFIG_NO_CONVERSION 1.496 +STRING_PARAM(paramConverterDefault, ucnv_getDefaultName()) 1.497 +#endif 1.498 + 1.499 +#if !UCONFIG_NO_FORMATTING 1.500 +STRING_PARAM(paramTimezoneVersion, ucal_getTZDataVersion(status)) 1.501 +#endif 1.502 + 1.503 +static const USystemParams systemParams[] = { 1.504 + { "copyright", paramStatic, U_COPYRIGHT_STRING,0 }, 1.505 + { "product", paramStatic, "icu4c",0 }, 1.506 + { "product.full", paramStatic, "International Components for Unicode for C/C++",0 }, 1.507 + { "version", paramStatic, U_ICU_VERSION,0 }, 1.508 + { "version.unicode", paramStatic, U_UNICODE_VERSION,0 }, 1.509 + { "platform.number", paramInteger, "d",U_PLATFORM}, 1.510 + { "platform.type", paramPlatform, NULL ,0}, 1.511 + { "locale.default", paramLocaleDefault, NULL, 0}, 1.512 + { "locale.default.bcp47", paramLocaleDefaultBcp47, NULL, 0}, 1.513 +#if !UCONFIG_NO_CONVERSION 1.514 + { "converter.default", paramConverterDefault, NULL, 0}, 1.515 +#endif 1.516 + { "icudata.name", paramStatic, U_ICUDATA_NAME, 0}, 1.517 + { "icudata.path", paramIcudataPath, NULL, 0}, 1.518 + 1.519 + { "cldr.version", paramCldrVersion, NULL, 0}, 1.520 + 1.521 +#if !UCONFIG_NO_FORMATTING 1.522 + { "tz.version", paramTimezoneVersion, NULL, 0}, 1.523 + { "tz.default", paramTimezoneDefault, NULL, 0}, 1.524 +#endif 1.525 + 1.526 + { "cpu.bits", paramInteger, "d", (sizeof(void*))*8}, 1.527 + { "cpu.big_endian", paramInteger, "b", U_IS_BIG_ENDIAN}, 1.528 + { "os.wchar_width", paramInteger, "d", U_SIZEOF_WCHAR_T}, 1.529 + { "os.charset_family", paramInteger, "d", U_CHARSET_FAMILY}, 1.530 +#if defined (U_HOST) 1.531 + { "os.host", paramStatic, U_HOST, 0}, 1.532 +#endif 1.533 +#if defined (U_BUILD) 1.534 + { "build.build", paramStatic, U_BUILD, 0}, 1.535 +#endif 1.536 +#if defined (U_CC) 1.537 + { "build.cc", paramStatic, U_CC, 0}, 1.538 +#endif 1.539 +#if defined (U_CXX) 1.540 + { "build.cxx", paramStatic, U_CXX, 0}, 1.541 +#endif 1.542 +#if defined (CYGWINMSVC) 1.543 + { "build.cygwinmsvc", paramInteger, "b", 1}, 1.544 +#endif 1.545 + { "uconfig.internal_digitlist", paramInteger, "b", 1}, /* always 1 */ 1.546 + { "uconfig.have_parseallinput", paramInteger, "b", UCONFIG_HAVE_PARSEALLINPUT}, 1.547 + { "uconfig.format_fastpaths_49",paramInteger, "b", UCONFIG_FORMAT_FASTPATHS_49}, 1.548 + 1.549 + 1.550 +}; 1.551 + 1.552 +#define U_SYSPARAM_COUNT (sizeof(systemParams)/sizeof(systemParams[0])) 1.553 + 1.554 +U_CAPI const char *udbg_getSystemParameterNameByIndex(int32_t i) { 1.555 + if(i>=0 && i < (int32_t)U_SYSPARAM_COUNT) { 1.556 + return systemParams[i].paramName; 1.557 + } else { 1.558 + return NULL; 1.559 + } 1.560 +} 1.561 + 1.562 + 1.563 +U_CAPI int32_t udbg_getSystemParameterValueByIndex(int32_t i, char *buffer, int32_t bufferCapacity, UErrorCode *status) { 1.564 + if(i>=0 && i< (int32_t)U_SYSPARAM_COUNT) { 1.565 + return systemParams[i].paramFunction(&(systemParams[i]),buffer,bufferCapacity,status); 1.566 + } else { 1.567 + return 0; 1.568 + } 1.569 +} 1.570 + 1.571 +U_CAPI void udbg_writeIcuInfo(FILE *out) { 1.572 + char str[2000]; 1.573 + /* todo: API for writing DTD? */ 1.574 + fprintf(out, " <icuSystemParams type=\"icu4c\">\n"); 1.575 + const char *paramName; 1.576 + for(int32_t i=0;(paramName=udbg_getSystemParameterNameByIndex(i))!=NULL;i++) { 1.577 + UErrorCode status2 = U_ZERO_ERROR; 1.578 + udbg_getSystemParameterValueByIndex(i, str,2000,&status2); 1.579 + if(U_SUCCESS(status2)) { 1.580 + fprintf(out," <param name=\"%s\">%s</param>\n", paramName,str); 1.581 + } else { 1.582 + fprintf(out," <!-- n=\"%s\" ERROR: %s -->\n", paramName, u_errorName(status2)); 1.583 + } 1.584 + } 1.585 + fprintf(out, " </icuSystemParams>\n"); 1.586 +} 1.587 + 1.588 +#define ICU_TRAC_URL "http://bugs.icu-project.org/trac/ticket/" 1.589 +#define CLDR_TRAC_URL "http://unicode.org/cldr/trac/ticket/" 1.590 +#define CLDR_TICKET_PREFIX "cldrbug:" 1.591 + 1.592 +U_CAPI char *udbg_knownIssueURLFrom(const char *ticket, char *buf) { 1.593 + if( ticket==NULL ) { 1.594 + return NULL; 1.595 + } 1.596 + 1.597 + if( !strncmp(ticket, CLDR_TICKET_PREFIX, strlen(CLDR_TICKET_PREFIX)) ) { 1.598 + strcpy( buf, CLDR_TRAC_URL ); 1.599 + strcat( buf, ticket+strlen(CLDR_TICKET_PREFIX) ); 1.600 + } else { 1.601 + strcpy( buf, ICU_TRAC_URL ); 1.602 + strcat( buf, ticket ); 1.603 + } 1.604 + return buf; 1.605 +} 1.606 + 1.607 + 1.608 +#if !U_HAVE_STD_STRING 1.609 +const char *warning = "WARNING: Don't have std::string (STL) - known issue logs will be deficient."; 1.610 + 1.611 +U_CAPI void *udbg_knownIssue_openU(void *ptr, const char *ticket, char *where, const UChar *msg, UBool *firstForTicket, 1.612 + UBool *firstForWhere) { 1.613 + if(ptr==NULL) { 1.614 + puts(warning); 1.615 + } 1.616 + printf("%s\tKnown Issue #%s\n", where, ticket); 1.617 + 1.618 + return (void*)warning; 1.619 +} 1.620 + 1.621 +U_CAPI void *udbg_knownIssue_open(void *ptr, const char *ticket, char *where, const char *msg, UBool *firstForTicket, 1.622 + UBool *firstForWhere) { 1.623 + if(ptr==NULL) { 1.624 + puts(warning); 1.625 + } 1.626 + if(msg==NULL) msg = ""; 1.627 + printf("%s\tKnown Issue #%s \"%s\n", where, ticket, msg); 1.628 + 1.629 + return (void*)warning; 1.630 +} 1.631 + 1.632 +U_CAPI UBool udbg_knownIssue_print(void *ptr) { 1.633 + puts(warning); 1.634 + return FALSE; 1.635 +} 1.636 + 1.637 +U_CAPI void udbg_knownIssue_close(void *ptr) { 1.638 + // nothing to do 1.639 +} 1.640 +#else 1.641 + 1.642 +#include <set> 1.643 +#include <map> 1.644 +#include <string> 1.645 +#include <ostream> 1.646 +#include <iostream> 1.647 + 1.648 +class KnownIssues { 1.649 +public: 1.650 + KnownIssues(); 1.651 + ~KnownIssues(); 1.652 + void add(const char *ticket, const char *where, const UChar *msg, UBool *firstForTicket, UBool *firstForWhere); 1.653 + void add(const char *ticket, const char *where, const char *msg, UBool *firstForTicket, UBool *firstForWhere); 1.654 + UBool print(); 1.655 +private: 1.656 + std::map< std::string, 1.657 + std::map < std::string, std::set < std::string > > > fTable; 1.658 +}; 1.659 + 1.660 +KnownIssues::KnownIssues() 1.661 + : fTable() 1.662 +{ 1.663 +} 1.664 + 1.665 +KnownIssues::~KnownIssues() 1.666 +{ 1.667 +} 1.668 + 1.669 +void KnownIssues::add(const char *ticket, const char *where, const UChar *msg, UBool *firstForTicket, UBool *firstForWhere) 1.670 +{ 1.671 + if(fTable.find(ticket) == fTable.end()) { 1.672 + if(firstForTicket!=NULL) *firstForTicket = TRUE; 1.673 + fTable[ticket] = std::map < std::string, std::set < std::string > >(); 1.674 + } else { 1.675 + if(firstForTicket!=NULL) *firstForTicket = FALSE; 1.676 + } 1.677 + if(where==NULL) return; 1.678 + 1.679 + if(fTable[ticket].find(where) == fTable[ticket].end()) { 1.680 + if(firstForWhere!=NULL) *firstForWhere = TRUE; 1.681 + fTable[ticket][where] = std::set < std::string >(); 1.682 + } else { 1.683 + if(firstForWhere!=NULL) *firstForWhere = FALSE; 1.684 + } 1.685 + if(msg==NULL || !*msg) return; 1.686 + 1.687 + std::string str; 1.688 + fTable[ticket][where].insert(icu::UnicodeString(msg).toUTF8String(str)); 1.689 +} 1.690 + 1.691 +void KnownIssues::add(const char *ticket, const char *where, const char *msg, UBool *firstForTicket, UBool *firstForWhere) 1.692 +{ 1.693 + if(fTable.find(ticket) == fTable.end()) { 1.694 + if(firstForTicket!=NULL) *firstForTicket = TRUE; 1.695 + fTable[ticket] = std::map < std::string, std::set < std::string > >(); 1.696 + } else { 1.697 + if(firstForTicket!=NULL) *firstForTicket = FALSE; 1.698 + } 1.699 + if(where==NULL) return; 1.700 + 1.701 + if(fTable[ticket].find(where) == fTable[ticket].end()) { 1.702 + if(firstForWhere!=NULL) *firstForWhere = TRUE; 1.703 + fTable[ticket][where] = std::set < std::string >(); 1.704 + } else { 1.705 + if(firstForWhere!=NULL) *firstForWhere = FALSE; 1.706 + } 1.707 + if(msg==NULL || !*msg) return; 1.708 + 1.709 + std::string str(msg); 1.710 + fTable[ticket][where].insert(str); 1.711 +} 1.712 + 1.713 +UBool KnownIssues::print() 1.714 +{ 1.715 + if(fTable.empty()) { 1.716 + return FALSE; 1.717 + } 1.718 + 1.719 + std::cout << "KNOWN ISSUES" << std::endl; 1.720 + for( std::map< std::string, 1.721 + std::map < std::string, std::set < std::string > > >::iterator i = fTable.begin(); 1.722 + i != fTable.end(); 1.723 + i++ ) { 1.724 + char URL[1024]; 1.725 + std::cout << '#' << (*i).first << " <" << udbg_knownIssueURLFrom( (*i).first.c_str(), URL ) << ">" << std::endl; 1.726 + 1.727 + for( std::map< std::string, std::set < std::string > >::iterator ii = (*i).second.begin(); 1.728 + ii != (*i).second.end(); 1.729 + ii++ ) { 1.730 + std::cout << " " << (*ii).first << std::endl; 1.731 + for ( std::set < std::string >::iterator iii = (*ii).second.begin(); 1.732 + iii != (*ii).second.end(); 1.733 + iii++ ) { 1.734 + std::cout << " " << '"' << (*iii) << '"' << std::endl; 1.735 + } 1.736 + } 1.737 + } 1.738 + return TRUE; 1.739 +} 1.740 + 1.741 +U_CAPI void *udbg_knownIssue_openU(void *ptr, const char *ticket, char *where, const UChar *msg, UBool *firstForTicket, 1.742 + UBool *firstForWhere) { 1.743 + KnownIssues *t = static_cast<KnownIssues*>(ptr); 1.744 + if(t==NULL) { 1.745 + t = new KnownIssues(); 1.746 + } 1.747 + 1.748 + t->add(ticket, where, msg, firstForTicket, firstForWhere); 1.749 + 1.750 + return static_cast<void*>(t); 1.751 +} 1.752 + 1.753 +U_CAPI void *udbg_knownIssue_open(void *ptr, const char *ticket, char *where, const char *msg, UBool *firstForTicket, 1.754 + UBool *firstForWhere) { 1.755 + KnownIssues *t = static_cast<KnownIssues*>(ptr); 1.756 + if(t==NULL) { 1.757 + t = new KnownIssues(); 1.758 + } 1.759 + 1.760 + t->add(ticket, where, msg, firstForTicket, firstForWhere); 1.761 + 1.762 + return static_cast<void*>(t); 1.763 +} 1.764 + 1.765 +U_CAPI UBool udbg_knownIssue_print(void *ptr) { 1.766 + KnownIssues *t = static_cast<KnownIssues*>(ptr); 1.767 + if(t==NULL) { 1.768 + return FALSE; 1.769 + } else { 1.770 + t->print(); 1.771 + return TRUE; 1.772 + } 1.773 +} 1.774 + 1.775 +U_CAPI void udbg_knownIssue_close(void *ptr) { 1.776 + KnownIssues *t = static_cast<KnownIssues*>(ptr); 1.777 + delete t; 1.778 +} 1.779 + 1.780 +#endif