]> granicus.if.org Git - icu/commitdiff
ICU-9329 document internals and usage. work with ICU 50.
authorSteven R. Loomis <srl@icu-project.org>
Tue, 18 Sep 2012 02:02:43 +0000 (02:02 +0000)
committerSteven R. Loomis <srl@icu-project.org>
Tue, 18 Sep 2012 02:02:43 +0000 (02:02 +0000)
X-SVN-Rev: 32401

tools/multi/proj/provider/Makefile
tools/multi/proj/provider/Makefile.local-sample
tools/multi/proj/provider/coldiff.cpp
tools/multi/proj/provider/datediff.cpp
tools/multi/proj/provider/glue/coll_fe.cpp
tools/multi/proj/provider/glue/date_fe.cpp
tools/multi/proj/provider/glue/include/icuglue/icuglue.h
tools/multi/proj/provider/icu2symver.sh
tools/multi/proj/provider/makegluren.sh
tools/multi/proj/provider/readme.txt

index 04e06da665816688992922f8a38c0a81194c400d..8825a60e18c42a5c138de0ca42fd419f12af6583 100644 (file)
@@ -98,7 +98,7 @@ MAKE_INSTALL_XTRA_OPTS=$(MAKE_XTRA_OPTS)
 
 # Munged source names: list of C++, O etc files for Frontend
 PARTSUFF=_fe
