diff options
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/tools/genrb')
27 files changed, 9727 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/Makefile.in b/Build/source/libs/icu/icu-xetex/tools/genrb/Makefile.in new file mode 100644 index 00000000000..6c7cb271ed6 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/Makefile.in @@ -0,0 +1,160 @@ +## Makefile.in for ICU - tools/genrb +## Copyright (c) 1999-2007, International Business Machines Corporation and +## others. All Rights Reserved. + +# SIMPLIFIED WAY TO BUILD ICU4J DATA FROM C +# +# Note: do NOT edit this file, Makefile or Makefile.in +# Create a new file, Makefile.local +# +# 1. Need to set the following variable in Makefile.local: +# +# ICU4J_HOME example: ICU4J_HOME=/home/srl/icu4j +# Path to your icu4j directory. Should contain build.xml +# If not set, will create a 'icu4j' directory in source/tools/genrb/icu4j +# +# 2. The next variable can be set by uncommenting and copying the following line to your Makefile.local.GENDTJAR_JARHOME +# +## GENDTJAR_JARHOME:=$(shell dirname `which jar`) +## (uncomment the above line and copy to Makefile.local) +# +# GENDTJAR_JARHOME is the directory containing the 'jar' binary, such as /usr/bin +# +# +# 3. Now, you can run 'make build-icu4j' from icu/source/data (convenience) +# or icu/source/tools/genrb (this directory) + + +## Source directory information +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ + +top_builddir = ../.. + +include $(top_builddir)/icudefs.mk + +## Build directory information +subdir = tools/genrb + +TARGET_STUB_NAME = genrb +DERB_STUB_NAME = derb + +SECTION = 1 + +MAN_FILES = $(TARGET_STUB_NAME).$(SECTION) $(DERB_STUB_NAME).$(SECTION) + + +## Extra files to remove for 'make clean' +CLEANFILES = *~ $(MAN_FILES) $(DEPS) $(DERB_DEPS) + +## Target information +TARGET = $(BINDIR)/$(TARGET_STUB_NAME)$(EXEEXT) +DERB = $(BINDIR)/$(DERB_STUB_NAME)$(EXEEXT) + +ifneq ($(top_builddir),$(top_srcdir)) +CPPFLAGS += -I$(top_builddir)/common +endif +CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(srcdir)/../toolutil +LIBS = $(LIBICUI18N) $(LIBICUTOOLUTIL) $(LIBICUUC) $(DEFAULT_LIBS) $(LIB_M) + +OBJECTS = errmsg.o genrb.o parse.o read.o reslist.o ustr.o rbutil.o \ +wrtjava.o rle.o wrtxml.o prscmnts.o +DERB_OBJ = derb.o + +DEPS = $(OBJECTS:.o=.d) +DERB_DEPS = $(DERB_OBJ:.o=.d) + +# build-icu4j variables +GENDTJAR_ICUHOME=$(shell pwd)/../../.. +GENDTJAR_OPTS=--icu-root="$(GENDTJAR_ICUHOME)" --jar="$(GENDTJAR_JARHOME)" --icu4j-root="$(ICU4J_HOME)" --verbose +GENDTJAR_TEMP=./temp/ +GENDTJAR=$(srcdir)/gendtjar.pl + +-include Makefile.local + +ifeq (,$(ICU4J_HOME)) +ICU4J_HOME=$(shell pwd)/icu4j +endif + + +## List of phony targets +.PHONY : all all-local install install-local clean clean-local \ +distclean distclean-local dist dist-local check check-local install-man \ +build-icu4j + +## Clear suffix list +.SUFFIXES : + +## List of standard targets +all: all-local +install: install-local +clean: clean-local +distclean : distclean-local +dist: dist-local +check: all check-local + +all-local: $(TARGET) $(DERB) $(MAN_FILES) + +install-local: all-local install-man + $(MKINSTALLDIRS) $(DESTDIR)$(bindir) + $(INSTALL) $(TARGET) $(DESTDIR)$(bindir) + $(INSTALL) $(DERB) $(DESTDIR)$(bindir) + +install-man: $(MAN_FILES) + $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$(SECTION) + $(INSTALL_DATA) $? $(DESTDIR)$(mandir)/man$(SECTION) + +dist-local: + +clean-local: + test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES) + $(RMV) $(TARGET) $(DERB) $(OBJECTS) $(DERB_OBJ) $(GENDTJAR_TEMP) + +distclean-local: clean-local + $(RMV) Makefile + +check-local: all-local + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(TARGET) : $(OBJECTS) + $(LINK.cc) $(OUTOPT)$@ $^ $(LIBS) + $(POST_BUILD_STEP) + +$(DERB) : $(DERB_OBJ) + $(LINK.c) $(OUTOPT)$@ $^ $(LIBS) + $(POST_BUILD_STEP) + +$(GENDTJAR_JARHOME)/jar: + @echo $@ not found - make sure GENDTJAR_JARHOME is set. See Makefile.in + exit 1 + +$(ICU4J_HOME)/build.xml: + @echo warning: $@ not found - make sure ICU4J_HOME is set. + +build-icu4j: $(GENDTJAR) $(ICU4J_HOME)/build.xml $(GENDTJAR_JARHOME)/jar + # clean up old temp files + -$(RMV) $(GENDTJAR_TEMP) + perl $(GENDTJAR) $(GENDTJAR_OPTS) + @echo Finished building to $(ICU4J_HOME) + + +# This line is needed to serialize builds when the gmake -j option is used. +$(TARGET_STUB_NAME).$(SECTION): $(DERB_STUB_NAME).$(SECTION) + +%.$(SECTION): $(srcdir)/%.$(SECTION).in + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +ifeq (,$(MAKECMDGOALS)) +-include $(DEPS) +-include $(DERB_DEPS) +else +ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),) +-include $(DEPS) +endif +endif + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/derb.1.in b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.1.in new file mode 100644 index 00000000000..c981a5b721f --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.1.in @@ -0,0 +1,198 @@ +.\" Hey, Emacs! This is -*-nroff-*- you know... +.\" +.\" derb.1: manual page for the derb utility +.\" +.\" Copyright (C) 2000-2002 IBM, Inc. and others. +.\" +.TH DERB 1 "16 April 2002" "ICU MANPAGE" "ICU @VERSION@ Manual" +.SH NAME +.B derb +\- disassemble a resource bundle +.SH SYNOPSIS +.B derb +[ +.BR "\-h\fP, \fB\-?\fP, \fB\-\-help" +] +[ +.BR "\-V\fP, \fB\-\-version" +] +[ +.BR "\-v\fP, \fB\-\-verbose" +] +[ +.BI "\-e\fP, \fB\-\-encoding" " encoding" +] +[ +.BI "\-\-bom" +] +[ +.BI "\-l\fP, \fB\-\-locale" " locale" +] +[ +.BI "\-t\fP, \fB\-\-truncate" " \fR[ \fPsize\fR ]\fP" +] +[ +.BI "\-s\fP, \fB\-\-sourcedir" " source" +] +[ +.BI "\-d\fP, \fB\-\-destdir" " destination" +] +[ +.BI "\-i\fP, \fB\-\-icudatadir" " directory" +] +[ +.BI "\-c\fP, \fB\-\-to\-stdout" +] +.IR bundle " \.\.\." +.SH DESCRIPTION +.B derb +reads the compiled resource +.I bundle +files passed on the command line and write them back in text form. +The resulting text files have a +.B .txt +extension while compiled resource bundle source files typically have a +.B .res +extension. +.PP +It is customary to name the resource bundles by their locale name, +i.e. to use a local identifier for the +.I bundle +filename, e.g. +.B ja_JP.res +for Japanese (Japan) data, or +.B root.res +for the root bundle. +This is especially important for +.B derb +since the locale name is not accessible directly from the compiled +resource bundle, and to know which locale to ask for when opening +the bundle. +.B derb +will produce a file whose base name is either the value of the +.BI "\-l\fP, \fB\-\-locale" +option, or the same as the base name of the compiled resource file itself. +If the +.BI "\-\-to\-stdout\fP, \fB\-c\fP" +option is used, however, the text will be written on the standard output. +.SH OPTIONS +.TP +.BR "\-h\fP, \fB\-?\fP, \fB\-\-help" +Print help about usage and exit. +.TP +.BR "\-V\fP, \fB\-\-version" +Print the version of +.B derb +and exit. +.TP +.BR "\-v\fP, \fB\-\-verbose" +Display extra informative messages during execution. +.TP +.BI "\-e\fP, \fB\-\-encoding" " encoding" +Set the encoding used to write output files to +.IR encoding . +The default encoding is the invariant (subset of ASCII or EBCDIC) +codepage for the system (see section +.BR "INVARIANT CHARACTERS" ). +The choice of the encoding does not affect the data, just their +representation. Characters that cannot be represented in the +.I encoding +will be represented using +.BI \eu "hhhh" +escape sequences. +.TP +.BI "\-\-bom" +Write a byte order mark (BOM) at the beginning of the file. +.TP +.BI "\-l\fP, \fB\-\-locale" " locale" +Set the +.I locale +for the resource bundle, which is used both in the generated text and +as the base name of the output file. +.TP +.BI "\-t\fP, \fB\-\-truncate" " \fR[ \fPsize\fR ]\fP" +Truncate individual resources (strings or binary data) to +.I size +bytes. The default if +.I size +is not specified is +.B 80 +bytes. +.TP +.BI "\-s\fP, \fB\-\-sourcedir" " source" +Set the source directory to +.IR source . +The default source directory is the current directory. +If +.B - +is passed for +.IR source , +then the +.I bundle +will be looked for in its default location, specified by +the +.B ICU_DATA +environment variable (or defaulting to +the location set when ICU was built if +.B ICU_DATA +is not set). +.TP +.BI "\-d\fP, \fB\-\-destdir" " destination" +Set the destination directory to +.IR destination . +The default destination directory is specified by the environment variable +.BR ICU_DATA +or is the location set when ICU was built if +.B ICU_DATA +is not set. +.TP +.BI "\-i\fP, \fB\-\-icudatadir" " directory" +Look for any necessary ICU data files in +.IR directory . +For example, when processing collation overrides, the file +.B ucadata.dat +must be located. +The default ICU data directory is specified by the environment variable +.BR ICU_DATA . +.TP +.BI "\-c\fP, \fB\-\-to\-stdout" +Write the disassembled +.I bundle +on standard output instead of into a file. +.SH CAVEATS +When the option +.BI \-\-bom +is used, the character +.B U+FEFF +is written in the destination +.I encoding +regardless of whether it is a Unicode transformation format (UTF) or not. +This option should only be used with an UTF encoding, as byte order marks +are not meaningful for other encodings. +.SH INVARIANT CHARACTERS +The +.B invariant character set +consists of the following set of characters, expressed as a standard POSIX +regular expression: +.BR "[a-z]|[A-Z]|[0-9]|_| |+|-|*|/" . +This is the set which is guaranteed to be available regardless of code page. +.SH ENVIRONMENT +.TP 10 +.B ICU_DATA +Specifies the directory containing ICU data. Defaults to +.BR @thepkgicudatadir@/@PACKAGE@/@VERSION@/ . +Some tools in ICU depend on the presence of the trailing slash. It is thus +important to make sure that it is present if +.B ICU_DATA +is set. +.SH AUTHORS +Vladimir Weinstein +.br +Yves Arrouye +.SH VERSION +1.0 +.SH COPYRIGHT +Copyright (C) 2002 IBM, Inc. and others. +.SH SEE ALSO +.BR genrb (1) + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/derb.c b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.c new file mode 100644 index 00000000000..d63c481193e --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.c @@ -0,0 +1,781 @@ +/* +******************************************************************************* +* +* Copyright (C) 1999-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: derb.c +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2000sep6 +* created by: Vladimir Weinstein as an ICU workshop example +* maintained by: Yves Arrouye <yves@realnames.com> +*/ + +#include "unicode/ucnv.h" +#include "unicode/ustring.h" +#include "unicode/putil.h" + +#include "uresimp.h" +#include "cmemory.h" +#include "cstring.h" +#include "uoptions.h" +#include "toolutil.h" +#include "ustrfmt.h" + +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> + +#if defined(U_WINDOWS) || defined(U_CYGWIN) +#include <io.h> +#include <fcntl.h> +#define USE_FILENO_BINARY_MODE 1 +/* Windows likes to rename Unix-like functions */ +#ifndef fileno +#define fileno _fileno +#endif +#ifndef setmode +#define setmode _setmode +#endif +#ifndef O_BINARY +#define O_BINARY _O_BINARY +#endif +#endif + +#define DERB_VERSION "1.0" + +#define DERB_DEFAULT_TRUNC 80 + +static UConverter *defaultConverter = 0; + +static const int32_t indentsize = 4; +static int32_t truncsize = DERB_DEFAULT_TRUNC; +static UBool trunc = FALSE; + +static const char *getEncodingName(const char *encoding); +static void reportError(const char *pname, UErrorCode *status, const char *when); +static UChar *quotedString(const UChar *string); +static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status); +static void printString(FILE *out, UConverter *converter, const UChar *str, int32_t len); +static void printCString(FILE *out, UConverter *converter, const char *str, int32_t len); +static void printIndent(FILE *out, UConverter *converter, int32_t indent); +static void printHex(FILE *out, UConverter *converter, uint8_t what); + +static UOption options[]={ + UOPTION_HELP_H, + UOPTION_HELP_QUESTION_MARK, +/* 2 */ UOPTION_ENCODING, +/* 3 */ { "to-stdout", NULL, NULL, NULL, 'c', UOPT_NO_ARG, 0 } , +/* 4 */ { "truncate", NULL, NULL, NULL, 't', UOPT_OPTIONAL_ARG, 0 }, +/* 5 */ UOPTION_VERBOSE, +/* 6 */ UOPTION_DESTDIR, +/* 7 */ UOPTION_SOURCEDIR, +/* 8 */ { "bom", NULL, NULL, NULL, 0, UOPT_NO_ARG, 0 }, +/* 9 */ UOPTION_ICUDATADIR, +/* 10 */ UOPTION_VERSION, +/* 11 */ { "suppressAliases", NULL, NULL, NULL, 'A', UOPT_NO_ARG, 0 } +}; + +static UBool verbose = FALSE; +static UBool suppressAliases = FALSE; + +extern int +main(int argc, char* argv[]) { + const char *encoding = NULL; + const char *outputDir = NULL; /* NULL = no output directory, use current */ + const char *inputDir = "."; + int tostdout = 0; + int prbom = 0; + + const char *pname; + + UResourceBundle *bundle = NULL; + UErrorCode status = U_ZERO_ERROR; + int32_t i = 0; + + UConverter *converter; + + const char* arg; + + /* Get the name of tool. */ + pname = uprv_strrchr(*argv, U_FILE_SEP_CHAR); +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (!pname) { + pname = uprv_strrchr(*argv, U_FILE_ALT_SEP_CHAR); + } +#endif + if (!pname) { + pname = *argv; + } else { + ++pname; + } + + /* error handling, printing usage message */ + argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); + + /* error handling, printing usage message */ + if(argc<0) { + fprintf(stderr, + "%s: error in command line argument \"%s\"\n", pname, + argv[-argc]); + } + if(argc<0 || options[0].doesOccur || options[1].doesOccur) { + fprintf(argc < 0 ? stderr : stdout, + "%csage: %s [ -h, -?, --help ] [ -V, --version ]\n" + " [ -v, --verbose ] [ -e, --encoding encoding ] [ --bom ]\n" + " [ -t, --truncate [ size ] ]\n" + " [ -s, --sourcedir source ] [ -d, --destdir destination ]\n" + " [ -i, --icudatadir directory ] [ -c, --to-stdout ]\n" + " [ -A, --suppressAliases]\n" + " bundle ...\n", argc < 0 ? 'u' : 'U', + pname); + return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; + } + + if(options[10].doesOccur) { + fprintf(stderr, + "%s version %s (ICU version %s).\n" + "%s\n", + pname, DERB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING); + return U_ZERO_ERROR; + } + if(options[2].doesOccur) { + encoding = options[2].value; + } + + if (options[3].doesOccur) { + tostdout = 1; + } + + if(options[4].doesOccur) { + trunc = TRUE; + if(options[4].value != NULL) { + truncsize = atoi(options[4].value); /* user defined printable size */ + } else { + truncsize = DERB_DEFAULT_TRUNC; /* we'll use default omitting size */ + } + } else { + trunc = FALSE; + } + + if(options[5].doesOccur) { + verbose = TRUE; + } + + if (options[6].doesOccur) { + outputDir = options[6].value; + } + + if(options[7].doesOccur) { + inputDir = options[7].value; /* we'll use users resources */ + } + + if (options[8].doesOccur) { + prbom = 1; + } + + if (options[9].doesOccur) { + u_setDataDirectory(options[9].value); + } + + if (options[11].doesOccur) { + suppressAliases = TRUE; + } + + converter = ucnv_open(encoding, &status); + if (U_FAILURE(status)) { + fprintf(stderr, "%s: couldn't create %s converter for encoding\n", pname, encoding ? encoding : ucnv_getDefaultName()); + return 2; + } + ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, 0, 0, &status); + if (U_FAILURE(status)) { + fprintf(stderr, "%s: couldn't configure converter for encoding\n", pname); + return 3; + } + + defaultConverter = ucnv_open(0, &status); + if (U_FAILURE(status)) { + fprintf(stderr, "%s: couldn't create %s converter for encoding\n", ucnv_getDefaultName(), pname); + return 2; + } + + for (i = 1; i < argc; ++i) { + static const UChar sp[] = { 0x0020 }; /* " " */ + char infile[4096]; /* XXX Sloppy. */ + char locale[64]; + const char *thename = 0, *p, *q; + UBool fromICUData = FALSE; + + arg = getLongPathname(argv[i]); + + if (verbose) { + printf("processing bundle \"%s\"\n", argv[i]); + } + + p = uprv_strrchr(arg, U_FILE_SEP_CHAR); +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (p == NULL) { + p = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); + } +#endif + if (!p) { + p = arg; + } else { + p++; + } + q = uprv_strrchr(p, '.'); + if (!q) { + for (q = p; *q; ++q) + ; + } + uprv_strncpy(locale, p, q - p); + locale[q - p] = 0; + + if (!(fromICUData = !uprv_strcmp(inputDir, "-"))) { + UBool absfilename = *arg == U_FILE_SEP_CHAR; +#ifdef U_WINDOWS + if (!absfilename) { + absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0]) + && arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR); + } +#endif + if (absfilename) { + thename = arg; + } else { + q = uprv_strrchr(arg, U_FILE_SEP_CHAR); +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (q == NULL) { + q = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); + } +#endif + uprv_strcpy(infile, inputDir); + if(q != NULL) { + uprv_strcat(infile, U_FILE_SEP_STRING); + strncat(infile, arg, q-arg); + } + thename = infile; + } + } + status = U_ZERO_ERROR; + if (thename) { + bundle = ures_openDirect(thename, locale, &status); + } else { + bundle = ures_open(fromICUData ? 0 : inputDir, locale, &status); + } + if (status == U_ZERO_ERROR) { + FILE *out; + + const char *filename = 0; + const char *ext = 0; + + if (!locale || !tostdout) { + filename = uprv_strrchr(arg, U_FILE_SEP_CHAR); + +#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR + if (!filename) { + filename = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR); + } +#endif + if (!filename) { + filename = arg; + } else { + ++filename; + } + ext = uprv_strrchr(arg, '.'); + if (!ext) { + ext = filename + uprv_strlen(filename); + } + } + + if (tostdout) { + out = stdout; +#if defined(U_WINDOWS) || defined(U_CYGWIN) + if (setmode(fileno(out), O_BINARY) == -1) { + fprintf(stderr, "%s: couldn't set standard output to binary mode\n", pname); + return 4; + } +#endif + } else { + char thefile[4096], *tp; + int32_t len; + + if (outputDir) { + uprv_strcpy(thefile, outputDir); + uprv_strcat(thefile, U_FILE_SEP_STRING); + } else { + *thefile = 0; + } + uprv_strcat(thefile, filename); + tp = thefile + uprv_strlen(thefile); + len = (int32_t)uprv_strlen(ext); + if (len) { + tp -= len - 1; + } else { + *tp++ = '.'; + } + uprv_strcpy(tp, "txt"); + + out = fopen(thefile, "w"); + if (!out) { + fprintf(stderr, "%s: couldn't create %s\n", pname, thefile); + return 4; + } + } + + if (prbom) { /* XXX: Should be done only for UTFs */ + static const UChar bom[] = { 0xFEFF }; + printString(out, converter, bom, (int32_t)(sizeof(bom)/sizeof(*bom))); + } + + printCString(out, converter, "// -*- Coding: ", -1); + printCString(out, converter, encoding ? encoding : getEncodingName(ucnv_getDefaultName()), -1); + printCString(out, converter, "; -*-\n//\n", -1); + printCString(out, converter, "// This file was dumped by derb(8) from ", -1); + if (thename) { + printCString(out, converter, thename, -1); + } else if (fromICUData) { + printCString(out, converter, "the ICU internal ", -1); + printCString(out, converter, locale, -1); + printCString(out, converter, " locale", -1); + } + + printCString(out, converter, "\n// derb(8) by Vladimir Weinstein and Yves Arrouye\n\n", -1); + + if (locale) { + printCString(out, converter, locale, -1); + } else { + printCString(out, converter, filename, (int32_t)(ext - filename)); + printString(out, converter, sp, (int32_t)(sizeof(sp)/sizeof(*sp))); + } + printOutBundle(out, converter, bundle, 0, pname, &status); + + if (out != stdout) { + fclose(out); + } + } + else { + reportError(pname, &status, "opening resource file"); + } + + ures_close(bundle); + } + + ucnv_close(defaultConverter); + ucnv_close(converter); + + return 0; +} + +static UChar *quotedString(const UChar *string) { + int len = u_strlen(string); + int alen = len; + const UChar *sp; + UChar *newstr, *np; + + for (sp = string; *sp; ++sp) { + switch (*sp) { + case '\n': + case 0x0022: + ++alen; + break; + } + } + + newstr = (UChar *) uprv_malloc((1 + alen) * sizeof(*newstr)); + for (sp = string, np = newstr; *sp; ++sp) { + switch (*sp) { + case '\n': + *np++ = 0x005C; + *np++ = 0x006E; + break; + + case 0x0022: + *np++ = 0x005C; + + default: + *np++ = *sp; + break; + } + } + *np = 0; + + return newstr; +} + + +static void printString(FILE *out, UConverter *converter, const UChar *str, int32_t len) { + char buf[256]; + const UChar *strEnd; + + if (len < 0) { + len = u_strlen(str); + } + strEnd = str + len; + + do { + UErrorCode err = U_ZERO_ERROR; + char *bufp = buf, *bufend = buf + sizeof(buf) - 1 ; + + ucnv_fromUnicode(converter, &bufp, bufend, &str, strEnd, 0, 0, &err); + *bufp = 0; + + fprintf(out, "%s", buf); + } while (str < strEnd); +} + +static void printCString(FILE *out, UConverter *converter, const char *str, int32_t len) { + UChar buf[256]; + const char *strEnd; + + if (len < 0) { + len = (int32_t)uprv_strlen(str); + } + strEnd = str + len; + + do { + UErrorCode err = U_ZERO_ERROR; + UChar *bufp = buf, *bufend = buf + (sizeof(buf)/sizeof(buf[0])) - 1 ; + + ucnv_toUnicode(defaultConverter, &bufp, bufend, &str, strEnd, 0, 0, &err); + *bufp = 0; + + printString(out, converter, buf, (int32_t)(bufp - buf)); + } while (str < strEnd); +} + +static void printIndent(FILE *out, UConverter *converter, int32_t indent) { + UChar inchar[256]; + int32_t i = 0; + for(i = 0; i<indent; i++) { + inchar[i] = 0x0020; + } + inchar[indent] = 0; + + printString(out, converter, inchar, indent); +} + +static void printHex(FILE *out, UConverter *converter, uint8_t what) { + static const char map[] = "0123456789ABCDEF"; + UChar hex[2]; + + hex[0] = map[what >> 4]; + hex[1] = map[what & 0xf]; + + printString(out, converter, hex, (int32_t)(sizeof(hex)/sizeof(*hex))); +} +static const UChar * +derb_getString(const ResourceData *pResData, const Resource res, int32_t *pLength) { + if(res!=RES_BOGUS) { + int32_t *p=(int32_t *)RES_GET_POINTER(pResData->pRoot, res); + if (pLength) { + *pLength=*p; + } + return (UChar *)++p; + } else { + if (pLength) { + *pLength=0; + } + return NULL; + } +} + +static const char * +derb_getTableKey(const Resource *pRoot, const Resource res, uint16_t indexS) { + uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); + if(indexS<*p) { + return ((const char *)(pRoot)+(p[indexS+1])); /*RES_GET_KEY(pRoot, p[indexS+1]);*/ + } else { + return NULL; /* indexS>itemCount */ + } +} + +static Resource +derb_getArrayItem(Resource *pRoot, Resource res, int32_t indexR) { + int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res); + if(indexR<*p) { + return ((Resource *)(p))[1+indexR]; + } else { + return RES_BOGUS; /* indexR>itemCount */ + } +} + +static Resource +derb_getTableItem(const Resource *pRoot, const Resource res, uint16_t indexR) { + uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); + uint16_t count=*p; + if(indexR<count) { + return ((Resource *)(p+1+count+(~count&1)))[indexR]; + } else { + return RES_BOGUS; /* indexR>itemCount */ + } +} + + +static void printOutAlias(FILE *out, UConverter *converter, UResourceBundle *parent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode *status) { + static const UChar cr[] = { '\n' }; + int32_t len = 0; + const UChar* thestr = derb_getString(&(parent->fResData), r, &len); + UChar *string = quotedString(thestr); + if(trunc && len > truncsize) { + char msg[128]; + printIndent(out, converter, indent); + sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", + (long)len, (long)truncsize/2); + printCString(out, converter, msg, -1); + len = truncsize; + } + if(U_SUCCESS(*status)) { + static const UChar openStr[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061, 0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */ + static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "\" } " */ + printIndent(out, converter, indent); + if(key != NULL) { + printCString(out, converter, key, -1); + } + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + printString(out, converter, string, len); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + if(verbose) { + printCString(out, converter, " // ALIAS", -1); + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + } else { + reportError(pname, status, "getting binary value"); + } +} + +static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status) +{ + static const UChar cr[] = { '\n' }; + +/* int32_t noOfElements = ures_getSize(resource);*/ + int32_t i = 0; + const char *key = ures_getKey(resource); + + switch(ures_getType(resource)) { + case RES_STRING : + { + int32_t len=0; + const UChar* thestr = ures_getString(resource, &len, status); + UChar *string = quotedString(thestr); + + /* TODO: String truncation */ + if(trunc && len > truncsize) { + char msg[128]; + printIndent(out, converter, indent); + sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", + (long)len, (long)(truncsize/2)); + printCString(out, converter, msg, -1); + len = truncsize/2; + } + printIndent(out, converter, indent); + if(key != NULL) { + static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */ + static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */ + printCString(out, converter, key, (int32_t)uprv_strlen(key)); + printString(out, converter, openStr, (int32_t)(sizeof(openStr)/sizeof(*openStr))); + printString(out, converter, string, len); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + } else { + static const UChar openStr[] = { 0x0022 }; /* "\"" */ + static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */ + + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + printString(out, converter, string, (int32_t)(u_strlen(string))); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + } + + if(verbose) { + printCString(out, converter, "// STRING", -1); + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + + uprv_free(string); + } + break; + + case RES_INT : + { + static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */ + static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */ + UChar num[20]; + + printIndent(out, converter, indent); + if(key != NULL) { + printCString(out, converter, key, -1); + } + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + uprv_itou(num, 20, ures_getInt(resource, status), 10, 0); + printString(out, converter, num, u_strlen(num)); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + + if(verbose) { + printCString(out, converter, "// INT", -1); + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + break; + } + case RES_BINARY : + { + int32_t len = 0; + const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status); + if(trunc && len > truncsize) { + char msg[128]; + printIndent(out, converter, indent); + sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", + (long)len, (long)(truncsize/2)); + printCString(out, converter, msg, -1); + len = truncsize; + } + if(U_SUCCESS(*status)) { + static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ + static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ + printIndent(out, converter, indent); + if(key != NULL) { + printCString(out, converter, key, -1); + } + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + for(i = 0; i<len; i++) { + printHex(out, converter, *data++); + } + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + if(verbose) { + printCString(out, converter, " // BINARY", -1); + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + } else { + reportError(pname, status, "getting binary value"); + } + } + break; + case RES_INT_VECTOR : + { + int32_t len = 0; + const int32_t *data = ures_getIntVector(resource, &len, status); + if(U_SUCCESS(*status)) { + static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */ + static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ + UChar num[20]; + + printIndent(out, converter, indent); + if(key != NULL) { + printCString(out, converter, key, -1); + } + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + for(i = 0; i < len - 1; i++) { + int32_t numLen = uprv_itou(num, 20, data[i], 10, 0); + num[numLen++] = 0x002C; /* ',' */ + num[numLen++] = 0x0020; /* ' ' */ + num[numLen] = 0; + printString(out, converter, num, u_strlen(num)); + } + if(len > 0) { + uprv_itou(num, 20, data[len - 1], 10, 0); + printString(out, converter, num, u_strlen(num)); + } + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + if(verbose) { + printCString(out, converter, "// INTVECTOR", -1); + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + } else { + reportError(pname, status, "getting int vector"); + } + } + break; + case RES_TABLE : + case RES_ARRAY : + { + static const UChar openStr[] = { 0x007B }; /* "{" */ + static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */ + + UResourceBundle *t = NULL; + ures_resetIterator(resource); + printIndent(out, converter, indent); + if(key != NULL) { + printCString(out, converter, key, -1); + } + printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); + if(verbose) { + if(ures_getType(resource) == RES_TABLE) { + printCString(out, converter, "// TABLE", -1); + } else { + printCString(out, converter, "// ARRAY", -1); + } + } + printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); + + if(suppressAliases == FALSE) { + while(U_SUCCESS(*status) && ures_hasNext(resource)) { + t = ures_getNextResource(resource, t, status); + if(U_SUCCESS(*status)) { + printOutBundle(out, converter, t, indent+indentsize, pname, status); + } else { + reportError(pname, status, "While processing table"); + *status = U_ZERO_ERROR; + } + } + } else { /* we have to use low level access to do this */ + Resource r = RES_BOGUS; + for(i = 0; i < ures_getSize(resource); i++) { + /* need to know if it's an alias */ + if(ures_getType(resource) == RES_TABLE) { + r = derb_getTableItem(resource->fResData.pRoot, resource->fRes, (int16_t)i); + key = derb_getTableKey(resource->fResData.pRoot, resource->fRes, (int16_t)i); + } else { + r = derb_getArrayItem(resource->fResData.pRoot, resource->fRes, i); + } + if(U_SUCCESS(*status)) { + if(RES_GET_TYPE(r) == RES_ALIAS) { + printOutAlias(out, converter, resource, r, key, indent+indentsize, pname, status); + } else { + t = ures_getByIndex(resource, i, t, status); + printOutBundle(out, converter, t, indent+indentsize, pname, status); + } + } else { + reportError(pname, status, "While processing table"); + *status = U_ZERO_ERROR; + } + } + } + + printIndent(out, converter, indent); + printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); + ures_close(t); + } + break; + default: + break; + } + +} + +static const char *getEncodingName(const char *encoding) { + UErrorCode err; + const char *enc; + + err = U_ZERO_ERROR; + if (!(enc = ucnv_getStandardName(encoding, "MIME", &err))) { + err = U_ZERO_ERROR; + if (!(enc = ucnv_getStandardName(encoding, "IANA", &err))) { + ; + } + } + + return enc; +} + +static void reportError(const char *pname, UErrorCode *status, const char *when) { + fprintf(stderr, "%s: error %d while %s: %s\n", pname, *status, when, u_errorName(*status)); +} + +/* + * Local Variables: + * indent-tabs-mode: nil + * End: + */ + + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/derb.vcproj b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.vcproj new file mode 100644 index 00000000000..0a779c22bba --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/derb.vcproj @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="derb" + ProjectGUID="{D3065ADB-8820-4CC7-9B6C-9510833961A3}" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory=".\derb_Win32_Release" + IntermediateDirectory=".\derb_Win32_Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="copy "$(TargetPath)" ..\..\..\bin
" + Outputs="..\..\..\bin\$(TargetFileName)" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="NDEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName=".\derb_Win32_Release/derb.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\common;..\toolutil" + PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE" + StringPooling="true" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + PrecompiledHeaderFile=".\derb_Win32_Release/derb.pch" + AssemblerListingLocation=".\derb_Win32_Release/" + ObjectFile=".\derb_Win32_Release/" + ProgramDataBaseFileName=".\derb_Win32_Release/" + WarningLevel="3" + SuppressStartupBanner="true" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile=".\derb_Win32_Release/derb.exe" + LinkIncremental="1" + SuppressStartupBanner="true" + ProgramDatabaseFile=".\derb_Win32_Release/derb.pdb" + SubSystem="1" + OptimizeForWindows98="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\derb_Win32_Debug" + IntermediateDirectory=".\derb_Win32_Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="copy "$(TargetPath)" ..\..\..\bin
" + Outputs="..\..\..\bin\$(TargetFileName)" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName=".\derb_Win32_Debug/derb.tlb" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\common;..\toolutil" + PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + PrecompiledHeaderFile=".\derb_Win32_Debug/derb.pch" + AssemblerListingLocation=".\derb_Win32_Debug/" + ObjectFile=".\derb_Win32_Debug/" + ProgramDataBaseFileName=".\derb_Win32_Debug/" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="4" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile=".\derb_Win32_Debug/derb.exe" + LinkIncremental="2" + SuppressStartupBanner="true" + GenerateDebugInformation="true" + ProgramDatabaseFile=".\derb_Win32_Debug/derb.pdb" + SubSystem="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + UseFAT32Workaround="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath=".\derb.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.c b/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.c new file mode 100644 index 00000000000..8b47f261a32 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.c @@ -0,0 +1,72 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2004, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File error.c +* +* Modification History: +* +* Date Name Description +* 05/28/99 stephen Creation. +******************************************************************************* +*/ + +#include <stdarg.h> +#include <stdio.h> +#include "cstring.h" +#include "errmsg.h" + +void error(uint32_t linenumber, const char *msg, ...) +{ + va_list va; + + va_start(va, msg); + fprintf(stderr, "%s:%u: ", gCurrentFileName, (int)linenumber); + vfprintf(stderr, msg, va); + fprintf(stderr, "\n"); + va_end(va); +} + +static UBool gShowWarning = TRUE; + +void setShowWarning(UBool val) +{ + gShowWarning = val; +} + +UBool getShowWarning(){ + return gShowWarning; +} + +static UBool gStrict =FALSE; +UBool isStrict(){ + return gStrict; +} +void setStrict(UBool val){ + gStrict = val; +} +static UBool gVerbose =FALSE; +UBool isVerbose(){ + return gVerbose; +} +void setVerbose(UBool val){ + gVerbose = val; +} +void warning(uint32_t linenumber, const char *msg, ...) +{ + if (gShowWarning) + { + va_list va; + + va_start(va, msg); + fprintf(stderr, "%s:%u: warning: ", gCurrentFileName, (int)linenumber); + vfprintf(stderr, msg, va); + fprintf(stderr, "\n"); + va_end(va); + } +} + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.h b/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.h new file mode 100644 index 00000000000..dbb8c66ffeb --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/errmsg.h @@ -0,0 +1,38 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-1999, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File error.h +* +* Modification History: +* +* Date Name Description +* 05/28/99 stephen Creation. +******************************************************************************* +*/ + +#ifndef ERROR_H +#define ERROR_H 1 + +extern const char *gCurrentFileName; + +void error (uint32_t linenumber, const char *msg, ...); +void warning (uint32_t linenumber, const char *msg, ...); + + +/* Show warnings? */ +U_CFUNC void setShowWarning(UBool val); +U_CFUNC UBool getShowWarning(void); + +/* strict */ +U_CFUNC void setStrict(UBool val); +U_CFUNC UBool isStrict(void); + +/* verbosity */ +U_CFUNC void setVerbose(UBool val); +U_CFUNC UBool isVerbose(void); +#endif diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/gendtjar.pl b/Build/source/libs/icu/icu-xetex/tools/genrb/gendtjar.pl new file mode 100755 index 00000000000..8f9a552d382 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/gendtjar.pl @@ -0,0 +1,376 @@ +#!/usr/bin/perl +# ******************************************************************** +# * COPYRIGHT: +# * Copyright (c) 2002-2007, International Business Machines Corporation and +# * others. All Rights Reserved. +# ******************************************************************** + +# Script to generate the icudata.jar and testdata.jar files. This file is +# part of icu4j. It is checked into CVS. It is generated from +# locale data in the icu4c project. See usage() notes (below) +# for more information. + +# This script requires perl. For Win32, I recommend www.activestate.com. + +# Ram Viswanadha +# copied heavily from genrbjar.pl +use File::Find; +use File::Basename; +use IO::File; +use Cwd; +use File::Copy; +use Getopt::Long; +use File::Path; +use File::Copy; +use Cwd; +use Cwd 'abs_path'; + +main(); + +#------------------------------------------------------------------ +sub main(){ + + GetOptions( + "--icu-root=s" => \$icuRootDir, + "--jar=s" => \$jarDir, + "--icu4j-root=s" => \$icu4jDir, + "--version=s" => \$version, + "--verbose" => \$verbose, + "--help" => \$help + ); + $cwd = abs_path(getcwd); + + if($help){ + usage(); + } + unless (defined $icuRootDir){ + $icuRootDir =abs_path($cwd."/../../.."); + } + unless (defined $icu4jDir){ + $icu4jDir =abs_path($icuRootDir."/../icu4j"); + } + unless (defined $jarDir){ + if(defined $ENV{'JAVA_HOME'}){ + $jarDir=$ENV{'JAVA_HOME'}."/bin"; + }else{ + print("ERROR: JAVA_HOME enviroment variable undefined and --jar argument not specifed.\n"); + usage(); + } + } + + $platform = getPlatform(); + $icuBinDir = $icuRootDir; + + $path=$ENV{'PATH'}; + + if(($platform eq "cygwin") || ($platform eq "linux")){ + $icuBinDir .= "/source/bin"; + $icuLibDir = abs_path($icuBinDir."/../lib"); + $path .=":$icuBinDir:$icuLibDir"; + + $libpath = $ENV{'LD_LIBRARY_PATH'}.":$icuLibDir"; + $ENV{'LD_LIBRARY_PATH'} = $libpath; + + #print ("##### LD_LIBRARY_PATH = $ENV{'LD_LIBRARY_PATH'}\n"); + + }elsif($platform eq "aix"){ + + $icuBinDir .= "/source/bin"; + $icuLibDir = abs_path($icuBinDir."/../lib"); + $path .=":$icuBinDir:$icuLibDir"; + + $libpath = $ENV{'LIBPATH'}.":$icuLibDir"; + $ENV{'LIBPATH'} = $libpath; + #print ("##### LIBPATH = $ENV{'LIBPATH'}\n"); + }elsif($platform eq "darwin"){ + $icuBinDir .= "/source/bin"; + $icuLibDir = abs_path($icuBinDir."/../lib"); + $path .=":$icuBinDir:$icuLibDir"; + + $libpath = $ENV{'DYLD_LIBRARY_PATH'}.":$icuLibDir"; + $ENV{'DYLD_LIBRARY_PATH'} = $libpath; + + }elsif($platform eq "MSWin32"){ + $icuBinDir =$icuRootDir."/bin"; + $path .=$icuBinDir; + + } + $ENV{'PATH'} = $path; + #print ("##### PATH = $ENV{'PATH'}\n"); + # TODO add more platforms and test on Linux and Unix + + $icuBuildDir =$icuRootDir."/source/data/out/build"; + $icuTestDataSrcDir =$icuRootDir."/source/test/testdata/"; + $icuTestDataDir =$icuRootDir."/source/test/testdata/out/build/"; + + # now build ICU + buildICU($platform, $icuRootDir, $icuTestDataDir, $verbose); + + #figure out the version and endianess + unless (defined $version){ + ($version, $endian) = getVersion(); + #print "#################### $version, $endian ######\n"; + } + + $icupkg = $icuBinDir."/icupkg -tb"; + $tempDir = $cwd."/temp"; + $version =~ s/\.//; + $icu4jImpl = "com/ibm/icu/impl/data/"; + $icu4jDataDir = $icu4jImpl."icudt".$version."b"; + $icu4jDevDataDir = "com/ibm/icu/dev/data/"; + $icu4jTestDataDir = "$icu4jDevDataDir/testdata"; + + $icuDataDir =$icuBuildDir."/icudt".$version.checkPlatformEndianess(); + + #remove the stale directories + unlink($tempDir); + + convertData($icuDataDir, $icupkg, $tempDir, $icu4jDataDir, $verbose); + #convertData($icuDataDir."/coll/", $icupkg, $tempDir, $icu4jDataDir."/coll"); + createJar("\"$jarDir/jar\"", "icudata.jar", $tempDir, $icu4jDataDir, $verbose); + + convertTestData($icuTestDataDir, $icupkg, $tempDir, $icu4jTestDataDir, $verbose); + createJar("\"$jarDir/jar\"", "testdata.jar", $tempDir, $icu4jTestDataDir, $verbose); + copyData($icu4jDir, $icu4jImpl, $icu4jDevDataDir, $tempDir, $verbose); +} + +#----------------------------------------------------------------------- +sub buildICU{ + local($platform, $icuRootDir, $icuTestDataDir, $verbose) = @_; + $icuSrcDir = $icuRootDir."/source"; + $icuSrcDataDir = $icuSrcDir."/data"; + + chdir($icuSrcDir); + # clean the data directories + unlink($icuBuildDir."../"); + unlink($icuTestDataDir."../"); + + if(($platform eq "cygwin")||($platform eq "darwin")||($platform eq "linux")){ + + # make all in ICU + cmd("make all", $verbose); + chdir($icuSrcDataDir); + cmd("make uni-core-data", $verbose); + if(chdir($icuTestDataSrcDir)){ + print("Invoking make in directory $icuTestDataSrcDir\n"); + cmd("make JAVA_OUT_DIR=\"$icu4jDir/src/com/ibm/icu/dev/test/util/\" all java-output", $verbose); + }else{ + die "Could not cd to $icuTestDataSrcDir\n"; + } + }elsif($platform eq "aix"){ + # make all in ICU + cmd("gmake all", $verbose); + chdir($icuSrcDataDir); + cmd("gmake uni-core-data", $verbose); + chdir($icuTestDataDir."../../"); + cmd("gmake JAVA_OUT_DIR=\"$icu4jDir/src/com/ibm/icu/dev/test/util/\" all java-output", $verbose); + }elsif($platform eq "MSWin32"){ + #devenv.com $projectFileName \/build $configurationName > \"$cLogFile\" 2>&1 + cmd("devenv.com allinone/allinone.sln /useenv /build Debug", $verbose); + # build required data. this is required coz building icu will not build all the data + chdir($icuSrcDataDir); + cmd("NMAKE /f makedata.mak ICUMAKE=\"$icuSrcDataDir\" CFG=debug uni-core-data", $verbose); + print "WARNING: Don't know how to build java-output on $platform. \n"; + }else{ + print "ERROR: Could not build ICU unknown platform $platform. \n"; + exit(-1); + } + + chdir($cwd); +} +#----------------------------------------------------------------------- +sub getVersion{ + my @list; + opendir(DIR,$icuBuildDir); + + @list = readdir(DIR); + closedir(DIR); + + if(scalar(@list)>3){ + print("ERROR: More than 1 directory in build. Can't decide the version"); + exit(-1); + } + foreach $item (@list){ + next if($item eq "." || $item eq ".."); + my ($ver, $end) =$item =~ m/icudt(.*)(l|b|e)$/; + return $ver,$end; + } +} + +#----------------------------------------------------------------------- +sub getPlatform{ + $platform = $^O; + return $platform; +} +#----------------------------------------------------------------------- +sub createJar{ + local($jar, $jarFile, $tempDir, $dirToJar, $verbose) = @_; + chdir($tempDir); + $command=""; + print "INFO: Creating $jarFile\n"; + if($platform eq "cygwin") { + $jar = `cygpath -au $jar`; + chop($jar); + $tempDir = `cygpath -aw $tempDir`; + chop($tempDir); + $tempDir =~ s/\\/\\\\/g; + } + if(defined $verbose){ + $command = "$jar cvf $jarFile -C $tempDir $dirToJar"; + }else{ + $command = "$jar cf $jarFile -C $tempDir $dirToJar"; + } + cmd($command, $verbose); +} +#----------------------------------------------------------------------- +sub checkPlatformEndianess { + my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/; + if ($is_big_endian) { + return "b"; + }else{ + return "l"; + } +} +#----------------------------------------------------------------------- +sub copyData{ + local($icu4jDir, $icu4jImpl, $icu4jDevDataDir, $tempDir) =@_; + print("INFO: Copying $tempDir/icudata.jar to $icu4jDir/src/$icu4jImpl\n"); + mkpath("$icu4jDir/src/$icu4jImpl"); + copy("$tempDir/icudata.jar", "$icu4jDir/src/$icu4jImpl"); + print("INFO: Copying $tempDir/testdata.jar $icu4jDir/src/$icu4jDevDataDir\n"); + mkpath("$icu4jDir/src/$icu4jDevDataDir"); + copy("$tempDir/testdata.jar","$icu4jDir/src/$icu4jDevDataDir"); +} +#----------------------------------------------------------------------- +sub convertData{ + local($icuDataDir, $icupkg, $tempDir, $icu4jDataDir) =@_; + my $dir = $tempDir."/".$icu4jDataDir; + # create the temp directory + mkpath($dir) ; + # cd to the temp directory + chdir($tempDir); + my $endian = checkPlatformEndianess(); + my @list; + opendir(DIR,$icuDataDir); + #print $icuDataDir; + @list = readdir(DIR); + closedir(DIR); + my $op = $icupkg; + #print "####### $endian ############\n"; + if($endian eq "l"){ + print "INFO: {Command: $op $icuDataDir/*.*}\n"; + }else{ + print "INFO: {Command: copy($icuDataDir/*.*, $tempDir/$icu4jDataDir/*)}\n"; + } + + $i=0; + # now convert + foreach $item (@list){ + next if($item eq "." || $item eq ".."); + # next if($item =~ /^t_.*$\.res/ ||$item =~ /^translit_.*$\.res/ || + # $item=~/$\.crs/ || $item=~ /$\.txt/ || + # $item=~/icudata\.res/ || $item=~/$\.exp/ || $item=~/$\.lib/ || + # $item=~/$\.obj/ || $item=~/$\.lst/); + next if($item =~ /^t_.*$\.res/ ||$item =~ /^translit_.*$\.res/ || + $item=~/$\.crs/ || $item=~ /$\.txt/ || + $item=~/icudata\.res/ || $item=~/$\.exp/ || $item=~/$\.lib/ || $item=~/$\.obj/ || + $item=~/$\.lst/); + if(-d "$icuDataDir/$item"){ + convertData("$icuDataDir/$item/", $icupkg, $tempDir, "$icu4jDataDir/$item/"); + next; + } + if($endian eq "l"){ + $command = $icupkg." $icuDataDir/$item $tempDir/$icu4jDataDir/$item"; + cmd($command, $verbose); + }else{ + $rc = copy("$icuDataDir/$item", "$tempDir/$icu4jDataDir/$item"); + if($rc==1){ + #die "ERROR: Could not copy $icuDataDir/$item to $tempDir/$icu4jDataDir/$item, $!"; + } + } + + } + chdir(".."); + print "INFO: DONE\n"; +} +#----------------------------------------------------------------------- +sub convertTestData{ + local($icuDataDir, $icupkg, $tempDir, $icu4jDataDir) =@_; + my $dir = $tempDir."/".$icu4jDataDir; + # create the temp directory + mkpath($dir); + # cd to the temp directory + chdir($tempDir); + my $op = $icupkg; + print "INFO: {Command: $op $icuDataDir/*.*}\n"; + my @list; + opendir(DIR,$icuDataDir) or die "ERROR: Could not open the $icuDataDir directory for reading $!"; + #print $icuDataDir; + @list = readdir(DIR); + closedir(DIR); + my $endian = checkPlatformEndianess(); + $i=0; + # now convert + foreach $item (@list){ + next if($item eq "." || $item eq ".."); + next if( item=~/$\.crs/ || $item=~ /$\.txt/ || + $item=~/$\.exp/ || $item=~/$\.lib/ || $item=~/$\.obj/ || + $item=~/$\.mak/ || $item=~/test\.icu/ || $item=~/$\.lst/); + $file = $item; + $file =~ s/testdata_//g; + if($endian eq "l"){ + $command = "$icupkg $icuDataDir/$item $tempDir/$icu4jDataDir/$file"; + cmd($command, $verbose); + }else{ + #print("Copying $icuDataDir/$item $tempDir/$icu4jDataDir/$file\n"); + copy("$icuDataDir/$item", "$tempDir/$icu4jDataDir/$file"); + } + + + } + chdir(".."); + print "INFO: DONE\n"; +} +#------------------------------------------------------------------------------------------------ +sub cmd { + my $cmd = shift; + my $verbose = shift; + my $prompt = shift; + + $prompt = "Command: $cmd.." unless ($prompt); + if(defined $verbose){ + print $prompt."\n"; + } + system($cmd); + my $exit_value = $? >> 8; + #my $signal_num = $? & 127; + #my $dumped_core = $? & 128; + if ($exit_value == 0) { + if(defined $verbose){ + print "ok\n"; + } + } else { + ++$errCount; + print "ERROR: Execution of $prompt returned ($exit_value)\n"; + exit(1); + } +} +#----------------------------------------------------------------------- +sub usage { + print << "END"; +Usage: +gendtjar.pl +Options: + --icu-root=<directory where icu4c lives> + --jar=<directory where jar.exe lives> + --icu4j-root=<directory> + --version=<ICU4C version> + --verbose + --help +e.g: +gendtjar.pl --icu-root=\\work\\icu --jar=\\jdk1.4.1\\bin --icu4j-root=\\work\\icu4j --version=3.0 +END + exit(0); +} + + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.1.in b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.1.in new file mode 100644 index 00000000000..b636bd93650 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.1.in @@ -0,0 +1,146 @@ +.\" Hey, Emacs! This is -*-nroff-*- you know... +.\" +.\" genrb.1: manual page for the genrb utility +.\" +.\" Copyright (C) 2000-2002 IBM, Inc. and others. +.\" +.\" Manual page by Yves Arrouye <yves@realnames.com>. +.\" +.TH GENRB 1 "16 April 2002" "ICU MANPAGE" "ICU @VERSION@ Manual" +.SH NAME +.B genrb +\- compile a resource bundle +.SH SYNOPSIS +.B genrb +[ +.BR "\-h\fP, \fB\-?\fP, \fB\-\-help" +] +[ +.BR "\-V\fP, \fB\-\-version" +] +[ +.BR "\-v\fP, \fB\-\-verbose" +] +[ +.BI "\-e\fP, \fB\-\-encoding" " encoding" +] +[ +.BI "\-j\fP, \fB\-\-write\-java" " \fR[ \fPencoding\fR ]\fP" +] +[ +.BI "\-s\fP, \fB\-\-sourcedir" " source" +] +[ +.BI "\-d\fP, \fB\-\-destdir" " destination" +] +[ +.BI "\-i\fP, \fB\-\-icudatadir" " directory" +] +.IR bundle " \.\.\." +.SH DESCRIPTION +.B genrb +converts the resource +.I bundle +source files passed on the command line to their binary form or to +a Java source file for use with ICU4J. +The resulting binary files have a +.B .res +extension while resource bundle source files typically have a +.B .txt +extension. Java source files have a +.B java +extension and follow the ICU4J naming conventions. +.PP +It is customary to name the resource bundles by their locale name, +i.e. to use a local identifier for the +.I bundle +filename, e.g. +.B ja_JP.txt +for Japanese (Japan) data, or +.B root.txt +for the root bundle. +In any case, +.B genrb +will produce a file whose base name is the name of the locale found +in the resource file, not the base name of the resource file itself. +.PP +The binary files can be read directly by ICU, or used by +.BR pkgdata (1) +for incorporation into a larger archive or library. +.SH OPTIONS +.TP +.BR "\-h\fP, \fB\-?\fP, \fB\-\-help" +Print help about usage and exit. +.TP +.BR "\-V\fP, \fB\-\-version" +Print the version of +.B genrb +and exit. +.TP +.BR "\-v\fP, \fB\-\-verbose" +Display extra informative messages during execution. +.TP +.BI "\-e\fP, \fB\-\-encoding" " encoding" +Set the encoding used to read input files to +.IR encoding . +The default encoding is the invariant (subset of ASCII or EBCDIC) +codepage for the system (see section +.BR "INVARIANT CHARACTERS" ). +The encodings UTF-8, UTF-16BE, and UTF-16LE are automatically detected +if a byte order mark (BOM) is present. +.TP +.BI "\-j\fP, \fB\-\-write\-java" " \fR[ \fPencoding\fR ]\fP" +Generate a Java source code for use with ICU4J. An optional +.I encoding +for the Java file can be given. +.TP +.BI "\-s\fP, \fB\-\-sourcedir" " source" +Set the source directory to +.IR source . +The default source directory is specified by the environment variable +.BR ICU_DATA , +or the location set when ICU was built if +.B ICU_DATA +is not set. +.TP +.BI "\-d\fP, \fB\-\-destdir" " destination" +Set the destination directory to +.IR destination . +The default destination directory is specified by the environment variable +.BR ICU_DATA +or is the location set when ICU was built if +.B ICU_DATA +is not set. +.TP +.BI "\-i\fP, \fB\-\-icudatadir" " directory" +Look for any necessary ICU data files in +.IR directory . +For example, when processing collation overrides, the file +.B ucadata.dat +must be located. +The default ICU data directory is specified by the environment variable +.BR ICU_DATA . +.SH INVARIANT CHARACTERS +The +.B invariant character set +consists of the following set of characters, expressed as a standard POSIX +regular expression: +.BR "[a-z]|[A-Z]|[0-9]|_| |+|-|*|/" . +This is the set which is guaranteed to be available regardless of code page. +.SH ENVIRONMENT +.TP 10 +.B ICU_DATA +Specifies the directory containing ICU data. Defaults to +.BR @thepkgicudatadir@/@PACKAGE@/@VERSION@/ . +Some tools in ICU depend on the presence of the trailing slash. It is thus +important to make sure that it is present if +.B ICU_DATA +is set. +.SH VERSION +@VERSION@ +.SH COPYRIGHT +Copyright (C) 2000-2002 IBM, Inc. and others. +.SH SEE ALSO +.BR derb (1) +.br +.BR pkgdata (1) diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.c b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.c new file mode 100644 index 00000000000..fcf7870f51f --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.c @@ -0,0 +1,517 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File genrb.c +* +* Modification History: +* +* Date Name Description +* 05/25/99 stephen Creation. +* 5/10/01 Ram removed ustdio dependency +******************************************************************************* +*/ + +#include "genrb.h" +#include "unicode/uclean.h" + +/* Protos */ +static void processFile(const char *filename, const char* cp, const char *inputDir, const char *outputDir, const char *packageName, UErrorCode *status); +static char *make_res_filename(const char *filename, const char *outputDir, + const char *packageName, UErrorCode *status); + +/* File suffixes */ +#define RES_SUFFIX ".res" +#define COL_SUFFIX ".col" + +static char theCurrentFileName[2048]; +const char *gCurrentFileName = theCurrentFileName; +#ifdef XP_MAC_CONSOLE +#include <console.h> +#endif + +enum +{ + HELP1, + HELP2, + VERBOSE, + QUIET, + VERSION, + SOURCEDIR, + DESTDIR, + ENCODING, + ICUDATADIR, + WRITE_JAVA, + COPYRIGHT, + PACKAGE_NAME, + BUNDLE_NAME, + WRITE_XLIFF, + STRICT, + NO_BINARY_COLLATION, + /*added by Jing*/ + LANGUAGE +}; + +UOption options[]={ + UOPTION_HELP_H, + UOPTION_HELP_QUESTION_MARK, + UOPTION_VERBOSE, + UOPTION_QUIET, + UOPTION_VERSION, + UOPTION_SOURCEDIR, + UOPTION_DESTDIR, + UOPTION_ENCODING, + UOPTION_ICUDATADIR, + UOPTION_WRITE_JAVA, + UOPTION_COPYRIGHT, + UOPTION_PACKAGE_NAME, + UOPTION_BUNDLE_NAME, + UOPTION_DEF( "write-xliff", 'x', UOPT_OPTIONAL_ARG), + UOPTION_DEF( "strict", 'k', UOPT_NO_ARG), /* 14 */ + UOPTION_DEF( "noBinaryCollation", 'C', UOPT_NO_ARG),/* 15 */ + UOPTION_DEF( "language", 'l', UOPT_REQUIRES_ARG) + }; + +static UBool write_java = FALSE; +static UBool write_xliff = FALSE; +static const char* outputEnc =""; +static const char* gPackageName=NULL; +static const char* bundleName=NULL; +/*added by Jing*/ +static const char* language = NULL; +static const char* xliffOutputFileName = NULL; +int +main(int argc, + char* argv[]) +{ + UErrorCode status = U_ZERO_ERROR; + const char *arg = NULL; + const char *outputDir = NULL; /* NULL = no output directory, use current */ + const char *inputDir = NULL; + const char *encoding = ""; + int i; + + U_MAIN_INIT_ARGS(argc, argv); + + argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])), options); + + /* error handling, printing usage message */ + if(argc<0) { + fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]); + } else if(argc<2) { + argc = -1; + } + + if(options[VERSION].doesOccur) { + fprintf(stderr, + "%s version %s (ICU version %s).\n" + "%s\n", + argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING); + return U_ZERO_ERROR; + } + + if(argc<0 || options[HELP1].doesOccur || options[HELP2].doesOccur) { + /* + * Broken into chucks because the C89 standard says the minimum + * required supported string length is 509 bytes. + */ + fprintf(stderr, + "Usage: %s [OPTIONS] [FILES]\n" + "\tReads the list of resource bundle source files and creates\n" + "\tbinary version of reosurce bundles (.res files)\n", + argv[0]); + fprintf(stderr, + "Options:\n" + "\t-h or -? or --help this usage text\n" + "\t-q or --quiet do not display warnings\n" + "\t-v or --verbose print extra information when processing files\n" + "\t-V or --version prints out version number and exits\n" + "\t-c or --copyright include copyright notice\n"); + fprintf(stderr, + "\t-e or --encoding encoding of source files\n" + "\t-d of --destdir destination directory, followed by the path, defaults to %s\n" + "\t-s or --sourcedir source directory for files followed by path, defaults to %s\n" + "\t-i or --icudatadir directory for locating any needed intermediate data files,\n" + "\t followed by path, defaults to %s\n", + u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory()); + fprintf(stderr, + "\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n" + "\t defaults to ASCII and \\uXXXX format.\n" + "\t-p or --package-name For ICU4J: package name for writing the ListResourceBundle for ICU4J,\n" + "\t defaults to com.ibm.icu.impl.data\n"); + fprintf(stderr, + "\t-b or --bundle-name bundle name for writing the ListResourceBundle for ICU4J,\n" + "\t defaults to LocaleElements\n" + "\t-x or --write-xliff write a XLIFF file for the resource bundle. Followed by an optional output file name.\n" + "\t-k or --strict use pedantic parsing of syntax\n" + /*added by Jing*/ + "\t-l or --language For XLIFF: language code compliant with ISO 639.\n"); + + return argc < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; + } + + if(options[VERBOSE].doesOccur) { + setVerbose(TRUE); + } + + if(options[QUIET].doesOccur) { + setShowWarning(FALSE); + } + if(options[STRICT].doesOccur) { + setStrict(TRUE); + } + if(options[COPYRIGHT].doesOccur){ + setIncludeCopyright(TRUE); + } + + if(options[SOURCEDIR].doesOccur) { + inputDir = options[SOURCEDIR].value; + } + + if(options[DESTDIR].doesOccur) { + outputDir = options[DESTDIR].value; + } + if(options[PACKAGE_NAME].doesOccur) { + gPackageName = options[PACKAGE_NAME].value; + if(!strcmp(gPackageName, "ICUDATA")) + { + gPackageName = U_ICUDATA_NAME; + } + if(gPackageName[0] == 0) + { + gPackageName = NULL; + } + } + + if(options[ENCODING].doesOccur) { + encoding = options[ENCODING].value; + } + + if(options[ICUDATADIR].doesOccur) { + u_setDataDirectory(options[ICUDATADIR].value); + } + /* Initialize ICU */ + u_init(&status); + if (U_FAILURE(status) && status != U_FILE_ACCESS_ERROR) { + /* Note: u_init() will try to open ICU property data. + * failures here are expected when building ICU from scratch. + * ignore them. + */ + fprintf(stderr, "%s: can not initialize ICU. status = %s\n", + argv[0], u_errorName(status)); + exit(1); + } + status = U_ZERO_ERROR; + if(options[WRITE_JAVA].doesOccur) { + write_java = TRUE; + outputEnc = options[WRITE_JAVA].value; + } + + if(options[BUNDLE_NAME].doesOccur) { + bundleName = options[BUNDLE_NAME].value; + } + + if(options[WRITE_XLIFF].doesOccur) { + write_xliff = TRUE; + if(options[WRITE_XLIFF].value != NULL){ + xliffOutputFileName = options[WRITE_XLIFF].value; + } + } + + if(options[NO_BINARY_COLLATION].doesOccur) { + initParser(FALSE); + } else { + initParser(TRUE); + } + + /*added by Jing*/ + if(options[LANGUAGE].doesOccur) { + language = options[LANGUAGE].value; + } + + /* generate the binary files */ + for(i = 1; i < argc; ++i) { + status = U_ZERO_ERROR; + arg = getLongPathname(argv[i]); + + if (inputDir) { + uprv_strcpy(theCurrentFileName, inputDir); + uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING); + } else { + *theCurrentFileName = 0; + } + uprv_strcat(theCurrentFileName, arg); + + if (isVerbose()) { + printf("Processing file \"%s\"\n", theCurrentFileName); + } + processFile(arg, encoding, inputDir, outputDir, gPackageName, &status); + } + + /* Dont return warnings as a failure */ + if (! U_FAILURE(status)) { + return 0; + } + + return status; +} + +/* Process a file */ +static void +processFile(const char *filename, const char *cp, const char *inputDir, const char *outputDir, const char *packageName, UErrorCode *status) { + /*FileStream *in = NULL;*/ + struct SRBRoot *data = NULL; + UCHARBUF *ucbuf = NULL; + char *rbname = NULL; + char *openFileName = NULL; + char *inputDirBuf = NULL; + + char outputFileName[256]; + + int32_t dirlen = 0; + int32_t filelen = 0; + + if (status==NULL || U_FAILURE(*status)) { + return; + } + if(filename==NULL){ + *status=U_ILLEGAL_ARGUMENT_ERROR; + return; + }else{ + filelen = (int32_t)uprv_strlen(filename); + } + if(inputDir == NULL) { + const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR); + openFileName = (char *) uprv_malloc(dirlen + filelen + 2); + openFileName[0] = '\0'; + if (filenameBegin != NULL) { + /* + * When a filename ../../../data/root.txt is specified, + * we presume that the input directory is ../../../data + * This is very important when the resource file includes + * another file, like UCARules.txt or thaidict.brk. + */ + int32_t filenameSize = (int32_t)(filenameBegin - filename + 1); + inputDirBuf = uprv_strncpy((char *)uprv_malloc(filenameSize), filename, filenameSize); + + /* test for NULL */ + if(inputDirBuf == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + inputDirBuf[filenameSize - 1] = 0; + inputDir = inputDirBuf; + dirlen = (int32_t)uprv_strlen(inputDir); + } + }else{ + dirlen = (int32_t)uprv_strlen(inputDir); + + if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { + openFileName = (char *) uprv_malloc(dirlen + filelen + 2); + + /* test for NULL */ + if(openFileName == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + openFileName[0] = '\0'; + /* + * append the input dir to openFileName if the first char in + * filename is not file seperation char and the last char input directory is not '.'. + * This is to support : + * genrb -s. /home/icu/data + * genrb -s. icu/data + * The user cannot mix notations like + * genrb -s. /icu/data --- the absolute path specified. -s redundant + * user should use + * genrb -s. icu/data --- start from CWD and look in icu/data dir + */ + if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){ + uprv_strcpy(openFileName, inputDir); + openFileName[dirlen] = U_FILE_SEP_CHAR; + } + openFileName[dirlen + 1] = '\0'; + } else { + openFileName = (char *) uprv_malloc(dirlen + filelen + 1); + + /* test for NULL */ + if(openFileName == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + uprv_strcpy(openFileName, inputDir); + + } + } + + uprv_strcat(openFileName, filename); + + ucbuf = ucbuf_open(openFileName, &cp,getShowWarning(),TRUE, status); + + if(*status == U_FILE_ACCESS_ERROR) { + + fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filename : openFileName); + goto finish; + } + if (ucbuf == NULL || U_FAILURE(*status)) { + fprintf(stderr, "An error occured processing file %s. Error: %s\n", openFileName == NULL ? filename : openFileName,u_errorName(*status)); + goto finish; + } + /* auto detected popular encodings? */ + if (cp!=NULL && isVerbose()) { + printf("autodetected encoding %s\n", cp); + } + /* Parse the data into an SRBRoot */ + data = parse(ucbuf, inputDir, outputDir, status); + + if (data == NULL || U_FAILURE(*status)) { + fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename,u_errorName(*status)); + goto finish; + } + + /* Determine the target rb filename */ + rbname = make_res_filename(filename, outputDir, packageName, status); + if(U_FAILURE(*status)) { + fprintf(stderr, "couldn't make the res fileName for bundle %s. Error:%s\n", filename,u_errorName(*status)); + goto finish; + } + if(write_java== TRUE){ + bundle_write_java(data,outputDir,outputEnc, outputFileName, sizeof(outputFileName),packageName,bundleName,status); + }else if(write_xliff ==TRUE){ + bundle_write_xml(data,outputDir,outputEnc, filename, outputFileName, sizeof(outputFileName),language, xliffOutputFileName,status); + }else{ + /* Write the data to the file */ + bundle_write(data, outputDir, packageName, outputFileName, sizeof(outputFileName), status); + } + if (U_FAILURE(*status)) { + fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName,u_errorName(*status)); + } + bundle_close(data, status); + +finish: + + if (inputDirBuf != NULL) { + uprv_free(inputDirBuf); + } + + if (openFileName != NULL) { + uprv_free(openFileName); + } + + if(ucbuf) { + ucbuf_close(ucbuf); + } + + if (rbname) { + uprv_free(rbname); + } +} + +/* Generate the target .res file name from the input file name */ +static char* +make_res_filename(const char *filename, + const char *outputDir, + const char *packageName, + UErrorCode *status) { + char *basename; + char *dirname; + char *resName; + + int32_t pkgLen = 0; /* length of package prefix */ + + if (U_FAILURE(*status)) { + return 0; + } + + if(packageName != NULL) + { + pkgLen = (int32_t)(1 + uprv_strlen(packageName)); + } + + /* setup */ + basename = dirname = resName = 0; + + /* determine basename, and compiled file names */ + basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); + if(basename == 0) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + get_basename(basename, filename); + + dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); + if(dirname == 0) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + get_dirname(dirname, filename); + + if (outputDir == NULL) { + /* output in same dir as .txt */ + resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname) + + pkgLen + + uprv_strlen(basename) + + uprv_strlen(RES_SUFFIX) + 8)); + if(resName == 0) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + uprv_strcpy(resName, dirname); + + if(packageName != NULL) + { + uprv_strcat(resName, packageName); + uprv_strcat(resName, "_"); + } + + uprv_strcat(resName, basename); + + } else { + int32_t dirlen = (int32_t)uprv_strlen(outputDir); + int32_t basenamelen = (int32_t)uprv_strlen(basename); + + resName = (char*) uprv_malloc(sizeof(char) * (dirlen + pkgLen + basenamelen + 8)); + + if (resName == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + goto finish; + } + + uprv_strcpy(resName, outputDir); + + if(outputDir[dirlen] != U_FILE_SEP_CHAR) { + resName[dirlen] = U_FILE_SEP_CHAR; + resName[dirlen + 1] = '\0'; + } + + if(packageName != NULL) + { + uprv_strcat(resName, packageName); + uprv_strcat(resName, "_"); + } + + uprv_strcat(resName, basename); + } + +finish: + uprv_free(basename); + uprv_free(dirname); + + return resName; +} + +/* + * Local Variables: + * indent-tabs-mode: nil + * End: + */ diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.h b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.h new file mode 100644 index 00000000000..995ad5ea15d --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.h @@ -0,0 +1,43 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File genrb.h +* +* Modification History: +******************************************************************************* +*/ + +#ifndef GENRB_H +#define GENRB_H + +#include <stdio.h> +#include "unicode/utypes.h" +#include "unicode/putil.h" +#include "cmemory.h" +#include "cstring.h" +#include "filestrm.h" + + +#include "ucbuf.h" +#include "errmsg.h" +#include "parse.h" +#include "rbutil.h" +#include "reslist.h" + + +#include "toolutil.h" +#include "uoptions.h" + +#include "unicode/ucol.h" +#include "unicode/uloc.h" + +/* The version of genrb */ +#define GENRB_VERSION "3.3" + +#endif + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.vcproj b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.vcproj new file mode 100644 index 00000000000..5beba7698d1 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/genrb.vcproj @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="genrb" + ProjectGUID="{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory=".\Release" + IntermediateDirectory=".\Release" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="copy "$(TargetPath)" ..\..\..\bin
" + Outputs="..\..\..\bin\$(TargetFileName)" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\Release/genrb.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\include;..\..\common;..\toolutil;..\..\i18n" + PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE" + StringPooling="true" + RuntimeLibrary="2" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + PrecompiledHeaderFile=".\Release/genrb.pch" + AssemblerListingLocation=".\Release/" + ObjectFile=".\Release/" + ProgramDataBaseFileName=".\Release/" + WarningLevel="3" + SuppressStartupBanner="true" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile=".\Release/genrb.exe" + LinkIncremental="1" + SuppressStartupBanner="true" + ProgramDatabaseFile=".\Release/genrb.pdb" + SubSystem="1" + OptimizeForWindows98="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\Debug" + IntermediateDirectory=".\Debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="copy "$(TargetPath)" ..\..\..\bin
" + Outputs="..\..\..\bin\$(TargetFileName)" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\Debug/genrb.tlb" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\include;..\..\common;..\toolutil;..\..\i18n" + PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="true" + DisableLanguageExtensions="true" + TreatWChar_tAsBuiltInType="true" + PrecompiledHeaderFile=".\Debug/genrb.pch" + AssemblerListingLocation=".\Debug/" + ObjectFile=".\Debug/" + ProgramDataBaseFileName=".\Debug/" + BrowseInformation="1" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="4" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile=".\Debug/genrb.exe" + LinkIncremental="2" + SuppressStartupBanner="true" + GenerateDebugInformation="true" + ProgramDatabaseFile=".\Debug/genrb.pdb" + SubSystem="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + UseFAT32Workaround="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + > + <File + RelativePath=".\errmsg.c" + > + </File> + <File + RelativePath=".\genrb.c" + > + </File> + <File + RelativePath=".\parse.c" + > + </File> + <File + RelativePath=".\prscmnts.cpp" + > + </File> + <File + RelativePath=".\rbutil.c" + > + </File> + <File + RelativePath=".\read.c" + > + </File> + <File + RelativePath=".\reslist.c" + > + </File> + <File + RelativePath=".\rle.c" + > + </File> + <File + RelativePath=".\ustr.c" + > + </File> + <File + RelativePath=".\wrtjava.c" + > + </File> + <File + RelativePath=".\wrtxml.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl" + > + <File + RelativePath=".\errmsg.h" + > + </File> + <File + RelativePath=".\genrb.h" + > + </File> + <File + RelativePath=".\parse.h" + > + </File> + <File + RelativePath=".\prscmnts.h" + > + </File> + <File + RelativePath=".\rbutil.h" + > + </File> + <File + RelativePath=".\read.h" + > + </File> + <File + RelativePath=".\reslist.h" + > + </File> + <File + RelativePath=".\rle.h" + > + </File> + <File + RelativePath=".\ustr.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/parse.c b/Build/source/libs/icu/icu-xetex/tools/genrb/parse.c new file mode 100644 index 00000000000..c6de231abc3 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/parse.c @@ -0,0 +1,1925 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File parse.c +* +* Modification History: +* +* Date Name Description +* 05/26/99 stephen Creation. +* 02/25/00 weiv Overhaul to write udata +* 5/10/01 Ram removed ustdio dependency +* 06/10/2001 Dominic Ludlam <dom@recoil.org> Rewritten +******************************************************************************* +*/ + +#include "ucol_imp.h" +#include "parse.h" +#include "errmsg.h" +#include "uhash.h" +#include "cmemory.h" +#include "cstring.h" +#include "uinvchar.h" +#include "read.h" +#include "ustr.h" +#include "reslist.h" +#include "rbt_pars.h" +#include "unicode/ustring.h" +#include "unicode/putil.h" +#include <stdio.h> + +/* Number of tokens to read ahead of the current stream position */ +#define MAX_LOOKAHEAD 3 + +#define CR 0x000D +#define LF 0x000A +#define SPACE 0x0020 +#define TAB 0x0009 +#define ESCAPE 0x005C +#define HASH 0x0023 +#define QUOTE 0x0027 +#define ZERO 0x0030 +#define STARTCOMMAND 0x005B +#define ENDCOMMAND 0x005D +#define OPENSQBRACKET 0x005B +#define CLOSESQBRACKET 0x005D + +typedef struct SResource * +ParseResourceFunction(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status); + +struct Lookahead +{ + enum ETokenType type; + struct UString value; + struct UString comment; + uint32_t line; +}; + +/* keep in sync with token defines in read.h */ +const char *tokenNames[TOK_TOKEN_COUNT] = +{ + "string", /* A string token, such as "MonthNames" */ + "'{'", /* An opening brace character */ + "'}'", /* A closing brace character */ + "','", /* A comma */ + "':'", /* A colon */ + + "<end of file>", /* End of the file has been reached successfully */ + "<end of line>" +}; + +/* Just to store "TRUE" */ +static const UChar trueValue[] = {0x0054, 0x0052, 0x0055, 0x0045, 0x0000}; + +static struct Lookahead lookahead[MAX_LOOKAHEAD + 1]; +static uint32_t lookaheadPosition; +static UCHARBUF *buffer; + +static struct SRBRoot *bundle; +static const char *inputdir; +static uint32_t inputdirLength; +static const char *outputdir; +static uint32_t outputdirLength; + +static UBool gMakeBinaryCollation = TRUE; + +static struct SResource *parseResource(char *tag, const struct UString *comment, UErrorCode *status); + +/* The nature of the lookahead buffer: + There are MAX_LOOKAHEAD + 1 slots, used as a circular buffer. This provides + MAX_LOOKAHEAD lookahead tokens and a slot for the current token and value. + When getToken is called, the current pointer is moved to the next slot and the + old slot is filled with the next token from the reader by calling getNextToken. + The token values are stored in the slot, which means that token values don't + survive a call to getToken, ie. + + UString *value; + + getToken(&value, NULL, status); + getToken(NULL, NULL, status); bad - value is now a different string +*/ +static void +initLookahead(UCHARBUF *buf, UErrorCode *status) +{ + static uint32_t initTypeStrings = 0; + uint32_t i; + + if (!initTypeStrings) + { + initTypeStrings = 1; + } + + lookaheadPosition = 0; + buffer = buf; + + resetLineNumber(); + + for (i = 0; i < MAX_LOOKAHEAD; i++) + { + lookahead[i].type = getNextToken(buffer, &lookahead[i].value, &lookahead[i].line, &lookahead[i].comment, status); + if (U_FAILURE(*status)) + { + return; + } + } + + *status = U_ZERO_ERROR; +} + +static enum ETokenType +getToken(struct UString **tokenValue, struct UString* comment, uint32_t *linenumber, UErrorCode *status) +{ + enum ETokenType result; + uint32_t i; + + result = lookahead[lookaheadPosition].type; + + if (tokenValue != NULL) + { + *tokenValue = &lookahead[lookaheadPosition].value; + } + + if (linenumber != NULL) + { + *linenumber = lookahead[lookaheadPosition].line; + } + + if (comment != NULL) + { + ustr_cpy(comment, &(lookahead[lookaheadPosition].comment), status); + } + + i = (lookaheadPosition + MAX_LOOKAHEAD) % (MAX_LOOKAHEAD + 1); + lookaheadPosition = (lookaheadPosition + 1) % (MAX_LOOKAHEAD + 1); + ustr_setlen(&lookahead[i].comment, 0, status); + ustr_setlen(&lookahead[i].value, 0, status); + lookahead[i].type = getNextToken(buffer, &lookahead[i].value, &lookahead[i].line, &lookahead[i].comment, status); + + /* printf("getToken, returning %s\n", tokenNames[result]); */ + + return result; +} + +static enum ETokenType +peekToken(uint32_t lookaheadCount, struct UString **tokenValue, uint32_t *linenumber, struct UString *comment, UErrorCode *status) +{ + uint32_t i = (lookaheadPosition + lookaheadCount) % (MAX_LOOKAHEAD + 1); + + if (U_FAILURE(*status)) + { + return TOK_ERROR; + } + + if (lookaheadCount >= MAX_LOOKAHEAD) + { + *status = U_INTERNAL_PROGRAM_ERROR; + return TOK_ERROR; + } + + if (tokenValue != NULL) + { + *tokenValue = &lookahead[i].value; + } + + if (linenumber != NULL) + { + *linenumber = lookahead[i].line; + } + + if(comment != NULL){ + ustr_cpy(comment, &(lookahead[lookaheadPosition].comment), status); + } + + return lookahead[i].type; +} + +static void +expect(enum ETokenType expectedToken, struct UString **tokenValue, struct UString *comment, uint32_t *linenumber, UErrorCode *status) +{ + uint32_t line; + + enum ETokenType token = getToken(tokenValue, comment, &line, status); + + if (linenumber != NULL) + { + *linenumber = line; + } + + if (U_FAILURE(*status)) + { + return; + } + + if (token != expectedToken) + { + *status = U_INVALID_FORMAT_ERROR; + error(line, "expecting %s, got %s", tokenNames[expectedToken], tokenNames[token]); + } + else /* "else" is added by Jing/GCL */ + { + *status = U_ZERO_ERROR; + } +} + +static char *getInvariantString(uint32_t *line, struct UString *comment, UErrorCode *status) +{ + struct UString *tokenValue; + char *result; + uint32_t count; + + expect(TOK_STRING, &tokenValue, comment, line, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + + count = u_strlen(tokenValue->fChars); + if(!uprv_isInvariantUString(tokenValue->fChars, count)) { + *status = U_INVALID_FORMAT_ERROR; + error(*line, "invariant characters required for table keys, binary data, etc."); + return NULL; + } + + result = uprv_malloc(count+1); + + if (result == NULL) + { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + u_UCharsToChars(tokenValue->fChars, result, count+1); + return result; +} + +static struct SResource * +parseUCARules(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct SResource *result = NULL; + struct UString *tokenValue; + FileStream *file = NULL; + char filename[256] = { '\0' }; + char cs[128] = { '\0' }; + uint32_t line; + int len=0; + UBool quoted = FALSE; + UCHARBUF *ucbuf=NULL; + UChar32 c = 0; + const char* cp = NULL; + UChar *pTarget = NULL; + UChar *target = NULL; + UChar *targetLimit = NULL; + int32_t size = 0; + + expect(TOK_STRING, &tokenValue, NULL, &line, status); + + if(isVerbose()){ + printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + if (U_FAILURE(*status)) + { + return NULL; + } + /* make the filename including the directory */ + if (inputdir != NULL) + { + uprv_strcat(filename, inputdir); + + if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR) + { + uprv_strcat(filename, U_FILE_SEP_STRING); + } + } + + u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + uprv_strcat(filename, cs); + + + ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); + + if (U_FAILURE(*status)) { + error(line, "An error occured while opening the input file %s\n", filename); + return NULL; + } + + /* We allocate more space than actually required + * since the actual size needed for storing UChars + * is not known in UTF-8 byte stream + */ + size = ucbuf_size(ucbuf) + 1; + pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * size); + uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); + target = pTarget; + targetLimit = pTarget+size; + + /* read the rules into the buffer */ + while (target < targetLimit) + { + c = ucbuf_getc(ucbuf, status); + if(c == QUOTE) { + quoted = (UBool)!quoted; + } + /* weiv (06/26/2002): adding the following: + * - preserving spaces in commands [...] + * - # comments until the end of line + */ + if (c == STARTCOMMAND && !quoted) + { + /* preserve commands + * closing bracket will be handled by the + * append at the end of the loop + */ + while(c != ENDCOMMAND) { + U_APPEND_CHAR32(c, target,len); + c = ucbuf_getc(ucbuf, status); + } + } + else if (c == HASH && !quoted) { + /* skip comments */ + while(c != CR && c != LF) { + c = ucbuf_getc(ucbuf, status); + } + continue; + } + else if (c == ESCAPE) + { + c = unescape(ucbuf, status); + + if (c == U_ERR) + { + uprv_free(pTarget); + T_FileStream_close(file); + return NULL; + } + } + else if (!quoted && (c == SPACE || c == TAB || c == CR || c == LF)) + { + /* ignore spaces carriage returns + * and line feed unless in the form \uXXXX + */ + continue; + } + + /* Append UChar * after dissembling if c > 0xffff*/ + if (c != U_EOF) + { + U_APPEND_CHAR32(c, target,len); + } + else + { + break; + } + } + + /* terminate the string */ + if(target < targetLimit){ + *target = 0x0000; + } + + result = string_open(bundle, tag, pTarget, (int32_t)(target - pTarget), NULL, status); + + + ucbuf_close(ucbuf); + uprv_free(pTarget); + T_FileStream_close(file); + + return result; +} + +static struct SResource * +parseTransliterator(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct SResource *result = NULL; + struct UString *tokenValue; + FileStream *file = NULL; + char filename[256] = { '\0' }; + char cs[128] = { '\0' }; + uint32_t line; + UCHARBUF *ucbuf=NULL; + const char* cp = NULL; + UChar *pTarget = NULL; + const UChar *pSource = NULL; + int32_t size = 0; + + expect(TOK_STRING, &tokenValue, NULL, &line, status); + + if(isVerbose()){ + printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + if (U_FAILURE(*status)) + { + return NULL; + } + /* make the filename including the directory */ + if (inputdir != NULL) + { + uprv_strcat(filename, inputdir); + + if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR) + { + uprv_strcat(filename, U_FILE_SEP_STRING); + } + } + + u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + uprv_strcat(filename, cs); + + + ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); + + if (U_FAILURE(*status)) { + error(line, "An error occured while opening the input file %s\n", filename); + return NULL; + } + + /* We allocate more space than actually required + * since the actual size needed for storing UChars + * is not known in UTF-8 byte stream + */ + pSource = ucbuf_getBuffer(ucbuf, &size, status); + pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (size + 1)); + uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); + +#if !UCONFIG_NO_TRANSLITERATION + size = utrans_stripRules(pSource, size, pTarget, status); +#else + size = 0; + fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_TRANSLITERATION ) \n"); +#endif + result = string_open(bundle, tag, pTarget, size, NULL, status); + + ucbuf_close(ucbuf); + uprv_free(pTarget); + T_FileStream_close(file); + + return result; +} +static struct SResource* dependencyArray = NULL; + +static struct SResource * +parseDependency(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct SResource *result = NULL; + struct SResource *elem = NULL; + struct UString *tokenValue; + uint32_t line; + char filename[256] = { '\0' }; + char cs[128] = { '\0' }; + + expect(TOK_STRING, &tokenValue, NULL, &line, status); + + if(isVerbose()){ + printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + if (U_FAILURE(*status)) + { + return NULL; + } + /* make the filename including the directory */ + if (outputdir != NULL) + { + uprv_strcat(filename, outputdir); + + if (outputdir[outputdirLength - 1] != U_FILE_SEP_CHAR) + { + uprv_strcat(filename, U_FILE_SEP_STRING); + } + } + + u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); + + if (U_FAILURE(*status)) + { + return NULL; + } + uprv_strcat(filename, cs); + if(!T_FileStream_file_exists(filename)){ + if(isStrict()){ + error(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); + }else{ + warning(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); + } + } + if(dependencyArray==NULL){ + dependencyArray = array_open(bundle, "%%DEPENDENCY", NULL, status); + } + if(tag!=NULL){ + result = string_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); + } + elem = string_open(bundle, NULL, tokenValue->fChars, tokenValue->fLength, comment, status); + + array_add(dependencyArray, elem, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + return result; +} +static struct SResource * +parseString(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct UString *tokenValue; + struct SResource *result = NULL; + +/* if (tag != NULL && uprv_strcmp(tag, "%%UCARULES") == 0) + { + return parseUCARules(tag, startline, status); + }*/ + if(isVerbose()){ + printf(" string %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + expect(TOK_STRING, &tokenValue, NULL, NULL, status); + + if (U_SUCCESS(*status)) + { + /* create the string now - tokenValue doesn't survive a call to getToken (and therefore + doesn't survive expect either) */ + + result = string_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); + if(U_SUCCESS(*status) && result) { + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + string_close(result, status); + return NULL; + } + } + } + + return result; +} + +static struct SResource * +parseAlias(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct UString *tokenValue; + struct SResource *result = NULL; + + expect(TOK_STRING, &tokenValue, NULL, NULL, status); + + if(isVerbose()){ + printf(" alias %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + if (U_SUCCESS(*status)) + { + /* create the string now - tokenValue doesn't survive a call to getToken (and therefore + doesn't survive expect either) */ + + result = alias_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + alias_close(result, status); + return NULL; + } + } + + return result; +} + +static struct SResource * +addCollation(struct SResource *result, uint32_t startline, UErrorCode *status) +{ + struct SResource *member = NULL; + struct UString *tokenValue; + struct UString comment; + enum ETokenType token; + char subtag[1024]; + UVersionInfo version; + UBool override = FALSE; + uint32_t line; + /* '{' . (name resource)* '}' */ + version[0]=0; version[1]=0; version[2]=0; version[3]=0; + + for (;;) + { + ustr_init(&comment); + token = getToken(&tokenValue, &comment, &line, status); + + if (token == TOK_CLOSE_BRACE) + { + return result; + } + + if (token != TOK_STRING) + { + table_close(result, status); + *status = U_INVALID_FORMAT_ERROR; + + if (token == TOK_EOF) + { + error(startline, "unterminated table"); + } + else + { + error(line, "Unexpected token %s", tokenNames[token]); + } + + return NULL; + } + + u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + + member = parseResource(subtag, NULL, status); + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + + if (uprv_strcmp(subtag, "Version") == 0) + { + char ver[40]; + int32_t length = member->u.fString.fLength; + + if (length >= (int32_t) sizeof(ver)) + { + length = (int32_t) sizeof(ver) - 1; + } + + u_UCharsToChars(member->u.fString.fChars, ver, length + 1); /* +1 for copying NULL */ + u_versionFromString(version, ver); + + table_add(result, member, line, status); + + } + else if (uprv_strcmp(subtag, "Override") == 0) + { + override = FALSE; + + if (u_strncmp(member->u.fString.fChars, trueValue, u_strlen(trueValue)) == 0) + { + override = TRUE; + } + table_add(result, member, line, status); + + } + else if(uprv_strcmp(subtag, "%%CollationBin")==0) + { + /* discard duplicate %%CollationBin if any*/ + } + else if (uprv_strcmp(subtag, "Sequence") == 0) + { +#if UCONFIG_NO_COLLATION + warning(line, "Not building collation elements because of UCONFIG_NO_COLLATION, see uconfig.h"); +#else + /* first we add the "Sequence", so that we always have rules */ + table_add(result, member, line, status); + if(gMakeBinaryCollation) { + UErrorCode intStatus = U_ZERO_ERROR; + + /* do the collation elements */ + int32_t len = 0; + uint8_t *data = NULL; + UCollator *coll = NULL; + UParseError parseError; + /* add sequence */ + /*table_add(result, member, line, status);*/ + + coll = ucol_openRules(member->u.fString.fChars, member->u.fString.fLength, + UCOL_OFF, UCOL_DEFAULT_STRENGTH,&parseError, &intStatus); + + if (U_SUCCESS(intStatus) && coll != NULL) + { + len = ucol_cloneBinary(coll, NULL, 0, &intStatus); + data = (uint8_t *)uprv_malloc(len); + intStatus = U_ZERO_ERROR; + len = ucol_cloneBinary(coll, data, len, &intStatus); + /*data = ucol_cloneRuleData(coll, &len, &intStatus);*/ + + /* tailoring rules version */ + /* This is wrong! */ + /*coll->dataInfo.dataVersion[1] = version[0];*/ + /* Copy tailoring version. Builder version already */ + /* set in ucol_openRules */ + ((UCATableHeader *)data)->version[1] = version[0]; + ((UCATableHeader *)data)->version[2] = version[1]; + ((UCATableHeader *)data)->version[3] = version[2]; + + if (U_SUCCESS(intStatus) && data != NULL) + { + member = bin_open(bundle, "%%CollationBin", len, data, NULL, NULL, status); + /*table_add(bundle->fRoot, member, line, status);*/ + table_add(result, member, line, status); + uprv_free(data); + } + else + { + warning(line, "could not obtain rules from collator"); + if(isStrict()){ + *status = U_INVALID_FORMAT_ERROR; + return NULL; + } + } + + ucol_close(coll); + } + else + { + warning(line, "%%Collation could not be constructed from CollationElements - check context!"); + if(isStrict()){ + *status = intStatus; + return NULL; + } + } + } else { + if(isVerbose()) { + printf("Not building Collation binary\n"); + } + } +#endif + } + + /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/ + + /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + } + + /* not reached */ + /* A compiler warning will appear if all paths don't contain a return statement. */ +/* *status = U_INTERNAL_PROGRAM_ERROR; + return NULL;*/ +} + +static struct SResource * +parseCollationElements(char *tag, uint32_t startline, UBool newCollation, UErrorCode *status) +{ + struct SResource *result = NULL; + struct SResource *member = NULL; + struct SResource *collationRes = NULL; + struct UString *tokenValue; + struct UString comment; + enum ETokenType token; + char subtag[1024], typeKeyword[1024]; + uint32_t line; + + result = table_open(bundle, tag, NULL, status); + + if (result == NULL || U_FAILURE(*status)) + { + return NULL; + } + if(isVerbose()){ + printf(" collation elements %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + if(!newCollation) { + return addCollation(result, startline, status); + } + else { + for(;;) { + ustr_init(&comment); + token = getToken(&tokenValue, &comment, &line, status); + + if (token == TOK_CLOSE_BRACE) + { + return result; + } + + if (token != TOK_STRING) + { + table_close(result, status); + *status = U_INVALID_FORMAT_ERROR; + + if (token == TOK_EOF) + { + error(startline, "unterminated table"); + } + else + { + error(line, "Unexpected token %s", tokenNames[token]); + } + + return NULL; + } + + u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + + if (uprv_strcmp(subtag, "default") == 0) + { + member = parseResource(subtag, NULL, status); + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + + table_add(result, member, line, status); + } + else + { + token = peekToken(0, &tokenValue, &line, &comment, status); + /* this probably needs to be refactored or recursively use the parser */ + /* first we assume that our collation table won't have the explicit type */ + /* then, we cannot handle aliases */ + if(token == TOK_OPEN_BRACE) { + token = getToken(&tokenValue, &comment, &line, status); + collationRes = table_open(bundle, subtag, NULL, status); + table_add(result, addCollation(collationRes, startline, status), startline, status); + } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ + /* we could have a table too */ + token = peekToken(1, &tokenValue, &line, &comment, status); + u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); + if(uprv_strcmp(typeKeyword, "alias") == 0) { + member = parseResource(subtag, NULL, status); + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + + table_add(result, member, line, status); + } else { + *status = U_INVALID_FORMAT_ERROR; + return NULL; + } + } else { + *status = U_INVALID_FORMAT_ERROR; + return NULL; + } + } + + /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/ + + /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ + + if (U_FAILURE(*status)) + { + table_close(result, status); + return NULL; + } + } + } +} + +/* Necessary, because CollationElements requires the bundle->fRoot member to be present which, + if this weren't special-cased, wouldn't be set until the entire file had been processed. */ +static struct SResource * +realParseTable(struct SResource *table, char *tag, uint32_t startline, UErrorCode *status) +{ + struct SResource *member = NULL; + struct UString *tokenValue=NULL; + struct UString comment; + enum ETokenType token; + char subtag[1024]; + uint32_t line; + UBool readToken = FALSE; + + /* '{' . (name resource)* '}' */ + if(isVerbose()){ + printf(" parsing table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + for (;;) + { + ustr_init(&comment); + token = getToken(&tokenValue, &comment, &line, status); + + if (token == TOK_CLOSE_BRACE) + { + if (!readToken) { + warning(startline, "Encountered empty table"); + } + return table; + } + + if (token != TOK_STRING) + { + table_close(table, status); + *status = U_INVALID_FORMAT_ERROR; + + if (token == TOK_EOF) + { + error(startline, "unterminated table"); + } + else + { + error(line, "unexpected token %s", tokenNames[token]); + } + + return NULL; + } + + if(uprv_isInvariantUString(tokenValue->fChars, -1)) { + u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); + } else { + *status = U_INVALID_FORMAT_ERROR; + error(line, "invariant characters required for table keys"); + table_close(table, status); + return NULL; + } + + if (U_FAILURE(*status)) + { + error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); + table_close(table, status); + return NULL; + } + + member = parseResource(subtag, &comment, status); + + if (member == NULL || U_FAILURE(*status)) + { + error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); + table_close(table, status); + return NULL; + } + + table_add(table, member, line, status); + + if (U_FAILURE(*status)) + { + error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); + table_close(table, status); + return NULL; + } + readToken = TRUE; + } + + /* not reached */ + /* A compiler warning will appear if all paths don't contain a return statement. */ +/* *status = U_INTERNAL_PROGRAM_ERROR; + return NULL;*/ +} + +static struct SResource * +parseTable(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct SResource *result; + + if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0) + { + return parseCollationElements(tag, startline, FALSE, status); + } + if (tag != NULL && uprv_strcmp(tag, "collations") == 0) + { + return parseCollationElements(tag, startline, TRUE, status); + } + if(isVerbose()){ + printf(" table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + result = table_open(bundle, tag, comment, status); + + if (result == NULL || U_FAILURE(*status)) + { + return NULL; + } + + return realParseTable(result, tag, startline, status); +} + +static struct SResource * +parseArray(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct SResource *result = NULL; + struct SResource *member = NULL; + struct UString *tokenValue; + struct UString memberComments; + enum ETokenType token; + UBool readToken = FALSE; + + result = array_open(bundle, tag, comment, status); + + if (result == NULL || U_FAILURE(*status)) + { + return NULL; + } + if(isVerbose()){ + printf(" array %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + ustr_init(&memberComments); + + /* '{' . resource [','] '}' */ + for (;;) + { + /* reset length */ + ustr_setlen(&memberComments, 0, status); + + /* check for end of array, but don't consume next token unless it really is the end */ + token = peekToken(0, &tokenValue, NULL, &memberComments, status); + + + if (token == TOK_CLOSE_BRACE) + { + getToken(NULL, NULL, NULL, status); + if (!readToken) { + warning(startline, "Encountered empty array"); + } + break; + } + + if (token == TOK_EOF) + { + array_close(result, status); + *status = U_INVALID_FORMAT_ERROR; + error(startline, "unterminated array"); + return NULL; + } + + /* string arrays are a special case */ + if (token == TOK_STRING) + { + getToken(&tokenValue, &memberComments, NULL, status); + member = string_open(bundle, NULL, tokenValue->fChars, tokenValue->fLength, &memberComments, status); + } + else + { + member = parseResource(NULL, &memberComments, status); + } + + if (member == NULL || U_FAILURE(*status)) + { + array_close(result, status); + return NULL; + } + + array_add(result, member, status); + + if (U_FAILURE(*status)) + { + array_close(result, status); + return NULL; + } + + /* eat optional comma if present */ + token = peekToken(0, NULL, NULL, NULL, status); + + if (token == TOK_COMMA) + { + getToken(NULL, NULL, NULL, status); + } + + if (U_FAILURE(*status)) + { + array_close(result, status); + return NULL; + } + readToken = TRUE; + } + + return result; +} + +static struct SResource * +parseIntVector(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct SResource *result = NULL; + enum ETokenType token; + char *string; + int32_t value; + UBool readToken = FALSE; + /* added by Jing/GCL */ + char *stopstring; + uint32_t len; + struct UString memberComments; + + result = intvector_open(bundle, tag, comment, status); + + if (result == NULL || U_FAILURE(*status)) + { + return NULL; + } + + if(isVerbose()){ + printf(" vector %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + ustr_init(&memberComments); + /* '{' . string [','] '}' */ + for (;;) + { + ustr_setlen(&memberComments, 0, status); + + /* check for end of array, but don't consume next token unless it really is the end */ + token = peekToken(0, NULL, NULL,&memberComments, status); + + if (token == TOK_CLOSE_BRACE) + { + /* it's the end, consume the close brace */ + getToken(NULL, NULL, NULL, status); + if (!readToken) { + warning(startline, "Encountered empty int vector"); + } + return result; + } + + string = getInvariantString(NULL, NULL, status); + + if (U_FAILURE(*status)) + { + intvector_close(result, status); + return NULL; + } + /* Commented by Jing/GCL */ + /*value = uprv_strtol(string, NULL, 10); + intvector_add(result, value, status); + + uprv_free(string); + + token = peekToken(0, NULL, NULL, status);*/ + + /* The following is added by Jing/GCL to handle illegal char in the Intvector */ + value = uprv_strtoul(string, &stopstring, 0);/* make intvector support decimal,hexdigit,octal digit ranging from -2^31-2^32-1*/ + len=(uint32_t)(stopstring-string); + + if(len==uprv_strlen(string)) + { + intvector_add(result, value, status); + uprv_free(string); + token = peekToken(0, NULL, NULL, NULL, status); + } + else + { + uprv_free(string); + *status=U_INVALID_CHAR_FOUND; + } + /* The above is added by Jing/GCL */ + + if (U_FAILURE(*status)) + { + intvector_close(result, status); + return NULL; + } + + /* the comma is optional (even though it is required to prevent the reader from concatenating + consecutive entries) so that a missing comma on the last entry isn't an error */ + if (token == TOK_COMMA) + { + getToken(NULL, NULL, NULL, status); + } + readToken = TRUE; + } + + /* not reached */ + /* A compiler warning will appear if all paths don't contain a return statement. */ +/* intvector_close(result, status); + *status = U_INTERNAL_PROGRAM_ERROR; + return NULL;*/ +} + +static struct SResource * +parseBinary(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct SResource *result = NULL; + uint8_t *value; + char *string; + char toConv[3] = {'\0', '\0', '\0'}; + uint32_t count; + uint32_t i; + uint32_t line; + /* added by Jing/GCL */ + char *stopstring; + uint32_t len; + + string = getInvariantString(&line, NULL, status); + + if (string == NULL || U_FAILURE(*status)) + { + return NULL; + } + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + uprv_free(string); + return NULL; + } + + if(isVerbose()){ + printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + count = (uint32_t)uprv_strlen(string); + if (count > 0){ + if((count % 2)==0){ + value = uprv_malloc(sizeof(uint8_t) * count); + + if (value == NULL) + { + uprv_free(string); + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + for (i = 0; i < count; i += 2) + { + toConv[0] = string[i]; + toConv[1] = string[i + 1]; + + value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16); + len=(uint32_t)(stopstring-toConv); + + if(len!=uprv_strlen(toConv)) + { + uprv_free(string); + *status=U_INVALID_CHAR_FOUND; + return NULL; + } + } + + result = bin_open(bundle, tag, (i >> 1), value,NULL, comment, status); + + uprv_free(value); + } + else + { + *status = U_INVALID_CHAR_FOUND; + uprv_free(string); + error(line, "Encountered invalid binary string"); + return NULL; + } + } + else + { + result = bin_open(bundle, tag, 0, NULL, "",comment,status); + warning(startline, "Encountered empty binary tag"); + } + uprv_free(string); + + return result; +} + +static struct SResource * +parseInteger(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) +{ + struct SResource *result = NULL; + int32_t value; + char *string; + /* added by Jing/GCL */ + char *stopstring; + uint32_t len; + + string = getInvariantString(NULL, NULL, status); + + if (string == NULL || U_FAILURE(*status)) + { + return NULL; + } + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + uprv_free(string); + return NULL; + } + + if(isVerbose()){ + printf(" integer %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + if (uprv_strlen(string) <= 0) + { + warning(startline, "Encountered empty integer. Default value is 0."); + } + + /* commented by Jing/GCL */ + /* value = uprv_strtol(string, NULL, 10);*/ + /* result = int_open(bundle, tag, value, status);*/ + /* The following is added by Jing/GCL*/ + /* to make integer support hexdecimal, octal digit and decimal*/ + /* to handle illegal char in the integer*/ + value = uprv_strtoul(string, &stopstring, 0); + len=(uint32_t)(stopstring-string); + if(len==uprv_strlen(string)) + { + result = int_open(bundle, tag, value, comment, status); + } + else + { + *status=U_INVALID_CHAR_FOUND; + } + uprv_free(string); + + return result; +} + +static struct SResource * +parseImport(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct SResource *result; + FileStream *file; + int32_t len; + uint8_t *data; + char *filename; + uint32_t line; + char *fullname = NULL; + int32_t numRead = 0; + filename = getInvariantString(&line, NULL, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + uprv_free(filename); + return NULL; + } + + if(isVerbose()){ + printf(" import %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + /* Open the input file for reading */ + if (inputdir == NULL) + { +#if 1 + /* + * Always save file file name, even if there's + * no input directory specified. MIGHT BREAK SOMETHING + */ + int32_t filenameLength = uprv_strlen(filename); + + fullname = (char *) uprv_malloc(filenameLength + 1); + uprv_strcpy(fullname, filename); +#endif + + file = T_FileStream_open(filename, "rb"); + } + else + { + + int32_t count = (int32_t)uprv_strlen(filename); + + if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR) + { + fullname = (char *) uprv_malloc(inputdirLength + count + 2); + + /* test for NULL */ + if(fullname == NULL) + { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + uprv_strcpy(fullname, inputdir); + + fullname[inputdirLength] = U_FILE_SEP_CHAR; + fullname[inputdirLength + 1] = '\0'; + + uprv_strcat(fullname, filename); + } + else + { + fullname = (char *) uprv_malloc(inputdirLength + count + 1); + + /* test for NULL */ + if(fullname == NULL) + { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + uprv_strcpy(fullname, inputdir); + uprv_strcat(fullname, filename); + } + + file = T_FileStream_open(fullname, "rb"); + + } + + if (file == NULL) + { + error(line, "couldn't open input file %s", filename); + *status = U_FILE_ACCESS_ERROR; + return NULL; + } + + len = T_FileStream_size(file); + data = (uint8_t*)uprv_malloc(len * sizeof(uint8_t)); + /* test for NULL */ + if(data == NULL) + { + *status = U_MEMORY_ALLOCATION_ERROR; + T_FileStream_close (file); + return NULL; + } + + numRead = T_FileStream_read (file, data, len); + T_FileStream_close (file); + + result = bin_open(bundle, tag, len, data, fullname, comment, status); + + uprv_free(data); + uprv_free(filename); + uprv_free(fullname); + + return result; +} + +static struct SResource * +parseInclude(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) +{ + struct SResource *result; + int32_t len=0; + char *filename; + uint32_t line; + UChar *pTarget = NULL; + + UCHARBUF *ucbuf; + char *fullname = NULL; + int32_t count = 0; + const char* cp = NULL; + const UChar* uBuffer = NULL; + + filename = getInvariantString(&line, NULL, status); + count = (int32_t)uprv_strlen(filename); + + if (U_FAILURE(*status)) + { + return NULL; + } + + expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status); + + if (U_FAILURE(*status)) + { + uprv_free(filename); + return NULL; + } + + if(isVerbose()){ + printf(" include %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + fullname = (char *) uprv_malloc(inputdirLength + count + 2); + /* test for NULL */ + if(fullname == NULL) + { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(filename); + return NULL; + } + + if(inputdir!=NULL){ + if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR) + { + + uprv_strcpy(fullname, inputdir); + + fullname[inputdirLength] = U_FILE_SEP_CHAR; + fullname[inputdirLength + 1] = '\0'; + + uprv_strcat(fullname, filename); + } + else + { + uprv_strcpy(fullname, inputdir); + uprv_strcat(fullname, filename); + } + }else{ + uprv_strcpy(fullname,filename); + } + + ucbuf = ucbuf_open(fullname, &cp,getShowWarning(),FALSE,status); + + if (U_FAILURE(*status)) { + error(line, "couldn't open input file %s\n", filename); + return NULL; + } + + uBuffer = ucbuf_getBuffer(ucbuf,&len,status); + result = string_open(bundle, tag, uBuffer, len, comment, status); + + uprv_free(pTarget); + + uprv_free(filename); + uprv_free(fullname); + + return result; +} + + + + + +U_STRING_DECL(k_type_string, "string", 6); +U_STRING_DECL(k_type_binary, "binary", 6); +U_STRING_DECL(k_type_bin, "bin", 3); +U_STRING_DECL(k_type_table, "table", 5); +U_STRING_DECL(k_type_table_no_fallback, "table(nofallback)", 17); +U_STRING_DECL(k_type_int, "int", 3); +U_STRING_DECL(k_type_integer, "integer", 7); +U_STRING_DECL(k_type_array, "array", 5); +U_STRING_DECL(k_type_alias, "alias", 5); +U_STRING_DECL(k_type_intvector, "intvector", 9); +U_STRING_DECL(k_type_import, "import", 6); +U_STRING_DECL(k_type_include, "include", 7); +U_STRING_DECL(k_type_reserved, "reserved", 8); + +/* Various non-standard processing plugins that create one or more special resources. */ +U_STRING_DECL(k_type_plugin_uca_rules, "process(uca_rules)", 18); +U_STRING_DECL(k_type_plugin_collation, "process(collation)", 18); +U_STRING_DECL(k_type_plugin_transliterator, "process(transliterator)", 23); +U_STRING_DECL(k_type_plugin_dependency, "process(dependency)", 19); + +typedef enum EResourceType +{ + RT_UNKNOWN, + RT_STRING, + RT_BINARY, + RT_TABLE, + RT_TABLE_NO_FALLBACK, + RT_INTEGER, + RT_ARRAY, + RT_ALIAS, + RT_INTVECTOR, + RT_IMPORT, + RT_INCLUDE, + RT_PROCESS_UCA_RULES, + RT_PROCESS_COLLATION, + RT_PROCESS_TRANSLITERATOR, + RT_PROCESS_DEPENDENCY, + RT_RESERVED +} EResourceType; + +static struct { + const char *nameChars; /* only used for debugging */ + const UChar *nameUChars; + ParseResourceFunction *parseFunction; +} gResourceTypes[] = { + {"Unknown", NULL, NULL}, + {"string", k_type_string, parseString}, + {"binary", k_type_binary, parseBinary}, + {"table", k_type_table, parseTable}, + {"table(nofallback)", k_type_table_no_fallback, NULL}, /* parseFunction will never be called */ + {"integer", k_type_integer, parseInteger}, + {"array", k_type_array, parseArray}, + {"alias", k_type_alias, parseAlias}, + {"intvector", k_type_intvector, parseIntVector}, + {"import", k_type_import, parseImport}, + {"include", k_type_include, parseInclude}, + {"process(uca_rules)", k_type_plugin_uca_rules, parseUCARules}, + {"process(collation)", k_type_plugin_collation, NULL /* not implemented yet */}, + {"process(transliterator)", k_type_plugin_transliterator, parseTransliterator}, + {"process(dependency)", k_type_plugin_dependency, parseDependency}, + {"reserved", NULL, NULL} +}; + +void initParser(UBool makeBinaryCollation) +{ + uint32_t i; + + U_STRING_INIT(k_type_string, "string", 6); + U_STRING_INIT(k_type_binary, "binary", 6); + U_STRING_INIT(k_type_bin, "bin", 3); + U_STRING_INIT(k_type_table, "table", 5); + U_STRING_INIT(k_type_table_no_fallback, "table(nofallback)", 17); + U_STRING_INIT(k_type_int, "int", 3); + U_STRING_INIT(k_type_integer, "integer", 7); + U_STRING_INIT(k_type_array, "array", 5); + U_STRING_INIT(k_type_alias, "alias", 5); + U_STRING_INIT(k_type_intvector, "intvector", 9); + U_STRING_INIT(k_type_import, "import", 6); + U_STRING_INIT(k_type_reserved, "reserved", 8); + U_STRING_INIT(k_type_include, "include", 7); + + U_STRING_INIT(k_type_plugin_uca_rules, "process(uca_rules)", 18); + U_STRING_INIT(k_type_plugin_collation, "process(collation)", 18); + U_STRING_INIT(k_type_plugin_transliterator, "process(transliterator)", 23); + U_STRING_INIT(k_type_plugin_dependency, "process(dependency)", 19); + + for (i = 0; i < MAX_LOOKAHEAD + 1; i++) + { + ustr_init(&lookahead[i].value); + } + gMakeBinaryCollation = makeBinaryCollation; +} + +static U_INLINE UBool isTable(enum EResourceType type) { + return (UBool)(type==RT_TABLE || type==RT_TABLE_NO_FALLBACK); +} + +static enum EResourceType +parseResourceType(UErrorCode *status) +{ + struct UString *tokenValue; + struct UString comment; + enum EResourceType result = RT_UNKNOWN; + uint32_t line=0; + ustr_init(&comment); + expect(TOK_STRING, &tokenValue, &comment, &line, status); + + if (U_FAILURE(*status)) + { + return RT_UNKNOWN; + } + + *status = U_ZERO_ERROR; + + /* Search for normal types */ + result=RT_UNKNOWN; + while (++result < RT_RESERVED) { + if (u_strcmp(tokenValue->fChars, gResourceTypes[result].nameUChars) == 0) { + break; + } + } + /* Now search for the aliases */ + if (u_strcmp(tokenValue->fChars, k_type_int) == 0) { + result = RT_INTEGER; + } + else if (u_strcmp(tokenValue->fChars, k_type_bin) == 0) { + result = RT_BINARY; + } + else if (result == RT_RESERVED) { + char tokenBuffer[1024]; + u_austrncpy(tokenBuffer, tokenValue->fChars, sizeof(tokenBuffer)); + tokenBuffer[sizeof(tokenBuffer) - 1] = 0; + *status = U_INVALID_FORMAT_ERROR; + error(line, "unknown resource type '%s'", tokenBuffer); + } + + return result; +} + +/* parse a non-top-level resource */ +static struct SResource * +parseResource(char *tag, const struct UString *comment, UErrorCode *status) +{ + enum ETokenType token; + enum EResourceType resType = RT_UNKNOWN; + ParseResourceFunction *parseFunction = NULL; + struct UString *tokenValue; + uint32_t startline; + uint32_t line; + + token = getToken(&tokenValue, NULL, &startline, status); + + if(isVerbose()){ + printf(" resource %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); + } + + /* name . [ ':' type ] '{' resource '}' */ + /* This function parses from the colon onwards. If the colon is present, parse the + type then try to parse a resource of that type. If there is no explicit type, + work it out using the lookahead tokens. */ + switch (token) + { + case TOK_EOF: + *status = U_INVALID_FORMAT_ERROR; + error(startline, "Unexpected EOF encountered"); + return NULL; + + case TOK_ERROR: + *status = U_INVALID_FORMAT_ERROR; + return NULL; + + case TOK_COLON: + resType = parseResourceType(status); + expect(TOK_OPEN_BRACE, &tokenValue, NULL, &startline, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + + break; + + case TOK_OPEN_BRACE: + break; + + default: + *status = U_INVALID_FORMAT_ERROR; + error(startline, "syntax error while reading a resource, expected '{' or ':'"); + return NULL; + } + + if (resType == RT_UNKNOWN) + { + /* No explicit type, so try to work it out. At this point, we've read the first '{'. + We could have any of the following: + { { => array (nested) + { :/} => array + { string , => string array + + commented by Jing/GCL + { string { => table + + added by Jing/GCL + + { string :/{ => table + { string } => string + */ + + token = peekToken(0, NULL, &line, NULL,status); + + if (U_FAILURE(*status)) + { + return NULL; + } + + /* Commented by Jing/GCL */ + /* if (token == TOK_OPEN_BRACE || token == TOK_COLON )*/ + if (token == TOK_OPEN_BRACE || token == TOK_COLON ||token ==TOK_CLOSE_BRACE ) + { + resType = RT_ARRAY; + } + else if (token == TOK_STRING) + { + token = peekToken(1, NULL, &line, NULL, status); + + if (U_FAILURE(*status)) + { + return NULL; + } + + switch (token) + { + case TOK_COMMA: resType = RT_ARRAY; break; + case TOK_OPEN_BRACE: resType = RT_TABLE; break; + case TOK_CLOSE_BRACE: resType = RT_STRING; break; + /* added by Jing/GCL to make table work when :table is omitted */ + case TOK_COLON: resType = RT_TABLE; break; + default: + *status = U_INVALID_FORMAT_ERROR; + error(line, "Unexpected token after string, expected ',', '{' or '}'"); + return NULL; + } + } + else + { + *status = U_INVALID_FORMAT_ERROR; + error(line, "Unexpected token after '{'"); + return NULL; + } + + /* printf("Type guessed as %s\n", resourceNames[resType]); */ + } else if(resType == RT_TABLE_NO_FALLBACK) { + *status = U_INVALID_FORMAT_ERROR; + error(startline, "error: %s resource type not valid except on top bundle level", gResourceTypes[resType].nameChars); + return NULL; + } + + /* We should now know what we need to parse next, so call the appropriate parser + function and return. */ + parseFunction = gResourceTypes[resType].parseFunction; + if (parseFunction != NULL) { + return parseFunction(tag, startline, comment, status); + } + else { + *status = U_INTERNAL_PROGRAM_ERROR; + error(startline, "internal error: %s resource type found and not handled", gResourceTypes[resType].nameChars); + } + + return NULL; +} + +/* parse the top-level resource */ +struct SRBRoot * +parse(UCHARBUF *buf, const char *inputDir, const char *outputDir, UErrorCode *status) +{ + struct UString *tokenValue; + struct UString comment; + uint32_t line; + /* added by Jing/GCL */ + enum EResourceType bundleType; + enum ETokenType token; + + initLookahead(buf, status); + + inputdir = inputDir; + inputdirLength = (inputdir != NULL) ? (uint32_t)uprv_strlen(inputdir) : 0; + outputdir = outputDir; + outputdirLength = (outputdir != NULL) ? (uint32_t)uprv_strlen(outputdir) : 0; + + ustr_init(&comment); + expect(TOK_STRING, &tokenValue, &comment, NULL, status); + + bundle = bundle_open(&comment, status); + + if (bundle == NULL || U_FAILURE(*status)) + { + return NULL; + } + + + bundle_setlocale(bundle, tokenValue->fChars, status); + /* Commented by Jing/GCL */ + /* expect(TOK_OPEN_BRACE, NULL, &line, status); */ + /* The following code is to make Empty bundle work no matter with :table specifer or not */ + token = getToken(NULL, NULL, &line, status); + if(token==TOK_COLON) { + *status=U_ZERO_ERROR; + bundleType=parseResourceType(status); + + if(isTable(bundleType)) + { + expect(TOK_OPEN_BRACE, NULL, NULL, &line, status); + } + else + { + *status=U_PARSE_ERROR; + error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); + } + } + else + { + /* not a colon */ + if(token==TOK_OPEN_BRACE) + { + *status=U_ZERO_ERROR; + bundleType=RT_TABLE; + } + else + { + /* neither colon nor open brace */ + *status=U_PARSE_ERROR; + bundleType=RT_UNKNOWN; + error(line, "parse error, did not find open-brace '{' or colon ':', stopped with %s", u_errorName(*status)); + } + } + /* The above is added by Jing/GCL */ + + if (U_FAILURE(*status)) + { + bundle_close(bundle, status); + return NULL; + } + + if(bundleType==RT_TABLE_NO_FALLBACK) { + /* + * Parse a top-level table with the table(nofallback) declaration. + * This is the same as a regular table, but also sets the + * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] . + */ + bundle->noFallback=TRUE; + } + /* top-level tables need not handle special table names like "collations" */ + realParseTable(bundle->fRoot, NULL, line, status); + + if(dependencyArray!=NULL){ + table_add(bundle->fRoot, dependencyArray, 0, status); + dependencyArray = NULL; + } + if (U_FAILURE(*status)) + { + bundle_close(bundle, status); + array_close(dependencyArray, status); + return NULL; + } + + if (getToken(NULL, NULL, &line, status) != TOK_EOF) + { + warning(line, "extraneous text after resource bundle (perhaps unmatched braces)"); + if(isStrict()){ + *status = U_INVALID_FORMAT_ERROR; + return NULL; + } + } + + return bundle; +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/parse.h b/Build/source/libs/icu/icu-xetex/tools/genrb/parse.h new file mode 100644 index 00000000000..da5b345beb1 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/parse.h @@ -0,0 +1,35 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File parse.h +* +* Modification History: +* +* Date Name Description +* 05/26/99 stephen Creation. +******************************************************************************* +*/ + +#ifndef PARSE_H +#define PARSE_H 1 + +#include "unicode/utypes.h" +#include "filestrm.h" +#include "ucbuf.h" + +U_CDECL_BEGIN +/* One time parser initalisation */ +void initParser(UBool makeBinaryCollation); + +/* Parse a ResourceBundle text file */ +struct SRBRoot* parse(UCHARBUF *buf, const char* inputDir, const char* outputDir, UErrorCode *status); + +U_CDECL_END + +#endif + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.cpp b/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.cpp new file mode 100644 index 00000000000..758cf831cee --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.cpp @@ -0,0 +1,234 @@ +/* + ******************************************************************************* + * Copyright (C) 2003-2007, International Business Machines + * Corporation and others. All Rights Reserved. + ******************************************************************************* + * + * File prscmnts.cpp + * + * Modification History: + * + * Date Name Description + * 08/22/2003 ram Creation. + ******************************************************************************* + */ + +#include "unicode/regex.h" +#include "unicode/unistr.h" +#include "unicode/parseerr.h" +#include "prscmnts.h" +#include <stdio.h> +#include <stdlib.h> + +U_NAMESPACE_USE + +#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when RegularExpressions not available */ + +#define MAX_SPLIT_STRINGS 20 + +const char *patternStrings[UPC_LIMIT]={ + "^translate\\s*(.*)", + "^note\\s*(.*)" +}; + +U_CFUNC int32_t +removeText(UChar *source, int32_t srcLen, + UnicodeString patString,uint32_t options, + UnicodeString replaceText, UErrorCode *status){ + + if(status == NULL || U_FAILURE(*status)){ + return 0; + } + + UnicodeString src(source, srcLen); + + RegexMatcher myMatcher(patString, src, options, *status); + if(U_FAILURE(*status)){ + return 0; + } + UnicodeString dest; + + + dest = myMatcher.replaceAll(replaceText,*status); + + + return dest.extract(source, srcLen, *status); + +} +U_CFUNC int32_t +trim(UChar *src, int32_t srcLen, UErrorCode *status){ + srcLen = removeText(src, srcLen, "^[ \\r\\n]+ ", 0, "", status); // remove leading new lines + srcLen = removeText(src, srcLen, "^\\s+", 0, "", status); // remove leading spaces + srcLen = removeText(src, srcLen, "\\s+$", 0, "", status); // remvoe trailing spcaes + return srcLen; +} + +U_CFUNC int32_t +removeCmtText(UChar* source, int32_t srcLen, UErrorCode* status){ + srcLen = trim(source, srcLen, status); + UnicodeString patString = "^\\s*?\\*\\s*?"; // remove pattern like " * " at the begining of the line + srcLen = removeText(source, srcLen, patString, UREGEX_MULTILINE, "", status); + return removeText(source, srcLen, "[ \\r\\n]+", 0, " ", status);// remove new lines; +} + +U_CFUNC int32_t +getText(const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UnicodeString patternString, + UErrorCode* status){ + + if(status == NULL || U_FAILURE(*status)){ + return 0; + } + + UnicodeString stringArray[MAX_SPLIT_STRINGS]; + RegexPattern *pattern = RegexPattern::compile("@", 0, *status); + UnicodeString src (source,srcLen); + + if (U_FAILURE(*status)) { + return 0; + } + pattern->split(src, stringArray, MAX_SPLIT_STRINGS, *status); + + RegexMatcher matcher(patternString, UREGEX_DOTALL, *status); + if (U_FAILURE(*status)) { + return 0; + } + for(int32_t i=0; i<MAX_SPLIT_STRINGS; i++){ + matcher.reset(stringArray[i]); + if(matcher.lookingAt(*status)){ + UnicodeString out = matcher.group(1, *status); + + return out.extract(*dest, destCapacity,*status); + } + } + return 0; +} + + +#define AT_SIGN 0x0040 + +U_CFUNC int32_t +getDescription( const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status){ + if(status == NULL || U_FAILURE(*status)){ + return 0; + } + + UnicodeString stringArray[MAX_SPLIT_STRINGS]; + RegexPattern *pattern = RegexPattern::compile("@", UREGEX_MULTILINE, *status); + UnicodeString src(source, srcLen); + + if (U_FAILURE(*status)) { + return 0; + } + pattern->split(src, stringArray,MAX_SPLIT_STRINGS , *status); + + if(stringArray[0].indexOf((UChar)AT_SIGN)==-1){ + int32_t destLen = stringArray[0].extract(*dest, destCapacity, *status); + return trim(*dest, destLen, status); + } + return 0; +} + +U_CFUNC int32_t +getCount(const UChar* source, int32_t srcLen, + UParseCommentsOption option, UErrorCode *status){ + + if(status == NULL || U_FAILURE(*status)){ + return 0; + } + + UnicodeString stringArray[MAX_SPLIT_STRINGS]; + RegexPattern *pattern = RegexPattern::compile("@", UREGEX_MULTILINE, *status); + UnicodeString src (source, srcLen); + + + if (U_FAILURE(*status)) { + return 0; + } + int32_t retLen = pattern->split(src, stringArray, MAX_SPLIT_STRINGS, *status); + + RegexMatcher matcher(patternStrings[option], UREGEX_DOTALL, *status); + if (U_FAILURE(*status)) { + return 0; + } + int32_t count = 0; + for(int32_t i=0; i<retLen; i++){ + matcher.reset(stringArray[i]); + if(matcher.lookingAt(*status)){ + count++; + } + } + if(option == UPC_TRANSLATE && count > 1){ + fprintf(stderr, "Multiple @translate tags cannot be supported.\n"); + exit(U_UNSUPPORTED_ERROR); + } + return count; +} + +U_CFUNC int32_t +getAt(const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + int32_t index, + UParseCommentsOption option, + UErrorCode* status){ + + if(status == NULL || U_FAILURE(*status)){ + return 0; + } + + UnicodeString stringArray[MAX_SPLIT_STRINGS]; + RegexPattern *pattern = RegexPattern::compile("@", UREGEX_MULTILINE, *status); + UnicodeString src (source, srcLen); + + + if (U_FAILURE(*status)) { + return 0; + } + int32_t retLen = pattern->split(src, stringArray, MAX_SPLIT_STRINGS, *status); + + RegexMatcher matcher(patternStrings[option], UREGEX_DOTALL, *status); + if (U_FAILURE(*status)) { + return 0; + } + int32_t count = 0; + for(int32_t i=0; i<retLen; i++){ + matcher.reset(stringArray[i]); + if(matcher.lookingAt(*status)){ + if(count == index){ + UnicodeString out = matcher.group(1, *status); + return out.extract(*dest, destCapacity,*status); + } + count++; + + } + } + return 0; + +} + +U_CFUNC int32_t +getTranslate( const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status){ + UnicodeString notePatternString = "^translate\\s*?(.*)"; + + int32_t destLen = getText(source, srcLen, dest, destCapacity, notePatternString, status); + return trim(*dest, destLen, status); +} + +U_CFUNC int32_t +getNote(const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status){ + + UnicodeString notePatternString = "^note\\s*?(.*)"; + int32_t destLen = getText(source, srcLen, dest, destCapacity, notePatternString, status); + return trim(*dest, destLen, status); + +} + +#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.h b/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.h new file mode 100644 index 00000000000..c4f27054567 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/prscmnts.h @@ -0,0 +1,62 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File read.h +* +* Modification History: +* +* Date Name Description +* 05/26/99 stephen Creation. +* 5/10/01 Ram removed ustdio dependency +******************************************************************************* +*/ + +#ifndef PRSCMNTS_H +#define PRSCMNTS_H 1 + +#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */ + +enum UParseCommentsOption { + UPC_TRANSLATE, + UPC_NOTE, + UPC_LIMIT +}; + +typedef enum UParseCommentsOption UParseCommentsOption; + +U_CFUNC int32_t +getNote(const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status); +U_CFUNC int32_t +removeCmtText(UChar* source, int32_t srcLen, UErrorCode* status); + +U_CFUNC int32_t +getDescription( const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status); +U_CFUNC int32_t +getTranslate( const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + UErrorCode* status); + +U_CFUNC int32_t +getAt(const UChar* source, int32_t srcLen, + UChar** dest, int32_t destCapacity, + int32_t index, + UParseCommentsOption option, + UErrorCode* status); + +U_CFUNC int32_t +getCount(const UChar* source, int32_t srcLen, + UParseCommentsOption option, UErrorCode *status); + +#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ + +#endif + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.c b/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.c new file mode 100644 index 00000000000..92d45fd7f5a --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.c @@ -0,0 +1,108 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File util.c +* +* Modification History: +* +* Date Name Description +* 06/10/99 stephen Creation. +******************************************************************************* +*/ + +#include "unicode/putil.h" +#include "rbutil.h" +#include "cmemory.h" +#include "cstring.h" + + +/* go from "/usr/local/include/curses.h" to "/usr/local/include" */ +void +get_dirname(char *dirname, + const char *filename) +{ + const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR) + 1; + + if(lastSlash>filename) { + uprv_strncpy(dirname, filename, (lastSlash - filename)); + *(dirname + (lastSlash - filename)) = '\0'; + } else { + *dirname = '\0'; + } +} + +/* go from "/usr/local/include/curses.h" to "curses" */ +void +get_basename(char *basename, + const char *filename) +{ + /* strip off any leading directory portions */ + const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR) + 1; + char *lastDot; + + if(lastSlash>filename) { + uprv_strcpy(basename, lastSlash); + } else { + uprv_strcpy(basename, filename); + } + + /* strip off any suffix */ + lastDot = uprv_strrchr(basename, '.'); + + if(lastDot != NULL) { + *lastDot = '\0'; + } +} + +#define MAX_DIGITS 10 +int32_t +itostr(char * buffer, int32_t i, uint32_t radix, int32_t pad) +{ + int32_t length = 0; + int32_t num = 0; + int32_t save = i; + int digit; + int32_t j; + char temp; + + /* if i is negative make it positive */ + if(i<0){ + i=-i; + } + + do{ + digit = (int)(i % radix); + buffer[length++]=(char)(digit<=9?(0x0030+digit):(0x0030+digit+7)); + i=i/radix; + } while(i); + + while (length < pad){ + buffer[length++] = 0x0030;/*zero padding */ + } + + /* if i is negative add the negative sign */ + if(save < 0){ + buffer[length++]='-'; + } + + /* null terminate the buffer */ + if(length<MAX_DIGITS){ + buffer[length] = 0x0000; + } + + num= (pad>=length) ? pad :length; + + + /* Reverses the string */ + for (j = 0; j < (num / 2); j++){ + temp = buffer[(length-1) - j]; + buffer[(length-1) - j] = buffer[j]; + buffer[j] = temp; + } + return length; +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.h b/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.h new file mode 100644 index 00000000000..b059bfa00d4 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/rbutil.h @@ -0,0 +1,28 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File rbutil.h +* +* Modification History: +* +* Date Name Description +* 06/10/99 stephen Creation. +******************************************************************************* +*/ + +#ifndef UTIL_H +#define UTIL_H 1 + +U_CDECL_BEGIN + +void get_dirname(char *dirname, const char *filename); +void get_basename(char *basename, const char *filename); +int32_t itostr(char * buffer, int32_t i, uint32_t radix, int32_t pad); +U_CDECL_END +#endif /* ! UTIL_H */ + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/read.c b/Build/source/libs/icu/icu-xetex/tools/genrb/read.c new file mode 100644 index 00000000000..be8cea118ef --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/read.c @@ -0,0 +1,473 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File read.c +* +* Modification History: +* +* Date Name Description +* 05/26/99 stephen Creation. +* 5/10/01 Ram removed ustdio dependency +******************************************************************************* +*/ + +#include "read.h" +#include "errmsg.h" +#include "unicode/ustring.h" + +#define OPENBRACE 0x007B +#define CLOSEBRACE 0x007D +#define COMMA 0x002C +#define QUOTE 0x0022 +#define ESCAPE 0x005C +#define SLASH 0x002F +#define ASTERISK 0x002A +#define SPACE 0x0020 +#define COLON 0x003A +#define BADBOM 0xFFFE +#define CR 0x000D +#define LF 0x000A + +static int32_t lineCount; + +/* Protos */ +static enum ETokenType getStringToken(UCHARBUF *buf, + UChar32 initialChar, + struct UString *token, + UErrorCode *status); + +static UChar32 getNextChar (UCHARBUF *buf, UBool skipwhite, struct UString *token, UErrorCode *status); +static void seekUntilNewline (UCHARBUF *buf, struct UString *token, UErrorCode *status); +static void seekUntilEndOfComment (UCHARBUF *buf, struct UString *token, UErrorCode *status); +static UBool isWhitespace (UChar32 c); +static UBool isNewline (UChar32 c); + +void resetLineNumber() { + lineCount = 1; +} + +/* Read and return the next token from the stream. If the token is of + type eString, fill in the token parameter with the token. If the + token is eError, then the status parameter will contain the + specific error. This will be eItemNotFound at the end of file, + indicating that all tokens have been returned. This method will + never return eString twice in a row; instead, multiple adjacent + string tokens will be merged into one, with no intervening + space. */ +enum ETokenType getNextToken(UCHARBUF* buf, + struct UString *token, + uint32_t *linenumber, /* out: linenumber of token */ + struct UString *comment, + UErrorCode *status) { + enum ETokenType result; + UChar32 c; + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + /* Skip whitespace */ + c = getNextChar(buf, TRUE, comment, status); + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + *linenumber = lineCount; + + switch(c) { + case BADBOM: + return TOK_ERROR; + case OPENBRACE: + return TOK_OPEN_BRACE; + case CLOSEBRACE: + return TOK_CLOSE_BRACE; + case COMMA: + return TOK_COMMA; + case U_EOF: + return TOK_EOF; + case COLON: + return TOK_COLON; + + default: + result = getStringToken(buf, c, token, status); + } + + *linenumber = lineCount; + return result; +} + +/* Copy a string token into the given UnicodeString. Upon entry, we + have already read the first character of the string token, which is + not a whitespace character (but may be a QUOTE or ESCAPE). This + function reads all subsequent characters that belong with this + string, and copy them into the token parameter. The other + important, and slightly convoluted purpose of this function is to + merge adjacent strings. It looks forward a bit, and if the next + non comment, non whitespace item is a string, it reads it in as + well. If two adjacent strings are quoted, they are merged without + intervening space. Otherwise a single SPACE character is + inserted. */ +static enum ETokenType getStringToken(UCHARBUF* buf, + UChar32 initialChar, + struct UString *token, + UErrorCode *status) { + UBool lastStringWasQuoted; + UChar32 c; + UChar target[3] = { '\0' }; + UChar *pTarget = target; + int len=0; + UBool isFollowingCharEscaped=FALSE; + UBool isNLUnescaped = FALSE; + UChar32 prevC=0; + + /* We are guaranteed on entry that initialChar is not a whitespace + character. If we are at the EOF, or have some other problem, it + doesn't matter; we still want to validly return the initialChar + (if nothing else) as a string token. */ + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + /* setup */ + lastStringWasQuoted = FALSE; + c = initialChar; + ustr_setlen(token, 0, status); + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + for (;;) { + if (c == QUOTE) { + if (!lastStringWasQuoted && token->fLength > 0) { + ustr_ucat(token, SPACE, status); + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + } + + lastStringWasQuoted = TRUE; + + for (;;) { + c = ucbuf_getc(buf,status); + + /* EOF reached */ + if (c == U_EOF) { + return TOK_EOF; + } + + /* Unterminated quoted strings */ + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + if (c == QUOTE && !isFollowingCharEscaped) { + break; + } + + if (c == ESCAPE && !isFollowingCharEscaped) { + pTarget = target; + c = unescape(buf, status); + + if (c == U_ERR) { + return TOK_ERROR; + } + if(c == CR || c == LF){ + isNLUnescaped = TRUE; + } + } + + if(c==ESCAPE && !isFollowingCharEscaped){ + isFollowingCharEscaped = TRUE; + }else{ + U_APPEND_CHAR32(c, pTarget,len); + pTarget = target; + ustr_uscat(token, pTarget,len, status); + isFollowingCharEscaped = FALSE; + len=0; + if(c == CR || c == LF){ + if(isNLUnescaped == FALSE && prevC!=CR){ + lineCount++; + } + isNLUnescaped = FALSE; + } + } + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + prevC = c; + } + } else { + if (token->fLength > 0) { + ustr_ucat(token, SPACE, status); + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + } + + if(lastStringWasQuoted){ + if(getShowWarning()){ + warning(lineCount, "Mixing quoted and unquoted strings"); + } + if(isStrict()){ + return TOK_ERROR; + } + + } + + lastStringWasQuoted = FALSE; + + /* if we reach here we are mixing + * quoted and unquoted strings + * warn in normal mode and error in + * pedantic mode + */ + + if (c == ESCAPE) { + pTarget = target; + c = unescape(buf, status); + + /* EOF reached */ + if (c == U_EOF) { + return TOK_ERROR; + } + } + + U_APPEND_CHAR32(c, pTarget,len); + pTarget = target; + ustr_uscat(token, pTarget,len, status); + len=0; + + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + + for (;;) { + /* DON'T skip whitespace */ + c = getNextChar(buf, FALSE, NULL, status); + + /* EOF reached */ + if (c == U_EOF) { + ucbuf_ungetc(c, buf); + return TOK_STRING; + } + + if (U_FAILURE(*status)) { + return TOK_STRING; + } + + if (c == QUOTE + || c == OPENBRACE + || c == CLOSEBRACE + || c == COMMA + || c == COLON) { + ucbuf_ungetc(c, buf); + break; + } + + if (isWhitespace(c)) { + break; + } + + if (c == ESCAPE) { + pTarget = target; + c = unescape(buf, status); + + if (c == U_ERR) { + return TOK_ERROR; + } + } + + U_APPEND_CHAR32(c, pTarget,len); + pTarget = target; + ustr_uscat(token, pTarget,len, status); + len=0; + if (U_FAILURE(*status)) { + return TOK_ERROR; + } + } + } + + /* DO skip whitespace */ + c = getNextChar(buf, TRUE, NULL, status); + + if (U_FAILURE(*status)) { + return TOK_STRING; + } + + if (c == OPENBRACE || c == CLOSEBRACE || c == COMMA || c == COLON) { + ucbuf_ungetc(c, buf); + return TOK_STRING; + } + } +} + +/* Retrieve the next character. If skipwhite is + true, whitespace is skipped as well. */ +static UChar32 getNextChar(UCHARBUF* buf, + UBool skipwhite, + struct UString *token, + UErrorCode *status) { + UChar32 c, c2; + + if (U_FAILURE(*status)) { + return U_EOF; + } + + for (;;) { + c = ucbuf_getc(buf,status); + + if (c == U_EOF) { + return U_EOF; + } + + if (skipwhite && isWhitespace(c)) { + continue; + } + + /* This also handles the get() failing case */ + if (c != SLASH) { + return c; + } + + c = ucbuf_getc(buf,status); + + if (c == U_EOF) { + return U_EOF; + } + + switch (c) { + case SLASH: + seekUntilNewline(buf, NULL, status); + break; + + case ASTERISK: + c2 = ucbuf_getc(buf, status); + if(c2== ASTERISK){ + /* parse multi-line comment and store it in token*/ + seekUntilEndOfComment(buf, token, status); + }else{ + ucbuf_ungetc(c, buf); + seekUntilEndOfComment(buf, NULL, status); + } + break; + + default: + ucbuf_ungetc(c, buf); + /* If get() failed this is a NOP */ + return SLASH; + } + + } +} + +static void seekUntilNewline(UCHARBUF* buf, + struct UString *token, + UErrorCode *status) { + UChar32 c; + + if (U_FAILURE(*status)) { + return; + } + + do { + c = ucbuf_getc(buf,status); + /* add the char to token */ + if(token!=NULL){ + ustr_u32cat(token, c, status); + } + } while (!isNewline(c) && c != U_EOF && *status == U_ZERO_ERROR); +} + +static void seekUntilEndOfComment(UCHARBUF *buf, + struct UString *token, + UErrorCode *status) { + UChar32 c, d; + uint32_t line; + + if (U_FAILURE(*status)) { + return; + } + + line = lineCount; + + do { + c = ucbuf_getc(buf, status); + + if (c == ASTERISK) { + d = ucbuf_getc(buf, status); + + if (d != SLASH) { + ucbuf_ungetc(d, buf); + } else { + break; + } + } + /* add the char to token */ + if(token!=NULL){ + ustr_u32cat(token, c, status); + } + /* increment the lineCount */ + isNewline(c); + + } while (c != U_EOF && *status == U_ZERO_ERROR); + + if (c == U_EOF) { + *status = U_INVALID_FORMAT_ERROR; + error(line, "unterminated comment detected"); + } +} + +UChar32 unescape(UCHARBUF *buf, + UErrorCode *status) { + if (U_FAILURE(*status)) { + return U_EOF; + } + + /* We expect to be called after the ESCAPE has been seen, but + * u_fgetcx needs an ESCAPE to do its magic. */ + ucbuf_ungetc(ESCAPE, buf); + + return ucbuf_getcx32(buf, status); +} + +static UBool isWhitespace(UChar32 c) { + switch (c) { + /* ' ', '\t', '\n', '\r', 0x2029, 0xFEFF */ + case 0x000A: + case 0x2029: + lineCount++; + case 0x000D: + case 0x0020: + case 0x0009: + case 0xFEFF: + return TRUE; + + default: + return FALSE; + } +} + +static UBool isNewline(UChar32 c) { + switch (c) { + /* '\n', '\r', 0x2029 */ + case 0x000A: + case 0x2029: + lineCount++; + case 0x000D: + return TRUE; + + default: + return FALSE; + } +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/read.h b/Build/source/libs/icu/icu-xetex/tools/genrb/read.h new file mode 100644 index 00000000000..96bd9608128 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/read.h @@ -0,0 +1,51 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File read.h +* +* Modification History: +* +* Date Name Description +* 05/26/99 stephen Creation. +* 5/10/01 Ram removed ustdio dependency +******************************************************************************* +*/ + +#ifndef READ_H +#define READ_H 1 + +#include "unicode/utypes.h" +#include "ustr.h" +#include "ucbuf.h" + +/* The types of tokens which may be returned by getNextToken. + NOTE: Keep these in sync with tokenNames in parse.c */ +enum ETokenType +{ + TOK_STRING, /* A string token, such as "MonthNames" */ + TOK_OPEN_BRACE, /* An opening brace character */ + TOK_CLOSE_BRACE, /* A closing brace character */ + TOK_COMMA, /* A comma */ + TOK_COLON, /* A colon */ + + TOK_EOF, /* End of the file has been reached successfully */ + TOK_ERROR, /* An error, such an unterminated quoted string */ + TOK_TOKEN_COUNT /* Number of "real" token types */ +}; + +UChar32 unescape(UCHARBUF *buf, UErrorCode *status); + +void resetLineNumber(void); + +enum ETokenType getNextToken(UCHARBUF *buf, + struct UString *token, + uint32_t *linenumber, /* out: linenumber of token */ + struct UString *comment, + UErrorCode *status); + +#endif diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.c b/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.c new file mode 100644 index 00000000000..9f30ca9c108 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.c @@ -0,0 +1,1041 @@ +/* +******************************************************************************* +* +* Copyright (C) 2000-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File reslist.c +* +* Modification History: +* +* Date Name Description +* 02/21/00 weiv Creation. +******************************************************************************* +*/ + +#include <assert.h> +#include <stdio.h> +#include "reslist.h" +#include "unewdata.h" +#include "unicode/ures.h" +#include "unicode/putil.h" +#include "errmsg.h" + +#define BIN_ALIGNMENT 16 + +static UBool gIncludeCopyright = FALSE; + +uint32_t res_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status); + +static const UDataInfo dataInfo= { + sizeof(UDataInfo), + 0, + + U_IS_BIG_ENDIAN, + U_CHARSET_FAMILY, + sizeof(UChar), + 0, + + {0x52, 0x65, 0x73, 0x42}, /* dataFormat="resb" */ + {1, 2, 0, 0}, /* formatVersion */ + {1, 4, 0, 0} /* dataVersion take a look at version inside parsed resb*/ +}; + +static uint8_t calcPadding(uint32_t size) { + /* returns space we need to pad */ + return (uint8_t) ((size % sizeof(uint32_t)) ? (sizeof(uint32_t) - (size % sizeof(uint32_t))) : 0); + +} + +void setIncludeCopyright(UBool val){ + gIncludeCopyright=val; +} + +UBool getIncludeCopyright(void){ + return gIncludeCopyright; +} + +/* Writing Functions */ +static uint32_t string_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + udata_write32(mem, res->u.fString.fLength); + udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1); + udata_writePadding(mem, calcPadding(res->fSize)); + + return usedOffset; +} + +/* Writing Functions */ +static uint32_t alias_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + udata_write32(mem, res->u.fString.fLength); + udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1); + udata_writePadding(mem, calcPadding(res->fSize)); + + return usedOffset; +} + +static uint32_t array_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + uint32_t *resources = NULL; + uint32_t i = 0; + + struct SResource *current = NULL; + + if (U_FAILURE(*status)) { + return 0; + } + + if (res->u.fArray.fCount > 0) { + resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fArray.fCount); + + if (resources == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + + current = res->u.fArray.fFirst; + i = 0; + + while (current != NULL) { + if (current->fType == URES_INT) { + resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF); + } else if (current->fType == URES_BINARY) { + uint32_t uo = usedOffset; + + usedOffset = res_write(mem, current, usedOffset, status); + resources[i] = (current->fType << 28) | (usedOffset >> 2); + usedOffset += current->fSize + calcPadding(current->fSize) - (usedOffset - uo); + } else { + usedOffset = res_write(mem, current, usedOffset, status); + resources[i] = (current->fType << 28) | (usedOffset >> 2); + usedOffset += current->fSize + calcPadding(current->fSize); + } + + i++; + current = current->fNext; + } + + /* usedOffset += res->fSize + pad; */ + + udata_write32(mem, res->u.fArray.fCount); + udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fArray.fCount); + uprv_free(resources); + } else { + /* array is empty */ + udata_write32(mem, 0); + } + + return usedOffset; +} + +static uint32_t intvector_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + uint32_t i = 0; + udata_write32(mem, res->u.fIntVector.fCount); + for(i = 0; i<res->u.fIntVector.fCount; i++) { + udata_write32(mem, res->u.fIntVector.fArray[i]); + } + + return usedOffset; +} + +static uint32_t bin_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + uint32_t pad = 0; + uint32_t extrapad = calcPadding(res->fSize); + uint32_t dataStart = usedOffset + sizeof(res->u.fBinaryValue.fLength); + + if (dataStart % BIN_ALIGNMENT) { + pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT); + udata_writePadding(mem, pad); + usedOffset += pad; + } + + udata_write32(mem, res->u.fBinaryValue.fLength); + if (res->u.fBinaryValue.fLength > 0) { + udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength); + } + udata_writePadding(mem, (BIN_ALIGNMENT - pad + extrapad)); + + return usedOffset; +} + +static uint32_t int_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + return usedOffset; +} + +static uint32_t table_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + uint8_t pad = 0; + uint32_t i = 0; + uint16_t *keys16 = NULL; + int32_t *keys32 = NULL; + uint32_t *resources = NULL; + + struct SResource *current = NULL; + + if (U_FAILURE(*status)) { + return 0; + } + + pad = calcPadding(res->fSize); + + if (res->u.fTable.fCount > 0) { + if(res->fType == URES_TABLE) { + keys16 = (uint16_t *) uprv_malloc(sizeof(uint16_t) * res->u.fTable.fCount); + if (keys16 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + } else { + keys32 = (int32_t *) uprv_malloc(sizeof(int32_t) * res->u.fTable.fCount); + if (keys32 == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + } + + resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fTable.fCount); + + if (resources == NULL) { + uprv_free(keys16); + uprv_free(keys32); + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + + current = res->u.fTable.fFirst; + i = 0; + + while (current != NULL) { + assert(i < res->u.fTable.fCount); + + /* where the key is */ + if(res->fType == URES_TABLE) { + keys16[i] = (uint16_t) current->fKey; + } else { + keys32[i] = current->fKey; + } + + if (current->fType == URES_INT) { + resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF); + } else if (current->fType == URES_BINARY) { + uint32_t uo = usedOffset; + + usedOffset = res_write(mem, current, usedOffset, status); + resources[i] = (current->fType << 28) | (usedOffset >> 2); + usedOffset += current->fSize + calcPadding(current->fSize) - (usedOffset - uo); + } else { + usedOffset = res_write(mem, current, usedOffset, status); + resources[i] = (current->fType << 28) | (usedOffset >> 2); + usedOffset += current->fSize + calcPadding(current->fSize); + } + + i++; + current = current->fNext; + } + + if(res->fType == URES_TABLE) { + udata_write16(mem, (uint16_t)res->u.fTable.fCount); + + udata_writeBlock(mem, keys16, sizeof(uint16_t) * res->u.fTable.fCount); + udata_writePadding(mem, pad); + } else { + udata_write32(mem, res->u.fTable.fCount); + + udata_writeBlock(mem, keys32, sizeof(int32_t) * res->u.fTable.fCount); + } + + udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fTable.fCount); + + uprv_free(keys16); + uprv_free(keys32); + uprv_free(resources); + } else { + /* table is empty */ + if(res->fType == URES_TABLE) { + udata_write16(mem, 0); + udata_writePadding(mem, pad); + } else { + udata_write32(mem, 0); + } + } + + return usedOffset; +} + +uint32_t res_write(UNewDataMemory *mem, struct SResource *res, + uint32_t usedOffset, UErrorCode *status) { + if (U_FAILURE(*status)) { + return 0; + } + + if (res != NULL) { + switch (res->fType) { + case URES_STRING: + return string_write (mem, res, usedOffset, status); + case URES_ALIAS: + return alias_write (mem, res, usedOffset, status); + case URES_INT_VECTOR: + return intvector_write (mem, res, usedOffset, status); + case URES_BINARY: + return bin_write (mem, res, usedOffset, status); + case URES_INT: + return int_write (mem, res, usedOffset, status); + case URES_ARRAY: + return array_write (mem, res, usedOffset, status); + case URES_TABLE: + case URES_TABLE32: + return table_write (mem, res, usedOffset, status); + + default: + break; + } + } + + *status = U_INTERNAL_PROGRAM_ERROR; + return 0; +} + +void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status) { + UNewDataMemory *mem = NULL; + uint8_t pad = 0; + uint32_t root = 0; + uint32_t usedOffset = 0; + uint32_t top, size; + char dataName[1024]; + int32_t indexes[URES_INDEX_TOP]; + + if (writtenFilename && writtenFilenameLen) { + *writtenFilename = 0; + } + + if (U_FAILURE(*status)) { + return; + } + + if (writtenFilename) { + int32_t off = 0, len = 0; + if (outputDir) { + len = (int32_t)uprv_strlen(outputDir); + if (len > writtenFilenameLen) { + len = writtenFilenameLen; + } + uprv_strncpy(writtenFilename, outputDir, len); + } + if (writtenFilenameLen -= len) { + off += len; + writtenFilename[off] = U_FILE_SEP_CHAR; + if (--writtenFilenameLen) { + ++off; + if(outputPkg != NULL) + { + uprv_strcpy(writtenFilename+off, outputPkg); + off += (int32_t)uprv_strlen(outputPkg); + writtenFilename[off] = '_'; + ++off; + } + + len = (int32_t)uprv_strlen(bundle->fLocale); + if (len > writtenFilenameLen) { + len = writtenFilenameLen; + } + uprv_strncpy(writtenFilename + off, bundle->fLocale, len); + if (writtenFilenameLen -= len) { + off += len; + len = 5; + if (len > writtenFilenameLen) { + len = writtenFilenameLen; + } + uprv_strncpy(writtenFilename + off, ".res", len); + } + } + } + } + + if(outputPkg) + { + uprv_strcpy(dataName, outputPkg); + uprv_strcat(dataName, "_"); + uprv_strcat(dataName, bundle->fLocale); + } + else + { + uprv_strcpy(dataName, bundle->fLocale); + } + + mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status); + if(U_FAILURE(*status)){ + return; + } + pad = calcPadding(bundle->fKeyPoint); + + usedOffset = bundle->fKeyPoint + pad ; /* top of the strings */ + + /* we're gonna put the main table at the end */ + top = usedOffset + bundle->fRoot->u.fTable.fChildrenSize; + root = (top) >> 2 | (bundle->fRoot->fType << 28); + + /* write the root item */ + udata_write32(mem, root); + + /* add to top the size of the root item */ + top += bundle->fRoot->fSize; + top += calcPadding(top); + + /* + * formatVersion 1.1 (ICU 2.8): + * write int32_t indexes[] after root and before the strings + * to make it easier to parse resource bundles in icuswap or from Java etc. + */ + uprv_memset(indexes, 0, sizeof(indexes)); + indexes[URES_INDEX_LENGTH]= URES_INDEX_TOP; + indexes[URES_INDEX_STRINGS_TOP]= (int32_t)(usedOffset>>2); + indexes[URES_INDEX_RESOURCES_TOP]= (int32_t)(top>>2); + indexes[URES_INDEX_BUNDLE_TOP]= indexes[URES_INDEX_RESOURCES_TOP]; + indexes[URES_INDEX_MAX_TABLE_LENGTH]= bundle->fMaxTableLength; + + /* + * formatVersion 1.2 (ICU 3.6): + * write indexes[URES_INDEX_ATTRIBUTES] with URES_ATT_NO_FALLBACK set or not set + * the memset() above initialized all indexes[] to 0 + */ + if(bundle->noFallback) { + indexes[URES_INDEX_ATTRIBUTES]=URES_ATT_NO_FALLBACK; + } + + /* write the indexes[] */ + udata_writeBlock(mem, indexes, sizeof(indexes)); + + /* write the table key strings */ + udata_writeBlock(mem, bundle->fKeys+URES_STRINGS_BOTTOM, + bundle->fKeyPoint-URES_STRINGS_BOTTOM); + + /* write the padding bytes after the table key strings */ + udata_writePadding(mem, pad); + + /* write all of the bundle contents: the root item and its children */ + usedOffset = res_write(mem, bundle->fRoot, usedOffset, status); + + size = udata_finish(mem, status); + if(top != size) { + fprintf(stderr, "genrb error: wrote %u bytes but counted %u\n", + (int)size, (int)top); + *status = U_INTERNAL_PROGRAM_ERROR; + } +} + +/* Opening Functions */ +struct SResource* res_open(const struct UString* comment, UErrorCode* status){ + struct SResource *res; + + if (U_FAILURE(*status)) { + return NULL; + } + + res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); + + if (res == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + uprv_memset(res, 0, sizeof(struct SResource)); + + res->fComment = NULL; + if(comment != NULL){ + res->fComment = (struct UString *) uprv_malloc(sizeof(struct UString)); + if(res->fComment == NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + ustr_init(res->fComment); + ustr_cpy(res->fComment, comment, status); + } + return res; + +} +struct SResource* table_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status) { + + struct SResource *res = res_open(comment, status); + + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + + /* + * always open a table not a table32 in case it remains empty - + * try to use table32 only when necessary + */ + res->fType = URES_TABLE; + res->fSize = sizeof(uint16_t); + + res->u.fTable.fCount = 0; + res->u.fTable.fChildrenSize = 0; + res->u.fTable.fFirst = NULL; + res->u.fTable.fRoot = bundle; + + return res; +} + +struct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) { + + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_ARRAY; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + res->fSize = sizeof(int32_t); + + res->u.fArray.fCount = 0; + res->u.fArray.fChildrenSize = 0; + res->u.fArray.fFirst = NULL; + res->u.fArray.fLast = NULL; + + return res; +} + +struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_STRING; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + + res->u.fString.fLength = len; + res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1)); + + if (res->u.fString.fChars == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + + uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1)); + res->fSize = sizeof(int32_t) + sizeof(UChar) * (len+1); + + return res; +} + +/* TODO: make alias_open and string_open use the same code */ +struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_ALIAS; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + + res->u.fString.fLength = len; + res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1)); + + if (res->u.fString.fChars == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + + uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1)); + res->fSize = sizeof(int32_t) + sizeof(UChar) * (len + 1); + + return res; +} + + +struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_INT_VECTOR; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + res->fSize = sizeof(int32_t); + + res->u.fIntVector.fCount = 0; + res->u.fIntVector.fArray = (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR); + + if (res->u.fIntVector.fArray == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + + return res; +} + +struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_INT; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fSize = 0; + res->fNext = NULL; + res->u.fIntValue.fValue = value; + + return res; +} + +struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, const struct UString* comment, UErrorCode *status) { + struct SResource *res = res_open(comment, status); + + if (U_FAILURE(*status)) { + return NULL; + } + + res->fType = URES_BINARY; + res->fKey = bundle_addtag(bundle, tag, status); + + if (U_FAILURE(*status)) { + uprv_free(res->fComment); + uprv_free(res); + return NULL; + } + + res->fNext = NULL; + + res->u.fBinaryValue.fLength = length; + res->u.fBinaryValue.fFileName = NULL; + if(fileName!=NULL && uprv_strcmp(fileName, "") !=0){ + res->u.fBinaryValue.fFileName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(fileName)+1)); + uprv_strcpy(res->u.fBinaryValue.fFileName,fileName); + } + if (length > 0) { + res->u.fBinaryValue.fData = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length); + + if (res->u.fBinaryValue.fData == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(res); + return NULL; + } + + uprv_memcpy(res->u.fBinaryValue.fData, data, length); + } + else { + res->u.fBinaryValue.fData = NULL; + } + + res->fSize = sizeof(int32_t) + sizeof(uint8_t) * length + BIN_ALIGNMENT; + + return res; +} + +struct SRBRoot *bundle_open(const struct UString* comment, UErrorCode *status) { + struct SRBRoot *bundle = NULL; + + if (U_FAILURE(*status)) { + return NULL; + } + + bundle = (struct SRBRoot *) uprv_malloc(sizeof(struct SRBRoot)); + + if (bundle == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + uprv_memset(bundle, 0, sizeof(struct SRBRoot)); + + bundle->fLocale = NULL; + + bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE); + bundle->fKeysCapacity = KEY_SPACE_SIZE; + + if(comment != NULL){ + + } + + if (bundle->fKeys == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(bundle); + return NULL; + } + + /* formatVersion 1.1: start fKeyPoint after the root item and indexes[] */ + bundle->fKeyPoint = URES_STRINGS_BOTTOM; + uprv_memset(bundle->fKeys, 0, URES_STRINGS_BOTTOM); + + bundle->fCount = 0; + bundle->fRoot = table_open(bundle, NULL, comment, status); + + if (bundle->fRoot == NULL || U_FAILURE(*status)) { + if (U_SUCCESS(*status)) { + *status = U_MEMORY_ALLOCATION_ERROR; + } + + uprv_free(bundle->fKeys); + uprv_free(bundle); + + return NULL; + } + + return bundle; +} + +/* Closing Functions */ +void table_close(struct SResource *table, UErrorCode *status) { + struct SResource *current = NULL; + struct SResource *prev = NULL; + + current = table->u.fTable.fFirst; + + while (current != NULL) { + prev = current; + current = current->fNext; + + res_close(prev, status); + } + + table->u.fTable.fFirst = NULL; +} + +void array_close(struct SResource *array, UErrorCode *status) { + struct SResource *current = NULL; + struct SResource *prev = NULL; + + if(array==NULL){ + return; + } + current = array->u.fArray.fFirst; + + while (current != NULL) { + prev = current; + current = current->fNext; + + res_close(prev, status); + } + array->u.fArray.fFirst = NULL; +} + +void string_close(struct SResource *string, UErrorCode *status) { + if (string->u.fString.fChars != NULL) { + uprv_free(string->u.fString.fChars); + string->u.fString.fChars =NULL; + } +} + +void alias_close(struct SResource *alias, UErrorCode *status) { + if (alias->u.fString.fChars != NULL) { + uprv_free(alias->u.fString.fChars); + alias->u.fString.fChars =NULL; + } +} + +void intvector_close(struct SResource *intvector, UErrorCode *status) { + if (intvector->u.fIntVector.fArray != NULL) { + uprv_free(intvector->u.fIntVector.fArray); + intvector->u.fIntVector.fArray =NULL; + } +} + +void int_close(struct SResource *intres, UErrorCode *status) { + /* Intentionally left blank */ +} + +void bin_close(struct SResource *binres, UErrorCode *status) { + if (binres->u.fBinaryValue.fData != NULL) { + uprv_free(binres->u.fBinaryValue.fData); + binres->u.fBinaryValue.fData = NULL; + } +} + +void res_close(struct SResource *res, UErrorCode *status) { + if (res != NULL) { + switch(res->fType) { + case URES_STRING: + string_close(res, status); + break; + case URES_ALIAS: + alias_close(res, status); + break; + case URES_INT_VECTOR: + intvector_close(res, status); + break; + case URES_BINARY: + bin_close(res, status); + break; + case URES_INT: + int_close(res, status); + break; + case URES_ARRAY: + array_close(res, status); + break; + case URES_TABLE: + case URES_TABLE32: + table_close(res, status); + break; + default: + /* Shouldn't happen */ + break; + } + + uprv_free(res); + } +} + +void bundle_close(struct SRBRoot *bundle, UErrorCode *status) { + struct SResource *current = NULL; + struct SResource *prev = NULL; + + if (bundle->fRoot != NULL) { + current = bundle->fRoot->u.fTable.fFirst; + + while (current != NULL) { + prev = current; + current = current->fNext; + + res_close(prev, status); + } + + uprv_free(bundle->fRoot); + } + + if (bundle->fLocale != NULL) { + uprv_free(bundle->fLocale); + } + + if (bundle->fKeys != NULL) { + uprv_free(bundle->fKeys); + } + + uprv_free(bundle); +} + +/* Adding Functions */ +void table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status) { + struct SResource *current = NULL; + struct SResource *prev = NULL; + struct SResTable *list; + + if (U_FAILURE(*status)) { + return; + } + + /* remember this linenumber to report to the user if there is a duplicate key */ + res->line = linenumber; + + /* here we need to traverse the list */ + list = &(table->u.fTable); + + if(table->fType == URES_TABLE && res->fKey > 0xffff) { + /* this table straddles the 64k strings boundary, update to a table32 */ + table->fType = URES_TABLE32; + + /* + * increase the size because count and each string offset + * increase from uint16_t to int32_t + */ + table->fSize += (1 + list->fCount) * 2; + } + + ++(list->fCount); + if(list->fCount > (uint32_t)list->fRoot->fMaxTableLength) { + list->fRoot->fMaxTableLength = list->fCount; + } + + /* + * URES_TABLE: 6 bytes = 1 uint16_t key string offset + 1 uint32_t Resource + * URES_TABLE32: 8 bytes = 1 int32_t key string offset + 1 uint32_t Resource + */ + table->fSize += table->fType == URES_TABLE ? 6 : 8; + + table->u.fTable.fChildrenSize += res->fSize + calcPadding(res->fSize); + + if (res->fType == URES_TABLE || res->fType == URES_TABLE32) { + table->u.fTable.fChildrenSize += res->u.fTable.fChildrenSize; + } else if (res->fType == URES_ARRAY) { + table->u.fTable.fChildrenSize += res->u.fArray.fChildrenSize; + } + + /* is list still empty? */ + if (list->fFirst == NULL) { + list->fFirst = res; + res->fNext = NULL; + return; + } + + current = list->fFirst; + + while (current != NULL) { + if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) < 0) { + prev = current; + current = current->fNext; + } else if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) > 0) { + /* we're either in front of list, or in middle */ + if (prev == NULL) { + /* front of the list */ + list->fFirst = res; + } else { + /* middle of the list */ + prev->fNext = res; + } + + res->fNext = current; + return; + } else { + /* Key already exists! ERROR! */ + error(linenumber, "duplicate key '%s' in table, first appeared at line %d", list->fRoot->fKeys + current->fKey, current->line); + *status = U_UNSUPPORTED_ERROR; + return; + } + } + + /* end of list */ + prev->fNext = res; + res->fNext = NULL; +} + +void array_add(struct SResource *array, struct SResource *res, UErrorCode *status) { + if (U_FAILURE(*status)) { + return; + } + + if (array->u.fArray.fFirst == NULL) { + array->u.fArray.fFirst = res; + array->u.fArray.fLast = res; + } else { + array->u.fArray.fLast->fNext = res; + array->u.fArray.fLast = res; + } + + (array->u.fArray.fCount)++; + + array->fSize += sizeof(uint32_t); + array->u.fArray.fChildrenSize += res->fSize + calcPadding(res->fSize); + + if (res->fType == URES_TABLE || res->fType == URES_TABLE32) { + array->u.fArray.fChildrenSize += res->u.fTable.fChildrenSize; + } else if (res->fType == URES_ARRAY) { + array->u.fArray.fChildrenSize += res->u.fArray.fChildrenSize; + } +} + +void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) { + if (U_FAILURE(*status)) { + return; + } + + *(intvector->u.fIntVector.fArray + intvector->u.fIntVector.fCount) = value; + intvector->u.fIntVector.fCount++; + + intvector->fSize += sizeof(uint32_t); +} + +/* Misc Functions */ + +void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) { + + if(U_FAILURE(*status)) { + return; + } + + if (bundle->fLocale!=NULL) { + uprv_free(bundle->fLocale); + } + + bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1)); + + if(bundle->fLocale == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return; + } + + /*u_strcpy(bundle->fLocale, locale);*/ + u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1); + +} + + +int32_t +bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) { + int32_t keypos, length; + + if (U_FAILURE(*status)) { + return -1; + } + + if (tag == NULL) { + /* do not set an error: the root table has a NULL tag */ + return -1; + } + + keypos = bundle->fKeyPoint; + + bundle->fKeyPoint += length = (int32_t) (uprv_strlen(tag) + 1); + + if (bundle->fKeyPoint >= bundle->fKeysCapacity) { + /* overflow - resize the keys buffer */ + bundle->fKeysCapacity += KEY_SPACE_SIZE; + bundle->fKeys = uprv_realloc(bundle->fKeys, bundle->fKeysCapacity); + if(bundle->fKeys == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return -1; + } + } + + uprv_memcpy(bundle->fKeys + keypos, tag, length); + + return keypos; +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.h b/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.h new file mode 100644 index 00000000000..2d6a3783df6 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/reslist.h @@ -0,0 +1,152 @@ +/* +******************************************************************************* +* +* Copyright (C) 2000-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File reslist.h +* +* Modification History: +* +* Date Name Description +* 02/21/00 weiv Creation. +******************************************************************************* +*/ + +#ifndef RESLIST_H +#define RESLIST_H + +#define KEY_SPACE_SIZE 65536 +#define RESLIST_MAX_INT_VECTOR 2048 + +#include "unicode/utypes.h" +#include "unicode/ures.h" +#include "unicode/ustring.h" +#include "uresdata.h" +#include "cmemory.h" +#include "cstring.h" +#include "unewdata.h" +#include "ustr.h" + +U_CDECL_BEGIN + +/* Resource bundle root table */ +struct SRBRoot { + char *fLocale; + int32_t fKeyPoint; + char *fKeys; + int32_t fKeysCapacity; + int32_t fCount; + struct SResource *fRoot; + int32_t fMaxTableLength; + UBool noFallback; /* see URES_ATT_NO_FALLBACK */ +}; + +struct SRBRoot *bundle_open(const struct UString* comment, UErrorCode *status); +void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status); + +/* write a java resource file */ +void bundle_write_java(struct SRBRoot *bundle, const char *outputDir, const char* outputEnc, char *writtenFilename, + int writtenFilenameLen, const char* packageName, const char* bundleName, UErrorCode *status); + +/* write a xml resource file */ +/* commented by Jing*/ +/* void bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, + char *writtenFilename, int writtenFilenameLen,UErrorCode *status); */ + +/* added by Jing*/ +void bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* rbname, + char *writtenFilename, int writtenFilenameLen, const char* language, const char* package, UErrorCode *status); + +void bundle_close(struct SRBRoot *bundle, UErrorCode *status); +void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status); +int32_t bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status); + +/* Various resource types */ +struct SResource* res_open(const struct UString* comment, UErrorCode* status); + +struct SResTable { + uint32_t fCount; + uint32_t fChildrenSize; + struct SResource *fFirst; + struct SRBRoot *fRoot; +}; + +struct SResource* table_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status); +void table_close(struct SResource *table, UErrorCode *status); +void table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status); + +struct SResArray { + uint32_t fCount; + uint32_t fChildrenSize; + struct SResource *fFirst; + struct SResource *fLast; +}; + +struct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); +void array_close(struct SResource *array, UErrorCode *status); +void array_add(struct SResource *array, struct SResource *res, UErrorCode *status); + +struct SResString { + uint32_t fLength; + UChar *fChars; +}; + +struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); +void string_close(struct SResource *string, UErrorCode *status); + +struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); +void alias_close(struct SResource *string, UErrorCode *status); + +struct SResIntVector { + uint32_t fCount; + uint32_t *fArray; +}; + +struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status); +void intvector_close(struct SResource *intvector, UErrorCode *status); +void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status); + +struct SResInt { + uint32_t fValue; +}; + +struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, const struct UString* comment, UErrorCode *status); +void int_close(struct SResource *intres, UErrorCode *status); + +struct SResBinary { + uint32_t fLength; + uint8_t *fData; + char* fFileName; /* file name for binary or import binary tags if any */ +}; + +struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, const struct UString* comment, UErrorCode *status); +void bin_close(struct SResource *binres, UErrorCode *status); + +/* Resource place holder */ + +struct SResource { + UResType fType; + int32_t fKey; + uint32_t fSize; /* Size in bytes outside the header part */ + int line; /* used internally to report duplicate keys in tables */ + struct SResource *fNext; /*This is for internal chaining while building*/ + struct UString *fComment; + union { + struct SResTable fTable; + struct SResArray fArray; + struct SResString fString; + struct SResIntVector fIntVector; + struct SResInt fIntValue; + struct SResBinary fBinaryValue; + } u; +}; + +void res_close(struct SResource *res, UErrorCode *status); +void setIncludeCopyright(UBool val); +UBool getIncludeCopyright(void); + +U_CDECL_END +#endif /* #ifndef RESLIST_H */ diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/rle.c b/Build/source/libs/icu/icu-xetex/tools/genrb/rle.c new file mode 100644 index 00000000000..053cb33e49f --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/rle.c @@ -0,0 +1,405 @@ +/* +******************************************************************************* +* +* Copyright (C) 2000-2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File writejava.c +* +* Modification History: +* +* Date Name Description +* 01/11/02 Ram Creation. +******************************************************************************* +*/ +#include "rle.h" +/** + * The ESCAPE character is used during run-length encoding. It signals + * a run of identical chars. + */ +static const uint16_t ESCAPE = 0xA5A5; + +/** + * The ESCAPE_BYTE character is used during run-length encoding. It signals + * a run of identical bytes. + */ +static const uint8_t ESCAPE_BYTE = (uint8_t)0xA5; + +/** + * Append a byte to the given StringBuffer, packing two bytes into each + * character. The state parameter maintains intermediary data between + * calls. + * @param state A two-element array, with state[0] == 0 if this is the + * first byte of a pair, or state[0] != 0 if this is the second byte + * of a pair, in which case state[1] is the first byte. + */ +static uint16_t* +appendEncodedByte(uint16_t* buffer, uint16_t* buffLimit, uint8_t value, uint8_t state[],UErrorCode* status) { + if(!status || U_FAILURE(*status)){ + return NULL; + } + if (state[0] != 0) { + uint16_t c = (uint16_t) ((state[1] << 8) | (((int32_t) value) & 0xFF)); + if(buffer < buffLimit){ + *buffer++ = c; + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + } + state[0] = 0; + return buffer; + } + else { + state[0] = 1; + state[1] = value; + return buffer; + } +} +/** + * Encode a run, possibly a degenerate run (of < 4 values). + * @param length The length of the run; must be > 0 && <= 0xFF. + */ +static uint16_t* +encodeRunByte(uint16_t* buffer,uint16_t* bufLimit, uint8_t value, int32_t length, uint8_t state[], UErrorCode* status) { + if(!status || U_FAILURE(*status)){ + return NULL; + } + if (length < 4) { + int32_t j=0; + for (; j<length; ++j) { + if (value == ESCAPE_BYTE) { + buffer = appendEncodedByte(buffer,bufLimit, ESCAPE_BYTE, state,status); + } + buffer = appendEncodedByte(buffer,bufLimit, value, state, status); + } + } + else { + if (length == ESCAPE_BYTE) { + if (value == ESCAPE_BYTE){ + buffer = appendEncodedByte(buffer, bufLimit,ESCAPE_BYTE, state,status); + } + buffer = appendEncodedByte(buffer,bufLimit, value, state, status); + --length; + } + buffer = appendEncodedByte(buffer,bufLimit, ESCAPE_BYTE, state,status); + buffer = appendEncodedByte(buffer,bufLimit, (char)length, state, status); + buffer = appendEncodedByte(buffer,bufLimit, value, state, status); /* Don't need to escape this value*/ + } + return buffer; +} + +#define APPEND( buffer, bufLimit, value, num, status){ \ + if(buffer<bufLimit){ \ + *buffer++=(value); \ + }else{ \ + *status = U_BUFFER_OVERFLOW_ERROR; \ + } \ + num++; \ +} + +/** + * Encode a run, possibly a degenerate run (of < 4 values). + * @param length The length of the run; must be > 0 && <= 0xFFFF. + */ +static uint16_t* +encodeRunShort(uint16_t* buffer,uint16_t* bufLimit, uint16_t value, int32_t length,UErrorCode* status) { + int32_t num=0; + if (length < 4) { + int j=0; + for (; j<length; ++j) { + if (value == (int32_t) ESCAPE){ + APPEND(buffer,bufLimit,ESCAPE, num, status); + + } + APPEND(buffer,bufLimit,value,num, status); + } + } + else { + if (length == (int32_t) ESCAPE) { + if (value == (int32_t) ESCAPE){ + APPEND(buffer,bufLimit,ESCAPE,num,status); + + } + APPEND(buffer,bufLimit,value,num,status); + --length; + } + APPEND(buffer,bufLimit,ESCAPE,num,status); + APPEND(buffer,bufLimit,(uint16_t) length, num,status); + APPEND(buffer,bufLimit,(uint16_t)value, num, status); /* Don't need to escape this value */ + } + return buffer; +} + +/** + * Construct a string representing a char array. Use run-length encoding. + * A character represents itself, unless it is the ESCAPE character. Then + * the following notations are possible: + * ESCAPE ESCAPE ESCAPE literal + * ESCAPE n c n instances of character c + * Since an encoded run occupies 3 characters, we only encode runs of 4 or + * more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF. + * If we encounter a run where n == ESCAPE, we represent this as: + * c ESCAPE n-1 c + * The ESCAPE value is chosen so as not to collide with commonly + * seen values. + */ +int32_t +usArrayToRLEString(const uint16_t* src,int32_t srcLen,uint16_t* buffer, int32_t bufLen,UErrorCode* status) { + uint16_t* bufLimit = buffer+bufLen; + uint16_t* saveBuffer = buffer; + if(buffer < bufLimit){ + *buffer++ = (uint16_t)(srcLen>>16); + if(buffer<bufLimit){ + uint16_t runValue = src[0]; + int32_t runLength = 1; + int i=1; + *buffer++ = (uint16_t) srcLen; + + for (; i<srcLen; ++i) { + uint16_t s = src[i]; + if (s == runValue && runLength < 0xFFFF){ + ++runLength; + }else { + buffer = encodeRunShort(buffer,bufLimit, (uint16_t)runValue, runLength,status); + runValue = s; + runLength = 1; + } + } + buffer= encodeRunShort(buffer,bufLimit,(uint16_t)runValue, runLength,status); + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + } + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + } + return (int32_t)(buffer - saveBuffer); +} + +/** + * Construct a string representing a byte array. Use run-length encoding. + * Two bytes are packed into a single char, with a single extra zero byte at + * the end if needed. A byte represents itself, unless it is the + * ESCAPE_BYTE. Then the following notations are possible: + * ESCAPE_BYTE ESCAPE_BYTE ESCAPE_BYTE literal + * ESCAPE_BYTE n b n instances of byte b + * Since an encoded run occupies 3 bytes, we only encode runs of 4 or + * more bytes. Thus we have n > 0 and n != ESCAPE_BYTE and n <= 0xFF. + * If we encounter a run where n == ESCAPE_BYTE, we represent this as: + * b ESCAPE_BYTE n-1 b + * The ESCAPE_BYTE value is chosen so as not to collide with commonly + * seen values. + */ +int32_t +byteArrayToRLEString(const uint8_t* src,int32_t srcLen, uint16_t* buffer,int32_t bufLen, UErrorCode* status) { + const uint16_t* saveBuf = buffer; + uint16_t* bufLimit = buffer+bufLen; + if(buffer < bufLimit){ + *buffer++ = ((uint16_t) (srcLen >> 16)); + + if(buffer<bufLimit){ + uint8_t runValue = src[0]; + int runLength = 1; + uint8_t state[2]= {0}; + int i=1; + *buffer++=((uint16_t) srcLen); + for (; i<srcLen; ++i) { + uint8_t b = src[i]; + if (b == runValue && runLength < 0xFF){ + ++runLength; + } + else { + buffer = encodeRunByte(buffer, bufLimit,runValue, runLength, state,status); + runValue = b; + runLength = 1; + } + } + buffer = encodeRunByte(buffer,bufLimit, runValue, runLength, state, status); + + /* We must save the final byte, if there is one, by padding + * an extra zero. + */ + if (state[0] != 0) { + buffer = appendEncodedByte(buffer,bufLimit, 0, state ,status); + } + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + } + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + } + return (int32_t) (buffer - saveBuf); +} + + +/** + * Construct an array of shorts from a run-length encoded string. + */ +int32_t +rleStringToUCharArray(uint16_t* src, int32_t srcLen, uint16_t* target, int32_t tgtLen, UErrorCode* status) { + int32_t length = 0; + int32_t ai = 0; + int i=2; + + if(!status || U_FAILURE(*status)){ + return 0; + } + /* the source is null terminated */ + if(srcLen == -1){ + srcLen = u_strlen(src); + } + if(srcLen <= 2){ + return 2; + } + length = (((int32_t) src[0]) << 16) | ((int32_t) src[1]); + + if(target == NULL){ + return length; + } + if(tgtLen < length){ + *status = U_BUFFER_OVERFLOW_ERROR; + return length; + } + + for (; i<srcLen; ++i) { + uint16_t c = src[i]; + if (c == ESCAPE) { + c = src[++i]; + if (c == ESCAPE) { + target[ai++] = c; + } else { + int32_t runLength = (int32_t) c; + uint16_t runValue = src[++i]; + int j=0; + for (; j<runLength; ++j) { + target[ai++] = runValue; + } + } + } + else { + target[ai++] = c; + } + } + + if (ai != length){ + *status = U_INTERNAL_PROGRAM_ERROR; + } + + return length; +} + +/** + * Construct an array of bytes from a run-length encoded string. + */ +int32_t +rleStringToByteArray(uint16_t* src, int32_t srcLen, uint8_t* target, int32_t tgtLen, UErrorCode* status) { + + int32_t length = 0; + UBool nextChar = TRUE; + uint16_t c = 0; + int32_t node = 0; + int32_t runLength = 0; + int32_t i = 2; + int32_t ai=0; + + if(!status || U_FAILURE(*status)){ + return 0; + } + /* the source is null terminated */ + if(srcLen == -1){ + srcLen = u_strlen(src); + } + if(srcLen <= 2){ + return 2; + } + length = (((int32_t) src[0]) << 16) | ((int32_t) src[1]); + + if(target == NULL){ + return length; + } + if(tgtLen < length){ + *status = U_BUFFER_OVERFLOW_ERROR; + return length; + } + + for (; ai<tgtLen; ) { + /* This part of the loop places the next byte into the local + * variable 'b' each time through the loop. It keeps the + * current character in 'c' and uses the boolean 'nextChar' + * to see if we've taken both bytes out of 'c' yet. + */ + uint8_t b; + if (nextChar) { + c = src[i++]; + b = (uint8_t) (c >> 8); + nextChar = FALSE; + } + else { + b = (uint8_t) (c & 0xFF); + nextChar = TRUE; + } + + /* This part of the loop is a tiny state machine which handles + * the parsing of the run-length encoding. This would be simpler + * if we could look ahead, but we can't, so we use 'node' to + * move between three nodes in the state machine. + */ + switch (node) { + case 0: + /* Normal idle node */ + if (b == ESCAPE_BYTE) { + node = 1; + } + else { + target[ai++] = b; + } + break; + case 1: + /* We have seen one ESCAPE_BYTE; we expect either a second + * one, or a run length and value. + */ + if (b == ESCAPE_BYTE) { + target[ai++] = ESCAPE_BYTE; + node = 0; + } + else { + runLength = b; + node = 2; + } + break; + case 2: + { + int j=0; + /* We have seen an ESCAPE_BYTE and length byte. We interpret + * the next byte as the value to be repeated. + */ + for (; j<runLength; ++j){ + if(ai<tgtLen){ + target[ai++] = b; + }else{ + *status = U_BUFFER_OVERFLOW_ERROR; + return ai; + } + } + node = 0; + break; + } + } + } + + if (node != 0){ + *status = U_INTERNAL_PROGRAM_ERROR; + /*("Bad run-length encoded byte array")*/ + return 0; + } + + + if (i != srcLen){ + /*("Excess data in RLE byte array string");*/ + *status = U_INTERNAL_PROGRAM_ERROR; + return ai; + } + + return ai; +} + diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/rle.h b/Build/source/libs/icu/icu-xetex/tools/genrb/rle.h new file mode 100644 index 00000000000..60f6bdc6a75 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/rle.h @@ -0,0 +1,72 @@ +/* +******************************************************************************* +* +* Copyright (C) 2000, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File writejava.c +* +* Modification History: +* +* Date Name Description +* 01/11/02 Ram Creation. +******************************************************************************* +*/ + +#ifndef RLE_H +#define RLE_H 1 + +#include "unicode/utypes.h" +#include "unicode/ustring.h" + +U_CDECL_BEGIN +/** + * Construct a string representing a byte array. Use run-length encoding. + * Two bytes are packed into a single char, with a single extra zero byte at + * the end if needed. A byte represents itself, unless it is the + * ESCAPE_BYTE. Then the following notations are possible: + * ESCAPE_BYTE ESCAPE_BYTE ESCAPE_BYTE literal + * ESCAPE_BYTE n b n instances of byte b + * Since an encoded run occupies 3 bytes, we only encode runs of 4 or + * more bytes. Thus we have n > 0 and n != ESCAPE_BYTE and n <= 0xFF. + * If we encounter a run where n == ESCAPE_BYTE, we represent this as: + * b ESCAPE_BYTE n-1 b + * The ESCAPE_BYTE value is chosen so as not to collide with commonly + * seen values. + */ +int32_t +byteArrayToRLEString(const uint8_t* src,int32_t srcLen, uint16_t* buffer,int32_t bufLen, UErrorCode* status); + + +/** + * Construct a string representing a char array. Use run-length encoding. + * A character represents itself, unless it is the ESCAPE character. Then + * the following notations are possible: + * ESCAPE ESCAPE ESCAPE literal + * ESCAPE n c n instances of character c + * Since an encoded run occupies 3 characters, we only encode runs of 4 or + * more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF. + * If we encounter a run where n == ESCAPE, we represent this as: + * c ESCAPE n-1 c + * The ESCAPE value is chosen so as not to collide with commonly + * seen values. + */ +int32_t +usArrayToRLEString(const uint16_t* src,int32_t srcLen,uint16_t* buffer, int32_t bufLen,UErrorCode* status); + +/** + * Construct an array of bytes from a run-length encoded string. + */ +int32_t +rleStringToByteArray(uint16_t* src, int32_t srcLen, uint8_t* target, int32_t tgtLen, UErrorCode* status); +/** + * Construct an array of shorts from a run-length encoded string. + */ +int32_t +rleStringToUCharArray(uint16_t* src, int32_t srcLen, uint16_t* target, int32_t tgtLen, UErrorCode* status); + +U_CDECL_END + +#endif diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.c b/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.c new file mode 100644 index 00000000000..aafcec54241 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.c @@ -0,0 +1,214 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File ustr.c +* +* Modification History: +* +* Date Name Description +* 05/28/99 stephen Creation. +******************************************************************************* +*/ + +#include "ustr.h" +#include "cmemory.h" +#include "cstring.h" +#include "unicode/ustring.h" +#include "unicode/putil.h" + +/* Protos */ +static void ustr_resize(struct UString *s, int32_t len, UErrorCode *status); + +/* Macros */ +#define ALLOCATION(minSize) (minSize < 0x80 ? 0x80 : (2 * minSize + 0x80) & ~(0x80 - 1)) + +void +ustr_init(struct UString *s) +{ + s->fChars = 0; + s->fLength = s->fCapacity = 0; +} + +void +ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status) +{ + int i = 0; + if (U_FAILURE(*status)) return; + s->fChars = 0; + s->fLength = s->fCapacity = 0; + if (length == -1) { + length = (int32_t)uprv_strlen(source); + } + if(s->fCapacity < length) { + ustr_resize(s, ALLOCATION(length), status); + if(U_FAILURE(*status)) return; + } + for (; i < length; i++) + { + UChar charToAppend; + u_charsToUChars(source+i, &charToAppend, 1); + ustr_ucat(s, charToAppend, status); + /* +#if U_CHARSET_FAMILY==U_ASCII_FAMILY + ustr_ucat(s, (UChar)(uint8_t)(source[i]), status); +#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY + ustr_ucat(s, (UChar)asciiFromEbcdic[(uint8_t)(*cs++)], status); +#else +# error U_CHARSET_FAMILY is not valid +#endif + */ + } +} + +void +ustr_deinit(struct UString *s) +{ + uprv_free(s->fChars); + s->fChars = 0; + s->fLength = s->fCapacity = 0; +} + +void +ustr_cpy(struct UString *dst, + const struct UString *src, + UErrorCode *status) +{ + if(U_FAILURE(*status) || dst == src) + return; + + if(dst->fCapacity < src->fLength) { + ustr_resize(dst, ALLOCATION(src->fLength), status); + if(U_FAILURE(*status)) + return; + } + if(src->fChars == NULL || dst->fChars == NULL){ + return; + } + uprv_memcpy(dst->fChars, src->fChars, sizeof(UChar) * src->fLength); + dst->fLength = src->fLength; + dst->fChars[dst->fLength] = 0x0000; +} + +void +ustr_setlen(struct UString *s, + int32_t len, + UErrorCode *status) +{ + if(U_FAILURE(*status)) + return; + + if(s->fCapacity < (len + 1)) { + ustr_resize(s, ALLOCATION(len), status); + if(U_FAILURE(*status)) + return; + } + + s->fLength = len; + s->fChars[len] = 0x0000; +} + +void +ustr_cat(struct UString *dst, + const struct UString *src, + UErrorCode *status) +{ + ustr_ncat(dst, src, src->fLength, status); +} + +void +ustr_ncat(struct UString *dst, + const struct UString *src, + int32_t n, + UErrorCode *status) +{ + if(U_FAILURE(*status) || dst == src) + return; + + if(dst->fCapacity < (dst->fLength + n)) { + ustr_resize(dst, ALLOCATION(dst->fLength + n), status); + if(U_FAILURE(*status)) + return; + } + + uprv_memcpy(dst->fChars + dst->fLength, src->fChars, + sizeof(UChar) * n); + dst->fLength += src->fLength; + dst->fChars[dst->fLength] = 0x0000; +} + +void +ustr_ucat(struct UString *dst, + UChar c, + UErrorCode *status) +{ + if(U_FAILURE(*status)) + return; + + if(dst->fCapacity < (dst->fLength + 1)) { + ustr_resize(dst, ALLOCATION(dst->fLength + 1), status); + if(U_FAILURE(*status)) + return; + } + + uprv_memcpy(dst->fChars + dst->fLength, &c, + sizeof(UChar) * 1); + dst->fLength += 1; + dst->fChars[dst->fLength] = 0x0000; +} +void +ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){ + if(c > 0x10FFFF){ + *status = U_ILLEGAL_CHAR_FOUND; + return; + } + if(c >0xFFFF){ + ustr_ucat(dst, U16_LEAD(c), status); + ustr_ucat(dst, U16_TRAIL(c), status); + }else{ + ustr_ucat(dst, (UChar) c, status); + } +} +void +ustr_uscat(struct UString *dst, + const UChar* src,int len, + UErrorCode *status) +{ + if(U_FAILURE(*status)) + return; + + if(dst->fCapacity < (dst->fLength + len)) { + ustr_resize(dst, ALLOCATION(dst->fLength + len), status); + if(U_FAILURE(*status)) + return; + } + + uprv_memcpy(dst->fChars + dst->fLength, src, + sizeof(UChar) * len); + dst->fLength += len; + dst->fChars[dst->fLength] = 0x0000; +} + +/* Destroys data in the string */ +static void +ustr_resize(struct UString *s, + int32_t len, + UErrorCode *status) +{ + if(U_FAILURE(*status)) + return; + + /* +1 for trailing 0x0000 */ + s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1)); + if(s->fChars == 0) { + *status = U_MEMORY_ALLOCATION_ERROR; + s->fLength = s->fCapacity = 0; + return; + } + + s->fCapacity = len; +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.h b/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.h new file mode 100644 index 00000000000..085643a8d7a --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/ustr.h @@ -0,0 +1,66 @@ +/* +******************************************************************************* +* +* Copyright (C) 1998-2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File ustr.h +* +* Modification History: +* +* Date Name Description +* 05/28/99 stephen Creation. +******************************************************************************* +*/ + +#ifndef USTR_H +#define USTR_H 1 + +#include "unicode/utypes.h" + +#define U_APPEND_CHAR32(c,target,len) { \ + if (c <= 0xffff) \ + { \ + *(target)++ = (UChar) c; \ + len=1; \ + } \ + else \ + { \ + target[0] = U16_LEAD(c); \ + target[1] = U16_TRAIL(c); \ + len=2; \ + target +=2; \ + } \ +} + +/* A C representation of a string "object" (to avoid realloc all the time) */ +struct UString { + UChar *fChars; + int32_t fLength; + int32_t fCapacity; +}; + +void ustr_init(struct UString *s); + +void +ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status); + +void ustr_deinit(struct UString *s); + +void ustr_setlen(struct UString *s, int32_t len, UErrorCode *status); + +void ustr_cpy(struct UString *dst, const struct UString *src, + UErrorCode *status); + +void ustr_cat(struct UString *dst, const struct UString *src, + UErrorCode *status); + +void ustr_ncat(struct UString *dst, const struct UString *src, + int32_t n, UErrorCode *status); + +void ustr_ucat(struct UString *dst, UChar c, UErrorCode *status); +void ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status); +void ustr_uscat(struct UString *dst, const UChar* src,int len,UErrorCode *status); +#endif diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/wrtjava.c b/Build/source/libs/icu/icu-xetex/tools/genrb/wrtjava.c new file mode 100644 index 00000000000..a4293ae2807 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/wrtjava.c @@ -0,0 +1,831 @@ +/* +******************************************************************************* +* +* Copyright (C) 2000-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File wrtjava.c +* +* Modification History: +* +* Date Name Description +* 01/11/02 Ram Creation. +******************************************************************************* +*/ + +#include <assert.h> +#include "reslist.h" +#include "unewdata.h" +#include "unicode/ures.h" +#include "errmsg.h" +#include "filestrm.h" +#include "cstring.h" +#include "unicode/ucnv.h" +#include "genrb.h" +#include "rle.h" +#include "ucol_tok.h" +#include "uhash.h" +#include "uresimp.h" +#include "unicode/ustring.h" + +void res_write_java(struct SResource *res,UErrorCode *status); + + +static const char copyRight[] = + "/* \n" + " *******************************************************************************\n" + " *\n" + " * Copyright (C) International Business Machines\n" + " * Corporation and others. All Rights Reserved.\n" + " *\n" + " *******************************************************************************\n" + " * $" "Source: $ \n" + " * $" "Date: $ \n" + " * $" "Revision: $ \n" + " *******************************************************************************\n" + " */\n\n"; +static const char warningMsg[] = + "/*********************************************************************\n" + "######################################################################\n" + "\n" + " WARNING: This file is generated by genrb Version " GENRB_VERSION ".\n" + " If you edit this file, please make sure that, the source\n" + " of this file (XXXX.txt in LocaleElements_XXXX.java)\n" + " is also edited.\n" + "######################################################################\n" + " *********************************************************************\n" + " */\n\n"; +static const char* openBrace="{\n"; +static const char* closeClass=" };\n" + "}\n"; + +static const char* javaClass = "import java.util.ListResourceBundle;\n" + "import com.ibm.icu.impl.ICUListResourceBundle;\n\n" + "public class "; + +static const char* javaClass1= " extends ICUListResourceBundle {\n\n" + " /**\n" + " * Overrides ListResourceBundle \n" + " */\n" + " public final Object[][] getContents() { \n" + " return contents;\n" + " }\n" + " private static Object[][] contents = {\n"; +static const char* javaClassICU= " extends ICUListResourceBundle {\n\n" + " public %s () {\n" + " super.contents = data;\n" + " }\n" + " static final Object[][] data = new Object[][] { \n"; +static int tabCount = 3; + +static FileStream* out=NULL; +static struct SRBRoot* srBundle ; +static const char* outDir = NULL; + +static const char* bName=NULL; +static const char* pName=NULL; + +static void write_tabs(FileStream* os){ + int i=0; + for(;i<=tabCount;i++){ + T_FileStream_write(os," ",4); + } +} + +#define ZERO 0x30 + +static const char* enc =""; +static UConverter* conv = NULL; +static char NUMBER = ZERO; + +static int32_t +uCharsToChars( char* target,int32_t targetLen, UChar* source, int32_t sourceLen,UErrorCode* status){ + int i=0, j=0; + char str[30]={'\0'}; + while(i<sourceLen){ + if (source[i] == '\n') { + if (j + 2 < targetLen) { + uprv_strcat(target, "\\n"); + } + j += 2; + }else if(source[i]==0x0D){ + if(j+2<targetLen){ + uprv_strcat(target,"\\f"); + } + j+=2; + }else if(source[i] == '"'){ + if(source[i-1]=='\''){ + if(j+2<targetLen){ + uprv_strcat(target,"\\"); + target[j+1]= (char)source[i]; + } + j+=2; + }else if(source[i-1]!='\\'){ + + if(j+2<targetLen){ + uprv_strcat(target,"\\"); + target[j+1]= (char)source[i]; + } + j+=2; + }else if(source[i-1]=='\\'){ + target[j++]= (char)source[i]; + } + }else if(source[i]=='\\'){ + if(i+1<sourceLen){ + switch(source[i+1]){ + case ',': + case '!': + case '?': + case '#': + case '.': + case '%': + case '&': + case ':': + case ';': + if(j+2<targetLen){ + uprv_strcat(target,"\\\\"); + } + j+=2; + break; + case '"': + case '\'': + if(j+3<targetLen){ + uprv_strcat(target,"\\\\\\"); + } + j+=3; + break; + default : + if(j<targetLen){ + target[j]=(char)source[i]; + } + j++; + break; + } + }else{ + if(j<targetLen){ + uprv_strcat(target,"\\\\"); + } + j+=2; + } + }else if(source[i]>=0x20 && source[i]<0x7F/*ASCII*/){ + if(j<targetLen){ + target[j] = (char) source[i]; + } + j++; + }else{ + if(*enc =='\0' || source[i]==0x0000){ + uprv_strcpy(str,"\\u"); + itostr(str+2,source[i],16,4); + if(j+6<targetLen){ + uprv_strcat(target,str); + } + j+=6; + }else{ + char dest[30] = {0}; + int retVal=ucnv_fromUChars(conv,dest,30,source+i,1,status); + if(U_FAILURE(*status)){ + return 0; + } + if(j+retVal<targetLen){ + uprv_strcat(target,dest); + } + j+=retVal; + } + } + i++; + } + return j; +} + + +static uint32_t +strrch(const char* source,uint32_t sourceLen,char find){ + const char* tSourceEnd =source + (sourceLen-1); + while(tSourceEnd>= source){ + if(*tSourceEnd==find){ + return (uint32_t)(tSourceEnd-source); + } + tSourceEnd--; + } + return (uint32_t)(tSourceEnd-source); +} + +static int32_t getColumnCount(int32_t len){ + int32_t columnCount = 80; + int32_t maxLines = 3000; + int32_t adjustedLen = len*5; /* assume that every codepoint is represented in \uXXXX format*/ + /* + * calculate the number of lines that + * may be required if column count is 80 + */ + if (maxLines < (adjustedLen / columnCount) ){ + columnCount = adjustedLen / maxLines; + } + return columnCount; +} +static void +str_write_java( uint16_t* src, int32_t srcLen, UBool printEndLine, UErrorCode *status){ + + uint32_t length = srcLen*8; + uint32_t bufLen = 0; + uint32_t columnCount; + char* buf = (char*) malloc(sizeof(char)*length); + + if(buf == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return; + } + + columnCount = getColumnCount(srcLen); + memset(buf,0,length); + + bufLen = uCharsToChars(buf,length,src,srcLen,status); + + if(printEndLine) + write_tabs(out); + + if(U_FAILURE(*status)){ + uprv_free(buf); + return; + } + + if(bufLen+(tabCount*4) > columnCount ){ + uint32_t len = 0; + char* current = buf; + uint32_t add; + while(len < bufLen){ + add = columnCount-(tabCount*4)-5/* for ", +\n */; + current = buf +len; + if (add < (bufLen-len)) { + uint32_t index = strrch(current,add,'\\'); + if (index > add) { + index = add; + } else { + int32_t num =index-1; + uint32_t seqLen; + while(num>0){ + if(current[num]=='\\'){ + num--; + }else{ + break; + } + } + if ((index-num)%2==0) { + index--; + } + seqLen = (current[index+1]=='u') ? 6 : 2; + if ((add-index) < seqLen) { + add = index + seqLen; + } + } + } + T_FileStream_write(out,"\"",1); + if(len+add<bufLen){ + T_FileStream_write(out,current,add); + T_FileStream_write(out,"\" +\n",4); + write_tabs(out); + }else{ + T_FileStream_write(out,current,bufLen-len); + } + len+=add; + } + }else{ + T_FileStream_write(out,"\"",1); + T_FileStream_write(out, buf,bufLen); + } + if(printEndLine){ + T_FileStream_write(out,"\",\n",3); + }else{ + T_FileStream_write(out,"\"",1); + } + uprv_free(buf); +} + +static void +write_utf8_file(struct SResource *res, const char *file, UErrorCode *status){ + char fileName[1024] ={0}; + FileStream* datFile = NULL; + const char* type = "new ICUListResourceBundle.ResourceString("; + char* dest = (char*) uprv_malloc( 8 * res->u.fString.fLength); + int32_t len = 0; + if(outDir){ + uprv_strcat(fileName,outDir); + if(outDir[uprv_strlen(outDir)-1]!=U_FILE_SEP_CHAR){ + uprv_strcat(fileName,U_FILE_SEP_STRING); + } + } + uprv_strcat(fileName,file);/* UCARULES.utf8 UTF-8 file */ + + write_tabs(out); + + T_FileStream_write(out, type, (int32_t)uprv_strlen(type)); + T_FileStream_write(out, "\"", 1); + T_FileStream_write(out, file, (int32_t)uprv_strlen(file)); + T_FileStream_write(out, "\")\n", 3); + datFile=T_FileStream_open(fileName,"w"); + + if(!dest){ + *status=U_MEMORY_ALLOCATION_ERROR; + } + + u_strToUTF8(dest,8*res->u.fString.fLength,&len,res->u.fString.fChars,res->u.fString.fLength,status); + if(U_FAILURE(*status)){ + T_FileStream_close(datFile); + uprv_free(dest); + return; + } + T_FileStream_write(datFile,dest,len); + T_FileStream_close(datFile); + uprv_free(dest); +} +#define MAX_SEQUENCE_LENGTH 30000 +/* Writing Functions */ +static void +string_write_java(struct SResource *res,UErrorCode *status) { + if(res->fKey > 0 && uprv_strcmp(srBundle->fKeys+res->fKey,"%%UCARULES")==0 ){ + + const char* file = "UCARules.utf8"; + write_utf8_file(res, file, status); + }else if(res->fKey > 0 && uprv_strcmp(srBundle->fKeys+res->fKey,"Sequence")==0 + && res->fType == RES_STRING + && res->u.fString.fLength > MAX_SEQUENCE_LENGTH){ + char file[1024] = {0}; + uprv_strcpy(file, "CollationSequence_"); + uprv_strcat(file, srBundle->fLocale); + uprv_strcat(file, ".utf8"); + write_utf8_file(res, file, status); + + }else{ + str_write_java(res->u.fString.fChars,res->u.fString.fLength,TRUE,status); + + if(res->fKey > 0 && uprv_strcmp(srBundle->fKeys+res->fKey,"Rule")==0){ + UChar* buf = (UChar*) uprv_malloc(sizeof(UChar)*res->u.fString.fLength); + uprv_memcpy(buf,res->u.fString.fChars,res->u.fString.fLength); + uprv_free(buf); + } + } + +} + +static void +alias_write_java(struct SResource *res,UErrorCode *status) { + static const char str[] = "new ICUListResourceBundle.Alias("; + write_tabs(out); + T_FileStream_write(out,str,(int32_t)uprv_strlen(str)); + + /*str_write_java(res->u.fString.fChars,res->u.fString.fLength,FALSE,status);*/ + /*if(*res->u.fString.fChars == RES_PATH_SEPARATOR) {*/ + /* there is a path included + locale = u_strchr(res->u.fString.fChars +1, RES_PATH_SEPARATOR); + *locale = 0; + locale++; + + T_FileStream_write(out,"\"/",2); + T_FileStream_write(out,apName,(int32_t)uprv_strlen(apName)); + T_FileStream_write(out,"/",1); + T_FileStream_write(out,abName,(int32_t)uprv_strlen(abName)); + T_FileStream_write(out,"/\"+",3); + str_write_java(locale,res->u.fString.fLength-(locale-res->u.fString.fChars),FALSE,status); + } else { + str_write_java(res->u.fString.fChars,res->u.fString.fLength,FALSE,status); + }*/ + + str_write_java(res->u.fString.fChars,res->u.fString.fLength,FALSE,status); + + T_FileStream_write(out,"),\n",3); +} + +static void +array_write_java( struct SResource *res, UErrorCode *status) { + + uint32_t i = 0; + const char* arr ="new String[] { \n"; + struct SResource *current = NULL; + struct SResource *first =NULL; + UBool decrementTabs = FALSE; + UBool allStrings = TRUE; + + if (U_FAILURE(*status)) { + return; + } + + if (res->u.fArray.fCount > 0) { + + current = res->u.fArray.fFirst; + i = 0; + while(current != NULL){ + if(current->fType!=URES_STRING){ + allStrings = FALSE; + break; + } + current= current->fNext; + } + + current = res->u.fArray.fFirst; + if(allStrings==FALSE){ + const char* object = "new Object[]{\n"; + write_tabs(out); + T_FileStream_write(out, object, (int32_t)uprv_strlen(object)); + tabCount++; + decrementTabs = TRUE; + }else{ + write_tabs(out); + T_FileStream_write(out, arr, (int32_t)uprv_strlen(arr)); + tabCount++; + } + first=current; + while (current != NULL) { + /*if(current->fType==URES_STRING){ + write_tabs(out); + }*/ + res_write_java(current, status); + if(U_FAILURE(*status)){ + return; + } + i++; + current = current->fNext; + } + T_FileStream_write(out,"\n",1); + + tabCount--; + write_tabs(out); + T_FileStream_write(out,"},\n",3); + + } else { + write_tabs(out); + T_FileStream_write(out,arr,(int32_t)uprv_strlen(arr)); + write_tabs(out); + T_FileStream_write(out,"},\n",3); + } +} + +static void +intvector_write_java( struct SResource *res, UErrorCode *status) { + uint32_t i = 0; + const char* intArr = "new Integer[] {\n"; + const char* intC = "new Integer("; + const char* stringArr = "new String[]{\n"; + char buf[100]; + int len =0; + buf[0]=0; + write_tabs(out); + + if(res->fKey > 0 && uprv_strcmp(srBundle->fKeys+res->fKey,"DateTimeElements")==0){ + T_FileStream_write(out, stringArr, (int32_t)uprv_strlen(stringArr)); + tabCount++; + for(i = 0; i<res->u.fIntVector.fCount; i++) { + write_tabs(out); + len=itostr(buf,res->u.fIntVector.fArray[i],10,0); + T_FileStream_write(out,"\"",1); + T_FileStream_write(out,buf,len); + T_FileStream_write(out,"\",",2); + T_FileStream_write(out,"\n",1); + } + }else{ + T_FileStream_write(out, intArr, (int32_t)uprv_strlen(intArr)); + tabCount++; + for(i = 0; i<res->u.fIntVector.fCount; i++) { + write_tabs(out); + T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); + len=itostr(buf,res->u.fIntVector.fArray[i],10,0); + T_FileStream_write(out,buf,len); + T_FileStream_write(out,"),",2); + T_FileStream_write(out,"\n",1); + } + } + tabCount--; + write_tabs(out); + T_FileStream_write(out,"},\n",3); +} + +static void +int_write_java(struct SResource *res,UErrorCode *status) { + const char* intC = "new Integer("; + char buf[100]; + int len =0; + buf[0]=0; + + /* write the binary data */ + write_tabs(out); + T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); + len=itostr(buf, res->u.fIntValue.fValue, 10, 0); + T_FileStream_write(out,buf,len); + T_FileStream_write(out,"),\n",3 ); + +} + +static void +bin_write_java( struct SResource *res, UErrorCode *status) { + const char* type = "new ICUListResourceBundle.CompressedBinary("; + const char* ext; + int32_t srcLen=res->u.fBinaryValue.fLength; + + if(srcLen>0 ){ + uint16_t* target=NULL; + uint16_t* saveTarget = NULL; + int32_t tgtLen = 0; + + if(res->fKey > 0 && (uprv_strcmp(srBundle->fKeys+res->fKey,"%%CollationBin")==0 || uprv_strcmp(srBundle->fKeys+res->fKey,"BreakDictionaryData")==0)){ + char fileName[1024] ={0}; + char fn[1024] = {0}; + FileStream* datFile = NULL; + if(uprv_strcmp(srBundle->fKeys+res->fKey,"BreakDictionaryData")==0){ + uprv_strcat(fileName,"BreakDictionaryData"); + ext = ".brk"; + }else{ + uprv_strcat(fileName,"CollationElements"); + ext=".col"; + } + if(uprv_strcmp(srBundle->fLocale,"root")!=0){ + uprv_strcat(fileName,"_"); + uprv_strcat(fileName,srBundle->fLocale); + if(NUMBER > ZERO){ + uprv_strcat(fileName, "_"); + uprv_strcat(fileName, &NUMBER); + } + NUMBER++; + } + + uprv_strcat(fileName,ext); + if(outDir ){ + uprv_strcat(fn,outDir); + if(outDir[uprv_strlen(outDir)-1]!=U_FILE_SEP_CHAR){ + uprv_strcat(fn,U_FILE_SEP_STRING); + } + } + uprv_strcat(fn,fileName); + type = "new ICUListResourceBundle.ResourceBinary("; + write_tabs(out); + T_FileStream_write(out, type, (int32_t)uprv_strlen(type)); + T_FileStream_write(out, "\"", 1); + T_FileStream_write(out, fileName, (int32_t)uprv_strlen(fileName)); + T_FileStream_write(out, "\"),\n", 4); + + datFile=T_FileStream_open(fn,"w"); + T_FileStream_write(datFile, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength); + T_FileStream_close(datFile); + + }else{ + + srcLen = res->u.fBinaryValue.fLength; + tgtLen = srcLen * 2; + target = (uint16_t*)malloc(sizeof(uint16_t) * tgtLen); + saveTarget = target; + if(target){ + tgtLen = byteArrayToRLEString(res->u.fBinaryValue.fData, + srcLen,target, tgtLen,status); + if(U_FAILURE(*status)){ + printf("Could not encode got error : %s \n", u_errorName(*status)); + return; + } +#if DEBUG + /***************** Test Roundtripping *********************/ + { + int32_t myTargetLen = rleStringToByteArray(target,tgtLen,NULL,0,status); + uint8_t* myTarget = (uint8_t*) malloc(sizeof(uint8_t) * myTargetLen); + + /* test for NULL */ + if(myTarget == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return; + } + + int i=0; + int32_t retVal=0; + + *status = U_ZERO_ERROR; + retVal=rleStringToByteArray(target,tgtLen,myTarget,myTargetLen,status); + if(U_SUCCESS(*status)){ + + for(i=0; i< srcLen;i++){ + if(res->u.fBinaryValue.fData[i]!= myTarget[i]){ + printf("the encoded string cannot be decoded Expected : 0x%02X Got : %: 0x%02X at %i\n",res->u.fBinaryValue.fData[i],myTarget[i], i); + } + } + }else{ + printf("Could not decode got error : %s \n", u_errorName(*status)); + } + free(myTarget); + + } +#endif + + }else{ + *status = U_MEMORY_ALLOCATION_ERROR; + return; + } + + write_tabs(out); + T_FileStream_write(out, type, (int32_t)uprv_strlen(type)); + T_FileStream_write(out, "\n", 1); + tabCount++; + write_tabs(out); + str_write_java(target, tgtLen,FALSE, status); + tabCount--; + T_FileStream_write(out, "),\n", 3); + + free(target); + + } + + }else{ + write_tabs(out); + T_FileStream_write(out,type,(int32_t)uprv_strlen(type)); + T_FileStream_write(out,"null),\n",7); + } + +} + + +static UBool start = TRUE; + +static void +table_write_java(struct SResource *res, UErrorCode *status) { + uint32_t i = 0; + UBool allStrings =TRUE; + struct SResource *current = NULL; + struct SResource *save = NULL; + const char* obj = "new Object[][]{\n"; + + if (U_FAILURE(*status)) { + return ; + } + + if (res->u.fTable.fCount > 0) { + if(start==FALSE){ + write_tabs(out); + T_FileStream_write(out, obj, (int32_t)uprv_strlen(obj)); + tabCount++; + } + start = FALSE; + save = current = res->u.fTable.fFirst; + i = 0; + + + while (current != NULL) { + assert(i < res->u.fTable.fCount); + write_tabs(out); + + T_FileStream_write(out, openBrace, 2); + + + tabCount++; + allStrings=FALSE; + + write_tabs(out); + if(current->fKey > 0){ + T_FileStream_write(out, "\"", 1); + T_FileStream_write(out, srBundle->fKeys+current->fKey, + (int32_t)uprv_strlen(srBundle->fKeys+current->fKey)); + T_FileStream_write(out, "\",\n", 2); + + T_FileStream_write(out, "\n", 1); + } + res_write_java(current, status); + if(U_FAILURE(*status)){ + return; + } + i++; + current = current->fNext; + tabCount--; + write_tabs(out); + T_FileStream_write(out, "},\n", 3); + } + if(tabCount>4){ + tabCount--; + write_tabs(out); + T_FileStream_write(out, "},\n", 3); + } + + } else { + write_tabs(out); + T_FileStream_write(out,obj,(int32_t)uprv_strlen(obj)); + + write_tabs(out); + T_FileStream_write(out,"},\n",3); + + } + +} + +void +res_write_java(struct SResource *res,UErrorCode *status) { + + if (U_FAILURE(*status)) { + return ; + } + + if (res != NULL) { + switch (res->fType) { + case URES_STRING: + string_write_java (res, status); + return; + case URES_ALIAS: + alias_write_java (res, status); + return; + case URES_INT_VECTOR: + intvector_write_java (res, status); + return; + case URES_BINARY: + bin_write_java (res, status); + return; + case URES_INT: + int_write_java (res, status); + return; + case URES_ARRAY: + array_write_java (res, status); + return; + case URES_TABLE: + case URES_TABLE32: + table_write_java (res, status); + return; + + default: + break; + } + } + + *status = U_INTERNAL_PROGRAM_ERROR; +} + +void +bundle_write_java(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, + char *writtenFilename, int writtenFilenameLen, + const char* packageName, const char* bundleName, + UErrorCode *status) { + + char fileName[256] = {'\0'}; + char className[256]={'\0'}; + char constructor[1000] = { 0 }; + UBool j1 =FALSE; + outDir = outputDir; + + bName = (bundleName==NULL) ? "LocaleElements" : bundleName; + pName = (packageName==NULL)? "com.ibm.icu.impl.data" : packageName; + + uprv_strcpy(className, bName); + srBundle = bundle; + if(uprv_strcmp(srBundle->fLocale,"root")!=0){ + uprv_strcat(className,"_"); + uprv_strcat(className,srBundle->fLocale); + } + if(outputDir){ + uprv_strcpy(fileName, outputDir); + if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){ + uprv_strcat(fileName,U_FILE_SEP_STRING); + } + uprv_strcat(fileName,className); + uprv_strcat(fileName,".java"); + }else{ + uprv_strcat(fileName,className); + uprv_strcat(fileName,".java"); + } + + if (writtenFilename) { + uprv_strncpy(writtenFilename, fileName, writtenFilenameLen); + } + + if (U_FAILURE(*status)) { + return; + } + + out= T_FileStream_open(fileName,"w"); + + if(out==NULL){ + *status = U_FILE_ACCESS_ERROR; + return; + } + if(getIncludeCopyright()){ + T_FileStream_write(out, copyRight, (int32_t)uprv_strlen(copyRight)); + T_FileStream_write(out, warningMsg, (int32_t)uprv_strlen(warningMsg)); + } + T_FileStream_write(out,"package ",(int32_t)uprv_strlen("package ")); + T_FileStream_write(out,pName,(int32_t)uprv_strlen(pName)); + T_FileStream_write(out,";\n\n",3); + T_FileStream_write(out, javaClass, (int32_t)uprv_strlen(javaClass)); + T_FileStream_write(out, className, (int32_t)uprv_strlen(className)); + if(j1){ + T_FileStream_write(out, javaClass1, (int32_t)uprv_strlen(javaClass1)); + }else{ + sprintf(constructor,javaClassICU,className); + T_FileStream_write(out, constructor, (int32_t)uprv_strlen(constructor)); + } + + if(outputEnc && *outputEnc!='\0'){ + /* store the output encoding */ + enc = outputEnc; + conv=ucnv_open(enc,status); + if(U_FAILURE(*status)){ + return; + } + } + res_write_java(bundle->fRoot, status); + + T_FileStream_write(out, closeClass, (int32_t)uprv_strlen(closeClass)); + + T_FileStream_close(out); + + ucnv_close(conv); +} diff --git a/Build/source/libs/icu/icu-xetex/tools/genrb/wrtxml.c b/Build/source/libs/icu/icu-xetex/tools/genrb/wrtxml.c new file mode 100644 index 00000000000..fbcbec3813c --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/tools/genrb/wrtxml.c @@ -0,0 +1,1165 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* +* File wrtxml.c +* +* Modification History: +* +* Date Name Description +* 10/01/02 Ram Creation. +******************************************************************************* +*/ +#include "reslist.h" +#include "unewdata.h" +#include "unicode/ures.h" +#include "errmsg.h" +#include "filestrm.h" +#include "cstring.h" +#include "unicode/ucnv.h" +#include "genrb.h" +#include "rle.h" +#include "ucol_tok.h" +#include "uhash.h" +#include "uresimp.h" +#include "unicode/ustring.h" +#include "unicode/uchar.h" +#include "ustr.h" +#include "prscmnts.h" +#include <time.h> + +static int tabCount = 0; + +static FileStream* out=NULL; +static struct SRBRoot* srBundle ; +static const char* outDir = NULL; +static const char* enc =""; +static UConverter* conv = NULL; + +const char* const* ISOLanguages; +const char* const* ISOCountries; +const char* textExt = ".txt"; +const char* xliffExt = ".xlf"; + +/*write indentation for formatting*/ +static void write_tabs(FileStream* os){ + int i=0; + for(;i<=tabCount;i++){ + T_FileStream_write(os," ",4); + } +} + +/*get ID for each element. ID is globally unique.*/ +static char* getID(const char* id, char* curKey, char* result) { + if(curKey == NULL) { + result = uprv_malloc(sizeof(char)*uprv_strlen(id) + 1); + uprv_memset(result, 0, sizeof(char)*uprv_strlen(id) + 1); + uprv_strcpy(result, id); + } else { + result = uprv_malloc(sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1); + uprv_memset(result, 0, sizeof(char)*(uprv_strlen(id) + 1 + uprv_strlen(curKey)) + 1); + if(id[0]!='\0'){ + uprv_strcpy(result, id); + uprv_strcat(result, "_"); + } + uprv_strcat(result, curKey); + } + return result; +} + +/*compute CRC for binary code*/ +/* The code is from http://www.theorem.com/java/CRC32.java + * Calculates the CRC32 - 32 bit Cyclical Redundancy Check + * <P> This check is used in numerous systems to verify the integrity + * of information. It's also used as a hashing function. Unlike a regular + * checksum, it's sensitive to the order of the characters. + * It produces a 32 bit + * + * @author Michael Lecuyer (mjl@theorem.com) + * @version 1.1 August 11, 1998 + */ + +/* ICU is not endian portable, because ICU data generated on big endian machines can be + * ported to big endian machines but not to little endian machines and vice versa. The + * conversion is not portable across platforms with different endianess. + */ + +static uint32_t computeCRC(char *ptr, uint32_t len, uint32_t lastcrc){ + int32_t crc; + uint32_t temp1; + uint32_t temp2; + + int32_t crc_ta[256]; + int i = 0; + int j = 0; + uint32_t crc2 = 0; + +#define CRC32_POLYNOMIAL 0xEDB88320 + + /*build crc table*/ + for (i = 0; i <= 255; i++) { + crc2 = i; + for (j = 8; j > 0; j--) { + if ((crc2 & 1) == 1) { + crc2 = (crc2 >> 1) ^ CRC32_POLYNOMIAL; + } else { + crc2 >>= 1; + } + } + crc_ta[i] = crc2; + } + + crc = lastcrc; + while(len--!=0) { + temp1 = (uint32_t)crc>>8; + temp2 = crc_ta[(crc^*ptr) & 0xFF]; + crc = temp1^temp2; + ptr++; + } + return(crc); +} + +static void strnrepchr(char* src, int32_t srcLen, char s, char r){ + int32_t i = 0; + for(i=0;i<srcLen;i++){ + if(src[i]==s){ + src[i]=r; + } + } +} +/* Parse the filename, and get its language information. + * If it fails to get the language information from the filename, + * use "en" as the default value for language + */ +static char* parseFilename(const char* id, char* lang) { + int idLen = (int) uprv_strlen(id); + char* localeID = (char*) uprv_malloc(idLen); + int pos = 0; + int canonCapacity = 0; + char* canon = NULL; + int canonLen = 0; + /*int i;*/ + UErrorCode status = U_ZERO_ERROR; + char *ext = uprv_strchr(id, '.'); + + if(ext != NULL){ + pos = (int) (ext - id); + } else { + pos = idLen; + } + uprv_memcpy(localeID, id, pos); + localeID[pos]=0; /* NUL terminate the string */ + + canonCapacity =pos*3; + canon = (char*) uprv_malloc(canonCapacity); + canonLen = uloc_canonicalize(localeID, canon, canonCapacity, &status); + + if(U_FAILURE(status)){ + fprintf(stderr, "Could not canonicalize the locale ID: %s. Error: %s\n", localeID, u_errorName(status)); + exit(status); + } + strnrepchr(canon, canonLen, '_', '-'); + return canon; +} + +static const char* xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; +#if 0 +static const char* bundleStart = "<xliff version = \"1.2\" " + "xmlns='urn:oasis:names:tc:xliff:document:1.2' " + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " + "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd'>\n"; +#else +static const char* bundleStart = "<xliff version = \"1.1\" " + "xmlns='urn:oasis:names:tc:xliff:document:1.1' " + "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " + "xsi:schemaLocation='urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd'>\n"; +#endif +static const char* bundleEnd = "</xliff>\n"; + +void res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status); + +static char* convertAndEscape(char** pDest, int32_t destCap, int32_t* destLength, + const UChar* src, int32_t srcLen, UErrorCode* status){ + int32_t srcIndex=0; + char* dest=NULL; + char* temp=NULL; + int32_t destLen=0; + UChar32 c = 0; + + if(status==NULL || U_FAILURE(*status) || pDest==NULL || srcLen==0 || src == NULL){ + return NULL; + } + dest =*pDest; + if(dest==NULL || destCap <=0){ + destCap = srcLen * 8; + dest = (char*) uprv_malloc(sizeof(char) * destCap); + if(dest==NULL){ + *status=U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + } + + dest[0]=0; + + while(srcIndex<srcLen){ + U16_NEXT(src, srcIndex, srcLen, c); + + if (U16_IS_LEAD(c) || U16_IS_TRAIL(c)) { + *status = U_ILLEGAL_CHAR_FOUND; + fprintf(stderr, "Illegal Surrogate! \n"); + uprv_free(dest); + return NULL; + } + + if((destLen+UTF8_CHAR_LENGTH(c)) < destCap){ + + /* ASCII Range */ + if(c <=0x007F){ + switch(c) { + case '&': + uprv_strcpy(dest+( destLen),"&"); + destLen+=(int32_t)uprv_strlen("&"); + break; + case '<': + uprv_strcpy(dest+(destLen),"<"); + destLen+=(int32_t)uprv_strlen("<"); + break; + case '>': + uprv_strcpy(dest+(destLen),">"); + destLen+=(int32_t)uprv_strlen(">"); + break; + case '"': + uprv_strcpy(dest+(destLen),"""); + destLen+=(int32_t)uprv_strlen("""); + break; + case '\'': + uprv_strcpy(dest+(destLen),"'"); + destLen+=(int32_t)uprv_strlen("'"); + break; + + /* Disallow C0 controls except TAB, CR, LF*/ + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + /*case 0x09:*/ + /*case 0x0A: */ + case 0x0B: + case 0x0C: + /*case 0x0D:*/ + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + *status = U_ILLEGAL_CHAR_FOUND; + fprintf(stderr, "Illegal Character \\u%04X!\n",(int)c); + uprv_free(dest); + return NULL; + default: + dest[destLen++]=(char)c; + } + }else{ + UBool isError = FALSE; + U8_APPEND((unsigned char*)dest,destLen,destCap,c,isError); + if(isError){ + *status = U_ILLEGAL_CHAR_FOUND; + fprintf(stderr, "Illegal Character \\U%08X!\n",(int)c); + uprv_free(dest); + return NULL; + } + } + }else{ + destCap += destLen; + + temp = (char*) uprv_malloc(sizeof(char)*destCap); + if(temp==NULL){ + *status=U_MEMORY_ALLOCATION_ERROR; + uprv_free(dest); + return NULL; + } + uprv_memmove(temp,dest,destLen); + destLen=0; + uprv_free(dest); + dest=temp; + temp=NULL; + } + + } + *destLength = destLen; + return dest; +} + +#define ASTERISK 0x002A +#define SPACE 0x0020 +#define CR 0x000A +#define LF 0x000D +#define AT_SIGN 0x0040 + +static void +trim(char **src, int32_t *len){ + + char *s = NULL; + int32_t i = 0; + if(src == NULL || *src == NULL){ + return; + } + s = *src; + /* trim from the end */ + for( i=(*len-1); i>= 0; i--){ + switch(s[i]){ + case ASTERISK: + case SPACE: + case CR: + case LF: + s[i] = 0; + continue; + default: + break; + } + break; + + } + *len = i+1; +} + +static void +print(UChar* src, int32_t srcLen,const char *tagStart,const char *tagEnd, UErrorCode *status){ + int32_t bufCapacity = srcLen*4; + char *buf = NULL; + int32_t bufLen = 0; + + if(U_FAILURE(*status)){ + return; + } + + buf = (char*) (uprv_malloc(bufCapacity)); + if(buf==0){ + fprintf(stderr, "Could not allocate memory!!"); + exit(U_MEMORY_ALLOCATION_ERROR); + } + buf = convertAndEscape(&buf, bufCapacity, &bufLen, src, srcLen,status); + if(U_SUCCESS(*status)){ + trim(&buf,&bufLen); + T_FileStream_write(out,tagStart, (int32_t)uprv_strlen(tagStart)); + T_FileStream_write(out, buf, bufLen); + T_FileStream_write(out,tagEnd, (int32_t)uprv_strlen(tagEnd)); + T_FileStream_write(out,"\n",1); + + } +} +static void +printNoteElements(struct UString *src, UErrorCode *status){ + +#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */ + + int32_t capacity = 0; + UChar* note = NULL; + int32_t noteLen = 0; + int32_t count = 0,i; + + if(src == NULL){ + return; + } + + capacity = src->fLength; + note = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity); + + count = getCount(src->fChars,src->fLength, UPC_NOTE, status); + if(U_FAILURE(*status)){ + return; + } + for(i=0; i < count; i++){ + noteLen = getAt(src->fChars,src->fLength, ¬e, capacity, i, UPC_NOTE, status); + if(U_FAILURE(*status)){ + return; + } + if(noteLen > 0){ + write_tabs(out); + print(note, noteLen,"<note>", "</note>", status); + } + } + uprv_free(note); +#else + + fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n"); + +#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ + +} + +static void printAttribute(const char *name, const char *value, int32_t len) +{ + T_FileStream_write(out, " ", 1); + T_FileStream_write(out, name, (int32_t) uprv_strlen(name)); + T_FileStream_write(out, " = \"", 4); + T_FileStream_write(out, value, (int32_t) len); + T_FileStream_write(out, "\"", 1); +} + +static void +printComments(struct UString *src, const char *resName, UBool printTranslate, UErrorCode *status){ + +#if UCONFIG_NO_REGULAR_EXPRESSIONS==0 /* donot compile when no RegularExpressions are available */ + + int32_t capacity = src->fLength; + char* buf = NULL; + int32_t bufLen = 0; + UChar* desc = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity); + UChar* trans = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * capacity); + + int32_t descLen = 0, transLen=0; + if(status==NULL || U_FAILURE(*status)){ + uprv_free(desc); + uprv_free(trans); + return; + } + if(desc==NULL || trans==NULL){ + *status = U_MEMORY_ALLOCATION_ERROR; + uprv_free(desc); + uprv_free(trans); + return; + } + src->fLength = removeCmtText(src->fChars, src->fLength, status); + descLen = getDescription(src->fChars,src->fLength, &desc, capacity, status); + transLen = getTranslate(src->fChars,src->fLength, &trans, capacity, status); + + /* first print translate attribute */ + if(transLen > 0){ + if(printTranslate){ + /* print translate attribute */ + buf = convertAndEscape(&buf, 0, &bufLen, trans, transLen, status); + if(U_SUCCESS(*status)){ + printAttribute("translate", buf, bufLen); + T_FileStream_write(out,">\n", 2); + } + }else if(getShowWarning()){ + fprintf(stderr, "Warning: Tranlate attribute for resource %s cannot be set. XLIFF prohibits it.\n", resName); + /* no translate attribute .. just close the tag */ + T_FileStream_write(out,">\n", 2); + } + }else{ + /* no translate attribute .. just close the tag */ + T_FileStream_write(out,">\n", 2); + } + + if(descLen > 0){ + write_tabs(out); + print(desc, descLen, "<!--", "-->", status); + } +#else + + fprintf(stderr, "Warning: Could not output comments to XLIFF file. ICU has been built without RegularExpression support.\n"); + +#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ + +} + +/* + * Print out a containing element, like: + * <trans-unit id = "blah" resname = "blah" restype = "x-id-alias" translate = "no"> + * <group id "calendar_gregorian" resname = "gregorian" restype = "x-icu-array"> + */ +static char *printContainer(struct SResource *res, const char *container, const char *restype, const char *mimetype, const char *id, UErrorCode *status) +{ + char *resname = NULL; + char *sid = NULL; + + write_tabs(out); + + if (res->fKey >= 0 && uprv_strcmp(srBundle->fKeys + res->fKey, "") != 0) { + resname = srBundle->fKeys + res->fKey; + sid = getID(id, resname, sid); + } else { + sid = getID(id, NULL, sid); + } + + T_FileStream_write(out, "<", 1); + T_FileStream_write(out, container, (int32_t) uprv_strlen(container)); + printAttribute("id", sid, (int32_t) uprv_strlen(sid)); + + if (resname != NULL) { + printAttribute("resname", resname, (int32_t) uprv_strlen(resname)); + } + + if (mimetype != NULL) { + printAttribute("mime-type", mimetype, (int32_t) uprv_strlen(mimetype)); + } + + if (restype != NULL) { + printAttribute("restype", restype, (int32_t) uprv_strlen(restype)); + } + + tabCount += 1; + if (res->fComment != NULL && res->fComment->fChars != NULL) { + /* printComments will print the closing ">\n" */ + printComments(res->fComment, resname, TRUE, status); + } else { + T_FileStream_write(out, ">\n", 2); + } + + return sid; +} + +/* Writing Functions */ + +static const char *trans_unit = "trans-unit"; +static const char *close_trans_unit = "</trans-unit>\n"; +static const char *source = "<source>"; +static const char *close_source = "</source>\n"; +static const char *group = "group"; +static const char *close_group = "</group>\n"; + +static const char *bin_unit = "bin-unit"; +static const char *close_bin_unit = "</bin-unit>\n"; +static const char *bin_source = "<bin-source>\n"; +static const char *close_bin_source = "</bin-source>\n"; +static const char *external_file = "<external-file"; +/*static const char *close_external_file = "</external-file>\n";*/ +static const char *internal_file = "<internal-file"; +static const char *close_internal_file = "</internal-file>\n"; + +static const char *application_mimetype = "application"; /* add "/octet-stream"? */ + +static const char *alias_restype = "x-icu-alias"; +static const char *array_restype = "x-icu-array"; +static const char *binary_restype = "x-icu-binary"; +static const char *integer_restype = "x-icu-integer"; +static const char *intvector_restype = "x-icu-intvector"; +static const char *table_restype = "x-icu-table"; + +static void +string_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) { + + char *sid = NULL; + char* buf = NULL; + int32_t bufLen = 0; + + if(status==NULL || U_FAILURE(*status)){ + return; + } + + sid = printContainer(res, trans_unit, NULL, NULL, id, status); + + write_tabs(out); + + T_FileStream_write(out, source, (int32_t) uprv_strlen(source)); + + buf = convertAndEscape(&buf, 0, &bufLen, res->u.fString.fChars, res->u.fString.fLength, status); + + if (U_FAILURE(*status)) { + return; + } + + T_FileStream_write(out, buf, bufLen); + T_FileStream_write(out, close_source, (int32_t) uprv_strlen(close_source)); + + printNoteElements(res->fComment, status); + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_trans_unit, (int32_t) uprv_strlen(close_trans_unit)); + + uprv_free(buf); + uprv_free(sid); +} + +static void +alias_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) { + char *sid = NULL; + char* buf = NULL; + int32_t bufLen=0; + + sid = printContainer(res, trans_unit, alias_restype, NULL, id, status); + + write_tabs(out); + + T_FileStream_write(out, source, (int32_t) uprv_strlen(source)); + + buf = convertAndEscape(&buf, 0, &bufLen, res->u.fString.fChars, res->u.fString.fLength, status); + + if(U_FAILURE(*status)){ + return; + } + T_FileStream_write(out, buf, bufLen); + T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source)); + + printNoteElements(res->fComment, status); + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit)); + + uprv_free(buf); + uprv_free(sid); +} + +static void +array_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) { + char* sid = NULL; + int index = 0; + + struct SResource *current = NULL; + struct SResource *first =NULL; + + sid = printContainer(res, group, array_restype, NULL, id, status); + + current = res->u.fArray.fFirst; + first=current; + + while (current != NULL) { + char c[256] = {0}; + char* subId = NULL; + + itostr(c, index, 10, 0); + index += 1; + subId = getID(sid, c, subId); + + res_write_xml(current, subId, language, FALSE, status); + uprv_free(subId); + subId = NULL; + + if(U_FAILURE(*status)){ + return; + } + + current = current->fNext; + } + + tabCount -= 1; + write_tabs(out); + T_FileStream_write(out, close_group, (int32_t) uprv_strlen(close_group)); + + uprv_free(sid); +} + +static void +intvector_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) { + char* sid = NULL; + char* ivd = NULL; + uint32_t i=0; + uint32_t len=0; + char buf[256] = {'0'}; + + sid = printContainer(res, group, intvector_restype, NULL, id, status); + + for(i = 0; i < res->u.fIntVector.fCount; i += 1) { + char c[256] = {0}; + + itostr(c, i, 10, 0); + ivd = getID(sid, c, ivd); + len = itostr(buf, res->u.fIntVector.fArray[i], 10, 0); + + write_tabs(out); + T_FileStream_write(out, "<", 1); + T_FileStream_write(out, trans_unit, (int32_t)uprv_strlen(trans_unit)); + + printAttribute("id", ivd, (int32_t)uprv_strlen(ivd)); + printAttribute("restype", integer_restype, (int32_t) strlen(integer_restype)); + + T_FileStream_write(out,">\n", 2); + + tabCount += 1; + write_tabs(out); + T_FileStream_write(out, source, (int32_t)uprv_strlen(source)); + + T_FileStream_write(out, buf, len); + + T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source)); + tabCount -= 1; + write_tabs(out); + T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit)); + + uprv_free(ivd); + ivd = NULL; + } + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_group, (int32_t)uprv_strlen(close_group)); + uprv_free(sid); + sid = NULL; +} + +static void +int_write_xml(struct SResource *res, const char* id, const char* language, UErrorCode *status) { + char* sid = NULL; + char buf[256] = {0}; + uint32_t len = 0; + + sid = printContainer(res, trans_unit, integer_restype, NULL, id, status); + + write_tabs(out); + + T_FileStream_write(out, source, (int32_t) uprv_strlen(source)); + + len = itostr(buf, res->u.fIntValue.fValue, 10, 0); + T_FileStream_write(out, buf, len); + + T_FileStream_write(out, close_source, (int32_t)uprv_strlen(close_source)); + + printNoteElements(res->fComment, status); + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_trans_unit, (int32_t)uprv_strlen(close_trans_unit)); + + uprv_free(sid); + sid = NULL; +} + +static void +bin_write_xml( struct SResource *res, const char* id, const char* language, UErrorCode *status) { + const char* m_type = application_mimetype; + char* sid = NULL; + uint32_t crc = 0xFFFFFFFF; + + char fileName[1024] ={0}; + int32_t tLen = ( outDir == NULL) ? 0 :(int32_t)uprv_strlen(outDir); + char* fn = (char*) uprv_malloc(sizeof(char) * (tLen+1024 + + (res->u.fBinaryValue.fFileName !=NULL ? + uprv_strlen(res->u.fBinaryValue.fFileName) :0))); + const char* ext = NULL; + + char* f = NULL; + + fn[0]=0; + + if(res->u.fBinaryValue.fFileName != NULL){ + uprv_strcpy(fileName, res->u.fBinaryValue.fFileName); + f = uprv_strrchr(fileName, '\\'); + + if (f != NULL) { + f++; + } else { + f = fileName; + } + + ext = uprv_strrchr(fileName, '.'); + + if (ext == NULL) { + fprintf(stderr, "Error: %s is an unknown binary filename type.\n", fileName); + exit(U_ILLEGAL_ARGUMENT_ERROR); + } + + if(uprv_strcmp(ext, ".jpg")==0 || uprv_strcmp(ext, ".jpeg")==0 || uprv_strcmp(ext, ".gif")==0 ){ + m_type = "image"; + } else if(uprv_strcmp(ext, ".wav")==0 || uprv_strcmp(ext, ".au")==0 ){ + m_type = "audio"; + } else if(uprv_strcmp(ext, ".avi")==0 || uprv_strcmp(ext, ".mpg")==0 || uprv_strcmp(ext, ".mpeg")==0){ + m_type = "video"; + } else if(uprv_strcmp(ext, ".txt")==0 || uprv_strcmp(ext, ".text")==0){ + m_type = "text"; + } + + sid = printContainer(res, bin_unit, binary_restype, m_type, id, status); + + write_tabs(out); + + T_FileStream_write(out, bin_source, (int32_t)uprv_strlen(bin_source)); + + tabCount+= 1; + write_tabs(out); + + T_FileStream_write(out, external_file, (int32_t)uprv_strlen(external_file)); + printAttribute("href", f, (int32_t)uprv_strlen(f)); + T_FileStream_write(out, "/>\n", 3); + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_bin_source, (int32_t)uprv_strlen(close_bin_source)); + + printNoteElements(res->fComment, status); + tabCount -= 1; + write_tabs(out); + T_FileStream_write(out, close_bin_unit, (int32_t)uprv_strlen(close_bin_unit)); + } else { + char temp[256] = {0}; + uint32_t i = 0; + int32_t len=0; + + sid = printContainer(res, bin_unit, binary_restype, m_type, id, status); + + write_tabs(out); + T_FileStream_write(out, bin_source, (int32_t)uprv_strlen(bin_source)); + + tabCount += 1; + write_tabs(out); + + T_FileStream_write(out, internal_file, (int32_t)uprv_strlen(internal_file)); + printAttribute("form", application_mimetype, (int32_t) uprv_strlen(application_mimetype)); + + while(i <res->u.fBinaryValue.fLength){ + len = itostr(temp, res->u.fBinaryValue.fData[i], 16, 2); + crc = computeCRC(temp, len, crc); + i++; + } + + len = itostr(temp, crc, 10, 0); + printAttribute("crc", temp, len); + + T_FileStream_write(out, ">", 1); + + i = 0; + while(i <res->u.fBinaryValue.fLength){ + len = itostr(temp, res->u.fBinaryValue.fData[i], 16, 2); + T_FileStream_write(out ,temp ,len); + i += 1; + } + + T_FileStream_write(out, close_internal_file, (int32_t)uprv_strlen(close_internal_file)); + + tabCount -= 2; + write_tabs(out); + + T_FileStream_write(out, close_bin_source, (int32_t)uprv_strlen(close_bin_source)); + printNoteElements(res->fComment, status); + + tabCount -= 1; + write_tabs(out); + T_FileStream_write(out, close_bin_unit, (int32_t)uprv_strlen(close_bin_unit)); + + uprv_free(sid); + sid = NULL; + } + + uprv_free(fn); +} + + + +static void +table_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) { + + uint32_t i = 0; + + struct SResource *current = NULL; + struct SResource *save = NULL; + char* sid = NULL; + + if (U_FAILURE(*status)) { + return ; + } + + sid = printContainer(res, group, table_restype, NULL, id, status); + + if(isTopLevel) { + sid[0] = '\0'; + } + + save = current = res->u.fTable.fFirst; + i = 0; + + while (current != NULL) { + res_write_xml(current, sid, language, FALSE, status); + + if(U_FAILURE(*status)){ + return; + } + + i += 1; + current = current->fNext; + } + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out, close_group,(int32_t)uprv_strlen(close_group)); + + uprv_free(sid); + sid = NULL; +} + +void +res_write_xml(struct SResource *res, const char* id, const char* language, UBool isTopLevel, UErrorCode *status) { + + if (U_FAILURE(*status)) { + return ; + } + + if (res != NULL) { + switch (res->fType) { + case URES_STRING: + string_write_xml (res, id, language, status); + return; + + case URES_ALIAS: + alias_write_xml (res, id, language, status); + return; + + case URES_INT_VECTOR: + intvector_write_xml (res, id, language, status); + return; + + case URES_BINARY: + bin_write_xml (res, id, language, status); + return; + + case URES_INT: + int_write_xml (res, id, language, status); + return; + + case URES_ARRAY: + array_write_xml (res, id, language, status); + return; + + case URES_TABLE: + case URES_TABLE32: + table_write_xml (res, id, language, isTopLevel, status); + return; + + default: + break; + } + } + + *status = U_INTERNAL_PROGRAM_ERROR; +} + +void +bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* filename, + char *writtenFilename, int writtenFilenameLen, + const char* language, const char* outFileName, UErrorCode *status) { + + char* xmlfileName = NULL; + char* outputFileName = NULL; + char* originalFileName = NULL; + const char* fileStart = "<file xml:space = \"preserve\" source-language = \""; + const char* file1 = "\" datatype = \"x-icu-resource-bundle\" "; + const char* file2 = "original = \""; + const char* file4 = "\" date = \""; + const char* fileEnd = "</file>\n"; + const char* headerStart = "<header>\n"; + const char* headerEnd = "</header>\n"; + const char* bodyStart = "<body>\n"; + const char* bodyEnd = "</body>\n"; + + const char *tool_start = "<tool"; + const char *tool_id = "genrb-" GENRB_VERSION "-icu-" U_ICU_VERSION; + const char *tool_name = "genrb"; + + char* pid = NULL; + char* temp = NULL; + char* lang = NULL; + char* pos; + int32_t first, index; + time_t currTime; + char timeBuf[128]; + + outDir = outputDir; + + srBundle = bundle; + + pos = uprv_strrchr(filename, '\\'); + if(pos != NULL) { + first = (int32_t)(pos - filename + 1); + } else { + first = 0; + } + index = (int32_t)(uprv_strlen(filename) - uprv_strlen(textExt) - first); + originalFileName = uprv_malloc(sizeof(char)*index+1); + uprv_memset(originalFileName, 0, sizeof(char)*index+1); + uprv_strncpy(originalFileName, filename + first, index); + + if(uprv_strcmp(originalFileName, srBundle->fLocale) != 0) { + fprintf(stdout, "Warning: The file name is not same as the resource name!\n"); + } + + temp = originalFileName; + originalFileName = uprv_malloc(sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1); + uprv_memset(originalFileName, 0, sizeof(char)* (uprv_strlen(temp)+uprv_strlen(textExt)) + 1); + uprv_strcat(originalFileName, temp); + uprv_strcat(originalFileName, textExt); + uprv_free(temp); + temp = NULL; + + + if (language == NULL) { +/* lang = parseFilename(filename, lang); + if (lang == NULL) {*/ + /* now check if locale name is valid or not + * this is to cater for situation where + * pegasusServer.txt contains + * + * en{ + * .. + * } + */ + lang = parseFilename(srBundle->fLocale, lang); + /* + * Neither the file name nor the table name inside the + * txt file contain a valid country and language codes + * throw an error. + * pegasusServer.txt contains + * + * testelements{ + * .... + * } + */ + if(lang==NULL){ + fprintf(stderr, "Error: The file name and table name do not contain a valid language code. Please use -l option to specify it.\n"); + exit(U_ILLEGAL_ARGUMENT_ERROR); + } + /* }*/ + } else { + lang = uprv_malloc(sizeof(char)*uprv_strlen(language) +1); + uprv_memset(lang, 0, sizeof(char)*uprv_strlen(language) +1); + uprv_strcpy(lang, language); + } + + if(outFileName) { + outputFileName = uprv_malloc(sizeof(char)*uprv_strlen(outFileName) + 1); + uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(outFileName) + 1); + uprv_strcpy(outputFileName,outFileName); + } else { + outputFileName = uprv_malloc(sizeof(char)*uprv_strlen(srBundle->fLocale) + 1); + uprv_memset(outputFileName, 0, sizeof(char)*uprv_strlen(srBundle->fLocale) + 1); + uprv_strcpy(outputFileName,srBundle->fLocale); + } + + if(outputDir) { + xmlfileName = uprv_malloc(sizeof(char)*(uprv_strlen(outputDir) + uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1); + uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputDir)+ uprv_strlen(outputFileName) + uprv_strlen(xliffExt) + 1) +1); + } else { + xmlfileName = uprv_malloc(sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1); + uprv_memset(xmlfileName, 0, sizeof(char)*(uprv_strlen(outputFileName) + uprv_strlen(xliffExt)) +1); + } + + if(outputDir){ + uprv_strcpy(xmlfileName, outputDir); + if(outputDir[uprv_strlen(outputDir)-1] !=U_FILE_SEP_CHAR){ + uprv_strcat(xmlfileName,U_FILE_SEP_STRING); + } + } + uprv_strcat(xmlfileName,outputFileName); + uprv_strcat(xmlfileName,xliffExt); + + if (writtenFilename) { + uprv_strncpy(writtenFilename, xmlfileName, writtenFilenameLen); + } + + if (U_FAILURE(*status)) { + goto cleanup_bundle_write_xml; + } + + out= T_FileStream_open(xmlfileName,"w"); + + if(out==NULL){ + *status = U_FILE_ACCESS_ERROR; + goto cleanup_bundle_write_xml; + } + T_FileStream_write(out,xmlHeader, (int32_t)uprv_strlen(xmlHeader)); + + if(outputEnc && *outputEnc!='\0'){ + /* store the output encoding */ + enc = outputEnc; + conv=ucnv_open(enc,status); + if(U_FAILURE(*status)){ + goto cleanup_bundle_write_xml; + } + } + T_FileStream_write(out,bundleStart, (int32_t)uprv_strlen(bundleStart)); + write_tabs(out); + T_FileStream_write(out, fileStart, (int32_t)uprv_strlen(fileStart)); + /* check if lang and language are the same */ + if(language != NULL && uprv_strcmp(lang, srBundle->fLocale)!=0){ + fprintf(stderr,"Warning: The top level tag in the resource and language specified are not the same. Please check the input.\n"); + } + T_FileStream_write(out,lang, (int32_t)uprv_strlen(lang)); + T_FileStream_write(out,file1, (int32_t)uprv_strlen(file1)); + T_FileStream_write(out,file2, (int32_t)uprv_strlen(file2)); + T_FileStream_write(out,originalFileName, (int32_t)uprv_strlen(originalFileName)); T_FileStream_write(out,file4, (int32_t)uprv_strlen(file4)); + + time(&currTime); + strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&currTime)); + T_FileStream_write(out,timeBuf, (int32_t)uprv_strlen(timeBuf)); + + T_FileStream_write(out,"\">\n", 3); + + tabCount += 1; + write_tabs(out); + T_FileStream_write(out,headerStart, (int32_t)uprv_strlen(headerStart)); + + tabCount += 1; + write_tabs(out); + + T_FileStream_write(out, tool_start, (int32_t) uprv_strlen(tool_start)); + printAttribute("tool-id", tool_id, (int32_t) uprv_strlen(tool_id)); + printAttribute("tool-name", tool_name, (int32_t) uprv_strlen(tool_name)); + T_FileStream_write(out, "/>\n", 3); + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out,headerEnd, (int32_t)uprv_strlen(headerEnd)); + + write_tabs(out); + tabCount += 1; + + T_FileStream_write(out,bodyStart, (int32_t)uprv_strlen(bodyStart)); + + + res_write_xml(bundle->fRoot, bundle->fLocale, lang, TRUE, status); + + tabCount -= 1; + write_tabs(out); + + T_FileStream_write(out,bodyEnd, (int32_t)uprv_strlen(bodyEnd)); + tabCount--; + write_tabs(out); + T_FileStream_write(out,fileEnd, (int32_t)uprv_strlen(fileEnd)); + tabCount--; + write_tabs(out); + T_FileStream_write(out,bundleEnd,(int32_t)uprv_strlen(bundleEnd)); + T_FileStream_close(out); + + ucnv_close(conv); + +cleanup_bundle_write_xml: + if(originalFileName!= NULL) { + uprv_free(originalFileName); + originalFileName = NULL; + } + if(lang != NULL) { + uprv_free(lang); + lang = NULL; + } + if(pid != NULL) { + uprv_free(pid); + pid = NULL; + } + if(xmlfileName != NULL) { + uprv_free(xmlfileName); + pid = NULL; + } + if(outputFileName != NULL){ + uprv_free(outputFileName); + pid = NULL; + } +} |