]> granicus.if.org Git - icu/commitdiff
ICU-8653 update icuinfo, add icuinfo to howexpensive benchmark.
authorSteven R. Loomis <srl@icu-project.org>
Thu, 15 Dec 2011 23:16:20 +0000 (23:16 +0000)
committerSteven R. Loomis <srl@icu-project.org>
Thu, 15 Dec 2011 23:16:20 +0000 (23:16 +0000)
X-SVN-Rev: 31127

.gitignore
icu4c/source/Makefile.in
icu4c/source/test/perf/howExpensiveIs/Makefile.in
icu4c/source/test/perf/howExpensiveIs/howExpensiveIs.cpp
icu4c/source/test/perf/howExpensiveIs/sieve.cpp
icu4c/source/test/perf/howExpensiveIs/sieve.h
icu4c/source/tools/icuinfo/Makefile.in
icu4c/source/tools/icuinfo/icuinfo.cpp
icu4c/source/tools/toolutil/Makefile.in
icu4c/source/tools/toolutil/udbgutil.cpp
icu4c/source/tools/toolutil/udbgutil.h

index 7c4469509907e395c206014bee359b66634dfb8a..dc4b5d40cda3c548b515f85ee8f22825c9c0b3ee 100644 (file)
@@ -42,6 +42,7 @@ icu4c/source/config/icu-config.1
 icu4c/source/config/icu.pc
 icu4c/source/config/icu.pc.out
 icu4c/source/config/icucross.mk
+icu4c/source/config/icuinfo.xml
 icu4c/source/config/pkgdata.inc
 icu4c/source/config/pkgdataMakefile
 icu4c/source/configure-local.mk
index 9050e4cefb9ad9aec4938147268a9a6e7ce1102f..4f3c5576cc6e4684045b022870a42a8db5319fc8 100644 (file)
@@ -94,6 +94,9 @@ xcheck-recursive: all xcheck-local
 xperf-recursive: all tests
        @$(MAKE) -C test/perf xperf
 
+$(top_builddir)/config/icuinfo.xml: all
+       @$(MAKE) -C tools/icuinfo check
+
 ifeq ($(DOXYGEN),)
 doc doc-searchengine:
        @echo you need Doxygen to generate documentation. Doxygen can be found on the Web
@@ -161,6 +164,8 @@ install-icu: $(INSTALLED_BUILT_FILES)
        $(INSTALL_SCRIPT) $(top_builddir)/config/icu-config $(DESTDIR)$(bindir)/icu-config
        $(INSTALL_DATA) $(top_builddir)/config/Makefile.inc $(DESTDIR)$(pkglibdir)/Makefile.inc
        $(INSTALL_DATA) $(top_builddir)/config/pkgdata.inc $(DESTDIR)$(pkglibdir)/pkgdata.inc
+#      @echo icuinfo.xml is built after make check.
+#      -$(INSTALL_DATA) $(top_builddir)/config/icuinfo.xml $(DESTDIR)$(pkglibdir)/icuinfo.xml
        cd $(DESTDIR)$(pkglibdir)/..; \
            $(RM) current && ln -s $(VERSION) current; \
            $(RM) Makefile.inc && ln -s current/Makefile.inc Makefile.inc; \
@@ -187,7 +192,7 @@ clean-local:
        test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
        -$(RMV) "test-*.xml"
        -$(RMV) "perf-*.xml"
-       -$(RMV) $(ALL_PKGCONFIG_FILES)
+       -$(RMV) $(ALL_PKGCONFIG_FILES) $(top_builddir)/config/icuinfo.xml
        $(RMV) Doxyfile doc $(DOCZIP)
 
 distclean-local: clean-local
index 755b3a68d995d6220971b364eac1571083efd77c..190a0c2fdee4901ca81cc9e6d5a369eff2656397 100644 (file)
@@ -19,7 +19,7 @@ subdir = test/perf/$(TARGET)
 ## Extra files to remove for 'make clean'
 CLEANFILES = *~ $(DEPS)
 
-CPPFLAGS += -I$(top_srcdir)/common -I$(top_builddir)/i18n -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw
+CPPFLAGS += -I$(top_srcdir)/common -I$(top_builddir)/i18n -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw 
 
 LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M)
 
