ICU-9769 provider updates

X-SVN-Rev: 32896
This commit is contained in:
Steven R. Loomis 2012-11-27 23:03:15 +00:00
parent c5c2e31ad9
commit 5a03f4acbc
6 changed files with 640 additions and 36 deletions

View File

@ -6,7 +6,7 @@ all: glurens ii plugs testprog
# extra files that need generation.
PLUG_EXTRA_DEPS=
UNAME=$(shell uname)
DOT=../../c
SOBJ=ao
ifeq ($(UNAME),Linux)
LIBPATH_VAR=LD_LIBRARY_PATH
@ -34,6 +34,8 @@ endif
endif
endif
SUBHEAD="*** ICU"
srcdir=$(shell pwd)
PROVIDER=provider
@ -87,7 +89,7 @@ OK=ok
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))
@ -121,16 +123,22 @@ ICU_CONFIG_CC=--cc $(ICU_CONFIG_COMMON) --cflags
# 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))
@ -151,14 +159,13 @@ $(ALLDIRS):
# 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
@ -166,28 +173,24 @@ $(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) ; \
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 $@
@ -222,20 +225,26 @@ $(OUT)/icuplugins$(PLUGLIB_MAJ).txt: $(PLUGLIB_OUTLIBS) Makefile
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
@ -243,14 +252,13 @@ 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)
@ -279,7 +287,7 @@ $(BUILD)/%/config/$(ICU_CONFIG): $(BUILD)/%/config/$(ICU_CONFIG_ORIG) icu-config
# 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))
@ -288,23 +296,23 @@ $(INST)/%/ok: $(BUILD)/%/ok
# 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 \
@ -321,7 +329,7 @@ $(BUILD)/%/ok: $(BUILD)/%/config.status
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:"
@ -333,18 +341,18 @@ info help:
@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

View File

@ -0,0 +1,144 @@
/*
*******************************************************************************
*
* 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
}

View File

@ -0,0 +1,428 @@
/*
*******************************************************************************
*
* 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) */

View File

@ -305,7 +305,7 @@ const UnicodeString
//static URegistryKey rkdate = NULL;
VersionDateFormatFactory vdf;
static VersionDateFormatFactory vdf;
extern "C" UDateFormat *versionDateFormatOpener(UDateFormatStyle timeStyle,
UDateFormatStyle dateStyle,

View 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.
*
*******************************************************************************
@ -109,6 +109,30 @@ OICU_udat_format( const UDateFormat* format,
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