# extra files that need generation.
PLUG_EXTRA_DEPS=
UNAME=$(shell uname)
-
+DOT=../../c
SOBJ=ao
ifeq ($(UNAME),Linux)
LIBPATH_VAR=LD_LIBRARY_PATH
endif
endif
+SUBHEAD="*** ICU"
+
srcdir=$(shell pwd)
PROVIDER=provider
MOPTS=
# directories that need to be built
-ALLDIRS=$(INST) $(BUILD) $(SRC) $(GLOUT) $(OUT)
+ALLDIRS=$(INST) $(BUILD) $(SRC) $(GLOUT) $(OUT) $(GLOUT)/$(PLUGLIB) $(OUT)/$(PLUGLIB)/bin
# The 'ok' flag file for installations
INST_ICU=$(PLUGLIB_AVAILABLE:%=$(INST)/%/$(OK))
BUILD_ICU=$(PLUGLIB_AVAILABLE:%=$(BUILD)/%/$(OK))
# icu-config switches for C++
ICU_CONFIG_CXX=--cxx $(ICU_CONFIG_COMMON) --cxxflags
+# sigh, include common.
+PLUG_EXTRA_FLAGS=-I$(BUILD)/$(PLUGLIB)/common -I$(M_TMP)/build/r$(PLUGLIB)/icu/source/common
+
include Makefile.local
+
# Usage: $(call SILENT_COMPILE,logfile,cmd)
ifndef VERBOSE
- LOG_COMPILE=echo build with VERBOSE=1 to unhide compile ; ($(2) 2>&1 > $(1) || (echo "Compile failed, see logfile in $(1) for details." ;false))
+ LOG_COMPILE=echo build with VERBOSE=1 to unhide compile ; ( ($(2) 2>&1) > $(1) || (echo "Compile failed, see logfile in $(1) for details." ;exit 1))
else
LOG_COMPILE=$(2) 2>&1 | tee $(1)
endif
+ECHO_COMPILE=echo "\# ${subst ",\",$(1)}" ; ( $(1) || ( exit 1) )
+
PLUGLIB=$(shell echo $(PROVIDER_TARGET) | tr '.' '_' )
PLUGLIB_MAJ=$(shell ./icu2symver.sh $(PLUGLIB))
# Build r$(PLUGLIB) from ../../c
$(PLUGLIB_ICU_CONFIG):
- @echo ICU $(PLUGLIB) "(plugin) building..."
- $(call LOG_COMPILE,../../c/ricus$(PLUGLIB).log,$(MAKE) -C ../../c ICUVERS=$(PLUGLIB) ricus)
+ @echo "$(SUBHEAD) "$(PLUGLIB) "(plugin) building..."
+ $(call LOG_COMPILE,../../c/ricus$(PLUGLIB).log,$(MAKE) MAKE_OPTS=$(MAKE_OPTS) XTRA_RICU_CPPFLAGS=$(XTRA_RICU_CPPFLAGS) -C ../../c ICUVERS=$(PLUGLIB) ricus)
# build the glue objects for TARGET
# used to be %/* instead of $(PLUGLIB) - now, wire it down to pluglib.
-$(GLOUT)/$(PLUGLIB)/obj-$(OK): $(GLOUT) glurens $(PLUGLIB_ICU_CONFIG) $(GL_FE_FILES)
- @echo ICU $* "(plugin) building glue.."
- -mkdir $(GLOUT)/$(PLUGLIB)
+$(GLOUT)/$(PLUGLIB)/obj-$(OK): $(GLOUT) glurens $(PLUGLIB_ICU_CONFIG) $(GL_FE_FILES) $(ALLDIRS)
+ @echo $(SUBHEAD) $(PLUGLIB) "(plugin) building glue.."
# $(shell $(BUILD)/$(PLUGLIB)/config/$(ICU_CONFIG) $(ICU_CONFIG_CC)) $(GLUE_CFLAGS) -c -DICUGLUE_VER=$(PLUGLIB) -o $(GLOUT)/$(PLUGLIB)/gl_be_c_$(PLUGLIB).o $(GL_BE_C:%.c=$(GLUE)/%.c)
# $(shell $(BUILD)/$(PLUGLIB)/config/$(ICU_CONFIG) $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -c -DICUGLUE_VER=$(PLUGLIB) -o $(GLOUT)/$(PLUGLIB)/gl_be_cxx_$(PLUGLIB).o $(GL_BE_CXX:%.cpp=$(GLUE)/%.cpp)
-rm -rf $(GLOUT)/$(PLUGLIB)/include
# 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) ; \
+ echo "*$(SUBHEAD)" $$ver "(provider)" for $(PLUGLIB) "(plugin)" ; \
if [ ! "$$ver" = "$(PLUGLIB)" ]; \
then \
for part in $(GL_PARTS) ; \
do \
- echo $(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -c -I$(TOP)/$(BUILD)/$$ver/gluren/include -DICUGLUE_VER=$$ver "-DICUGLUE_VER_STR=\"$$ver\"" "-DGLUE_SYM(x)=glue ## x ## $$ver" -o $(GLOUT)/$(PLUGLIB)/$${part}_$${ver}_for_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) ; \
- $(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -c -I$(TOP)/$(BUILD)/$$ver/gluren/include -DICUGLUE_VER=$$ver "-DICUGLUE_VER_STR=\"$$ver\"" "-DGLUE_SYM(x)=glue ## x ## $$ver" -o $(GLOUT)/$(PLUGLIB)/$${part}_$${ver}_for_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) || exit 1; \
+ echo "**$(SUBHEAD)" $$ver "(provider) backend: ---- " "$$part" "----" ; \
+ $(call ECHO_COMPILE,$(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -c -I$(TOP)/$(BUILD)/$$ver/gluren/include -DICUGLUE_VER=$$ver -DICUGLUE_VER_STR=\"$$ver\" "-DGLUE_SYM(x)=glue ## x ## $$ver" -o $(GLOUT)/$(PLUGLIB)/$${part}_$${ver}_for_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) ) || exit 1 ; \
done ; \
echo " GLUE_VER( $$ver ) " >> $(GLOUT)/$(PLUGLIB)/include/icuglue/glver.h; \
fi \
done
# build 'this version' FE files
- @echo Building FE for $(PLUGLIB)
@for part in $(GL_PARTS) ; \
do \
- echo $(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -I$(GLOUT)/$(PLUGLIB)/include -c -o $(GLOUT)/$(PLUGLIB)/$${part}_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) ; \
- $(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -I$(GLOUT)/$(PLUGLIB)/include -c -o $(GLOUT)/$(PLUGLIB)/$${part}_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) || exit 1; \
+ echo "ICU" $(PLUGLIB) "(plugin) building plugin for ------- $$part -----" ; \
+ $(call ECHO_COMPILE,$(shell $(PLUGLIB_ICU_CONFIG) --noverify $(ICU_CONFIG_CXX)) $(GLUE_CFLAGS) -I$(GLOUT)/$(PLUGLIB)/include -c -o $(GLOUT)/$(PLUGLIB)/$${part}_$(PLUGLIB).o $(GLUE)/$${part}$(PARTSUFF).cpp $(XOPTS) $(PLUG_EXTRA_FLAGS) ) || exit 1 ; \
done
touch $@
echo " $${part}_provider_plugin" ; \
done
-TESTPROG=coldiff datediff
+TESTPROG=$(GL_PARTS:%=%diff$(EXEEXT))
testprog: $(PLUGLIB:%=$(OUT)/%/bin/$(TESTPROG))
check-icu2symver:
./check-icu2symver.sh
+generate-gdbrc:
+ echo "# generated by $@" > .gdbrc
+ echo "set environment ICU_PLUGINS=$(OUT)" >> .gdbrc
+ echo "set environment $(LIBPATH_VAR)=$(OUT)/../$(PLUGLIB_INST)/lib:$(OUT)/$(PLUGLIB)/lib" >> .gdbrc
+
+
check: check-icu2symver all testprog $(OUT)/icuplugins$(PLUGLIB_MAJ).txt
ICU_PLUGINS=$(OUT) $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib:out/$(PLUGLIB)/lib $(PLUGLIB_INST)/bin/icuinfo || ( echo "ICU broken." ; /bin/false )
ICU_PLUGINS=$(OUT) $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib:out/$(PLUGLIB)/lib $(PLUGLIB_INST)/bin/icuinfo -L || ( echo "Plugin broken." ; /bin/false )
@for prog in $(TESTPROG) ; \
do \
echo "# ICU_PLUGINS=$(OUT) $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib:out/$(PLUGLIB)/lib out/$(PLUGLIB)/bin/$${prog}" ; \
- ICU_PLUGINS=$(OUT) $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib:out/$(PLUGLIB)/lib out/$(PLUGLIB)/bin/$${prog} || ( echo "$${prog} failed." ; /bin/false ) ; \
+ ICU_PLUGINS=$(OUT) $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib:out/$(PLUGLIB)/lib out/$(PLUGLIB)/bin/$${prog} || ( echo "$${prog} failed." ; exit 1 ) ; \
done
install-check: install-plugs
@for prog in $(TESTPROG) ; \
do \
echo "# $${prog}" ; \
- $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib out/$(PLUGLIB)/bin/$${prog} || ( echo "$${prog} against installed failed." ; /bin/false ) ; \
+ $(LIBPATH_VAR)=$(PLUGLIB_INST)/lib out/$(PLUGLIB)/bin/$${prog} || ( echo "$${prog} against installed failed." ; exit 1 ) ; \
done
-$(OUT)/$(PLUGLIB)/bin/$(TESTPROG): $(GLOUT)/$(PLUGLIB)/obj-$(OK) $(OUT)/$(PLUGLIB)/provider_version.h
- -mkdir -p $(OUT)/$(PLUGLIB)/bin
+$(OUT)/$(PLUGLIB)/bin/$(TESTPROG): $(GLOUT)/$(PLUGLIB)/obj-$(OK) $(OUT)/$(PLUGLIB)/provider_version.h $(ALLDIRS)
@for prog in $(TESTPROG) ; \
do \
- $(shell $(PLUGLIB_ICU_CONFIG) --cxx --cxxflags --cppflags --ldflags) -o $(OUT)/$(PLUGLIB)/bin/$${prog} -I$(OUT)/$(PLUGLIB) $(srcdir)/$${prog}.cpp ; \
+ ${call ECHO_COMPILE,$(shell $(PLUGLIB_ICU_CONFIG) --cxx --cxxflags --cppflags --ldflags) -o $(OUT)/$(PLUGLIB)/bin/$${prog} -I$(OUT)/$(PLUGLIB) $(TESTPROG_XTRA_OPTS) $(srcdir)/$${prog}.cpp} || exit 1 ; \
done
$(OUT)/%/lib/$(PLUGLIB_NAME): $(GLOUT)/%/obj-$(OK) $(PLUG_EXTRA_DEPS)
# perform installation
$(INST)/%/ok: $(BUILD)/%/ok
- echo ICU $* "(backend) installing..."
+ echo $(SUBHEAD) $* "(backend) installing..."
echo "INST " "[" $* "]"
mkdir -p $(INST)/$*
-$(call LOG_COMPILE,$(BUILD)$*/ok.log,$(MAKE) $(MOPTS) -C $(BUILD)/$* install $(MAKE_INSTALL_XTRA_OPTS))
# unpack ICU and patch
$(SRC)/%/ok: $(ICUS)/icu4c-%-src.tgz
-[ -d $(SRC)/$* ] && rm -rf $(SRC)/$*
- @echo ICU $* "(backend) unpacking..."
+ @echo $(SUBHEAD) $* "(backend) unpacking..."
mkdir -p $(SRC)/$*
$(call LOG_COMPILE,$(SRC)/$*/unpack.log,( cd $(SRC)/$* && gunzip -d < $(TOP)/$(ICUS)/icu4c-$*-src.tgz | tar xvfp - ))
- @echo Should patch $* here
+ ([ -f $(DOT)/patch/$* ] && patch -d $(SRC)/$* -p1 < $(DOT)/patch/$*) || true
touch $@
# config
$(BUILD)/%/config.status: $(SRC)/%/ok
- @echo ICU $* "(backend) configuring..."
+ @echo $(SUBHEAD) $* "(backend) configuring..."
-[ -d $(BUILD)/$* ] && rm -rf $(BUILD)/$*
mkdir -p $(BUILD)/$*
- ( cd $(BUILD)/$* && env CFLAGS="$(CFLAGS) $(PBLD_EXTRA_FLAGS)" CXXFLAGS="$(CXXFLAGS) $(PBLD_EXTRA_FLAGS)" $(shell $(SUPERCONF) $(TOP)/$(SRC)/$*/$(SOURCE) $*) $(CONFIGURE_OPTS) --srcdir=$(TOP)/$(SRC)/$*/$(SOURCE) --prefix=$(TOP)/$(INST)/$* )
+ $(call LOG_COMPILE,$(BUILD)/$*/configure.log,( cd $(BUILD)/$* && env CFLAGS="$(CFLAGS) $(PBLD_EXTRA_FLAGS)" CXXFLAGS="$(CXXFLAGS) $(PBLD_EXTRA_FLAGS)" $(shell $(SUPERCONF) $(TOP)/$(SRC)/$*/$(SOURCE) $*) $(CONFIGURE_OPTS) --srcdir=$(TOP)/$(SRC)/$*/$(SOURCE) --prefix=$(TOP)/$(INST)/$* ))
# build
# note: regex had renaming problems, and spoof depends on regex. Nuke them.
$(BUILD)/%/ok: $(BUILD)/%/config.status
- @echo ICU $* "(backend) building.."
+ @echo $(SUBHEAD) $* "(backend) building.."
$(call LOG_COMPILE,$(BUILD)/$*/ok2.log,( $(MAKE) $(MOPTS) -C $(BUILD)/$* all $(MAKE_XTRA_OPTS) ))
@if [ ! -f $(BUILD)/$*/common/putil.$(SOBJ) ]; \
then \
touch $@
info help:
- @echo ICU Provider Build
+ @echo $(SUBHEAD) Provider Build
@echo "Targetting Provider against ICU $(PROVIDER_TARGET) ($(PLUGLIB), major $(PLUGLIB_MAJ))"
@echo "Available plugins: $(PROVIDER_AVAILABLE) ($(PLUGLIB_AVAILABLE))"
@echo "Available keywords:"
@echo Available ICU tarballs: $(ICU_TARBALLS)
@echo Available ICU versions: $(shell echo $(ICU_TARBALLS_VERS) | tr '_' '.')
-$(OUT)/$(PLUGLIB)/provider_version.h: Makefile.local Makefile
- @echo Generating $@ ..
+$(OUT)/$(PLUGLIB)/provider_version.h: Makefile.local Makefile $(ALLDIRS)
+ @echo $(SUBHEAD) $(PLUGIN) "(plugin)" Generating $@ ..
@echo "/* Generated file. */" > $@
@echo "const char *provider_version[] = {" >> $@
@for ver in $(PROVIDER_AVAILABLE); do \
- echo VER $$ver ; \
sym=`echo $$ver | ./icu2symver.sh` ; \
- echo SYM $$sym ; \
+ echo Version $$ver, Symbol $$sym ; \
echo "\"$$sym\"", >> $@ ; \
done
@echo " }; " >> $@
@echo "#define PROVIDER_COUNT (sizeof(provider_version)/sizeof(provider_version[0]))" >> $@
@echo >> $@
+ @echo $(SUBHEAD) $(PLUGIN) "(plugin)" Generated $@
#-- for the prototype
--- /dev/null
+/*
+*******************************************************************************
+*
+* Copyright (C) 2009-2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+*/
+
+#include <unicode/datefmt.h>
+#include <unicode/udat.h>
+#include <unicode/uclean.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+/* String to use. */
+const UDate stuff = 1299977771000.0L;
+
+int err=0;
+#include "provider_version.h"
+
+
+#define LOCALE_COUNT 4
+const char *locale[LOCALE_COUNT] = { "es_GU", "fr_AD", "et_AM", "en_IE" }; /* List of locales to test */
+
+/**
+ * Set up ICU, print # of available collators
+ */
+void setup(UErrorCode &status) {
+ u_init(&status);
+
+ fprintf(stderr, "ICU %s init: %s\n", U_ICU_VERSION, u_errorName(status));
+
+ int32_t count;
+ const Locale *se = Calendar::getAvailableLocales(count);
+ fprintf(stderr, "# Calendars now available: %d,\t%s - %d providers expected.\n", count, u_errorName(status), (int32_t)PROVIDER_COUNT);
+}
+
+int main(int /* argc*/ , const char * /*argv*/ []) {
+#if 0
+ // 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;
+ UDateFormatStyle styles[] = { UDAT_FULL, UDAT_SHORT };
+ setup(status);
+ if(U_FAILURE(status)) return 1;
+
+ int expected = PROVIDER_COUNT;
+
+ for(uint32_t s=0;s<sizeof(styles)/sizeof(styles[0]);s++) {
+ for(int l=0;l<LOCALE_COUNT;l++) {
+ printf("\n");
+ char oldChars[200];
+ int32_t oldLen = -1;
+ for(int v=0;v<=expected;v++) {
+
+ // Construct the locale ID
+ char locID[200];
+ strcpy(locID, locale[l]);
+ if((v!=expected)) { // -1 = no version
+ strcat(locID, "@sp=icu");
+ strcat(locID, provider_version[v]);
+ }
+
+ printf("%18s : ", locID);
+
+ UErrorCode subStatus = U_ZERO_ERROR;
+ char outchars[200];
+
+ LocalPointer<Calendar> cal(Calendar::createInstance(Locale(locID), subStatus));
+
+ if(U_FAILURE(subStatus)) {
+ printf("ERR: %s\n", u_errorName(subStatus));
+ err++;
+ continue;
+ }
+
+ // int32_t len = udat_format(dat, stuff, outchars, 200, NULL, &subStatus);
+
+ // //printf("\n");
+ //char utf8[200];
+ // u_strToUTF8(utf8, 200, NULL, outchars, len, &subStatus);
+
+ sprintf(outchars, " cal: mindays=%d firstday=%d ", (int)cal->getMinimalDaysInFirstWeek(), (int)cal->getFirstDayOfWeek());
+ int32_t len = strlen(outchars);
+
+ if(oldLen!=len || memcmp(outchars,oldChars,len*sizeof(outchars[0]))) {
+ if(v==0) {
+ putchar(' ');
+ } else {
+ putchar ('!');
+ diffs++;
+ }
+ } else {
+ putchar ('=');
+ }
+ printf(" %s ", outchars);
+
+ for(int i=0;i<len;i++) {
+ if((i<oldLen)&&(outchars[i]!=oldChars[i])) {
+ diffs++;
+ printf("*", oldChars[i]);
+ } else {
+ printf(" ");
+ }
+ // // printf("U+%04X", (outchars[i]));
+ }
+ putchar('\n');
+
+ oldLen = len;
+ memcpy(oldChars, outchars, len*sizeof(oldChars[0]));
+ }
+ }
+ }
+
+ if(diffs==0) {
+ printf("ERROR: 0 differences found between platforms.. are the platforms installed? Try 'icuinfo -L'\n");
+ return 1;
+ } else {
+ printf("%d differences found among provider versions! Provider is working!\n", diffs);
+ }
+
+ // if(gbaddiffs>0) {
+ // printf("ERROR: %d diffs found between a collator and it's reopened (from shortstring) variant.\n", gbaddiffs);
+ // return 2;
+ // } else {
+ // printf("Collator and reopened (shortstring) are OK.\n");
+ // }
+
+ if(err) {
+ printf("%d errors - FAIL!\n", err);
+ return 1;
+ }
+
+ printf("Success!\n");
+
+ return 0;
+#endif
+}
--- /dev/null
+/*
+*******************************************************************************
+*
+* Copyright (C) 2009-2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+*/
+#define CAL_FE_DEBUG 1
+
+#ifndef CAL_FE_DEBUG
+#define CAL_FE_DEBUG 0
+#endif
+
+#if CAL_FE_DEBUG
+#define debugfprintf(x) fflush(stderr),fflush(stdout),fprintf x,fflush(stderr),fflush(stdout)
+#else
+#define debugfprintf(x)
+#endif
+
+#include <icuglue/icuglue.h>
+#include "unicode/ucal.h"
+//#include <unicode/tblcoll.h>
+#include "unicode/calendar.h"
+#include <string.h>
+#include <stdio.h>
+#include "unicode/ustring.h"
+#include "unicode/gregocal.h"
+
+
+
+/**
+ * Macro to define the Calendar_glue_4_2 class
+ */
+#ifdef GLUE_VER
+#error GLUE_VER is defined
+#endif
+
+#define GLUE_VER(x) class GLUE_SYM_V( Calendar, x ) : public Calendar { \
+public: /* static create */ \
+ UCalendar *_this; GLUE_SYM_V( Calendar, x ) ( const Locale&, UErrorCode& ); \
+private: \
+ virtual ~ GLUE_SYM_V ( Calendar, x) (); \
+ public: \
+ virtual void* getDynamicClassID() const; \
+ static void* getStaticClassID() ; \
+ /* overrides */ \
+ virtual UBool haveDefaultCentury() const; \
+ virtual UDate defaultCenturyStart() const ; \
+ virtual int32_t handleGetExtendedYear() ; \
+virtual const char * getType() const ; \
+virtual UBool inDaylightTime(UErrorCode& status) const ; \
+ virtual int32_t defaultCenturyStartYear() const ; \
+ virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const ; \
+ virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const ; \
+ virtual Calendar* clone(void) const; \
+ public: static int32_t countAvailable(); \
+public: static int32_t appendAvailable(UnicodeString* strs, int32_t i, int32_t count); \
+ };
+
+
+/** ==================================== The following code runs inside the 'target' version (i.e. old ICU) ========== **/
+#if defined ( ICUGLUE_VER )
+
+/* code for some version */
+#include <icuglue/gluren.h>
+#include "oicu.h"
+
+#ifdef GLUE_VER
+GLUE_VER( ICUGLUE_VER )
+#endif
+
+GLUE_SYM (Calendar ) :: GLUE_SYM(Calendar) ( const Locale& loc, UErrorCode& status ) :
+Calendar(status), _this(NULL)
+{
+
+ _this = OICU_ucal_open(NULL, -1, /*locale*/NULL, UCAL_DEFAULT, &status);
+
+ // copy some things over
+ setMinimalDaysInFirstWeek(OICU_ucal_getAttribute(_this, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK));
+ setFirstDayOfWeek((UCalendarDaysOfWeek)OICU_ucal_getAttribute(_this, UCAL_FIRST_DAY_OF_WEEK));
+}
+
+GLUE_SYM ( Calendar ) :: ~ GLUE_SYM(Calendar) () {
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucal_close");
+#endif
+ OICU_ucal_close(_this);
+}
+
+
+UBool GLUE_SYM ( Calendar ) :: haveDefaultCentury() const {
+ return FALSE;
+}
+UDate GLUE_SYM ( Calendar ) :: defaultCenturyStart() const {
+ return 0L;
+}
+int32_t GLUE_SYM ( Calendar ) :: handleGetExtendedYear() {
+ return 0;
+}
+const char * GLUE_SYM ( Calendar ) :: getType() const {
+ return "dilbert";
+}
+UBool GLUE_SYM ( Calendar ) :: inDaylightTime(UErrorCode& status) const {
+ return FALSE;
+}
+int32_t GLUE_SYM ( Calendar ) :: defaultCenturyStartYear() const {
+ return 2012;
+}
+int32_t GLUE_SYM ( Calendar ) :: handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const {
+ return 0;
+}
+
+int32_t GLUE_SYM ( Calendar ) :: handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
+ return 1;
+}
+Calendar* GLUE_SYM ( Calendar ) :: clone(void) const {
+ return NULL;
+}
+
+
+// DateFormat *
+// GLUE_SYM ( DateFormat ) :: create(UDateFormatStyle timeStyle,
+// UDateFormatStyle dateStyle,
+// const char *locale,
+// const UChar *tzID,
+// int32_t tzIDLength,
+// const UChar *pattern,
+// int32_t patternLength,
+// UErrorCode *status,
+// const Locale &loc, const char */*ver*/) {
+// // TODO: save version
+// //char locBuf[200];
+// //char kwvBuf[200];
+// UDateFormat * uc = OICU_udat_open( timeStyle, dateStyle, locale,
+// tzID,
+// tzIDLength,
+// pattern,
+// patternLength,
+// status);
+// if(U_FAILURE(*status)) return NULL; // TODO: ERR?
+// DateFormat *c = new GLUE_SYM( DateFormat ) ( uc );
+// #if CAL_FE_DEBUG
+// fprintf(stderr, "VCF " ICUGLUE_VER_STR " udat_open=%s ->> %p\n", loc.getName(), (void*)c);
+// #endif
+// return c;
+// }
+
+
+ int32_t GLUE_SYM ( Calendar ) :: countAvailable() {
+ int32_t count = OICU_udat_countAvailable();
+ return count;
+ }
+
+
+int32_t GLUE_SYM ( Calendar ) :: appendAvailable(UnicodeString* strs, int32_t i, int32_t /*count*/) {
+ int avail = OICU_udat_countAvailable();
+ UErrorCode status = U_ZERO_ERROR;
+ OICU_u_init(&status);
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCF " ICUGLUE_VER_STR " avail %d - init %s\n", avail, u_errorName(status));
+#endif
+ for(int j=0;j<avail;j++) {
+ strs[i+j].append(OICU_udat_getAvailable(j));
+ strs[i+j].append("@sp=icu");
+ 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 CAL_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);
+ }
+#endif
+ }
+ return OICU_ucol_countAvailable();
+ }
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION( GLUE_SYM( Calendar ) )
+
+
+
+
+#else
+/** ==================================== The following code runs inside the 'provider' version (i.e. current ICU) ========== **/
+
+// #if (U_ICU_VERSION_MAJOR_NUM < 49)
+// #define CAL_PROVIDER_UNSUPPORTED
+// #endif
+
+#ifndef CAL_PROVIDER_UNSUPPORTED
+// define Collator_XX
+#include "icuglue/glver.h"
+
+#include "servloc.h"
+
+// generate list of versions
+static
+#include <icuglue/fe_verlist.h>
+
+class VersionCalendarFactory : public LocaleKeyFactory {
+public:
+ VersionCalendarFactory();
+ virtual UObject* handleCreate(const Locale &loc, int32_t kind, const ICUService* service, UErrorCode& status) const;
+ // virtual Calendar *createFormat(UCalendarStyle timeStyle,
+ // UCalendarStyle dateStyle,
+ // const char *locale,
+ // const UChar *tzID,
+ // int32_t tzIDLength,
+ // const UChar *pattern,
+ // int32_t patternLength,
+ // UErrorCode *status);
+ virtual void* getDynamicClassID() const;
+ static void* getStaticClassID() ;
+ virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;
+private:
+ const UnicodeString *getSupportedIDs(int32_t &count, UErrorCode &status) const;
+
+public:
+virtual UObject*
+ create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const ;
+
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION( VersionCalendarFactory )
+
+UObject*
+VersionCalendarFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const {
+ // UnicodeString id;
+ // key.currentID(id);
+ // Locale l(id);
+ Locale l;
+ const LocaleKey& lkey = (LocaleKey&)key;
+ lkey.currentLocale(l);
+ debugfprintf((stderr, "VCalF::create() .. %s err=%s\n", (const char*)l.getName(), u_errorName(status)));
+
+ char kw[100];
+ int32_t kwlen = l.getKeywordValue("sp", kw, 100, status);
+
+ UObject *f;
+ if(kwlen>0) {
+ debugfprintf((stderr, "Trying for kw=%s\n", kw));
+ f = handleCreate(l, -1, service, status);
+ } else {
+ f = LocaleKeyFactory::create(key,service,status);
+ }
+
+
+
+ debugfprintf((stderr, "VCalF::create() .. = %p err=%s\n", (void*)f, u_errorName(status)));
+ return f;
+}
+
+VersionCalendarFactory::VersionCalendarFactory() :LocaleKeyFactory(LocaleKeyFactory::VISIBLE){
+#if CAL_FE_DEBUG
+ printf("VCalF: hi! pid=%d, this=%p\n", getpid(), (void*)this);
+#endif
+}
+UObject* VersionCalendarFactory::handleCreate(const Locale &loc, int32_t kind, const ICUService* service, UErrorCode& status) const {
+ //Locale loc(locale);
+ // pull off provider #
+ char provider[200];
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCalF:CC %s\n", loc.getName());
+#endif
+ int32_t len = loc.getKeywordValue("sp", provider, 200, status);
+ if(U_FAILURE(status)||len==0) return NULL;
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCalF:KWV> %s/%d\n", u_errorName(status), len);
+#endif
+ provider[len]=0;
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCalF:KWV %s\n", provider);
+#endif
+ if(strncmp(provider,"icu",3)) return NULL;
+ const char *icuver=provider+3;
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCalF:ICUV %s\n", icuver);
+#endif
+
+#if defined(GLUE_VER)
+#undef GLUE_VER
+#endif
+#define GLUE_VER(x) debugfprintf((stderr,"%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2])); if(CMP_VERSTR(icuver, (#x))) { Calendar *c = new glue ## Calendar ## x (loc, status); debugfprintf((stderr, "VCalF::CC %s -> %p\n", loc.getName(), c)); return c; }
+#include "icuglue/glver.h"
+#if CAL_FE_DEBUG
+ fprintf(stderr, "VCalF:CC %s failed\n", loc.getName());
+#endif
+
+ return NULL;
+}
+
+
+static const UnicodeString *gLocalesDate = NULL;
+static int32_t gLocCountDate = 0;
+
+const Hashtable *VersionCalendarFactory::getSupportedIDs (UErrorCode& status) const {
+ // from coll.cpp
+ Hashtable *_ids = NULL;
+ if (U_SUCCESS(status)) {
+ int32_t count = 0;
+ _ids = new Hashtable(status);
+ if (_ids) {
+ const UnicodeString * idlist = /* _delegate -> */ getSupportedIDs(count, status);
+ for (int i = 0; i < count; ++i) {
+ _ids->put(idlist[i], (void*)this, status);
+ if (U_FAILURE(status)) {
+ delete _ids;
+ _ids = NULL;
+ return;
+ }
+ }
+ } else {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ debugfprintf((stderr,"VCalF: hash=%p, count=%d, err=%s\n", (void*)_ids, count, u_errorName(status)));
+ }
+ return _ids;
+}
+
+const UnicodeString
+*VersionCalendarFactory::getSupportedIDs(int32_t &count, UErrorCode &/*status*/) const {
+ if(gLocalesDate==NULL) {
+ count = 0;
+
+
+ /* gather counts */
+
+#if defined(GLUE_VER)
+#undef GLUE_VER
+#endif
+#define GLUE_VER(x) count += glue ## Calendar ## x :: countAvailable();
+#include "icuglue/glver.h"
+
+#if CAL_FE_DEBUG
+ printf("VCalF: count=%d\n", count);
+#endif
+ UnicodeString *strs = new UnicodeString[count];
+ int32_t i = 0;
+
+#if defined(GLUE_VER)
+#undef GLUE_VER
+#endif
+#define GLUE_VER(x) i += glue ## Calendar ## x :: appendAvailable(strs, i, count);
+#include "icuglue/glver.h"
+
+#if CAL_FE_DEBUG
+ printf("VCalF: appended count=%d\n", count);
+#endif
+
+ gLocCountDate = count;
+ gLocalesDate = strs;
+ }
+ count = gLocCountDate;
+ return gLocalesDate;
+}
+
+
+/* Plugin Code */
+
+#include <stdio.h>
+#include <unicode/uversion.h>
+
+static URegistryKey rkcal = NULL;
+
+void cal_provider_register(UErrorCode &status) {
+ debugfprintf((stderr, "about to register VCalF\n"));
+ rkcal = Calendar::registerFactory(new VersionCalendarFactory(), status);
+ debugfprintf((stderr, ".. registered VCalF, key=%p\n", (void*)rkcal));
+}
+
+void cal_provider_unregister(UErrorCode &status) {
+ Calendar::unregister(rkcal, status);
+}
+
+#else
+
+/* no op- this ICU doesn't support date providers */
+
+void cal_provider_register(UErrorCode &) {
+ // not supported
+}
+
+void cal_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"
+
+U_CAPI UPlugTokenReturn U_EXPORT2 cal_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status);
+
+U_CAPI UPlugTokenReturn U_EXPORT2 cal_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status)
+{
+ switch(reason) {
+ case UPLUG_REASON_QUERY:
+ uplug_setPlugName(data, "Calendar Provider Plugin");
+ uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
+ break;
+ case UPLUG_REASON_LOAD:
+ cal_provider_register(*status);
+ break;
+ case UPLUG_REASON_UNLOAD:
+ cal_provider_unregister(*status);
+ break;
+ default:
+ break; /* not handled */
+ }
+ return UPLUG_TOKEN;
+}
+#else
+
+/*
+ Note: this ICU version must explicitly call 'cal_provider_plugin'
+*/
+
+#endif /* plugin */
+
+#endif /* provider side (vs target) */
//static URegistryKey rkdate = NULL;
-VersionDateFormatFactory vdf;
+static VersionDateFormatFactory vdf;
extern "C" UDateFormat *versionDateFormatOpener(UDateFormatStyle timeStyle,
UDateFormatStyle dateStyle,
/*
*******************************************************************************
*
-* Copyright (C) 2009-2011, International Business Machines
+* Copyright (C) 2009-2012, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
end ucol.h
*/
+#include "unicode/ucal.h"
+
+U_STABLE UCalendar* U_EXPORT2
+OICU_ucal_open(const UChar* zoneID,
+ int32_t len,
+ const char* locale,
+ UCalendarType type,
+ UErrorCode* status);
+
+/**
+ * Close a UCalendar.
+ * Once closed, a UCalendar may no longer be used.
+ * @param cal The UCalendar to close.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+OICU_ucal_close(UCalendar *cal);
+
+
+U_STABLE int32_t U_EXPORT2
+OICU_ucal_getAttribute(const UCalendar* cal,
+ UCalendarAttribute attr);
+
+
// define version
#endif