index 2b0184eab23023fb549589f7b362c6faf48dc677..b0205fc9687ae204d37476e5926480c590a8617e 100644 (file)
@@ -7,6 +7,8 @@
 #include <stdio.h>
 #include "sieve.h"
 #include "unicode/utimer.h"
+#include "udbgutil.h"
+
 void runTests(void);
 
 FILE *out = NULL;
@@ -20,7 +22,7 @@ int main(int argc, const char* argv[]){
   {
     double m;
     double s = uprv_getSieveTime(&m);
-    fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_TEN_MILLION_TIMES);
+    fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_LOTS_OF_TIMES);
   }
 #endif
 
@@ -30,7 +32,8 @@ int main(int argc, const char* argv[]){
       fprintf(stderr,"Err: can't open %s for writing.\n", argv[1]);
       return 1;
     }
-    fprintf(out, "<tests icu='%s'>\n", U_ICU_VERSION);
+    fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+    fprintf(out, "<tests icu=\"%s\">\n", U_ICU_VERSION);
     fprintf(out, "<!-- %s -->\n", U_COPYRIGHT_STRING);
   } else if(argc>2) {
     fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]);
@@ -41,6 +44,7 @@ int main(int argc, const char* argv[]){
   
 
   if(out!=NULL) {
+    udbg_writeIcuInfo(out);
     fprintf(out, "</tests>\n");
     fclose(out);
   }
@@ -81,6 +85,10 @@ public:
     int subIterations = 0;
     for(int i=0;i<ITERATIONS;i++) {
       subIterations = runTest(&times[i]);
+#if U_DEBUG
+      fprintf(stderr, "trial: %d/%d = %.9fs\n", i, ITERATIONS,times[i]);
+      fflush(stderr);
+#endif
     }
     *subTime = uprv_getMeanTime(times,ITERATIONS,marginOfError);
     return subIterations;
@@ -97,16 +105,21 @@ void runTestOn(HowExpensiveTest &t) {
   double sieveTime = uprv_getSieveTime(NULL);
   double st;
   double me;
-  /* warmup.. */
+  
+  fflush(stdout);
+  fflush(stderr);
   int32_t iter = t.runTests(&st,&me);
+  fflush(stdout);
+  fflush(stderr);
   
   double stn = st/sieveTime;
 
   printf("%s\t%.9f\t%.9f +/- %.9f,  @ %d iter\n", t.fName,stn,st,me,iter);
 
   if(out!=NULL) {
-    fprintf(out, "   <test name='%s' standardizedTime='%f' realDuration='%f' marginOfError='%f' iterations='%d' />\n",
+    fprintf(out, "   <test name=\"%s\" standardizedTime=\"%f\" realDuration=\"%f\" marginOfError=\"%f\" iterations=\"%d\" />\n",
             t.fName,stn,st,me,iter);
+    fflush(out);
   }
 }
 
@@ -119,11 +132,11 @@ public:
   virtual int32_t run(){return 0;} // dummy
   int32_t runTest(double *subTime) {
     *subTime = uprv_getSieveTime(NULL);
-    return U_TEN_MILLION_TIMES;
+    return U_LOTS_OF_TIMES;
   }
   virtual int32_t runTests(double *subTime, double *marginOfError) {
     *subTime = uprv_getSieveTime(marginOfError);
-    return U_TEN_MILLION_TIMES;
+    return U_LOTS_OF_TIMES;
   }
 };
 
@@ -135,7 +148,7 @@ public:
 #define OCStr(svc,ub,suffix,n) "Test_" # svc # ub # suffix # n
 #define OCRun(svc,ub,suffix) svc ## ub ## suffix
 // TODO: run away screaming
-#define OpenCloseTest(n, svc,suffix,c,a,d) class OCName(svc,_,Test_,suffix,n) : public HowExpensiveTest { public: OCName(svc,_,Test_,suffix,n)():HowExpensiveTest(OCStr(svc,_,suffix,n),__FILE__,__LINE__) c int32_t run() { int32_t i; for(i=0;i<U_TEN_MILLION_TIMES;i++){ OCRun(svc,_,close) (  OCRun(svc,_,suffix) a );  } return i; }   void warmup() { OCRun(svc,_,close) ( OCRun(svc,_,suffix) a); } virtual ~ OCName(svc,_,Test_,suffix,n) () d };
+#define OpenCloseTest(n, svc,suffix,c,a,d) class OCName(svc,_,Test_,suffix,n) : public HowExpensiveTest { public: OCName(svc,_,Test_,suffix,n)():HowExpensiveTest(OCStr(svc,_,suffix,n),__FILE__,__LINE__) c int32_t run() { int32_t i; for(i=0;i<U_LOTS_OF_TIMES;i++){ OCRun(svc,_,close) (  OCRun(svc,_,suffix) a );  } return i; }   void warmup() { OCRun(svc,_,close) ( OCRun(svc,_,suffix) a); } virtual ~ OCName(svc,_,Test_,suffix,n) () d };
 #define QuickTest(n,c,r,d)  class n : public HowExpensiveTest { public: n():HowExpensiveTest(#n,__FILE__,__LINE__) c int32_t run() r virtual ~n () d };
 
 // TODO: move, scope.
@@ -144,9 +157,10 @@ static UChar pattern[] = { 0x23 }; // '#'
 UNumberFormat *NumParseTest_fmt;
 
 // TODO: de-uglify.
-QuickTest(NumParseTest,{    static UChar pattern[] = { 0x23 };    NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL,         pattern,                    1,                    "en_US",                    0,                    &setupStatus);  },{    int32_t i;    static UChar str[] = { 0x31 };double val;    for(i=0;i<U_TEN_MILLION_TIMES;i++) {      val=unum_parse(NumParseTest_fmt,str,1,NULL,&setupStatus);    }    return i;  },{unum_close(NumParseTest_fmt);})
+QuickTest(NumParseTest,{    static UChar pattern[] = { 0x23 };    NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL,         pattern,                    1,                    "en_US",                    0,                    &setupStatus);  },{    int32_t i;    static UChar str[] = { 0x31 };double val;    for(i=0;i<U_LOTS_OF_TIMES;i++) {      val=unum_parse(NumParseTest_fmt,str,1,NULL,&setupStatus);    }    return i;  },{unum_close(NumParseTest_fmt);})
 
 
+QuickTest(NullTest,{},{int j=U_LOTS_OF_TIMES;while(--j);return U_LOTS_OF_TIMES;},{})
 OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,"en_US",0,&setupStatus),{})
 OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,"en_US",0,&setupStatus),{})
 #include "unicode/ucnv.h"
