intl/icu/source/tools/toolutil/udbgutil.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /********************************************************************
michael@0 2 * COPYRIGHT:
michael@0 3 * Copyright (c) 2007-2013, International Business Machines Corporation and
michael@0 4 * others. All Rights Reserved.
michael@0 5 ********************************************************************/
michael@0 6
michael@0 7 #include "udbgutil.h"
michael@0 8 #include <string.h>
michael@0 9 #include "ustr_imp.h"
michael@0 10 #include "cstring.h"
michael@0 11 #include "putilimp.h"
michael@0 12 #include "unicode/ulocdata.h"
michael@0 13 #include "unicode/ucnv.h"
michael@0 14 #include "unicode/unistr.h"
michael@0 15
michael@0 16 /*
michael@0 17 To add a new enum type
michael@0 18 (For example: UShoeSize with values USHOE_WIDE=0, USHOE_REGULAR, USHOE_NARROW, USHOE_COUNT)
michael@0 19
michael@0 20 1. udbgutil.h: add UDBG_UShoeSize to the UDebugEnumType enum before UDBG_ENUM_COUNT
michael@0 21 ( The subsequent steps involve this file, udbgutil.cpp )
michael@0 22 2. Find the marker "Add new enum types above this line"
michael@0 23 3. Before that marker, add a #include of any header file you need.
michael@0 24 4. Each enum type has three things in this section: a #define, a count_, and an array of Fields.
michael@0 25 It may help to copy and paste a previous definition.
michael@0 26 5. In the case of the USHOE_... strings above, "USHOE_" is common to all values- six characters
michael@0 27 " #define LEN_USHOE 6 "
michael@0 28 6 characters will strip off "USHOE_" leaving enum values of WIDE, REGULAR, and NARROW.
michael@0 29 6. Define the 'count_' variable, with the number of enum values. If the enum has a _MAX or _COUNT value,
michael@0 30 that can be helpful for automatically defining the count. Otherwise define it manually.
michael@0 31 " static const int32_t count_UShoeSize = USHOE_COUNT; "
michael@0 32 7. Define the field names, in order.
michael@0 33 " static const Field names_UShoeSize[] = {
michael@0 34 " FIELD_NAME_STR( LEN_USHOE, USHOE_WIDE ),
michael@0 35 " FIELD_NAME_STR( LEN_USHOE, USHOE_REGULAR ),
michael@0 36 " FIELD_NAME_STR( LEN_USHOE, USHOE_NARROW ),
michael@0 37 " };
michael@0 38 ( The following command was usedfor converting ucol.h into partially correct entities )
michael@0 39 grep "^[ ]*UCOL" < unicode/ucol.h |
michael@0 40 sed -e 's%^[ ]*\([A-Z]*\)_\([A-Z_]*\).*% FIELD_NAME_STR( LEN_\1, \1_\2 ),%g'
michael@0 41 8. Now, a bit farther down, add the name of the enum itself to the end of names_UDebugEnumType
michael@0 42 ( UDebugEnumType is an enum, too!)
michael@0 43 names_UDebugEnumType[] { ...
michael@0 44 " FIELD_NAME_STR( LEN_UDBG, UDBG_UShoeSize ), "
michael@0 45 9. Find the function _udbg_enumCount and add the count macro:
michael@0 46 " COUNT_CASE(UShoeSize)
michael@0 47 10. Find the function _udbg_enumFields and add the field macro:
michael@0 48 " FIELD_CASE(UShoeSize)
michael@0 49 11. verify that your test code, and Java data generation, works properly.
michael@0 50 */
michael@0 51
michael@0 52 /**
michael@0 53 * Structure representing an enum value
michael@0 54 */
michael@0 55 struct Field {
michael@0 56 int32_t prefix; /**< how many characters to remove in the prefix - i.e. UCHAR_ = 5 */
michael@0 57 const char *str; /**< The actual string value */
michael@0 58 int32_t num; /**< The numeric value */
michael@0 59 };
michael@0 60
michael@0 61 /**
michael@0 62 * Calculate the size of an array.
michael@0 63 */
michael@0 64 #define DBG_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
michael@0 65
michael@0 66 /**
michael@0 67 * Define another field name. Used in an array of Field s
michael@0 68 * @param y the common prefix length (i.e. 6 for "USHOE_" )
michael@0 69 * @param x the actual enum value - it will be copied in both string and symbolic form.
michael@0 70 * @see Field
michael@0 71 */
michael@0 72 #define FIELD_NAME_STR(y,x) { y, #x, x }
michael@0 73
michael@0 74
michael@0 75 // TODO: Currently, this whole functionality goes away with UCONFIG_NO_FORMATTING. Should be split up.
michael@0 76 #if !UCONFIG_NO_FORMATTING
michael@0 77
michael@0 78 // Calendar
michael@0 79 #include "unicode/ucal.h"
michael@0 80
michael@0 81 // 'UCAL_' = 5
michael@0 82 #define LEN_UCAL 5 /* UCAL_ */
michael@0 83 static const int32_t count_UCalendarDateFields = UCAL_FIELD_COUNT;
michael@0 84 static const Field names_UCalendarDateFields[] =
michael@0 85 {
michael@0 86 FIELD_NAME_STR( LEN_UCAL, UCAL_ERA ),
michael@0 87 FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR ),
michael@0 88 FIELD_NAME_STR( LEN_UCAL, UCAL_MONTH ),
michael@0 89 FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_YEAR ),
michael@0 90 FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_MONTH ),
michael@0 91 FIELD_NAME_STR( LEN_UCAL, UCAL_DATE ),
michael@0 92 FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_YEAR ),
michael@0 93 FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK ),
michael@0 94 FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK_IN_MONTH ),
michael@0 95 FIELD_NAME_STR( LEN_UCAL, UCAL_AM_PM ),
michael@0 96 FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR ),
michael@0 97 FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR_OF_DAY ),
michael@0 98 FIELD_NAME_STR( LEN_UCAL, UCAL_MINUTE ),
michael@0 99 FIELD_NAME_STR( LEN_UCAL, UCAL_SECOND ),
michael@0 100 FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECOND ),
michael@0 101 FIELD_NAME_STR( LEN_UCAL, UCAL_ZONE_OFFSET ),
michael@0 102 FIELD_NAME_STR( LEN_UCAL, UCAL_DST_OFFSET ),
michael@0 103 FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR_WOY ),
michael@0 104 FIELD_NAME_STR( LEN_UCAL, UCAL_DOW_LOCAL ),
michael@0 105 FIELD_NAME_STR( LEN_UCAL, UCAL_EXTENDED_YEAR ),
michael@0 106 FIELD_NAME_STR( LEN_UCAL, UCAL_JULIAN_DAY ),
michael@0 107 FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECONDS_IN_DAY ),
michael@0 108 FIELD_NAME_STR( LEN_UCAL, UCAL_IS_LEAP_MONTH ),
michael@0 109 };
michael@0 110
michael@0 111
michael@0 112 static const int32_t count_UCalendarMonths = UCAL_UNDECIMBER+1;
michael@0 113 static const Field names_UCalendarMonths[] =
michael@0 114 {
michael@0 115 FIELD_NAME_STR( LEN_UCAL, UCAL_JANUARY ),
michael@0 116 FIELD_NAME_STR( LEN_UCAL, UCAL_FEBRUARY ),
michael@0 117 FIELD_NAME_STR( LEN_UCAL, UCAL_MARCH ),
michael@0 118 FIELD_NAME_STR( LEN_UCAL, UCAL_APRIL ),
michael@0 119 FIELD_NAME_STR( LEN_UCAL, UCAL_MAY ),
michael@0 120 FIELD_NAME_STR( LEN_UCAL, UCAL_JUNE ),
michael@0 121 FIELD_NAME_STR( LEN_UCAL, UCAL_JULY ),
michael@0 122 FIELD_NAME_STR( LEN_UCAL, UCAL_AUGUST ),
michael@0 123 FIELD_NAME_STR( LEN_UCAL, UCAL_SEPTEMBER ),
michael@0 124 FIELD_NAME_STR( LEN_UCAL, UCAL_OCTOBER ),
michael@0 125 FIELD_NAME_STR( LEN_UCAL, UCAL_NOVEMBER ),
michael@0 126 FIELD_NAME_STR( LEN_UCAL, UCAL_DECEMBER ),
michael@0 127 FIELD_NAME_STR( LEN_UCAL, UCAL_UNDECIMBER)
michael@0 128 };
michael@0 129
michael@0 130 #include "unicode/udat.h"
michael@0 131
michael@0 132 #define LEN_UDAT 5 /* "UDAT_" */
michael@0 133 static const int32_t count_UDateFormatStyle = UDAT_SHORT+1;
michael@0 134 static const Field names_UDateFormatStyle[] =
michael@0 135 {
michael@0 136 FIELD_NAME_STR( LEN_UDAT, UDAT_FULL ),
michael@0 137 FIELD_NAME_STR( LEN_UDAT, UDAT_LONG ),
michael@0 138 FIELD_NAME_STR( LEN_UDAT, UDAT_MEDIUM ),
michael@0 139 FIELD_NAME_STR( LEN_UDAT, UDAT_SHORT ),
michael@0 140 /* end regular */
michael@0 141 /*
michael@0 142 * negative enums.. leave out for now.
michael@0 143 FIELD_NAME_STR( LEN_UDAT, UDAT_NONE ),
michael@0 144 FIELD_NAME_STR( LEN_UDAT, UDAT_PATTERN ),
michael@0 145 */
michael@0 146 };
michael@0 147
michael@0 148 #endif
michael@0 149
michael@0 150 #include "unicode/uloc.h"
michael@0 151
michael@0 152 #define LEN_UAR 12 /* "ULOC_ACCEPT_" */
michael@0 153 static const int32_t count_UAcceptResult = 3;
michael@0 154 static const Field names_UAcceptResult[] =
michael@0 155 {
michael@0 156 FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_FAILED ),
michael@0 157 FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_VALID ),
michael@0 158 FIELD_NAME_STR( LEN_UAR, ULOC_ACCEPT_FALLBACK ),
michael@0 159 };
michael@0 160
michael@0 161 #if !UCONFIG_NO_COLLATION
michael@0 162 #include "unicode/ucol.h"
michael@0 163 #define LEN_UCOL 5 /* UCOL_ */
michael@0 164 static const int32_t count_UColAttributeValue = UCOL_ATTRIBUTE_VALUE_COUNT;
michael@0 165 static const Field names_UColAttributeValue[] = {
michael@0 166 FIELD_NAME_STR( LEN_UCOL, UCOL_PRIMARY ),
michael@0 167 FIELD_NAME_STR( LEN_UCOL, UCOL_SECONDARY ),
michael@0 168 FIELD_NAME_STR( LEN_UCOL, UCOL_TERTIARY ),
michael@0 169 // FIELD_NAME_STR( LEN_UCOL, UCOL_CE_STRENGTH_LIMIT ),
michael@0 170 FIELD_NAME_STR( LEN_UCOL, UCOL_QUATERNARY ),
michael@0 171 // gap
michael@0 172 FIELD_NAME_STR( LEN_UCOL, UCOL_IDENTICAL ),
michael@0 173 // FIELD_NAME_STR( LEN_UCOL, UCOL_STRENGTH_LIMIT ),
michael@0 174 FIELD_NAME_STR( LEN_UCOL, UCOL_OFF ),
michael@0 175 FIELD_NAME_STR( LEN_UCOL, UCOL_ON ),
michael@0 176 // gap
michael@0 177 FIELD_NAME_STR( LEN_UCOL, UCOL_SHIFTED ),
michael@0 178 FIELD_NAME_STR( LEN_UCOL, UCOL_NON_IGNORABLE ),
michael@0 179 // gap
michael@0 180 FIELD_NAME_STR( LEN_UCOL, UCOL_LOWER_FIRST ),
michael@0 181 FIELD_NAME_STR( LEN_UCOL, UCOL_UPPER_FIRST ),
michael@0 182 };
michael@0 183
michael@0 184 #endif
michael@0 185
michael@0 186
michael@0 187 #include "unicode/icuplug.h"
michael@0 188
michael@0 189 #define LEN_UPLUG_REASON 13 /* UPLUG_REASON_ */
michael@0 190 static const int32_t count_UPlugReason = UPLUG_REASON_COUNT;
michael@0 191 static const Field names_UPlugReason[] = {
michael@0 192 FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_QUERY ),
michael@0 193 FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_LOAD ),
michael@0 194 FIELD_NAME_STR( LEN_UPLUG_REASON, UPLUG_REASON_UNLOAD ),
michael@0 195 };
michael@0 196
michael@0 197 #define LEN_UPLUG_LEVEL 12 /* UPLUG_LEVEL_ */
michael@0 198 static const int32_t count_UPlugLevel = UPLUG_LEVEL_COUNT;
michael@0 199 static const Field names_UPlugLevel[] = {
michael@0 200 FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_INVALID ),
michael@0 201 FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_UNKNOWN ),
michael@0 202 FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_LOW ),
michael@0 203 FIELD_NAME_STR( LEN_UPLUG_LEVEL, UPLUG_LEVEL_HIGH ),
michael@0 204 };
michael@0 205
michael@0 206 #define LEN_UDBG 5 /* "UDBG_" */
michael@0 207 static const int32_t count_UDebugEnumType = UDBG_ENUM_COUNT;
michael@0 208 static const Field names_UDebugEnumType[] =
michael@0 209 {
michael@0 210 FIELD_NAME_STR( LEN_UDBG, UDBG_UDebugEnumType ),
michael@0 211 #if !UCONFIG_NO_FORMATTING
michael@0 212 FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarDateFields ),
michael@0 213 FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarMonths ),
michael@0 214 FIELD_NAME_STR( LEN_UDBG, UDBG_UDateFormatStyle ),
michael@0 215 #endif
michael@0 216 FIELD_NAME_STR( LEN_UDBG, UDBG_UPlugReason ),
michael@0 217 FIELD_NAME_STR( LEN_UDBG, UDBG_UPlugLevel ),
michael@0 218 FIELD_NAME_STR( LEN_UDBG, UDBG_UAcceptResult ),
michael@0 219 #if !UCONFIG_NO_COLLATION
michael@0 220 FIELD_NAME_STR( LEN_UDBG, UDBG_UColAttributeValue ),
michael@0 221 #endif
michael@0 222 };
michael@0 223
michael@0 224
michael@0 225 // --- Add new enum types above this line ---
michael@0 226
michael@0 227 #define COUNT_CASE(x) case UDBG_##x: return (actual?count_##x:DBG_ARRAY_COUNT(names_##x));
michael@0 228 #define COUNT_FAIL_CASE(x) case UDBG_##x: return -1;
michael@0 229
michael@0 230 #define FIELD_CASE(x) case UDBG_##x: return names_##x;
michael@0 231 #define FIELD_FAIL_CASE(x) case UDBG_##x: return NULL;
michael@0 232
michael@0 233 // low level
michael@0 234
michael@0 235 /**
michael@0 236 * @param type type of item
michael@0 237 * @param actual TRUE: for the actual enum's type (UCAL_FIELD_COUNT, etc), or FALSE for the string count
michael@0 238 */
michael@0 239 static int32_t _udbg_enumCount(UDebugEnumType type, UBool actual) {
michael@0 240 switch(type) {
michael@0 241 COUNT_CASE(UDebugEnumType)
michael@0 242 #if !UCONFIG_NO_FORMATTING
michael@0 243 COUNT_CASE(UCalendarDateFields)
michael@0 244 COUNT_CASE(UCalendarMonths)
michael@0 245 COUNT_CASE(UDateFormatStyle)
michael@0 246 #endif
michael@0 247 COUNT_CASE(UPlugReason)
michael@0 248 COUNT_CASE(UPlugLevel)
michael@0 249 COUNT_CASE(UAcceptResult)
michael@0 250 #if !UCONFIG_NO_COLLATION
michael@0 251 COUNT_CASE(UColAttributeValue)
michael@0 252 #endif
michael@0 253 // COUNT_FAIL_CASE(UNonExistentEnum)
michael@0 254 default:
michael@0 255 return -1;
michael@0 256 }
michael@0 257 }
michael@0 258
michael@0 259 static const Field* _udbg_enumFields(UDebugEnumType type) {
michael@0 260 switch(type) {
michael@0 261 FIELD_CASE(UDebugEnumType)
michael@0 262 #if !UCONFIG_NO_FORMATTING
michael@0 263 FIELD_CASE(UCalendarDateFields)
michael@0 264 FIELD_CASE(UCalendarMonths)
michael@0 265 FIELD_CASE(UDateFormatStyle)
michael@0 266 #endif
michael@0 267 FIELD_CASE(UPlugReason)
michael@0 268 FIELD_CASE(UPlugLevel)
michael@0 269 FIELD_CASE(UAcceptResult)
michael@0 270 // FIELD_FAIL_CASE(UNonExistentEnum)
michael@0 271 #if !UCONFIG_NO_COLLATION
michael@0 272 FIELD_CASE(UColAttributeValue)
michael@0 273 #endif
michael@0 274 default:
michael@0 275 return NULL;
michael@0 276 }
michael@0 277 }
michael@0 278
michael@0 279 // implementation
michael@0 280
michael@0 281 int32_t udbg_enumCount(UDebugEnumType type) {
michael@0 282 return _udbg_enumCount(type, FALSE);
michael@0 283 }
michael@0 284
michael@0 285 int32_t udbg_enumExpectedCount(UDebugEnumType type) {
michael@0 286 return _udbg_enumCount(type, TRUE);
michael@0 287 }
michael@0 288
michael@0 289 const char * udbg_enumName(UDebugEnumType type, int32_t field) {
michael@0 290 if(field<0 ||
michael@0 291 field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items
michael@0 292 return NULL;
michael@0 293 } else {
michael@0 294 const Field *fields = _udbg_enumFields(type);
michael@0 295 if(fields == NULL) {
michael@0 296 return NULL;
michael@0 297 } else {
michael@0 298 return fields[field].str + fields[field].prefix;
michael@0 299 }
michael@0 300 }
michael@0 301 }
michael@0 302
michael@0 303 int32_t udbg_enumArrayValue(UDebugEnumType type, int32_t field) {
michael@0 304 if(field<0 ||
michael@0 305 field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items
michael@0 306 return -1;
michael@0 307 } else {
michael@0 308 const Field *fields = _udbg_enumFields(type);
michael@0 309 if(fields == NULL) {
michael@0 310 return -1;
michael@0 311 } else {
michael@0 312 return fields[field].num;
michael@0 313 }
michael@0 314 }
michael@0 315 }
michael@0 316
michael@0 317 int32_t udbg_enumByName(UDebugEnumType type, const char *value) {
michael@0 318 if(type<0||type>=_udbg_enumCount(UDBG_UDebugEnumType, TRUE)) {
michael@0 319 return -1; // type out of range
michael@0 320 }
michael@0 321 const Field *fields = _udbg_enumFields(type);
michael@0 322 for(int32_t field = 0;field<_udbg_enumCount(type, FALSE);field++) {
michael@0 323 if(!strcmp(value, fields[field].str + fields[field].prefix)) {
michael@0 324 return fields[field].num;
michael@0 325 }
michael@0 326 }
michael@0 327 // try with the prefix
michael@0 328 for(int32_t field = 0;field<_udbg_enumCount(type, FALSE);field++) {
michael@0 329 if(!strcmp(value, fields[field].str)) {
michael@0 330 return fields[field].num;
michael@0 331 }
michael@0 332 }
michael@0 333 // fail
michael@0 334 return -1;
michael@0 335 }
michael@0 336
michael@0 337 /* platform info */
michael@0 338 /**
michael@0 339 * Print the current platform
michael@0 340 */
michael@0 341 U_CAPI const char *udbg_getPlatform(void)
michael@0 342 {
michael@0 343 #if U_PLATFORM_HAS_WIN32_API
michael@0 344 return "Windows";
michael@0 345 #elif U_PLATFORM == U_PF_UNKNOWN
michael@0 346 return "unknown";
michael@0 347 #elif U_PLATFORM == U_PF_DARWIN
michael@0 348 return "Darwin";
michael@0 349 #elif U_PLATFORM == U_PF_BSD
michael@0 350 return "BSD";
michael@0 351 #elif U_PLATFORM == U_PF_QNX
michael@0 352 return "QNX";
michael@0 353 #elif U_PLATFORM == U_PF_LINUX
michael@0 354 return "Linux";
michael@0 355 #elif U_PLATFORM == U_PF_ANDROID
michael@0 356 return "Android";
michael@0 357 #elif U_PLATFORM == U_PF_CLASSIC_MACOS
michael@0 358 return "MacOS (Classic)";
michael@0 359 #elif U_PLATFORM == U_PF_OS390
michael@0 360 return "IBM z";
michael@0 361 #elif U_PLATFORM == U_PF_OS400
michael@0 362 return "IBM i";
michael@0 363 #else
michael@0 364 return "Other (POSIX-like)";
michael@0 365 #endif
michael@0 366 }
michael@0 367
michael@0 368 struct USystemParams;
michael@0 369
michael@0 370 typedef int32_t U_CALLCONV USystemParameterCallback(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status);
michael@0 371
michael@0 372 struct USystemParams {
michael@0 373 const char *paramName;
michael@0 374 USystemParameterCallback *paramFunction;
michael@0 375 const char *paramStr;
michael@0 376 int32_t paramInt;
michael@0 377 };
michael@0 378
michael@0 379 /* parameter types */
michael@0 380 U_CAPI int32_t
michael@0 381 paramEmpty(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 382 if(U_FAILURE(*status))return 0;
michael@0 383 return u_terminateChars(target, targetCapacity, 0, status);
michael@0 384 }
michael@0 385
michael@0 386 U_CAPI int32_t
michael@0 387 paramStatic(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 388 if(param->paramStr==NULL) return paramEmpty(param,target,targetCapacity,status);
michael@0 389 if(U_FAILURE(*status))return 0;
michael@0 390 int32_t len = uprv_strlen(param->paramStr);
michael@0 391 if(target!=NULL) {
michael@0 392 uprv_strncpy(target,param->paramStr,uprv_min(len,targetCapacity));
michael@0 393 }
michael@0 394 return u_terminateChars(target, targetCapacity, len, status);
michael@0 395 }
michael@0 396
michael@0 397 static const char *nullString = "(null)";
michael@0 398
michael@0 399 static int32_t stringToStringBuffer(char *target, int32_t targetCapacity, const char *str, UErrorCode *status) {
michael@0 400 if(str==NULL) str=nullString;
michael@0 401
michael@0 402 int32_t len = uprv_strlen(str);
michael@0 403 if (U_SUCCESS(*status)) {
michael@0 404 if(target!=NULL) {
michael@0 405 uprv_strncpy(target,str,uprv_min(len,targetCapacity));
michael@0 406 }
michael@0 407 } else {
michael@0 408 const char *s = u_errorName(*status);
michael@0 409 len = uprv_strlen(s);
michael@0 410 if(target!=NULL) {
michael@0 411 uprv_strncpy(target,s,uprv_min(len,targetCapacity));
michael@0 412 }
michael@0 413 }
michael@0 414 return u_terminateChars(target, targetCapacity, len, status);
michael@0 415 }
michael@0 416
michael@0 417 static int32_t integerToStringBuffer(char *target, int32_t targetCapacity, int32_t n, int32_t radix, UErrorCode *status) {
michael@0 418 if(U_FAILURE(*status)) return 0;
michael@0 419 char str[300];
michael@0 420 T_CString_integerToString(str,n,radix);
michael@0 421 return stringToStringBuffer(target,targetCapacity,str,status);
michael@0 422 }
michael@0 423
michael@0 424 U_CAPI int32_t
michael@0 425 paramInteger(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 426 if(U_FAILURE(*status))return 0;
michael@0 427 if(param->paramStr==NULL || param->paramStr[0]=='d') {
michael@0 428 return integerToStringBuffer(target,targetCapacity,param->paramInt, 10,status);
michael@0 429 } else if(param->paramStr[0]=='x') {
michael@0 430 return integerToStringBuffer(target,targetCapacity,param->paramInt, 16,status);
michael@0 431 } else if(param->paramStr[0]=='o') {
michael@0 432 return integerToStringBuffer(target,targetCapacity,param->paramInt, 8,status);
michael@0 433 } else if(param->paramStr[0]=='b') {
michael@0 434 return integerToStringBuffer(target,targetCapacity,param->paramInt, 2,status);
michael@0 435 } else {
michael@0 436 *status = U_INTERNAL_PROGRAM_ERROR;
michael@0 437 return 0;
michael@0 438 }
michael@0 439 }
michael@0 440
michael@0 441
michael@0 442 U_CAPI int32_t
michael@0 443 paramCldrVersion(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 444 if(U_FAILURE(*status))return 0;
michael@0 445 char str[200]="";
michael@0 446 UVersionInfo icu;
michael@0 447
michael@0 448 ulocdata_getCLDRVersion(icu, status);
michael@0 449 if(U_SUCCESS(*status)) {
michael@0 450 u_versionToString(icu, str);
michael@0 451 return stringToStringBuffer(target,targetCapacity,str,status);
michael@0 452 } else {
michael@0 453 return 0;
michael@0 454 }
michael@0 455 }
michael@0 456
michael@0 457
michael@0 458 #if !UCONFIG_NO_FORMATTING
michael@0 459 U_CAPI int32_t
michael@0 460 paramTimezoneDefault(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 461 if(U_FAILURE(*status))return 0;
michael@0 462 UChar buf[100];
michael@0 463 char buf2[100];
michael@0 464 int32_t len;
michael@0 465
michael@0 466 len = ucal_getDefaultTimeZone(buf, 100, status);
michael@0 467 if(U_SUCCESS(*status)&&len>0) {
michael@0 468 u_UCharsToChars(buf, buf2, len+1);
michael@0 469 return stringToStringBuffer(target,targetCapacity, buf2,status);
michael@0 470 } else {
michael@0 471 return 0;
michael@0 472 }
michael@0 473 }
michael@0 474 #endif
michael@0 475
michael@0 476 U_CAPI int32_t
michael@0 477 paramLocaleDefaultBcp47(const USystemParams * /* param */, char *target, int32_t targetCapacity, UErrorCode *status) {
michael@0 478 if(U_FAILURE(*status))return 0;
michael@0 479 const char *def = uloc_getDefault();
michael@0 480 return uloc_toLanguageTag(def,target,targetCapacity,FALSE,status);
michael@0 481 }
michael@0 482
michael@0 483
michael@0 484 /* simple 1-liner param functions */
michael@0 485 #define STRING_PARAM(func, str) U_CAPI int32_t \
michael@0 486 func(const USystemParams *, char *target, int32_t targetCapacity, UErrorCode *status) \
michael@0 487 { return stringToStringBuffer(target,targetCapacity,(str),status); }
michael@0 488
michael@0 489 STRING_PARAM(paramIcudataPath, u_getDataDirectory())
michael@0 490 STRING_PARAM(paramPlatform, udbg_getPlatform())
michael@0 491 STRING_PARAM(paramLocaleDefault, uloc_getDefault())
michael@0 492 #if !UCONFIG_NO_CONVERSION
michael@0 493 STRING_PARAM(paramConverterDefault, ucnv_getDefaultName())
michael@0 494 #endif
michael@0 495
michael@0 496 #if !UCONFIG_NO_FORMATTING
michael@0 497 STRING_PARAM(paramTimezoneVersion, ucal_getTZDataVersion(status))
michael@0 498 #endif
michael@0 499
michael@0 500 static const USystemParams systemParams[] = {
michael@0 501 { "copyright", paramStatic, U_COPYRIGHT_STRING,0 },
michael@0 502 { "product", paramStatic, "icu4c",0 },
michael@0 503 { "product.full", paramStatic, "International Components for Unicode for C/C++",0 },
michael@0 504 { "version", paramStatic, U_ICU_VERSION,0 },
michael@0 505 { "version.unicode", paramStatic, U_UNICODE_VERSION,0 },
michael@0 506 { "platform.number", paramInteger, "d",U_PLATFORM},
michael@0 507 { "platform.type", paramPlatform, NULL ,0},
michael@0 508 { "locale.default", paramLocaleDefault, NULL, 0},
michael@0 509 { "locale.default.bcp47", paramLocaleDefaultBcp47, NULL, 0},
michael@0 510 #if !UCONFIG_NO_CONVERSION
michael@0 511 { "converter.default", paramConverterDefault, NULL, 0},
michael@0 512 #endif
michael@0 513 { "icudata.name", paramStatic, U_ICUDATA_NAME, 0},
michael@0 514 { "icudata.path", paramIcudataPath, NULL, 0},
michael@0 515
michael@0 516 { "cldr.version", paramCldrVersion, NULL, 0},
michael@0 517
michael@0 518 #if !UCONFIG_NO_FORMATTING
michael@0 519 { "tz.version", paramTimezoneVersion, NULL, 0},
michael@0 520 { "tz.default", paramTimezoneDefault, NULL, 0},
michael@0 521 #endif
michael@0 522
michael@0 523 { "cpu.bits", paramInteger, "d", (sizeof(void*))*8},
michael@0 524 { "cpu.big_endian", paramInteger, "b", U_IS_BIG_ENDIAN},
michael@0 525 { "os.wchar_width", paramInteger, "d", U_SIZEOF_WCHAR_T},
michael@0 526 { "os.charset_family", paramInteger, "d", U_CHARSET_FAMILY},
michael@0 527 #if defined (U_HOST)
michael@0 528 { "os.host", paramStatic, U_HOST, 0},
michael@0 529 #endif
michael@0 530 #if defined (U_BUILD)
michael@0 531 { "build.build", paramStatic, U_BUILD, 0},
michael@0 532 #endif
michael@0 533 #if defined (U_CC)
michael@0 534 { "build.cc", paramStatic, U_CC, 0},
michael@0 535 #endif
michael@0 536 #if defined (U_CXX)
michael@0 537 { "build.cxx", paramStatic, U_CXX, 0},
michael@0 538 #endif
michael@0 539 #if defined (CYGWINMSVC)
michael@0 540 { "build.cygwinmsvc", paramInteger, "b", 1},
michael@0 541 #endif
michael@0 542 { "uconfig.internal_digitlist", paramInteger, "b", 1}, /* always 1 */
michael@0 543 { "uconfig.have_parseallinput", paramInteger, "b", UCONFIG_HAVE_PARSEALLINPUT},
michael@0 544 { "uconfig.format_fastpaths_49",paramInteger, "b", UCONFIG_FORMAT_FASTPATHS_49},
michael@0 545
michael@0 546
michael@0 547 };
michael@0 548
michael@0 549 #define U_SYSPARAM_COUNT (sizeof(systemParams)/sizeof(systemParams[0]))
michael@0 550
michael@0 551 U_CAPI const char *udbg_getSystemParameterNameByIndex(int32_t i) {
michael@0 552 if(i>=0 && i < (int32_t)U_SYSPARAM_COUNT) {
michael@0 553 return systemParams[i].paramName;
michael@0 554 } else {
michael@0 555 return NULL;
michael@0 556 }
michael@0 557 }
michael@0 558
michael@0 559
michael@0 560 U_CAPI int32_t udbg_getSystemParameterValueByIndex(int32_t i, char *buffer, int32_t bufferCapacity, UErrorCode *status) {
michael@0 561 if(i>=0 && i< (int32_t)U_SYSPARAM_COUNT) {
michael@0 562 return systemParams[i].paramFunction(&(systemParams[i]),buffer,bufferCapacity,status);
michael@0 563 } else {
michael@0 564 return 0;
michael@0 565 }
michael@0 566 }
michael@0 567
michael@0 568 U_CAPI void udbg_writeIcuInfo(FILE *out) {
michael@0 569 char str[2000];
michael@0 570 /* todo: API for writing DTD? */
michael@0 571 fprintf(out, " <icuSystemParams type=\"icu4c\">\n");
michael@0 572 const char *paramName;
michael@0 573 for(int32_t i=0;(paramName=udbg_getSystemParameterNameByIndex(i))!=NULL;i++) {
michael@0 574 UErrorCode status2 = U_ZERO_ERROR;
michael@0 575 udbg_getSystemParameterValueByIndex(i, str,2000,&status2);
michael@0 576 if(U_SUCCESS(status2)) {
michael@0 577 fprintf(out," <param name=\"%s\">%s</param>\n", paramName,str);
michael@0 578 } else {
michael@0 579 fprintf(out," <!-- n=\"%s\" ERROR: %s -->\n", paramName, u_errorName(status2));
michael@0 580 }
michael@0 581 }
michael@0 582 fprintf(out, " </icuSystemParams>\n");
michael@0 583 }
michael@0 584
michael@0 585 #define ICU_TRAC_URL "http://bugs.icu-project.org/trac/ticket/"
michael@0 586 #define CLDR_TRAC_URL "http://unicode.org/cldr/trac/ticket/"
michael@0 587 #define CLDR_TICKET_PREFIX "cldrbug:"
michael@0 588
michael@0 589 U_CAPI char *udbg_knownIssueURLFrom(const char *ticket, char *buf) {
michael@0 590 if( ticket==NULL ) {
michael@0 591 return NULL;
michael@0 592 }
michael@0 593
michael@0 594 if( !strncmp(ticket, CLDR_TICKET_PREFIX, strlen(CLDR_TICKET_PREFIX)) ) {
michael@0 595 strcpy( buf, CLDR_TRAC_URL );
michael@0 596 strcat( buf, ticket+strlen(CLDR_TICKET_PREFIX) );
michael@0 597 } else {
michael@0 598 strcpy( buf, ICU_TRAC_URL );
michael@0 599 strcat( buf, ticket );
michael@0 600 }
michael@0 601 return buf;
michael@0 602 }
michael@0 603
michael@0 604
michael@0 605 #if !U_HAVE_STD_STRING
michael@0 606 const char *warning = "WARNING: Don't have std::string (STL) - known issue logs will be deficient.";
michael@0 607
michael@0 608 U_CAPI void *udbg_knownIssue_openU(void *ptr, const char *ticket, char *where, const UChar *msg, UBool *firstForTicket,
michael@0 609 UBool *firstForWhere) {
michael@0 610 if(ptr==NULL) {
michael@0 611 puts(warning);
michael@0 612 }
michael@0 613 printf("%s\tKnown Issue #%s\n", where, ticket);
michael@0 614
michael@0 615 return (void*)warning;
michael@0 616 }
michael@0 617
michael@0 618 U_CAPI void *udbg_knownIssue_open(void *ptr, const char *ticket, char *where, const char *msg, UBool *firstForTicket,
michael@0 619 UBool *firstForWhere) {
michael@0 620 if(ptr==NULL) {
michael@0 621 puts(warning);
michael@0 622 }
michael@0 623 if(msg==NULL) msg = "";
michael@0 624 printf("%s\tKnown Issue #%s \"%s\n", where, ticket, msg);
michael@0 625
michael@0 626 return (void*)warning;
michael@0 627 }
michael@0 628
michael@0 629 U_CAPI UBool udbg_knownIssue_print(void *ptr) {
michael@0 630 puts(warning);
michael@0 631 return FALSE;
michael@0 632 }
michael@0 633
michael@0 634 U_CAPI void udbg_knownIssue_close(void *ptr) {
michael@0 635 // nothing to do
michael@0 636 }
michael@0 637 #else
michael@0 638
michael@0 639 #include <set>
michael@0 640 #include <map>
michael@0 641 #include <string>
michael@0 642 #include <ostream>
michael@0 643 #include <iostream>
michael@0 644
michael@0 645 class KnownIssues {
michael@0 646 public:
michael@0 647 KnownIssues();
michael@0 648 ~KnownIssues();
michael@0 649 void add(const char *ticket, const char *where, const UChar *msg, UBool *firstForTicket, UBool *firstForWhere);
michael@0 650 void add(const char *ticket, const char *where, const char *msg, UBool *firstForTicket, UBool *firstForWhere);
michael@0 651 UBool print();
michael@0 652 private:
michael@0 653 std::map< std::string,
michael@0 654 std::map < std::string, std::set < std::string > > > fTable;
michael@0 655 };
michael@0 656
michael@0 657 KnownIssues::KnownIssues()
michael@0 658 : fTable()
michael@0 659 {
michael@0 660 }
michael@0 661
michael@0 662 KnownIssues::~KnownIssues()
michael@0 663 {
michael@0 664 }
michael@0 665
michael@0 666 void KnownIssues::add(const char *ticket, const char *where, const UChar *msg, UBool *firstForTicket, UBool *firstForWhere)
michael@0 667 {
michael@0 668 if(fTable.find(ticket) == fTable.end()) {
michael@0 669 if(firstForTicket!=NULL) *firstForTicket = TRUE;
michael@0 670 fTable[ticket] = std::map < std::string, std::set < std::string > >();
michael@0 671 } else {
michael@0 672 if(firstForTicket!=NULL) *firstForTicket = FALSE;
michael@0 673 }
michael@0 674 if(where==NULL) return;
michael@0 675
michael@0 676 if(fTable[ticket].find(where) == fTable[ticket].end()) {
michael@0 677 if(firstForWhere!=NULL) *firstForWhere = TRUE;
michael@0 678 fTable[ticket][where] = std::set < std::string >();
michael@0 679 } else {
michael@0 680 if(firstForWhere!=NULL) *firstForWhere = FALSE;
michael@0 681 }
michael@0 682 if(msg==NULL || !*msg) return;
michael@0 683
michael@0 684 std::string str;
michael@0 685 fTable[ticket][where].insert(icu::UnicodeString(msg).toUTF8String(str));
michael@0 686 }
michael@0 687
michael@0 688 void KnownIssues::add(const char *ticket, const char *where, const char *msg, UBool *firstForTicket, UBool *firstForWhere)
michael@0 689 {
michael@0 690 if(fTable.find(ticket) == fTable.end()) {
michael@0 691 if(firstForTicket!=NULL) *firstForTicket = TRUE;
michael@0 692 fTable[ticket] = std::map < std::string, std::set < std::string > >();
michael@0 693 } else {
michael@0 694 if(firstForTicket!=NULL) *firstForTicket = FALSE;
michael@0 695 }
michael@0 696 if(where==NULL) return;
michael@0 697
michael@0 698 if(fTable[ticket].find(where) == fTable[ticket].end()) {
michael@0 699 if(firstForWhere!=NULL) *firstForWhere = TRUE;
michael@0 700 fTable[ticket][where] = std::set < std::string >();
michael@0 701 } else {
michael@0 702 if(firstForWhere!=NULL) *firstForWhere = FALSE;
michael@0 703 }
michael@0 704 if(msg==NULL || !*msg) return;
michael@0 705
michael@0 706 std::string str(msg);
michael@0 707 fTable[ticket][where].insert(str);
michael@0 708 }
michael@0 709
michael@0 710 UBool KnownIssues::print()
michael@0 711 {
michael@0 712 if(fTable.empty()) {
michael@0 713 return FALSE;
michael@0 714 }
michael@0 715
michael@0 716 std::cout << "KNOWN ISSUES" << std::endl;
michael@0 717 for( std::map< std::string,
michael@0 718 std::map < std::string, std::set < std::string > > >::iterator i = fTable.begin();
michael@0 719 i != fTable.end();
michael@0 720 i++ ) {
michael@0 721 char URL[1024];
michael@0 722 std::cout << '#' << (*i).first << " <" << udbg_knownIssueURLFrom( (*i).first.c_str(), URL ) << ">" << std::endl;
michael@0 723
michael@0 724 for( std::map< std::string, std::set < std::string > >::iterator ii = (*i).second.begin();
michael@0 725 ii != (*i).second.end();
michael@0 726 ii++ ) {
michael@0 727 std::cout << " " << (*ii).first << std::endl;
michael@0 728 for ( std::set < std::string >::iterator iii = (*ii).second.begin();
michael@0 729 iii != (*ii).second.end();
michael@0 730 iii++ ) {
michael@0 731 std::cout << " " << '"' << (*iii) << '"' << std::endl;
michael@0 732 }
michael@0 733 }
michael@0 734 }
michael@0 735 return TRUE;
michael@0 736 }
michael@0 737
michael@0 738 U_CAPI void *udbg_knownIssue_openU(void *ptr, const char *ticket, char *where, const UChar *msg, UBool *firstForTicket,
michael@0 739 UBool *firstForWhere) {
michael@0 740 KnownIssues *t = static_cast<KnownIssues*>(ptr);
michael@0 741 if(t==NULL) {
michael@0 742 t = new KnownIssues();
michael@0 743 }
michael@0 744
michael@0 745 t->add(ticket, where, msg, firstForTicket, firstForWhere);
michael@0 746
michael@0 747 return static_cast<void*>(t);
michael@0 748 }
michael@0 749
michael@0 750 U_CAPI void *udbg_knownIssue_open(void *ptr, const char *ticket, char *where, const char *msg, UBool *firstForTicket,
michael@0 751 UBool *firstForWhere) {
michael@0 752 KnownIssues *t = static_cast<KnownIssues*>(ptr);
michael@0 753 if(t==NULL) {
michael@0 754 t = new KnownIssues();
michael@0 755 }
michael@0 756
michael@0 757 t->add(ticket, where, msg, firstForTicket, firstForWhere);
michael@0 758
michael@0 759 return static_cast<void*>(t);
michael@0 760 }
michael@0 761
michael@0 762 U_CAPI UBool udbg_knownIssue_print(void *ptr) {
michael@0 763 KnownIssues *t = static_cast<KnownIssues*>(ptr);
michael@0 764 if(t==NULL) {
michael@0 765 return FALSE;
michael@0 766 } else {
michael@0 767 t->print();
michael@0 768 return TRUE;
michael@0 769 }
michael@0 770 }
michael@0 771
michael@0 772 U_CAPI void udbg_knownIssue_close(void *ptr) {
michael@0 773 KnownIssues *t = static_cast<KnownIssues*>(ptr);
michael@0 774 delete t;
michael@0 775 }
michael@0 776
michael@0 777 #endif

mercurial