-GL_FE_CXX=$(shell cd $(GLUE) ; ls *$(PARTSUFF).cpp)
+GL_FE_CXX=$(notdir $(wildcard $(GLUE)/*$(PARTSUFF).cpp))
 GL_FE_FILES=$(GL_FE_CXX:%.cpp=$(GLUE)/%.cpp)
 GL_FE_O=$(GL_FE_CPP:%.cpp=%.o)
 GL_PARTS=$(GL_FE_CXX:%$(PARTSUFF).cpp=%)
@@ -146,6 +146,9 @@ $(GLOUT)/$(PLUGLIB)/obj-$(OK): $(GLOUT) glurens  $(PLUGLIB_ICU_CONFIG) $(GL_FE_F
 # for each version..  build all OTHER FE files
 # TODO: check is unnecessary, not permitted.
 # TODO: change to depend instead of for list. 
+       @echo GL_PARTS=$(GL_PARTS)
+       @echo GL_FE_CXX=$(GL_FE_CXX)
+       @echo PARTSUFF=$(PARTSUFF)
        @for ver in $(PLUGLIB_AVAILABLE) ; \
        do \
                echo building $$ver for $(PLUGLIB) ; \
@@ -249,6 +252,7 @@ glurens: $(GLUREN_ICU)
 $(BUILD)/%/$(GLUREN_H): $(BUILD)/%/ok Makefile makegluren.sh
        -mkdir -p $(BUILD)/$*/$(GLUREN)
        env SRC="$(SRC)" SOURCE="$(SOURCE)" GLUE="$(GLUE)" ./makegluren.sh $@ $*
+       @fgrep -q OICU_ $@ || ( echo "Error: $@: no OICU_ symbols found. Removing gluren.h " ; rm -f $@ ; exit 1)
 
 $(BUILD)/%/config/$(ICU_CONFIG): $(BUILD)/%/config/$(ICU_CONFIG_ORIG) icu-config.sed $(BUILD)/%/ok 
        sed -f icu-config.sed < $(BUILD)/$*/config/$(ICU_CONFIG_ORIG) >  $(BUILD)/$*/config/$(ICU_CONFIG) && chmod a+rx  $(BUILD)/$*/config/$(ICU_CONFIG)
@@ -302,7 +306,7 @@ info help:
        @echo "Available plugins: $(PROVIDER_AVAILABLE) ($(PLUGLIB_AVAILABLE))"
        @echo "Available keywords:"
        @for ver in $(PROVIDER_AVAILABLE); do \
-               echo "   ...@provider=icu"`echo $$ver | cut -d. -f1-2 | tr -d .`; \
+               echo "   ...@provider=icu"`echo $$ver | ./icu2symver.sh`; \
        done
        @echo "Plugin library will be $(PLUGLIB_NAME)"
        @echo
@@ -314,7 +318,10 @@ $(OUT)/$(PLUGLIB)/provider_version.h: Makefile.local Makefile
        @echo "/* Generated file. */" > $@
        @echo "const char *provider_version[] = {" >> $@
        @for ver in $(PROVIDER_AVAILABLE); do \
-               echo '"'`echo $$ver | cut -d. -f1-2 | tr -d .`'",' >> $@ ; \
+               echo VER $$ver ; \
+               sym=`echo $$ver | ./icu2symver.sh` ; \
+               echo SYM $$sym ; \
+               echo "\"$$sym\"",  >> $@ ; \
        done
        @echo " }; " >> $@
        @echo "#define PROVIDER_COUNT (sizeof(provider_version)/sizeof(provider_version[0]))" >> $@
index 88e8c8ac17548d83d4eb0385cb75a0119777f4f7..34a36ce56f5ab319c1e8c9ea5d4c38aed26a2134 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2008-2010 IBM Corporation and Others. All Rights Reserved
+# Copyright (C) 2008-2012 IBM Corporation and Others. All Rights Reserved
 
 # local definitions must go in Makefile.local
 # example:
@@ -8,9 +8,9 @@
 ## These two are REQUIRED.
 ##
 
-# The version of ICU you will build against, such as:  
-# EXAMPLE: 4.4.2
-PROVIDER_TARGET=4.4.2
+# The version of ICU you will build against (which API you will use).  Note, 49.1 is required for collation support, and for date support.
+# EXAMPLE: 49.1
+PROVIDER_TARGET=49.1
 
 # The versions of ICU you want to have available in the plugin. Space separated.  Don't include the PROVIDER_TARGET version.
 # EXAMPLE: 3.8.1  4.2.0.1
index 563816cc0a313afa1486e2932c0941726ac1cc66..a45cfc70da25e1b3989248ab0ad7cfd6843da6f6 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2011, International Business Machines
+*   Copyright (C) 2009-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -164,7 +164,11 @@ int main(int /* argc*/ , const char * /*argv*/ []) {
     }
 
     if(diffs==0) {
+#if (U_ICU_VERSION_MAJOR_NUM < 49)
+      printf("ERROR: 0 differences found between platforms. ICU " U_ICU_VERSION " does not support collator plugins properly (not until 49)\n");
+#else
       printf("ERROR: 0 differences found between platforms.. are the platforms installed? Try 'icuinfo -L'\n");
+#endif
       return 1;
     } else {
       printf("%d differences found among provider versions!\n", diffs);
index 0a21997772d86d60b412a9862cbf473a6e1a08e9..0f69b906ff417a1f399c769821922db8ec5ce93a 100644 (file)
@@ -39,6 +39,10 @@ void setup(UErrorCode &status) {
 }
 
 int main(int /* argc*/ , const char * /*argv*/ []) {
+#if (U_ICU_VERSION_MAJOR_NUM < 49)
+  fprintf(stderr, "Warning: ICU %s doesn't support date providers. Need at least 49.\n",  U_ICU_VERSION );
+  return 0;
+#else
     UErrorCode status = U_ZERO_ERROR;
     int diffs = 0;
     int gbaddiffs =0;
@@ -48,7 +52,7 @@ int main(int /* argc*/ , const char * /*argv*/ []) {
 
     int expected = PROVIDER_COUNT;
 
-    for(int s=0;s<sizeof(styles)/sizeof(styles[0]);s++) {
+    for(uint32_t s=0;s<sizeof(styles)/sizeof(styles[0]);s++) {
       for(int l=0;l<LOCALE_COUNT;l++) {
         printf("\n");
         UChar oldChars[200];
@@ -123,4 +127,5 @@ int main(int /* argc*/ , const char * /*argv*/ []) {
     printf("Success!\n");
     
     return 0;
+#endif
 }
index 3dc593aa8f5bd2a938633ca99e8f4ae09e6aa616..1b2442932a4f811b35ce9e46c48033c22b32b3cf 100644 (file)
 #include <stdio.h>
 #include "unicode/ustring.h"
 
+#if COLL_FE_DEBUG
+#define debugfprintf(x) fprintf x
+#else
+#define debugfprintf(x)
+#endif
 
-
+/*
+ * Before ICU 50.0.2 (50m2) - there was a different collator signature.
+ * see: ticket:9460 ticket:9346
+ */
+#if (U_ICU_VERSION_MAJOR_NUM < 50) || ((U_ICU_VERSION_MAJOR_NUM==50)&&(U_ICU_VERSION_MINOR_NUM==0)&&(U_ICU_VERSION_PATCHLEVEL_NUM<2))
+#define PRE_50_0_2_COLLATOR
+#define CONST_BEFORE_50_0_2 const
+#define CONST_AFTER_50_0_2 
+#define REF_AFTER_50_0_2
+#else
+/* "current" API */
+#define CONST_BEFORE_50_0_2
+#define CONST_AFTER_50_0_2 const
+#define REF_AFTER_50_0_2 &
+#endif
 
 /**
  * Macro to define the Collator_glue_4_2 class 
     virtual CollationKey& getCollationKey(const UnicodeString&, CollationKey&, UErrorCode&) const; \
     virtual CollationKey& getCollationKey(const UChar*, int32_t, CollationKey&, UErrorCode&) const; \
     virtual int32_t hashCode() const;                                   \
-    virtual const Locale getLocale(ULocDataLocaleType, UErrorCode&) const; \
+    virtual CONST_BEFORE_50_0_2 Locale getLocale(ULocDataLocaleType, UErrorCode&) const; \
     virtual ECollationStrength getStrength() const;                     \
     virtual void setStrength(ECollationStrength);                       \
     virtual void getVersion(uint8_t*) const;                            \
-    virtual void setAttribute(UColAttribute, UColAttributeValue, UErrorCode&); \
-    virtual UColAttributeValue getAttribute(UColAttribute, UErrorCode&); \
+    virtual void setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) ; \
+    virtual UColAttributeValue getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2; \
     virtual uint32_t setVariableTop(const UChar*, int32_t, UErrorCode&); \
-    virtual uint32_t setVariableTop(UnicodeString, UErrorCode&);        \
+    virtual uint32_t setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&);        \
     virtual void setVariableTop(uint32_t, UErrorCode&);                 \
     virtual uint32_t getVariableTop(UErrorCode&) const;                 \
-    virtual Collator* safeClone();                                      \
+    virtual Collator* safeClone() CONST_AFTER_50_0_2 ;                                      \
     virtual int32_t getSortKey(const UnicodeString&, uint8_t*, int32_t) const; \
     virtual int32_t getSortKey(const UChar*, int32_t, uint8_t*, int32_t) const; \
   public: static int32_t countAvailable();                              \
@@ -209,7 +228,7 @@ int32_t GLUE_SYM ( Collator ) :: hashCode() const  {
 }
 
 
-const Locale GLUE_SYM ( Collator ) :: getLocale(ULocDataLocaleType, UErrorCode&) const  {
+CONST_BEFORE_50_0_2 Locale GLUE_SYM ( Collator ) :: getLocale(ULocDataLocaleType, UErrorCode&) const  {
     return Locale();
 }
 
@@ -229,11 +248,11 @@ void GLUE_SYM ( Collator ) :: getVersion(uint8_t*) const  {
 }
 
 
-void GLUE_SYM ( Collator ) :: setAttribute(UColAttribute, UColAttributeValue, UErrorCode&)  {
+void GLUE_SYM ( Collator ) :: setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) {
 }
 
 
-UColAttributeValue GLUE_SYM ( Collator ) :: getAttribute(UColAttribute, UErrorCode&)  {
+UColAttributeValue GLUE_SYM ( Collator ) :: getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2 {
 return (UColAttributeValue)0;
 }
 
@@ -243,7 +262,7 @@ return 0;
 }
 
 
-uint32_t GLUE_SYM ( Collator ) :: setVariableTop(UnicodeString, UErrorCode&)  {
+uint32_t GLUE_SYM ( Collator ) :: setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&)  {
 return 0;
 }
 
@@ -257,7 +276,7 @@ return 0;
 }
 
 
-Collator* GLUE_SYM ( Collator ) :: safeClone()  {
+Collator* GLUE_SYM ( Collator ) :: safeClone() CONST_AFTER_50_0_2 {
     return clone();
 }
 
@@ -292,8 +311,8 @@ int32_t GLUE_SYM (Collator ) ::  internalGetShortDefinitionString(const char *lo
     char *p = buffer+strlen(buffer);
     strncat(p,"_PICU",5);
     p +=5 ;
-    *(p++) = ICUGLUE_VER_STR[0];
-    *(p++) = ICUGLUE_VER_STR[2];
+    CPY_VERSTR(p, ICUGLUE_VER_STR);
+    p +=2;
     if(remainCap>0) {
       *(p++)=0;
     }
@@ -319,14 +338,21 @@ int32_t GLUE_SYM ( Collator ) :: appendAvailable(UnicodeString* strs, int32_t i,
     for(int j=0;j<avail;j++) {
          strs[i+j].append(OICU_ucol_getAvailable(j));
          strs[i+j].append("@sp=icu");
-         strs[i+j].append( ICUGLUE_VER_STR[0] );  // X_y
-         strs[i+j].append( ICUGLUE_VER_STR[2] );  // x_Y
+         
+         if(IS_OLD_VERSTR(ICUGLUE_VER_STR)) {
+           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MAJ] );  // X_y
+           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MIN] );  // x_Y
+         } else {
+           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MAJ] );  // Xy_
+           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MIN] );  // xY_
+         }
+
 #if COLL_FE_DEBUG
          { 
             char foo[999];
             const UChar *ss = strs[i+j].getTerminatedBuffer();
             u_austrcpy(foo, ss);
-            //            fprintf(stderr,  "VCF " ICUGLUE_VER_STR " appending [%d+%d=%d] <<%s>>\n", i, j, i+j, foo);
+            debugfprintf((stderr,  "VCF " ICUGLUE_VER_STR " appending [%d+%d=%d] <<%s>>\n", i, j, i+j, foo));
         }
 #endif
     }
@@ -380,7 +406,15 @@ Collator *VersionCollatorFactory::createCollator(const Locale &loc) {
 #if defined(GLUE_VER)
 #undef GLUE_VER
 #endif
-#define GLUE_VER(x) /*printf("%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2]);*/  if(icuver[0]== (#x)[0] && icuver[1]==(#x)[2]) { Collator *c = glue ## Collator ## x :: create(loc, icuver); /*fprintf(stderr, "VCF::CC %s -> %p\n", loc.getName(), c);*/ return c; }
+
+#define GLUE_VER(x) \
+    debugfprintf((stderr,"%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2]));  \
+    if(CMP_VERSTR(icuver, (#x))) {                                      \
+      Collator *c = glue ## Collator ## x :: create(loc, icuver); \
+      debugfprintf((stderr, "VCF::CC %s -> %p\n", loc.getName(), c)); \
+      return c; \
+    }
+
 #include "icuglue/glver.h"
 #if COLL_FE_DEBUG
     fprintf(stderr,  "VCF:CC %s failed\n", loc.getName());
index 7042b22adc4463baa1dfaa5e336f2806e4fa0518..6e3c1f040b5a1e64cd82ec38dc9e5ce82c8c809a 100644 (file)
@@ -90,10 +90,10 @@ GLUE_SYM ( DateFormat ) :: create(UDateFormatStyle  timeStyle,
                                                     const UChar       *pattern,
                                                     int32_t           patternLength,
                                                     UErrorCode        *status,
-                                                    const Locale &loc, const char */*ver*/) {
+                                  const Locale &loc, const char */*ver*/) {
   // TODO: save version
-  char locBuf[200];
-  char kwvBuf[200];
+  //char locBuf[200];
+  //char kwvBuf[200];
   UDateFormat * uc =  OICU_udat_open( timeStyle, dateStyle, locale,
                                       tzID,
                                       tzIDLength,
@@ -185,6 +185,11 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION( GLUE_SYM( DateFormat ) )
 #else
 /** ==================================== The following code runs inside the 'provider' version (i.e. current ICU) ========== **/
 
+#if (U_ICU_VERSION_MAJOR_NUM < 49)
+#define DATE_PROVIDER_UNSUPPORTED
+#endif
+
+#ifndef DATE_PROVIDER_UNSUPPORTED
 // define Collator_XX
 #include "icuglue/glver.h"
 
@@ -324,6 +329,20 @@ void date_provider_unregister(UErrorCode &status) {
   udat_unregisterOpener(versionDateFormatOpener, &status);
 }
 
+#else
+
+/* no op- this ICU doesn't support date providers */
+
+void date_provider_register(UErrorCode &) {
+  // not supported
+}
+
+void date_provider_unregister(UErrorCode &) {
+  // not supported
+}
+
+#endif
+
 /* Plugin- only ICU 4.4+ */
 #if (U_ICU_VERSION_MAJOR_NUM > 4) || ((U_ICU_VERSION_MAJOR_NUM==4)&&(U_ICU_VERSION_MINOR_NUM>3))
 #include "unicode/icuplug.h"
index 8d916c5efacad659f6ff1800436a8ac7e7722201..61485618baedf5e9f8e85cdbf9238b0a932bf029 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2010, International Business Machines
+*   Copyright (C) 2009-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 
 #define GLUE_SYM_V(x, v) glue ## x ## v
 
+/**
+ * how to parse a version string.
+ * old:  3_6_X, 3_8_X, 4_4_X, 4_8_X
+ * new:  49_X, 50_X, 51_X, ...
+ *
+ * example use:
+ *  char *str = "50_0_0", str1="49_1_2",str2="4_8_1_1";
+ *  if(IS_OLD_VERSION(str)) {
+ *    maj = str[OLD_VERSTR_MAJ];
+ *    min = str[OLD_VERSTR_MIN];
+ *  } else {
+ *    maj = str[NEW_VERSTR_MAJ];
+ *    min = str[NEW_VERSTR_MIN];
+ *  }
+ */
+#define IS_OLD_VERSTR(x) ((x[0]<'4') || ((x[0]=='4') && (x[2]<'9') && (x[2]>='0')))
+#define OLD_VERSTR_MAJ 0 
+#define OLD_VERSTR_MIN 2
+#define NEW_VERSTR_MAJ 0
+#define NEW_VERSTR_MIN 1
+
+/**
+ * copy version into dst[0] and dst[1]
+ * does not modify dst ptr
+ */
+#define CPY_VERSTR(dst,ver) if(IS_OLD_VERSTR(ver)) \
+    { \
+      (dst)[0]=ver[OLD_VERSTR_MAJ];              \
+      (dst)[1]=ver[OLD_VERSTR_MIN];              \
+    } else {                      \
+      (dst)[0]=ver[NEW_VERSTR_MAJ];       \
+      (dst)[1]=ver[NEW_VERSTR_MIN];             \
+    }
+
+/**
+ * compare a verstr to a string
+ * @param str a 2 char string such as "50", "44", "49"
+ * @param ver a verstr such as "50_0_2", "4_8_1_1", etc
+ * @return true or false
+ */
+
+#define CMP_VERSTR(str,ver) \
+  ( (IS_OLD_VERSTR(ver)) ? \
+     ( \
+      (str)[0]==ver[OLD_VERSTR_MAJ] &&              \
+      (str)[1]==ver[OLD_VERSTR_MIN] \
+     ):(                                              \
+      (str)[0]==ver[NEW_VERSTR_MAJ]&&       \
+      (str)[1]==ver[NEW_VERSTR_MIN]             \
+     ) \
+   )
+
 #endif
index 597325f729fe55148c27a9f8cde374c56821cb4d..27cdddd3e97236caff74fa8003ca66a9b05f7262 100755 (executable)
@@ -1,6 +1,15 @@
 #!/bin/sh
 # Copyright (C) 2010-2012 IBM Corporation and Others, All Rights Reserved.
 
+PRE44=0
+
+# output 4_0 instead of 40
+if [ "$1" == "--pre44sym" ];
+then
+    PRE44=1
+    shift
+fi
+
 INVER="0.0"
 if [ $# -eq 0 ];
 then
@@ -18,11 +27,17 @@ MAJ0=`echo ${UND} | cut -d_ -f1`
 MIN1=`echo ${UND} | cut -d_ -f2`
 if [ ${MAJ0} -lt 49 ];
 then
-    # pre 50:  paste together "4" and "8" to get 48
-    echo -n "${MAJ0}${MIN1}"
+    if [ ${PRE44} -eq 0 ];
+    then
+        # pre 50:  paste together "4" and "8" to get 48
+        echo -n "${MAJ0}${MIN1}"
+    else
+        # pre 50: 4_8
+        echo -n "${MAJ0}_${MIN1}"
+    fi
 else
     # post 50:  just use the first #
     echo -n "${MAJ0}"
 fi
 
-exit 0
\ No newline at end of file
+exit 0
index 6343f752fccb2c085e9e16a321e4c221b17f408f..3b3deaf9afaefc3198af549579c97ff222592a00 100755 (executable)
@@ -9,19 +9,22 @@ VER=$1
 shift
 
 TINY=`./icu2symver.sh $VER`
+OLDSYM=`./icu2symver.sh --pre44sym $VER`
 
 echo "$0: Building ${OUT} for ${TINY} ------- " >&2
+echo "oldsym = ${OLDSYM}"
 #set -x 
-
+URENAME=${SRC}/${VER}/${SOURCE}/common/unicode/urename.h
 (
     cat ${GLUE}/gluren-top.h
+    echo "/* Generated from ${URENAME} by ${0} */"
     echo "#define GLUREN_VER" ${TINY}
     echo "#define GLUREN_TINY" ${TINY}
     echo
     echo '/* old style (<4.4)*/'
-    grep "^#define.*${TINY}$" ${SRC}/${VER}/${SOURCE}/common/unicode/urename.h   | fgrep -v '*' | sed -e "s@^#define \([^ ]*\) \([^ ]*\)@#define OICU_\1 \2@"
+    grep "^#define.*${OLDSYM}$" ${URENAME}   | fgrep -v '*' | sed -e "s@^#define \([^ ]*\) \([^ ]*\)@#define OICU_\1 \2@"
     echo '/* new style (4.4+) */'
-    fgrep " U_ICU_ENTRY_POINT_RENAME(" ${SRC}/${VER}/${SOURCE}/common/unicode/urename.h | sed -e "s@^#define \([^ ]*\) .*@#define OICU_\1 \1_${TINY}@"
+    fgrep " U_ICU_ENTRY_POINT_RENAME(" ${URENAME} | sed -e "s@^#define \([^ ]*\) .*@#define OICU_\1 \1_${TINY}@"
     cat ${GLUE}/gluren-bottom.h
 ) |
     cat > ${OUT}
index 91f36a7b33cfcb87fdefcfe78b220d1a71665dc9..1e7d3e4b81e59515c7323509f672d557dc905afc 100644 (file)
@@ -21,7 +21,7 @@ the provider interface).  As of this writing, 49, 4.8.1.1, 4.6.x, 4.4.x, 4.2.0.1
 
 1c. Copy the ICUs (named as they were downloaded) into the ../../packages/ directory relative to this readme.
 
-2a. Copy the file "Makefile-local.sample" into a new file "Makefile.local".
+2a. Copy the file "Makefile.local-sample" into a new file "Makefile.local".
 
 2b. Edit the Makefile.local to modify the PROVIDER_TARGET and
 PROVIDER_AVAILABLE settings.
@@ -77,3 +77,34 @@ format, but only through 'udat_open'.
 
 
 
+---------------------------
+THEORY (INTERNAL USE ONLY!)
+
+For discussion:  assume TARGET 50.0.2 and PROVIDER 4.0.1
+
+i. GENERAL
+
+ The "front end" for each module (date, collator, ..)  is built once for the target version, and the "back end" glue is built once for each provider version.  (TODO: fix wording here.)
+
+ The oicu.h header, combined with the generated gluren.h, provides a "renamed" symbol such as (literally) OICU_ucol_strcoll which is #defined  to some specific version, such as ucol_strcoll_4_0.  So, you can call the OICU_ version meaning "Old ICU". Thus, you have the ICU 4.0 function defined as an extern, by its explicit name, within the ICU 50 space. 
+
+ The icuglue/glver.h header file contains multiple calls to, for example, GLUE_VER(4_0_1)  GLUE_VER(49_1_2) ...   
+ A module can redefine GLUE_VER  in order to do some "each-version" process.  Thus, glver.h can be #included multiple times..
+
+ Generally, a locale such as en_US@sp=icu40  will refer to an ICU 4.0  provider.
+
+ There are lots of version-specific #ifdefs used to deal with the vagaries of a decade of ICU changes.
+
+ii. COLLATORS
+
+ For each back end, there's an icu_50::Collator class named, say, glueCollator4_0_1 which is implemented in the TARGET space. However, each function of this class, such as "compare", is implemented by calling, for example,  OICU_ucol_strcoll.  As noted above, this is directly calling ucol_strcoll_4_0. This is where the cross-version calls happen.  Such glue code must be very careful not to, for example,  call ucol_open_4_0 and pass the result to ucol_close_50 ! 
+
+ The FE builds a CollatorFactory subclass, VersionCollatorFactory.  It registers a collator for every localeid it can support. This is done by calling each glueCollator* subclass's static ::countAvailable and appendAvailable functions directly. 
+
+ The plugin simply registers and unregisters the VCF. Such collators are available to both C++ and C API, including the shortstring interface, using the _PICU## short string tag.
+
+iii. DATE FORMATTERS
+
+ Date formatters work in a similar fashion to collators.  DateFormat subclasses are registered which are implemented in terms of OICU_udat_* functions. A "DateFormatOpener" (factory equivalent) is registered to allow udat_open to process correctly. C++ date format registration is not addressed as of this writing.
+
+