@@ -159,6 +173,10 @@ void runTests() {
     SieveTest t;
     runTestOn(t);
   }
+  {
+    NullTest t;
+    runTestOn(t);
+  }
   {
     NumParseTest t;
     runTestOn(t);
index 4dcd0dbe3ac683abede9bd0e5e7e52ded701a8cc..ce626d7e7e4395b42359e58809845958ea621be3 100644 (file)
@@ -16,7 +16,7 @@
 
 U_CAPI double uprv_calcSieveTime() {
 #if 1
-#define SIEVE_SIZE U_TEN_MILLION_TIMES /* standardized size */
+#define SIEVE_SIZE U_LOTS_OF_TIMES /* standardized size */
 #else
 #define SIEVE_SIZE  <something_smaller>
 #endif
index f8646f5856caf295f1b572dae8fc97a7e4e01488..7ac86d28e6e55ff587dce7148a1dee67b6cc9d0d 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef SIEVE_H
 #define SIEVE_H
 
-#define U_TEN_MILLION_TIMES 10000000
+#define U_LOTS_OF_TIMES 1000000
 
 #include "unicode/utypes.h"
 /**
index 6a3f026e29db80d20099fd345dd26edb783b3bd1..4ba741d9f7897e7fda937a9159e9f2927866cc42 100644 (file)
@@ -31,9 +31,7 @@ DEPS = $(OBJECTS:.o=.d)
 
 # pass some information
 
-ICUINFO_OPTS=-i ../../data/out/build/$(ICUDATA_PLATFORM_NAME)
-
-CPPFLAGS+=  "-DU_BUILD=\"@build@\"" "-DU_HOST=\"@host@\"" "-DU_CC=\"@CC@\"" "-DU_CXX=\"@CXX@\""
+ICUINFO_OPTS=-i ../../data/out/build/$(ICUDATA_PLATFORM_NAME) -x $(top_builddir)/config/icuinfo.xml -v
 
 ## List of phony targets
 .PHONY : all all-local install install-local clean clean-local         \
index 6b93f4ff4af21cda6480c2ba8a6e56ea5684782e..52d79052eee202b71f8be3c83e550963d6820b43 100644 (file)
@@ -43,6 +43,7 @@ static UOption options[]={
   /*4*/ UOPTION_DEF("list-plugins", 'L', UOPT_NO_ARG),
   /*5*/ UOPTION_DEF("milisecond-time", 'm', UOPT_NO_ARG),
   /*6*/ UOPTION_DEF("cleanup", 'K', UOPT_NO_ARG),
+  /*7*/ UOPTION_DEF("xml", 'x', UOPT_REQUIRES_ARG),
 };
 
 static UErrorCode initStatus = U_ZERO_ERROR;
@@ -55,19 +56,6 @@ static void do_init() {
     }
 }
 
