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.

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

mercurial