-/** 
- * Print the current platform 
- */
-static const char *getPlatform()
-{
-#if U_PLATFORM_HAS_WIN32_API
-    return "Windows";
-#elif U_PLATFORM == U_PF_UNKNOWN
-    return "unknown"
-#else
-    return "Other (POSIX-like)";
-#endif
-}
 
 void cmd_millis()
 {
@@ -76,29 +64,21 @@ void cmd_millis()
 
 void cmd_version(UBool noLoad, UErrorCode &errorCode)
 {
+  char str[2000];
     UVersionInfo icu;
-    char str[200];
-    printf("<ICUINFO>\n");
-    printf("International Components for Unicode for C/C++\n");
-    printf("%s\n", U_COPYRIGHT_STRING);
-    printf("Compiled-Version: %s\n", U_ICU_VERSION);
-    u_getVersion(icu);
-    u_versionToString(icu, str);
-    printf("Runtime-Version: %s\n", str);
-    printf("Compiled-Unicode-Version: %s\n", U_UNICODE_VERSION);
-    u_getUnicodeVersion(icu);
-    u_versionToString(icu, str);
-    printf("Runtime-Unicode-Version: %s\n", str);
-    printf("Platform: %s\n", getPlatform());
-    printf("U_PLATFORM: %d\n", U_PLATFORM);
+    
+
+    do_init();
 
+    udbg_writeIcuInfo(stdout); /* print the XML format */
+    
     union {
         uint8_t byte;
         uint16_t word;
     } u;
     u.word=0x0100;
     if(U_IS_BIG_ENDIAN==u.byte) {
-        printf("U_IS_BIG_ENDIAN: %d\n", U_IS_BIG_ENDIAN);
+      //printf("U_IS_BIG_ENDIAN: %d\n", U_IS_BIG_ENDIAN);
     } else {
         fprintf(stderr, "  error: U_IS_BIG_ENDIAN=%d != %d=actual 'is big endian'\n",
                 U_IS_BIG_ENDIAN, u.byte);
@@ -106,7 +86,7 @@ void cmd_version(UBool noLoad, UErrorCode &errorCode)
     }
 
     if(U_SIZEOF_WCHAR_T==sizeof(wchar_t)) {
-        printf("U_SIZEOF_WCHAR_T: %d\n", U_SIZEOF_WCHAR_T);
+      //printf("U_SIZEOF_WCHAR_T: %d\n", U_SIZEOF_WCHAR_T);
     } else {
         fprintf(stderr, "  error: U_SIZEOF_WCHAR_T=%d != %d=sizeof(wchar_t)\n",
                 U_SIZEOF_WCHAR_T, (int)sizeof(wchar_t));
@@ -122,76 +102,15 @@ void cmd_version(UBool noLoad, UErrorCode &errorCode)
         charsetFamily=-1;  // unknown
     }
     if(U_CHARSET_FAMILY==charsetFamily) {
-        printf("U_CHARSET_FAMILY: %d\n", U_CHARSET_FAMILY);
+      //printf("U_CHARSET_FAMILY: %d\n", U_CHARSET_FAMILY);
     } else {
         fprintf(stderr, "  error: U_CHARSET_FAMILY=%d != %d=actual charset family\n",
                 U_CHARSET_FAMILY, charsetFamily);
         errorCode=U_INTERNAL_PROGRAM_ERROR;
     }
 
-#if defined(U_BUILD)
-    printf("Build: %s\n", U_BUILD);
-#if defined(U_HOST)
-    if(strcmp(U_BUILD,U_HOST)) {
-      printf("Host: %s\n", U_HOST);
-    }
-#endif
-#endif
-#if defined(U_CC)
-    printf("C compiler: %s\n", U_CC);
-#endif
-#if defined(U_CXX)
-    printf("C++ compiler: %s\n", U_CXX);
-#endif
-#if defined(CYGWINMSVC)
-    printf("Cygwin: CYGWINMSVC\n");
-#endif
-    printf("ICUDATA: %s\n", U_ICUDATA_NAME);
-    do_init();
-    printf("Data Directory: %s\n", u_getDataDirectory());
-    printf("ICU Initialization returned: %s\n", u_errorName(initStatus));
-    printf( "Default locale: %s\n", uloc_getDefault());
-    {
-      UErrorCode subStatus = U_ZERO_ERROR;
-      ulocdata_getCLDRVersion(icu, &subStatus);
-      if(U_SUCCESS(subStatus)) {
-       u_versionToString(icu, str);
-       printf("CLDR-Version: %s\n", str);
-      } else {
-       printf("CLDR-Version: %s\n", u_errorName(subStatus));
-      }
-    }
+    printf("\n\nICU Initialization returned: %s\n", u_errorName(initStatus));
     
-#if !UCONFIG_NO_CONVERSION
-    if(noLoad == FALSE)
-    {
-      printf("Default converter: %s\n", ucnv_getDefaultName());
-    }
-#endif
-#if !UCONFIG_NO_FORMATTING
-    {
-      UChar buf[100];
-      char buf2[100];
-      UErrorCode subsubStatus= U_ZERO_ERROR;
-      int32_t len;
-
-      len = ucal_getDefaultTimeZone(buf, 100, &subsubStatus);
-      if(U_SUCCESS(subsubStatus)&&len>0) {
-       u_UCharsToChars(buf, buf2, len+1);
-       printf("Default TZ: %s\n", buf2);
-      } else {
-       printf("Default TZ: %s\n", u_errorName(subsubStatus));
-      }
-    }
-    {
-      UErrorCode subStatus = U_ZERO_ERROR;
-      const char *tzVer = ucal_getTZDataVersion(&subStatus);
-      if(U_FAILURE(subStatus)) {
-       tzVer = u_errorName(subStatus);
-      }
-      printf("TZ data version: %s\n", tzVer);
-    }
-#endif
     
 #if U_ENABLE_DYLOAD
     const char *pluginFile = uplug_getPluginFile();
@@ -199,7 +118,6 @@ void cmd_version(UBool noLoad, UErrorCode &errorCode)
 #else
     fprintf(stderr, "Dynamic Loading: is disabled. No plugins will be loaded at start-up.\n");
 #endif
-    printf("</ICUINFO>\n\n");
 }
 
 void cmd_cleanup()
@@ -339,6 +257,19 @@ main(int argc, char* argv[]) {
       didSomething = TRUE;
     }
 
+    if(options[7].doesOccur) {  /* 2nd part of version: cleanup */
+      FILE *out = fopen(options[7].value, "w");
+      if(out==NULL) {
+        fprintf(stderr,"ERR: can't write to XML file %s\n", options[7].value);
+        return 1;
+      }
+      /* todo: API for writing DTD? */
+      fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+      udbg_writeIcuInfo(out);
+      fclose(out);
+      didSomething = TRUE;
+    }
+
     if(options[6].doesOccur) {  /* 2nd part of version: cleanup */
       cmd_cleanup();
       didSomething = TRUE;
index e613a682448bfd0dd1a291125e469a23e7f58280..5c281bc9fc9d109b20bed31b97d4cb2b3e117671 100644 (file)
@@ -44,6 +44,11 @@ CFLAGS += $(LIBCFLAGS)
 CXXFLAGS += $(LIBCXXFLAGS)
 
 CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/i18n $(LIBCPPFLAGS)
+
+# from icuinfo
+CPPFLAGS+=  "-DU_BUILD=\"@build@\"" "-DU_HOST=\"@host@\"" "-DU_CC=\"@CC@\"" "-DU_CXX=\"@CXX@\""
+
+
 DEFS += -DU_TOOLUTIL_IMPLEMENTATION
 LDFLAGS += $(LDFLAGSICUTOOLUTIL)
 LIBS = $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS)
index 3fa35d7edd7c5c8e9266cc0e94d938b520e96835..0255c11a8c2a34e5fcbce8e037f2fa6547220fc3 100644 (file)
@@ -1,12 +1,16 @@
 /********************************************************************
  * COPYRIGHT:
- * Copyright (c) 2007-2010, International Business Machines Corporation and
+ * Copyright (c) 2007-2011, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 
 #include "udbgutil.h"
 #include <string.h>
-
+#include "ustr_imp.h"
+#include "cstring.h"
+#include "putilimp.h"
+#include "unicode/ulocdata.h"
+#include "unicode/ucnv.h"
 /*
 To add a new enum type 
       (For example: UShoeSize  with values USHOE_WIDE=0, USHOE_REGULAR, USHOE_NARROW, USHOE_COUNT)
@@ -327,3 +331,221 @@ int32_t udbg_enumByName(UDebugEnumType type, const char *value) {
     // fail
     return -1;
 }
+
+/* platform info */
+/** 
+ * Print the current platform 
+ */
+U_CAPI const char *udbg_getPlatform(void)
+{
+#if U_PLATFORM_HAS_WIN32_API
+    return "Windows";
+#elif U_PLATFORM == U_PF_UNKNOWN
+    return "unknown"
+#else
+    return "Other (POSIX-like)";
+#endif
+}
+
+struct USystemParams;
+
+typedef int32_t U_CALLCONV USystemParameterCallback(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status);
+
+struct USystemParams {
+  const char *paramName;
+  USystemParameterCallback *paramFunction;
+  const char *paramStr;
+  int32_t paramInt;
+};
+
+/* parameter types */
+U_CAPI  int32_t
+paramEmpty(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(U_FAILURE(*status))return 0;
+  return u_terminateChars(target, targetCapacity, 0, status);
+}
+
+U_CAPI  int32_t
+paramStatic(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(param->paramStr==NULL) return paramEmpty(param,target,targetCapacity,status);
+  if(U_FAILURE(*status))return 0;
+  int32_t len = uprv_strlen(param->paramStr);
+  if(target!=NULL) {
+    uprv_strncpy(target,param->paramStr,uprv_min(len,targetCapacity));
+  }
+  return u_terminateChars(target, targetCapacity, len, status);
+}
+
+static int32_t stringToStringBuffer(char *target, int32_t targetCapacity, const char *str, UErrorCode *status) {
+  int32_t len = uprv_strlen(str);
+  if(target!=NULL) {
+    uprv_strncpy(target,str,uprv_min(len,targetCapacity));
+  }
+  return u_terminateChars(target, targetCapacity, len, status);
+}
+
+static int32_t integerToStringBuffer(char *target, int32_t targetCapacity, int32_t n, int32_t radix, UErrorCode *status) {
+  if(U_FAILURE(*status)) return 0;
+  char str[300];
+  int32_t len =  T_CString_integerToString(str,n,radix);
+  return stringToStringBuffer(target,targetCapacity,str,status);
+}
+
+U_CAPI  int32_t
+paramInteger(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(U_FAILURE(*status))return 0;
+  if(param->paramStr==NULL || param->paramStr[0]=='d') {
+    return integerToStringBuffer(target,targetCapacity,param->paramInt, 10,status);
+  } else if(param->paramStr[0]=='x') {
+    return integerToStringBuffer(target,targetCapacity,param->paramInt, 16,status);
+  } else if(param->paramStr[0]=='o') {
+    return integerToStringBuffer(target,targetCapacity,param->paramInt, 8,status);
+  } else if(param->paramStr[0]=='b') {
+    return integerToStringBuffer(target,targetCapacity,param->paramInt, 2,status);
+  } else {
+    *status = U_INTERNAL_PROGRAM_ERROR;
+    return 0;
+  }
+}
+
+
+U_CAPI  int32_t
+paramCldrVersion(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(U_FAILURE(*status))return 0;
+  char str[200]="";
+  UVersionInfo icu;
+
+  ulocdata_getCLDRVersion(icu, status);
+  if(U_SUCCESS(*status)) {
+    u_versionToString(icu, str);
+    return stringToStringBuffer(target,targetCapacity,str,status);
+  } else {
+    return 0;
+  }
+}
+
+
+#if !UCONFIG_NO_FORMATTING
+U_CAPI  int32_t
+paramTimezoneDefault(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(U_FAILURE(*status))return 0;
+  UChar buf[100];
+  char buf2[100];
+  int32_t len;
+  
+  len = ucal_getDefaultTimeZone(buf, 100, status);
+  if(U_SUCCESS(*status)&&len>0) {
+    u_UCharsToChars(buf, buf2, len+1);
+    return stringToStringBuffer(target,targetCapacity, buf2,status);
+  } else {
+    return 0;
+  }
+}
+#endif
+
+U_CAPI  int32_t
+paramLocaleDefaultBcp47(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) {
+  if(U_FAILURE(*status))return 0;
+  const char *def = uloc_getDefault();
+  return uloc_toLanguageTag(def,target,targetCapacity,FALSE,status);
+}
+
+
+/* simple 1-liner param functions */
+#define STRING_PARAM(func, str) U_CAPI  int32_t \
+  func(const USystemParams *param, char *target, int32_t targetCapacity, UErrorCode *status) \
+  {  return stringToStringBuffer(target,targetCapacity,(str),status); }
+
+STRING_PARAM(paramIcudataPath, u_getDataDirectory())
+STRING_PARAM(paramPlatform, udbg_getPlatform())
+STRING_PARAM(paramLocaleDefault, uloc_getDefault())
+#if !UCONFIG_NO_CONVERSION
+STRING_PARAM(paramConverterDefault, ucnv_getDefaultName())
+#endif
+
+#if !UCONFIG_NO_FORMATTING
+STRING_PARAM(paramTimezoneVersion, ucal_getTZDataVersion(status))
+#endif
+
+static USystemParams systemParams[] = {
+  { "copyright",    paramStatic, U_COPYRIGHT_STRING,0 },
+  { "product",      paramStatic, "icu4c",0 },
+  { "product.full", paramStatic, "International Components for Unicode for C/C++",0 },
+  { "version",      paramStatic, U_ICU_VERSION,0 },
+  { "version.unicode", paramStatic, U_UNICODE_VERSION,0 },
+  { "platform.number", paramInteger, "d",U_PLATFORM},
+  { "platform.type", paramPlatform, NULL ,0},
+  { "locale.default", paramLocaleDefault, NULL, 0},
+  { "locale.default.bcp47", paramLocaleDefaultBcp47, NULL, 0},
+#if !UCONFIG_NO_CONVERSION
+  { "converter.default", paramConverterDefault, NULL, 0},
+#endif
+  { "icudata.name", paramStatic, U_ICUDATA_NAME, 0},
+  { "icudata.path", paramIcudataPath, NULL, 0},
+
+  { "cldr.version", paramCldrVersion, NULL, 0},
+  
+#if !UCONFIG_NO_FORMATTING
+  { "tz.version", paramTimezoneVersion, NULL, 0},
+  { "tz.default", paramTimezoneDefault, NULL, 0},
+#endif
+  
+  { "cpu.bits",       paramInteger, "d", (sizeof(void*))*8},
+  { "cpu.big_endian", paramInteger, "b", U_IS_BIG_ENDIAN},
+  { "os.wchar_width", paramInteger, "d", U_SIZEOF_WCHAR_T},
+  { "os.charset_family", paramInteger, "d", U_CHARSET_FAMILY},
+#if defined (U_HOST)
+  { "os.host", paramStatic, U_HOST, 0},
+#endif
+#if defined (U_BUILD)
+  { "build.build", paramStatic, U_BUILD, 0},
+#endif
+#if defined (U_CC)
+  { "build.cc", paramStatic, U_CC, 0},
+#endif
+#if defined (U_CXX)
+  { "build.cxx", paramStatic, U_CXX, 0},
+#endif
+#if defined (CYGWINMSVC)
+  { "build.cygwinmsvc", paramInteger, "b", 1},
+#endif
+
+
+
+};
+
+#define U_SYSPARAM_COUNT (sizeof(systemParams)/sizeof(systemParams[0]))
+
+U_CAPI const char *udbg_getSystemParameterNameByIndex(int32_t i) {
+  if(i>=0 && i< U_SYSPARAM_COUNT) {
+    return systemParams[i].paramName;
+  } else {
+    return NULL;
+  }
+}
+
+
+U_CAPI int32_t udbg_getSystemParameterValueByIndex(int32_t i, char *buffer, int32_t bufferCapacity, UErrorCode *status) {
+  if(i>=0 && i< U_SYSPARAM_COUNT) {
+    return systemParams[i].paramFunction(&(systemParams[i]),buffer,bufferCapacity,status);
+  } else {
+    return NULL;
+  }
+}
+
+U_CAPI void udbg_writeIcuInfo(FILE *out) {
+  char str[2000];
+  /* todo: API for writing DTD? */
+  fprintf(out, " <icuSystemParams type=\"icu4c\">\n");
+  const char *paramName;
+  for(int32_t i=0;(paramName=udbg_getSystemParameterNameByIndex(i))!=NULL;i++) {
+    UErrorCode status2 = U_ZERO_ERROR;
+    int32_t l = udbg_getSystemParameterValueByIndex(i, str,2000,&status2);
+    if(U_SUCCESS(status2)) {
+      fprintf(out,"    <param name=\"%s\">%s</param>\n", paramName,str);
+    } else {
+      fprintf(out,"  <!-- n=\"%s\" ERROR: %s -->\n", paramName, u_errorName(status2));
+    }
+  }
+  fprintf(out, " </icuSystemParams>\n");
+}
index 1938c793b5e9961e35a5b35da39261081f5f68c4..0f4da6cbd7fdb7615a4effa73888ab42a1954f92 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ************************************************************************
-* Copyright (c) 2008-2010, International Business Machines
+* Copyright (c) 2008-2011, International Business Machines
 * Corporation and others.  All Rights Reserved.
 ************************************************************************
 */
@@ -11,7 +11,7 @@
 #define _UDBGUTIL_H
 
 #include "unicode/utypes.h"
-
+#include <stdio.h>
 
 enum UDebugEnumType {
     UDBG_UDebugEnumType = 0, /* Self-referential, strings for UDebugEnumType. Count=ENUM_COUNT. */
@@ -75,4 +75,32 @@ U_CAPI int32_t U_EXPORT2 udbg_enumArrayValue(UDebugEnumType type, int32_t field)
  */
 U_CAPI int32_t U_EXPORT2 udbg_enumByName(UDebugEnumType type, const char *name);
 
+
+/**
+ * Return the Platform (U_PLATFORM) as a string
+ */
+U_CAPI const char *udbg_getPlatform(void);
+
+/**
+ * Get the nth system parameter's name
+ * @param i index of name, starting from zero
+ * @return name, or NULL if off the end
+ * @see udbg_getSystemParameterValue
+ */
+U_CAPI const char *udbg_getSystemParameterNameByIndex(int32_t i);
+
+/**
+ * Get the nth system parameter's value, in a user supplied buffer
+ * @parameter i index of value, starting from zero
+ * @param status error status
+ * @return length written (standard termination rules)
+ * @see udbg_getSystemParameterName
+ */
+U_CAPI int32_t udbg_getSystemParameterValueByIndex(int32_t i, char *buffer, int32_t bufferCapacity, UErrorCode *status);
+
+/**
+ * Write ICU info as XML
+ */
+U_CAPI void udbg_writeIcuInfo(FILE *f);
+
 #endif