Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,657 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1999-2016, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: derb.cpp
* encoding: UTF-8
* 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/stringpiece.h"
#include "unicode/ucnv.h"
#include "unicode/unistr.h"
#include "unicode/ustring.h"
#include "unicode/putil.h"
#include "unicode/ustdio.h"
#include "charstr.h"
#include "uresimp.h"
#include "cmemory.h"
#include "cstring.h"
#include "uoptions.h"
#include "toolutil.h"
#include "ustrfmt.h"
#if !UCONFIG_NO_FORMATTING
#define DERB_VERSION "1.1"
#define DERB_DEFAULT_TRUNC 80
static const int32_t indentsize = 4;
static int32_t truncsize = DERB_DEFAULT_TRUNC;
static UBool opt_truncate = false;
static const char *getEncodingName(const char *encoding);
static void reportError(const char *pname, UErrorCode *status, const char *when);
static char16_t *quotedString(const char16_t *string);
static void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status);
static void printString(UFILE *out, const char16_t *str, int32_t len);
static void printCString(UFILE *out, const char *str, int32_t len);
static void printIndent(UFILE *out, int32_t indent);
static void printHex(UFILE *out, uint8_t what);
static UOption options[]={
UOPTION_HELP_H,
UOPTION_HELP_QUESTION_MARK,
/* 2 */ UOPTION_ENCODING,
/* 3 */ { "to-stdout", nullptr, nullptr, nullptr, 'c', UOPT_NO_ARG, 0 } ,
/* 4 */ { "truncate", nullptr, nullptr, nullptr, 't', UOPT_OPTIONAL_ARG, 0 },
/* 5 */ UOPTION_VERBOSE,
/* 6 */ UOPTION_DESTDIR,
/* 7 */ UOPTION_SOURCEDIR,
/* 8 */ { "bom", nullptr, nullptr, nullptr, 0, UOPT_NO_ARG, 0 },
/* 9 */ UOPTION_ICUDATADIR,
/* 10 */ UOPTION_VERSION,
/* 11 */ { "suppressAliases", nullptr, nullptr, nullptr, 'A', UOPT_NO_ARG, 0 },
};
static UBool verbose = false;
static UBool suppressAliases = false;
static UFILE *ustderr = nullptr;
extern int
main(int argc, char* argv[]) {
const char *encoding = nullptr;
const char *outputDir = nullptr; /* nullptr = no output directory, use current */
const char *inputDir = ".";
int tostdout = 0;
int prbom = 0;
const char *pname;
UResourceBundle *bundle = nullptr;
int32_t i = 0;
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, UPRV_LENGTHOF(options), 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) {
if(options[2].doesOccur) {
fprintf(stderr, "%s: Error: don't specify an encoding (-e) when writing to stdout (-c).\n", pname);
return 3;
}
tostdout = 1;
}
if(options[4].doesOccur) {
opt_truncate = true;
if(options[4].value != nullptr) {
truncsize = atoi(options[4].value); /* user defined printable size */
} else {
truncsize = DERB_DEFAULT_TRUNC; /* we'll use default omitting size */
}
} else {
opt_truncate = 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;
}
fflush(stderr); // use ustderr now.
ustderr = u_finit(stderr, nullptr, nullptr);
for (i = 1; i < argc; ++i) {
static const char16_t sp[] = { 0x0020 }; /* " " */
arg = getLongPathname(argv[i]);
if (verbose) {
u_fprintf(ustderr, "processing bundle \"%s\"\n", argv[i]);
}
icu::CharString locale;
UErrorCode status = U_ZERO_ERROR;
{
const char *p = findBasename(arg);
const char *q = uprv_strrchr(p, '.');
if (q == nullptr) {
locale.append(p, status);
} else {
locale.append(p, static_cast<int32_t>(q - p), status);
}
}
if (U_FAILURE(status)) {
return status;
}
icu::CharString infile;
const char *thename = nullptr;
UBool fromICUData = !uprv_strcmp(inputDir, "-");
if (!fromICUData) {
UBool absfilename = *arg == U_FILE_SEP_CHAR;
#if U_PLATFORM_HAS_WIN32_API
if (!absfilename) {
absfilename = (uprv_strlen(arg) > 2 && isalpha(arg[0])
&& arg[1] == ':' && arg[2] == U_FILE_SEP_CHAR);
}
#endif
if (absfilename) {
thename = arg;
} else {
const char *q = uprv_strrchr(arg, U_FILE_SEP_CHAR);
#if U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR
if (q == nullptr) {
q = uprv_strrchr(arg, U_FILE_ALT_SEP_CHAR);
}
#endif
infile.append(inputDir, status);
if(q != nullptr) {
infile.appendPathPart(icu::StringPiece(arg, static_cast<int32_t>(q - arg)), status);
}
if (U_FAILURE(status)) {
return status;
}
thename = infile.data();
}
}
if (thename) {
bundle = ures_openDirect(thename, locale.data(), &status);
} else {
bundle = ures_open(fromICUData ? nullptr : inputDir, locale.data(), &status);
}
if (U_SUCCESS(status)) {
UFILE *out = nullptr;
const char* filename = nullptr;
const char* ext = nullptr;
if (locale.isEmpty() || !tostdout) {
filename = findBasename(arg);
ext = uprv_strrchr(filename, '.');
if (!ext) {
ext = uprv_strchr(filename, 0);
}
}
if (tostdout) {
out = u_get_stdout();
} else {
icu::CharString thefile;
if (outputDir) {
thefile.append(outputDir, status);
}
thefile.appendPathPart(filename, status);
if (*ext) {
thefile.truncate(thefile.length() - static_cast<int32_t>(uprv_strlen(ext)));
}
thefile.append(".txt", status);
if (U_FAILURE(status)) {
return status;
}
out = u_fopen(thefile.data(), "w", nullptr, encoding);
if (!out) {
u_fprintf(ustderr, "%s: couldn't create %s\n", pname, thefile.data());
u_fclose(ustderr);
return 4;
}
}
// now, set the callback.
ucnv_setFromUCallBack(u_fgetConverter(out), UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, nullptr, nullptr, &status);
if (U_FAILURE(status)) {
u_fprintf(ustderr, "%s: couldn't configure converter for encoding\n", pname);
u_fclose(ustderr);
if(!tostdout) {
u_fclose(out);
}
return 3;
}
if (prbom) { /* XXX: Should be done only for UTFs */
u_fputc(0xFEFF, out);
}
u_fprintf(out, "// -*- Coding: %s; -*-\n//\n", encoding ? encoding : getEncodingName(ucnv_getDefaultName()));
u_fprintf(out, "// This file was dumped by derb(8) from ");
if (thename) {
u_fprintf(out, "%s", thename);
} else if (fromICUData) {
u_fprintf(out, "the ICU internal %s locale", locale.data());
}
u_fprintf(out, "\n// derb(8) by Vladimir Weinstein and Yves Arrouye\n\n");
if (!locale.isEmpty()) {
u_fprintf(out, "%s", locale.data());
} else {
u_fprintf(out, "%.*s%.*S", static_cast<int32_t>(ext - filename), filename, UPRV_LENGTHOF(sp), sp);
}
printOutBundle(out, bundle, 0, pname, &status);
if (!tostdout) {
u_fclose(out);
}
}
else {
reportError(pname, &status, "opening resource file");
}
ures_close(bundle);
}
return 0;
}
static char16_t *quotedString(const char16_t *string) {
int len = u_strlen(string);
int alen = len;
const char16_t *sp;
char16_t *newstr, *np;
for (sp = string; *sp; ++sp) {
switch (*sp) {
case '\n':
case 0x0022:
++alen;
break;
}
}
newstr = static_cast<char16_t*>(uprv_malloc((1 + alen) * U_SIZEOF_UCHAR));
for (sp = string, np = newstr; *sp; ++sp) {
switch (*sp) {
case '\n':
*np++ = 0x005C;
*np++ = 0x006E;
break;
case 0x0022:
*np++ = 0x005C;
U_FALLTHROUGH;
default:
*np++ = *sp;
break;
}
}
*np = 0;
return newstr;
}
static void printString(UFILE *out, const char16_t *str, int32_t len) {
u_file_write(str, len, out);
}
static void printCString(UFILE *out, const char *str, int32_t len) {
if(len==-1) {
u_fprintf(out, "%s", str);
} else {
u_fprintf(out, "%.*s", len, str);
}
}
static void printIndent(UFILE *out, int32_t indent) {
icu::UnicodeString inchar(indent, 0x20, indent);
printString(out, inchar.getBuffer(), indent);
}
static void printHex(UFILE *out, uint8_t what) {
static const char map[] = "0123456789ABCDEF";
char16_t hex[2];
hex[0] = map[what >> 4];
hex[1] = map[what & 0xf];
printString(out, hex, 2);
}
static void printOutAlias(UFILE *out, UResourceBundle *parent, Resource r, const char *key, int32_t indent, const char *pname, UErrorCode *status) {
static const char16_t cr[] = { 0xA }; // LF
int32_t len = 0;
const char16_t* thestr = res_getAlias(&(parent->getResData()), r, &len);
char16_t *string = quotedString(thestr);
if(opt_truncate && len > truncsize) {
char msg[128];
printIndent(out, indent);
snprintf(msg, sizeof(msg), "// WARNING: this resource, size %li is truncated to %li\n",
static_cast<long>(len), static_cast<long>(truncsize) / 2);
printCString(out, msg, -1);
len = truncsize;
}
if(U_SUCCESS(*status)) {
static const char16_t openStr[] = { 0x003A, 0x0061, 0x006C, 0x0069, 0x0061, 0x0073, 0x0020, 0x007B, 0x0020, 0x0022 }; /* ":alias { \"" */
static const char16_t closeStr[] = { 0x0022, 0x0020, 0x007D, 0x0020 }; /* "\" } " */
printIndent(out, indent);
if(key != nullptr) {
printCString(out, key, -1);
}
printString(out, openStr, UPRV_LENGTHOF(openStr));
printString(out, string, len);
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
if(verbose) {
printCString(out, " // ALIAS", -1);
}
printString(out, cr, UPRV_LENGTHOF(cr));
} else {
reportError(pname, status, "getting binary value");
}
uprv_free(string);
}
static void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status)
{
static const char16_t cr[] = { 0xA }; // LF
/* int32_t noOfElements = ures_getSize(resource);*/
int32_t i = 0;
const char *key = ures_getKey(resource);
switch(ures_getType(resource)) {
case URES_STRING :
{
int32_t len=0;
const char16_t* thestr = ures_getString(resource, &len, status);
char16_t *string = quotedString(thestr);
/* TODO: String truncation */
if(opt_truncate && len > truncsize) {
char msg[128];
printIndent(out, indent);
snprintf(msg, sizeof(msg), "// WARNING: this resource, size %li is truncated to %li\n",
static_cast<long>(len), static_cast<long>(truncsize / 2));
printCString(out, msg, -1);
len = truncsize/2;
}
printIndent(out, indent);
if(key != nullptr) {
static const char16_t openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */
static const char16_t closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */
printCString(out, key, static_cast<int32_t>(uprv_strlen(key)));
printString(out, openStr, UPRV_LENGTHOF(openStr));
printString(out, string, len);
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
} else {
static const char16_t openStr[] = { 0x0022 }; /* "\"" */
static const char16_t closeStr[] = { 0x0022, 0x002C }; /* "\"," */
printString(out, openStr, UPRV_LENGTHOF(openStr));
printString(out, string, u_strlen(string));
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
}
if(verbose) {
printCString(out, "// STRING", -1);
}
printString(out, cr, UPRV_LENGTHOF(cr));
uprv_free(string);
}
break;
case URES_INT :
{
static const char16_t openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */
static const char16_t closeStr[] = { 0x0020, 0x007D }; /* " }" */
char16_t num[20];
printIndent(out, indent);
if(key != nullptr) {
printCString(out, key, -1);
}
printString(out, openStr, UPRV_LENGTHOF(openStr));
uprv_itou(num, 20, ures_getInt(resource, status), 10, 0);
printString(out, num, u_strlen(num));
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
if(verbose) {
printCString(out, "// INT", -1);
}
printString(out, cr, UPRV_LENGTHOF(cr));
break;
}
case URES_BINARY :
{
int32_t len = 0;
const int8_t* data = reinterpret_cast<const int8_t*>(ures_getBinary(resource, &len, status));
if(opt_truncate && len > truncsize) {
char msg[128];
printIndent(out, indent);
snprintf(msg, sizeof(msg), "// WARNING: this resource, size %li is truncated to %li\n",
static_cast<long>(len), static_cast<long>(truncsize / 2));
printCString(out, msg, -1);
len = truncsize;
}
if(U_SUCCESS(*status)) {
static const char16_t openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */
static const char16_t closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
printIndent(out, indent);
if(key != nullptr) {
printCString(out, key, -1);
}
printString(out, openStr, UPRV_LENGTHOF(openStr));
for(i = 0; i<len; i++) {
printHex(out, *data++);
}
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
if(verbose) {
printCString(out, " // BINARY", -1);
}
printString(out, cr, UPRV_LENGTHOF(cr));
} else {
reportError(pname, status, "getting binary value");
}
}
break;
case URES_INT_VECTOR :
{
int32_t len = 0;
const int32_t *data = ures_getIntVector(resource, &len, status);
if(U_SUCCESS(*status)) {
static const char16_t openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */
static const char16_t closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
char16_t num[20];
printIndent(out, indent);
if(key != nullptr) {
printCString(out, key, -1);
}
printString(out, openStr, UPRV_LENGTHOF(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, num, u_strlen(num));
}
if(len > 0) {
uprv_itou(num, 20, data[len - 1], 10, 0);
printString(out, num, u_strlen(num));
}
printString(out, closeStr, UPRV_LENGTHOF(closeStr));
if(verbose) {
printCString(out, "// INTVECTOR", -1);
}
printString(out, cr, UPRV_LENGTHOF(cr));
} else {
reportError(pname, status, "getting int vector");
}
}
break;
case URES_TABLE :
case URES_ARRAY :
{
static const char16_t openStr[] = { 0x007B }; /* "{" */
static const char16_t closeStr[] = { 0x007D, '\n' }; /* "}\n" */
UResourceBundle *t = nullptr;
ures_resetIterator(resource);
printIndent(out, indent);
if(key != nullptr) {
printCString(out, key, -1);
}
printString(out, openStr, UPRV_LENGTHOF(openStr));
if(verbose) {
if(ures_getType(resource) == URES_TABLE) {
printCString(out, "// TABLE", -1);
} else {
printCString(out, "// ARRAY", -1);
}
}
printString(out, cr, UPRV_LENGTHOF(cr));
if(suppressAliases == false) {
while(U_SUCCESS(*status) && ures_hasNext(resource)) {
t = ures_getNextResource(resource, t, status);
if(U_SUCCESS(*status)) {
printOutBundle(out, 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;
int32_t resSize = ures_getSize(resource);
UBool isTable = static_cast<UBool>(ures_getType(resource) == URES_TABLE);
for(i = 0; i < resSize; i++) {
/* need to know if it's an alias */
if(isTable) {
r = res_getTableItemByIndex(&resource->getResData(), resource->fRes, i, &key);
} else {
r = res_getArrayItem(&resource->getResData(), resource->fRes, i);
}
if(U_SUCCESS(*status)) {
if(res_getPublicType(r) == URES_ALIAS) {
printOutAlias(out, resource, r, key, indent+indentsize, pname, status);
} else {
t = ures_getByIndex(resource, i, t, status);
printOutBundle(out, t, indent+indentsize, pname, status);
}
} else {
reportError(pname, status, "While processing table");
*status = U_ZERO_ERROR;
}
}
}
printIndent(out, indent);
printString(out, closeStr, UPRV_LENGTHOF(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))) {
// do nothing
}
}
return enc;
}
static void reportError(const char *pname, UErrorCode *status, const char *when) {
u_fprintf(ustderr, "%s: error %d while %s: %s\n", pname, *status, when, u_errorName(*status));
}
#else
extern int
main(int argc, char* argv[]) {
/* Changing stdio.h ustdio.h requires that formatting not be disabled. */
return 3;
}
#endif /* !UCONFIG_NO_FORMATTING */
/*
* Local Variables:
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,75 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2011, 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 <stdbool.h>
#include <stdio.h>
#include "cstring.h"
#include "errmsg.h"
#include "toolutil.h"
U_CFUNC 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;
U_CFUNC void setShowWarning(UBool val)
{
gShowWarning = val;
}
U_CFUNC UBool getShowWarning(void){
return gShowWarning;
}
static UBool gStrict =false;
U_CFUNC UBool isStrict(void){
return gStrict;
}
U_CFUNC void setStrict(UBool val){
gStrict = val;
}
static UBool gVerbose =false;
U_CFUNC UBool isVerbose(void){
return gVerbose;
}
U_CFUNC void setVerbose(UBool val){
gVerbose = val;
}
U_CFUNC 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);
}
}

View File

@ -0,0 +1,46 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2016, 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
#include "unicode/utypes.h"
U_CDECL_BEGIN
extern const char *gCurrentFileName;
U_CFUNC void error(uint32_t linenumber, const char *msg, ...);
U_CFUNC 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);
U_CDECL_END
#endif

View File

@ -0,0 +1,240 @@
// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
#include <iostream>
#include <memory>
#include <stack>
#include "filterrb.h"
#include "errmsg.h"
const char* PathFilter::kEInclusionNames[] = {
"INCLUDE",
"PARTIAL",
"EXCLUDE"
};
ResKeyPath::ResKeyPath() {}
ResKeyPath::ResKeyPath(const std::string& path, UErrorCode& status) {
if (path.empty() || path[0] != '/') {
std::cerr << "genrb error: path must start with /: " << path << std::endl;
status = U_PARSE_ERROR;
return;
}
if (path.length() == 1) {
return;
}
size_t i;
size_t j = 0;
while (true) {
i = j + 1;
j = path.find('/', i);
std::string key = path.substr(i, j - i);
if (key.empty()) {
std::cerr << "genrb error: empty subpaths and trailing slashes are not allowed: " << path << std::endl;
status = U_PARSE_ERROR;
return;
}
push(key);
if (j == std::string::npos) {
break;
}
}
}
void ResKeyPath::push(const std::string& key) {
fPath.push_back(key);
}
void ResKeyPath::pop() {
fPath.pop_back();
}
const std::list<std::string>& ResKeyPath::pieces() const {
return fPath;
}
std::ostream& operator<<(std::ostream& out, const ResKeyPath& value) {
if (value.pieces().empty()) {
out << "/";
} else for (const auto& key : value.pieces()) {
out << "/" << key;
}
return out;
}
PathFilter::~PathFilter() = default;
void SimpleRuleBasedPathFilter::addRule(const std::string& ruleLine, UErrorCode& status) {
if (ruleLine.empty()) {
std::cerr << "genrb error: empty filter rules are not allowed" << std::endl;
status = U_PARSE_ERROR;
return;
}
bool inclusionRule = false;
if (ruleLine[0] == '+') {
inclusionRule = true;
} else if (ruleLine[0] != '-') {
std::cerr << "genrb error: rules must start with + or -: " << ruleLine << std::endl;
status = U_PARSE_ERROR;
return;
}
ResKeyPath path(ruleLine.substr(1), status);
addRule(path, inclusionRule, status);
}
void SimpleRuleBasedPathFilter::addRule(const ResKeyPath& path, bool inclusionRule, UErrorCode& status) {
if (U_FAILURE(status)) {
return;
}
fRoot.applyRule(path, path.pieces().begin(), inclusionRule, status);
}
PathFilter::EInclusion SimpleRuleBasedPathFilter::match(const ResKeyPath& path) const {
const Tree* node = &fRoot;
// defaultResult "bubbles up" the nearest "definite" inclusion/exclusion rule
EInclusion defaultResult = INCLUDE;
if (node->fIncluded != PARTIAL) {
// rules handled here: "+/" and "-/"
defaultResult = node->fIncluded;
}
// isLeaf is whether the filter tree can provide no additional information
// even if additional subpaths are added to the given key
bool isLeaf = false;
for (const auto& key : path.pieces()) {
auto child = node->fChildren.find(key);
// Leaf case 1: input path descends outside the filter tree
if (child == node->fChildren.end()) {
if (node->fWildcard) {
// A wildcard pattern is present; continue checking
node = node->fWildcard.get();
} else {
isLeaf = true;
break;
}
} else {
node = &child->second;
}
if (node->fIncluded != PARTIAL) {
defaultResult = node->fIncluded;
}
}
// Leaf case 2: input path exactly matches a filter leaf
if (node->isLeaf()) {
isLeaf = true;
}
// Always return PARTIAL if we are not at a leaf
if (!isLeaf) {
return PARTIAL;
}
// If leaf node is PARTIAL, return the default
if (node->fIncluded == PARTIAL) {
return defaultResult;
}
return node->fIncluded;
}
SimpleRuleBasedPathFilter::Tree::Tree(const Tree& other)
: fIncluded(other.fIncluded), fChildren(other.fChildren) {
// Note: can't use the default copy assignment because of the std::unique_ptr
if (other.fWildcard) {
fWildcard = std::make_unique<Tree>(*other.fWildcard);
}
}
bool SimpleRuleBasedPathFilter::Tree::isLeaf() const {
return fChildren.empty() && !fWildcard;
}
void SimpleRuleBasedPathFilter::Tree::applyRule(
const ResKeyPath& path,
std::list<std::string>::const_iterator it,
bool inclusionRule,
UErrorCode& status) {
// Base Case
if (it == path.pieces().end()) {
if (isVerbose() && (fIncluded != PARTIAL || !isLeaf())) {
std::cout << "genrb info: rule on path " << path
<< " overrides previous rules" << std::endl;
}
fIncluded = inclusionRule ? INCLUDE : EXCLUDE;
fChildren.clear();
fWildcard.reset();
return;
}
// Recursive Step
const auto& key = *it;
if (key == "*") {
// Case 1: Wildcard
if (!fWildcard) {
fWildcard = std::make_unique<Tree>();
}
// Apply the rule to fWildcard and also to all existing children.
it++;
fWildcard->applyRule(path, it, inclusionRule, status);
for (auto& child : fChildren) {
child.second.applyRule(path, it, inclusionRule, status);
}
it--;
} else {
// Case 2: Normal Key
auto search = fChildren.find(key);
if (search == fChildren.end()) {
if (fWildcard) {
// Deep-copy the existing wildcard tree into the new key
search = fChildren.emplace(key, Tree(*fWildcard)).first;
} else {
search = fChildren.emplace(key, Tree()).first;
}
}
it++;
search->second.applyRule(path, it, inclusionRule, status);
it--;
}
}
void SimpleRuleBasedPathFilter::Tree::print(std::ostream& out, int32_t indent) const {
for (int32_t i=0; i<indent; i++) out << "\t";
out << "included: " << kEInclusionNames[fIncluded] << std::endl;
for (const auto& child : fChildren) {
for (int32_t i=0; i<indent; i++) out << "\t";
out << child.first << ": {" << std::endl;
child.second.print(out, indent + 1);
for (int32_t i=0; i<indent; i++) out << "\t";
out << "}" << std::endl;
}
if (fWildcard) {
for (int32_t i=0; i<indent; i++) out << "\t";
out << "* {" << std::endl;
fWildcard->print(out, indent + 1);
for (int32_t i=0; i<indent; i++) out << "\t";
out << "}" << std::endl;
}
}
void SimpleRuleBasedPathFilter::print(std::ostream& out) const {
out << "SimpleRuleBasedPathFilter {" << std::endl;
fRoot.print(out, 1);
out << "}" << std::endl;
}
std::ostream& operator<<(std::ostream& out, const SimpleRuleBasedPathFilter& value) {
value.print(out);
return out;
}

View File

@ -0,0 +1,180 @@
// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
#ifndef __FILTERRB_H__
#define __FILTERRB_H__
#include <list>
#include <map>
#include <memory>
#include <ostream>
#include <string>
#include "unicode/utypes.h"
/**
* Represents an absolute path into a resource bundle.
* For example: "/units/length/meter"
*/
class ResKeyPath {
public:
/** Constructs an empty path (top of tree) */
ResKeyPath();
/** Constructs from a string path */
ResKeyPath(const std::string& path, UErrorCode& status);
void push(const std::string& key);
void pop();
const std::list<std::string>& pieces() const;
private:
std::list<std::string> fPath;
};
std::ostream& operator<<(std::ostream& out, const ResKeyPath& value);
/**
* Interface used to determine whether to include or reject pieces of a
* resource bundle based on their absolute path.
*/
class PathFilter {
public:
enum EInclusion {
INCLUDE,
PARTIAL,
EXCLUDE
};
static const char* kEInclusionNames[];
virtual ~PathFilter();
/**
* Returns an EInclusion on whether or not the given path should be included.
*
* INCLUDE = include the whole subtree
* PARTIAL = recurse into the subtree
* EXCLUDE = reject the whole subtree
*/
virtual EInclusion match(const ResKeyPath& path) const = 0;
};
/**
* Implementation of PathFilter for a list of inclusion/exclusion rules.
*
* The wildcard pattern "*" means that the subsequent filters are applied to
* every other tree sharing the same parent.
*
* For example, given this list of filter rules:
*/
// -/alabama
// +/alabama/alaska/arizona
// -/fornia/hawaii
// -/mississippi
// +/mississippi/michigan
// +/mississippi/*/maine
// -/mississippi/*/iowa
// +/mississippi/louisiana/iowa
/*
* You get the following structure:
*
* SimpleRuleBasedPathFilter {
* included: PARTIAL
* alabama: {
* included: EXCLUDE
* alaska: {
* included: PARTIAL
* arizona: {
* included: INCLUDE
* }
* }
* }
* fornia: {
* included: PARTIAL
* hawaii: {
* included: EXCLUDE
* }
* }
* mississippi: {
* included: EXCLUDE
* louisiana: {
* included: PARTIAL
* iowa: {
* included: INCLUDE
* }
* maine: {
* included: INCLUDE
* }
* }
* michigan: {
* included: INCLUDE
* iowa: {
* included: EXCLUDE
* }
* maine: {
* included: INCLUDE
* }
* }
* * {
* included: PARTIAL
* iowa: {
* included: EXCLUDE
* }
* maine: {
* included: INCLUDE
* }
* }
* }
* }
*/
class SimpleRuleBasedPathFilter : public PathFilter {
public:
void addRule(const std::string& ruleLine, UErrorCode& status);
void addRule(const ResKeyPath& path, bool inclusionRule, UErrorCode& status);
EInclusion match(const ResKeyPath& path) const override;
void print(std::ostream& out) const;
private:
struct Tree {
Tree() = default;
/** Copy constructor */
Tree(const Tree& other);
/**
* Information on the USER-SPECIFIED inclusion/exclusion.
*
* INCLUDE = this path exactly matches a "+" rule
* PARTIAL = this path does not match any rule, but subpaths exist
* EXCLUDE = this path exactly matches a "-" rule
*/
EInclusion fIncluded = PARTIAL;
std::map<std::string, Tree> fChildren;
std::unique_ptr<Tree> fWildcard;
void applyRule(
const ResKeyPath& path,
std::list<std::string>::const_iterator it,
bool inclusionRule,
UErrorCode& status);
bool isLeaf() const;
void print(std::ostream& out, int32_t indent) const;
};
Tree fRoot;
};
std::ostream& operator<<(std::ostream& out, const SimpleRuleBasedPathFilter& value);
#endif //__FILTERRB_H__

View File

@ -0,0 +1,869 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2016, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File genrb.cpp
*
* Modification History:
*
* Date Name Description
* 05/25/99 stephen Creation.
* 5/10/01 Ram removed ustdio dependency
*******************************************************************************
*/
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#include <assert.h>
#include "genrb.h"
#include "unicode/localpointer.h"
#include "unicode/uclean.h"
#include "unicode/utf16.h"
#include "charstr.h"
#include "cmemory.h"
#include "filterrb.h"
#include "reslist.h"
#include "ucmndata.h" /* TODO: for reading the pool bundle */
#include "collationroot.h"
U_NAMESPACE_USE
/* Protos */
void processFile(const char *filename, const char* cp,
const char *inputDir, const char *outputDir, const char *filterDir,
const char *packageName,
SRBRoot *newPoolBundle, UBool omitBinaryCollation, 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"
const char *gCurrentFileName = nullptr;
#ifdef XP_MAC_CONSOLE
#include <console.h>
#endif
void ResFile::close() {
delete[] fBytes;
fBytes = nullptr;
delete fStrings;
fStrings = nullptr;
}
enum
{
HELP1,
HELP2,
VERBOSE,
QUIET,
VERSION,
SOURCEDIR,
DESTDIR,
ENCODING,
ICUDATADIR,
WRITE_JAVA,
COPYRIGHT,
JAVA_PACKAGE,
BUNDLE_NAME,
WRITE_XLIFF,
STRICT,
NO_BINARY_COLLATION,
LANGUAGE,
NO_COLLATION_RULES,
FORMAT_VERSION,
WRITE_POOL_BUNDLE,
USE_POOL_BUNDLE,
INCLUDE_UNIHAN_COLL,
FILTERDIR,
ICU4X_MODE,
UCADATA
};
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_DEF("java-package", '\x01', UOPT_REQUIRES_ARG),
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), /* 16 */
UOPTION_DEF("omitCollationRules", 'R', UOPT_NO_ARG),/* 17 */
UOPTION_DEF("formatVersion", '\x01', UOPT_REQUIRES_ARG),/* 18 */
UOPTION_DEF("writePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 19 */
UOPTION_DEF("usePoolBundle", '\x01', UOPT_OPTIONAL_ARG),/* 20 */
UOPTION_DEF("includeUnihanColl", '\x01', UOPT_NO_ARG),/* 21 */ /* temporary, don't display in usage info */
UOPTION_DEF("filterDir", '\x01', UOPT_OPTIONAL_ARG), /* 22 */
UOPTION_DEF("icu4xMode", 'X', UOPT_NO_ARG),/* 23 */
UOPTION_DEF("ucadata", '\x01', UOPT_REQUIRES_ARG),/* 24 */
};
static UBool write_java = false;
static UBool write_xliff = false;
static const char* outputEnc ="";
static ResFile poolBundle;
/*added by Jing*/
static const char* language = nullptr;
static const char* xliffOutputFileName = nullptr;
int
main(int argc,
char* argv[])
{
UErrorCode status = U_ZERO_ERROR;
const char *arg = nullptr;
const char *outputDir = nullptr; /* nullptr = no output directory, use current */
const char *inputDir = nullptr;
const char *filterDir = nullptr;
const char *encoding = "";
int i;
UBool illegalArg = false;
U_MAIN_INIT_ARGS(argc, argv);
options[JAVA_PACKAGE].value = "com.ibm.icu.impl.data";
options[BUNDLE_NAME].value = "LocaleElements";
argc = u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
/* error handling, printing usage message */
if(argc<0) {
fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]);
illegalArg = true;
} else if(argc<2) {
illegalArg = true;
}
if(options[WRITE_POOL_BUNDLE].doesOccur && options[USE_POOL_BUNDLE].doesOccur) {
fprintf(stderr, "%s: cannot combine --writePoolBundle and --usePoolBundle\n", argv[0]);
illegalArg = true;
}
if (options[ICU4X_MODE].doesOccur && !options[UCADATA].doesOccur) {
fprintf(stderr, "%s: --icu4xMode requires --ucadata\n", argv[0]);
illegalArg = true;
}
if(options[FORMAT_VERSION].doesOccur) {
const char *s = options[FORMAT_VERSION].value;
if(uprv_strlen(s) != 1 || (s[0] < '1' && '3' < s[0])) {
fprintf(stderr, "%s: unsupported --formatVersion %s\n", argv[0], s);
illegalArg = true;
} else if(s[0] == '1' &&
(options[WRITE_POOL_BUNDLE].doesOccur || options[USE_POOL_BUNDLE].doesOccur)
) {
fprintf(stderr, "%s: cannot combine --formatVersion 1 with --writePoolBundle or --usePoolBundle\n", argv[0]);
illegalArg = true;
} else {
setFormatVersion(s[0] - '0');
}
}
if((options[JAVA_PACKAGE].doesOccur || options[BUNDLE_NAME].doesOccur) &&
!options[WRITE_JAVA].doesOccur) {
fprintf(stderr,
"%s error: command line argument --java-package or --bundle-name "
"without --write-java\n",
argv[0]);
illegalArg = true;
}
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);
if(!illegalArg) {
return U_ZERO_ERROR;
}
}
if(illegalArg || options[HELP1].doesOccur || options[HELP2].doesOccur) {
/*
* Broken into chunks 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 resource 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 or --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 --java-package For --write-java: package name for writing the ListResourceBundle,\n"
"\t defaults to com.ibm.icu.impl.data\n");
fprintf(stderr,
"\t-b or --bundle-name For --write-java: root resource bundle name for writing the ListResourceBundle,\n"
"\t defaults to LocaleElements\n"
"\t-x or --write-xliff write an XLIFF file for the resource bundle. Followed by\n"
"\t 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 BCP 47.\n");
fprintf(stderr,
"\t-C or --noBinaryCollation do not generate binary collation image;\n"
"\t makes .res file smaller but collator instantiation much slower;\n"
"\t maintains ability to get tailoring rules\n"
"\t-R or --omitCollationRules do not include collation (tailoring) rules;\n"
"\t makes .res file smaller and maintains collator instantiation speed\n"
"\t but tailoring rules will not be available (they are rarely used)\n");
fprintf(stderr,
"\t --formatVersion write a .res file compatible with the requested formatVersion (single digit);\n"
"\t for example, --formatVersion 1\n");
fprintf(stderr,
"\t --writePoolBundle [directory] write a pool.res file with all of the keys of all input bundles\n"
"\t --usePoolBundle [directory] point to keys from the pool.res keys pool bundle if they are available there;\n"
"\t makes .res files smaller but dependent on the pool bundle\n"
"\t (--writePoolBundle and --usePoolBundle cannot be combined)\n");
fprintf(stderr,
"\t --filterDir Input directory where filter files are available.\n"
"\t For more on filter files, see ICU Data Build Tool.\n");
return illegalArg ? 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[FILTERDIR].doesOccur) {
filterDir = options[FILTERDIR].value;
}
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[WRITE_XLIFF].doesOccur) {
write_xliff = true;
if(options[WRITE_XLIFF].value != nullptr){
xliffOutputFileName = options[WRITE_XLIFF].value;
}
}
if (options[UCADATA].doesOccur) {
#if !UCONFIG_NO_COLLATION
CollationRoot::forceLoadFromFile(options[UCADATA].value, status);
#else
fprintf(stderr, "--ucadata was used with UCONFIG_NO_COLLATION\n");
return status;
#endif
}
initParser();
/*added by Jing*/
if(options[LANGUAGE].doesOccur) {
language = options[LANGUAGE].value;
}
LocalPointer<SRBRoot> newPoolBundle;
if(options[WRITE_POOL_BUNDLE].doesOccur) {
newPoolBundle.adoptInsteadAndCheckErrorCode(new SRBRoot(nullptr, true, status), status);
if(U_FAILURE(status)) {
fprintf(stderr, "unable to create an empty bundle for the pool keys: %s\n", u_errorName(status));
return status;
} else {
const char *poolResName = "pool.res";
char *nameWithoutSuffix = static_cast<char *>(uprv_malloc(uprv_strlen(poolResName) + 1));
if (nameWithoutSuffix == nullptr) {
fprintf(stderr, "out of memory error\n");
return U_MEMORY_ALLOCATION_ERROR;
}
uprv_strcpy(nameWithoutSuffix, poolResName);
*uprv_strrchr(nameWithoutSuffix, '.') = 0;
newPoolBundle->fLocale = nameWithoutSuffix;
}
}
if(options[USE_POOL_BUNDLE].doesOccur) {
const char *poolResName = "pool.res";
FileStream *poolFile;
int32_t poolFileSize;
int32_t indexLength;
/*
* TODO: Consolidate inputDir/filename handling from main() and processFile()
* into a common function, and use it here as well.
* Try to create toolutil functions for dealing with dir/filenames and
* loading ICU data files without udata_open().
* Share code with icupkg?
* Also, make_res_filename() seems to be unused. Review and remove.
*/
CharString poolFileName;
if (options[USE_POOL_BUNDLE].value!=nullptr) {
poolFileName.append(options[USE_POOL_BUNDLE].value, status);
} else if (inputDir) {
poolFileName.append(inputDir, status);
}
poolFileName.appendPathPart(poolResName, status);
if (U_FAILURE(status)) {
return status;
}
poolFile = T_FileStream_open(poolFileName.data(), "rb");
if (poolFile == nullptr) {
fprintf(stderr, "unable to open pool bundle file %s\n", poolFileName.data());
return 1;
}
poolFileSize = T_FileStream_size(poolFile);
if (poolFileSize < 32) {
fprintf(stderr, "the pool bundle file %s is too small\n", poolFileName.data());
return 1;
}
poolBundle.fBytes = new uint8_t[(poolFileSize + 15) & ~15];
if (poolFileSize > 0 && poolBundle.fBytes == nullptr) {
fprintf(stderr, "unable to allocate memory for the pool bundle file %s\n", poolFileName.data());
return U_MEMORY_ALLOCATION_ERROR;
}
UDataSwapper *ds;
const DataHeader *header;
int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, poolFileSize);
if (bytesRead != poolFileSize) {
fprintf(stderr, "unable to read the pool bundle file %s\n", poolFileName.data());
return 1;
}
/*
* Swap the pool bundle so that a single checked-in file can be used.
* The swapper functions also test that the data looks like
* a well-formed .res file.
*/
ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead,
U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &status);
if (U_FAILURE(status)) {
fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) failed: %s\n",
poolFileName.data(), u_errorName(status));
return status;
}
ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &status);
udata_closeSwapper(ds);
if (U_FAILURE(status)) {
fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n",
poolFileName.data(), u_errorName(status));
return status;
}
header = reinterpret_cast<const DataHeader*>(poolBundle.fBytes);
if (header->info.formatVersion[0] < 2) {
fprintf(stderr, "invalid format of pool bundle file %s\n", poolFileName.data());
return U_INVALID_FORMAT_ERROR;
}
const int32_t* pRoot = reinterpret_cast<const int32_t*>(
reinterpret_cast<const char*>(header) + header->dataHeader.headerSize);
poolBundle.fIndexes = pRoot + 1;
indexLength = poolBundle.fIndexes[URES_INDEX_LENGTH] & 0xff;
if (indexLength <= URES_INDEX_POOL_CHECKSUM) {
fprintf(stderr, "insufficient indexes[] in pool bundle file %s\n", poolFileName.data());
return U_INVALID_FORMAT_ERROR;
}
int32_t keysBottom = 1 + indexLength;
int32_t keysTop = poolBundle.fIndexes[URES_INDEX_KEYS_TOP];
poolBundle.fKeys = reinterpret_cast<const char*>(pRoot + keysBottom);
poolBundle.fKeysLength = (keysTop - keysBottom) * 4;
poolBundle.fChecksum = poolBundle.fIndexes[URES_INDEX_POOL_CHECKSUM];
for (i = 0; i < poolBundle.fKeysLength; ++i) {
if (poolBundle.fKeys[i] == 0) {
++poolBundle.fKeysCount;
}
}
// 16BitUnits[] begins with strings-v2.
// The strings-v2 may optionally be terminated by what looks like
// an explicit string length that exceeds the number of remaining 16-bit units.
int32_t stringUnitsLength = (poolBundle.fIndexes[URES_INDEX_16BIT_TOP] - keysTop) * 2;
if (stringUnitsLength >= 2 && getFormatVersion() >= 3) {
poolBundle.fStrings = new PseudoListResource(nullptr, status);
if (poolBundle.fStrings == nullptr) {
fprintf(stderr, "unable to allocate memory for the pool bundle strings %s\n",
poolFileName.data());
return U_MEMORY_ALLOCATION_ERROR;
}
// The PseudoListResource constructor call did not allocate further memory.
assert(U_SUCCESS(status));
const char16_t* p = reinterpret_cast<const char16_t*>(pRoot + keysTop);
int32_t remaining = stringUnitsLength;
do {
int32_t first = *p;
int8_t numCharsForLength;
int32_t length;
if (!U16_IS_TRAIL(first)) {
// NUL-terminated
numCharsForLength = 0;
for (length = 0;
length < remaining && p[length] != 0;
++length) {}
} else if (first < 0xdfef) {
numCharsForLength = 1;
length = first & 0x3ff;
} else if (first < 0xdfff && remaining >= 2) {
numCharsForLength = 2;
length = ((first - 0xdfef) << 16) | p[1];
} else if (first == 0xdfff && remaining >= 3) {
numCharsForLength = 3;
length = (static_cast<int32_t>(p[1]) << 16) | p[2];
} else {
break; // overrun
}
// Check for overrun before changing remaining,
// so that it is always accurate after the loop body.
if ((numCharsForLength + length) >= remaining ||
p[numCharsForLength + length] != 0) {
break; // overrun or explicitly terminated
}
int32_t poolStringIndex = stringUnitsLength - remaining;
// Maximum pool string index when suffix-sharing the last character.
int32_t maxStringIndex = poolStringIndex + numCharsForLength + length - 1;
if (maxStringIndex >= RES_MAX_OFFSET) {
// pool string index overrun
break;
}
p += numCharsForLength;
remaining -= numCharsForLength;
if (length != 0) {
StringResource *sr =
new StringResource(poolStringIndex, numCharsForLength,
p, length, status);
if (sr == nullptr) {
fprintf(stderr, "unable to allocate memory for a pool bundle string %s\n",
poolFileName.data());
return U_MEMORY_ALLOCATION_ERROR;
}
poolBundle.fStrings->add(sr);
poolBundle.fStringIndexLimit = maxStringIndex + 1;
// The StringResource constructor did not allocate further memory.
assert(U_SUCCESS(status));
}
p += length + 1;
remaining -= length + 1;
} while (remaining > 0);
if (poolBundle.fStrings->fCount == 0) {
delete poolBundle.fStrings;
poolBundle.fStrings = nullptr;
}
}
T_FileStream_close(poolFile);
setUsePoolBundle(true);
if (isVerbose() && poolBundle.fStrings != nullptr) {
printf("number of shared strings: %d\n", static_cast<int>(poolBundle.fStrings->fCount));
int32_t length = poolBundle.fStringIndexLimit + 1; // incl. last NUL
printf("16-bit units for strings: %6d = %6d bytes\n",
static_cast<int>(length), static_cast<int>(length) * 2);
}
}
if(!options[FORMAT_VERSION].doesOccur && getFormatVersion() == 3 &&
poolBundle.fStrings == nullptr &&
!options[WRITE_POOL_BUNDLE].doesOccur) {
// If we just default to formatVersion 3
// but there are no pool bundle strings to share
// and we do not write a pool bundle,
// then write formatVersion 2 which is just as good.
setFormatVersion(2);
}
if(options[INCLUDE_UNIHAN_COLL].doesOccur) {
puts("genrb option --includeUnihanColl ignored: \n"
"CLDR 26/ICU 54 unihan data is small, except\n"
"the ucadata-unihan.icu version of the collation root data\n"
"is about 300kB larger than the ucadata-implicithan.icu version.");
}
if((argc-1)!=1) {
printf("genrb number of files: %d\n", argc - 1);
}
/* generate the binary files */
for(i = 1; i < argc; ++i) {
status = U_ZERO_ERROR;
arg = getLongPathname(argv[i]);
CharString theCurrentFileName;
if (inputDir) {
theCurrentFileName.append(inputDir, status);
}
theCurrentFileName.appendPathPart(arg, status);
if (U_FAILURE(status)) {
break;
}
gCurrentFileName = theCurrentFileName.data();
if (isVerbose()) {
printf("Processing file \"%s\"\n", theCurrentFileName.data());
}
processFile(arg, encoding, inputDir, outputDir, filterDir, nullptr,
newPoolBundle.getAlias(),
options[NO_BINARY_COLLATION].doesOccur, status);
}
poolBundle.close();
if(U_SUCCESS(status) && options[WRITE_POOL_BUNDLE].doesOccur) {
const char* writePoolDir;
if (options[WRITE_POOL_BUNDLE].value!=nullptr) {
writePoolDir = options[WRITE_POOL_BUNDLE].value;
} else {
writePoolDir = outputDir;
}
char outputFileName[256];
newPoolBundle->write(writePoolDir, nullptr, outputFileName, sizeof(outputFileName), status);
if(U_FAILURE(status)) {
fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName(status));
}
}
u_cleanup();
/* Don't return warnings as a failure */
if (U_SUCCESS(status)) {
return 0;
}
return status;
}
/* Process a file */
void
processFile(const char *filename, const char *cp,
const char *inputDir, const char *outputDir, const char *filterDir,
const char *packageName,
SRBRoot *newPoolBundle,
UBool omitBinaryCollation, UErrorCode &status) {
LocalPointer<SRBRoot> data;
LocalUCHARBUFPointer ucbuf;
CharString openFileName;
CharString inputDirBuf;
char outputFileName[256];
int32_t dirlen = 0;
if (U_FAILURE(status)) {
return;
}
if(filename==nullptr){
status=U_ILLEGAL_ARGUMENT_ERROR;
return;
}
if(inputDir == nullptr) {
const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR);
if (filenameBegin != nullptr) {
/*
* 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 = static_cast<int32_t>(filenameBegin - filename + 1);
inputDirBuf.append(filename, filenameSize, status);
inputDir = inputDirBuf.data();
dirlen = inputDirBuf.length();
}
}else{
dirlen = static_cast<int32_t>(uprv_strlen(inputDir));
if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) {
/*
* append the input dir to openFileName if the first char in
* filename is not file separation 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] !='.')){
openFileName.append(inputDir, status);
}
} else {
openFileName.append(inputDir, status);
}
}
openFileName.appendPathPart(filename, status);
// Test for CharString failure
if (U_FAILURE(status)) {
return;
}
ucbuf.adoptInstead(ucbuf_open(openFileName.data(), &cp,getShowWarning(),true, &status));
if(status == U_FILE_ACCESS_ERROR) {
fprintf(stderr, "couldn't open file %s\n", openFileName.data());
return;
}
if (ucbuf.isNull() || U_FAILURE(status)) {
fprintf(stderr, "An error occurred processing file %s. Error: %s\n",
openFileName.data(), u_errorName(status));
return;
}
/* auto detected popular encodings? */
if (cp!=nullptr && isVerbose()) {
printf("autodetected encoding %s\n", cp);
}
/* Parse the data into an SRBRoot */
data.adoptInstead(parse(ucbuf.getAlias(), inputDir, outputDir, filename,
!omitBinaryCollation, options[NO_COLLATION_RULES].doesOccur, options[ICU4X_MODE].doesOccur, &status));
if (data.isNull() || U_FAILURE(status)) {
fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename, u_errorName(status));
return;
}
// Run filtering before writing pool bundle
if (filterDir != nullptr) {
CharString filterFileName(filterDir, status);
filterFileName.appendPathPart(filename, status);
if (U_FAILURE(status)) {
return;
}
// Open the file and read it into filter
SimpleRuleBasedPathFilter filter;
std::ifstream f(filterFileName.data());
if (f.fail()) {
std::cerr << "genrb error: unable to open " << filterFileName.data() << std::endl;
status = U_FILE_ACCESS_ERROR;
return;
}
std::string currentLine;
while (std::getline(f, currentLine)) {
// Ignore # comments and empty lines
if (currentLine.empty() || currentLine[0] == '#') {
continue;
}
filter.addRule(currentLine, status);
if (U_FAILURE(status)) {
return;
}
}
if (isVerbose()) {
filter.print(std::cout);
}
// Apply the filter to the data
ResKeyPath path;
data->fRoot->applyFilter(filter, path, data.getAlias());
}
if(options[WRITE_POOL_BUNDLE].doesOccur) {
data->fWritePoolBundle = newPoolBundle;
data->compactKeys(status);
int32_t newKeysLength;
const char *newKeys = data->getKeyBytes(&newKeysLength);
newPoolBundle->addKeyBytes(newKeys, newKeysLength, status);
if(U_FAILURE(status)) {
fprintf(stderr, "bundle_compactKeys(%s) or bundle_getKeyBytes() failed: %s\n",
filename, u_errorName(status));
return;
}
/* count the number of just-added key strings */
for(const char *newKeysLimit = newKeys + newKeysLength; newKeys < newKeysLimit; ++newKeys) {
if(*newKeys == 0) {
++newPoolBundle->fKeysCount;
}
}
}
if(options[USE_POOL_BUNDLE].doesOccur) {
data->fUsePoolBundle = &poolBundle;
}
/* Determine the target rb filename */
uprv_free(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));
return;
}
if(write_java== true){
bundle_write_java(data.getAlias(), outputDir, outputEnc,
outputFileName, sizeof(outputFileName),
options[JAVA_PACKAGE].value, options[BUNDLE_NAME].value, &status);
}else if(write_xliff ==true){
bundle_write_xml(data.getAlias(), outputDir, outputEnc,
filename, outputFileName, sizeof(outputFileName),
language, xliffOutputFileName, &status);
}else{
/* Write the data to the file */
data->write(outputDir, packageName, outputFileName, sizeof(outputFileName), status);
}
if (U_FAILURE(status)) {
fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName, u_errorName(status));
}
}
/* 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 nullptr;
}
if(packageName != nullptr)
{
pkgLen = static_cast<int32_t>(1 + uprv_strlen(packageName));
}
/* setup */
basename = dirname = resName = nullptr;
/* determine basename, and compiled file names */
basename = static_cast<char*>(uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)));
if (basename == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
goto finish;
}
get_basename(basename, filename);
dirname = static_cast<char*>(uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)));
if (dirname == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
goto finish;
}
get_dirname(dirname, filename);
if (outputDir == nullptr) {
/* output in same dir as .txt */
resName = static_cast<char*>(uprv_malloc(sizeof(char) * (uprv_strlen(dirname)
+ pkgLen
+ uprv_strlen(basename)
+ uprv_strlen(RES_SUFFIX) + 8)));
if (resName == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
goto finish;
}
uprv_strcpy(resName, dirname);
if(packageName != nullptr)
{
uprv_strcat(resName, packageName);
uprv_strcat(resName, "_");
}
uprv_strcat(resName, basename);
} else {
int32_t dirlen = static_cast<int32_t>(uprv_strlen(outputDir));
int32_t basenamelen = static_cast<int32_t>(uprv_strlen(basename));
resName = static_cast<char*>(uprv_malloc(sizeof(char) * (dirlen + pkgLen + basenamelen + 8)));
if (resName == nullptr) {
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 != nullptr)
{
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:
*/

View File

@ -0,0 +1,52 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 2002-2015, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File genrb.h
*/
#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 "toolutil.h"
#include "uoptions.h"
#include "unicode/ucol.h"
#include "unicode/uloc.h"
/* The version of genrb */
#define GENRB_VERSION "56"
U_CDECL_BEGIN
U_CAPI void processFile(
const char *filename,
const char* cp,
const char *inputDir,
const char *outputDir,
const char *packageName,
UBool omitBinaryCollation,
UErrorCode *status);
U_CDECL_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2014, 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 initialization */
void initParser();
/* Parse a ResourceBundle text file */
struct SRBRoot* parse(UCHARBUF *buf, const char* inputDir, const char* outputDir,
const char *filename,
UBool makeBinaryCollation, UBool omitCollationRules, UBool icu4xMode, UErrorCode *status);
U_CDECL_END
#endif

View File

@ -0,0 +1,248 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2003-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*
* File prscmnts.cpp
*
* Modification History:
*
* Date Name Description
* 08/22/2003 ram Creation.
*******************************************************************************
*/
// Safer use of UnicodeString.
#ifndef UNISTR_FROM_CHAR_EXPLICIT
# define UNISTR_FROM_CHAR_EXPLICIT explicit
#endif
// Less important, but still a good idea.
#ifndef UNISTR_FROM_STRING_EXPLICIT
# define UNISTR_FROM_STRING_EXPLICIT explicit
#endif
#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(char16_t *source, int32_t srcLen,
UnicodeString patString,uint32_t options,
UnicodeString replaceText, UErrorCode *status){
if(status == nullptr || 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(char16_t *src, int32_t srcLen, UErrorCode *status){
srcLen = removeText(src, srcLen, UnicodeString("^[ \\r\\n]+ "), 0, UnicodeString(), status); // remove leading new lines
srcLen = removeText(src, srcLen, UnicodeString("^\\s+"), 0, UnicodeString(), status); // remove leading spaces
srcLen = removeText(src, srcLen, UnicodeString("\\s+$"), 0, UnicodeString(), status); // remove trailing spcaes
return srcLen;
}
U_CFUNC int32_t
removeCmtText(char16_t* source, int32_t srcLen, UErrorCode* status){
srcLen = trim(source, srcLen, status);
UnicodeString patString("^\\s*?\\*\\s*?"); // remove pattern like " * " at the beginning of the line
srcLen = removeText(source, srcLen, patString, UREGEX_MULTILINE, UnicodeString(), status);
return removeText(source, srcLen, UnicodeString("[ \\r\\n]+"), 0, UnicodeString(" "), status);// remove new lines;
}
U_CFUNC int32_t
getText(const char16_t* source, int32_t srcLen,
char16_t** dest, int32_t destCapacity,
UnicodeString patternString,
UErrorCode* status){
if(status == nullptr || U_FAILURE(*status)){
return 0;
}
UnicodeString stringArray[MAX_SPLIT_STRINGS];
RegexPattern *pattern = RegexPattern::compile(UnicodeString("@"), 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 char16_t* source, int32_t srcLen,
char16_t** dest, int32_t destCapacity,
UErrorCode* status){
if(status == nullptr || U_FAILURE(*status)){
return 0;
}
UnicodeString stringArray[MAX_SPLIT_STRINGS];
RegexPattern *pattern = RegexPattern::compile(UnicodeString("@"), 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((char16_t)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 char16_t* source, int32_t srcLen,
UParseCommentsOption option, UErrorCode *status){
if(status == nullptr || U_FAILURE(*status)){
return 0;
}
UnicodeString stringArray[MAX_SPLIT_STRINGS];
RegexPattern *pattern = RegexPattern::compile(UnicodeString("@"), UREGEX_MULTILINE, *status);
UnicodeString src (source, srcLen);
if (U_FAILURE(*status)) {
return 0;
}
int32_t retLen = pattern->split(src, stringArray, MAX_SPLIT_STRINGS, *status);
UnicodeString patternString(patternStrings[option]);
RegexMatcher matcher(patternString, 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 char16_t* source, int32_t srcLen,
char16_t** dest, int32_t destCapacity,
int32_t index,
UParseCommentsOption option,
UErrorCode* status){
if(status == nullptr || U_FAILURE(*status)){
return 0;
}
UnicodeString stringArray[MAX_SPLIT_STRINGS];
RegexPattern *pattern = RegexPattern::compile(UnicodeString("@"), UREGEX_MULTILINE, *status);
UnicodeString src (source, srcLen);
if (U_FAILURE(*status)) {
return 0;
}
int32_t retLen = pattern->split(src, stringArray, MAX_SPLIT_STRINGS, *status);
UnicodeString patternString(patternStrings[option]);
RegexMatcher matcher(patternString, 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 char16_t* source, int32_t srcLen,
char16_t** 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 char16_t* source, int32_t srcLen,
char16_t** 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 */

View File

@ -0,0 +1,66 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2016, 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
#include "unicode/utypes.h"
#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

View File

@ -0,0 +1,119 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File util.c
*
* Modification History:
*
* Date Name Description
* 06/10/99 stephen Creation.
* 02/07/08 Spieth Correct XLIFF generation on EBCDIC platform
*
*******************************************************************************
*/
#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);
if (lastSlash != NULL) {
lastSlash++;
}
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);
if (lastSlash != NULL) {
lastSlash++;
}
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)
{
const char digits[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
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++]= digits[digit];
i=i/radix;
} while(i);
while (length < pad){
buffer[length++] = '0';/*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;
}

View File

@ -0,0 +1,33 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2016, 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
#include "unicode/utypes.h"
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 */

479
deps/icu-small/source/tools/genrb/read.c vendored Normal file
View File

@ -0,0 +1,479 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2012, 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 <stdbool.h>
#include "read.h"
#include "errmsg.h"
#include "toolutil.h"
#include "unicode/ustring.h"
#include "unicode/utf16.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);
U_CFUNC void resetLineNumber(void) {
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. */
U_CFUNC 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); /* "/c" */
if (c == U_EOF) {
return U_EOF;
}
switch (c) {
case SLASH: /* "//" */
seekUntilNewline(buf, NULL, status);
break;
case ASTERISK: /* " / * " */
c2 = ucbuf_getc(buf, status); /* "/ * c" */
if(c2 == ASTERISK){ /* "/ * *" */
/* parse multi-line comment and store it in token*/
seekUntilEndOfComment(buf, token, status);
} else {
ucbuf_ungetc(c2, buf); /* c2 is the non-asterisk following "/ *". Include c2 back in buffer. */
seekUntilEndOfComment(buf, NULL, status);
}
break;
default:
ucbuf_ungetc(c, buf); /* "/c" - put back the c */
/* 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");
}
}
U_CFUNC 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;
}
}

View File

@ -0,0 +1,54 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2011, 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 */
};
U_CFUNC UChar32 unescape(UCHARBUF *buf, UErrorCode *status);
U_CFUNC void resetLineNumber(void);
U_CFUNC enum ETokenType
getNextToken(UCHARBUF *buf,
struct UString *token,
uint32_t *linenumber, /* out: linenumber of token */
struct UString *comment,
UErrorCode *status);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,446 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 2000-2015, 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_INT_VECTOR_INIT_SIZE 2048
#include <functional>
#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "cmemory.h"
#include "cstring.h"
#include "uhash.h"
#include "unewdata.h"
#include "uresdata.h"
#include "ustr.h"
U_CDECL_BEGIN
class PathFilter;
class PseudoListResource;
class ResKeyPath;
struct ResFile {
ResFile()
: fBytes(nullptr), fIndexes(nullptr),
fKeys(nullptr), fKeysLength(0), fKeysCount(0),
fStrings(nullptr), fStringIndexLimit(0),
fChecksum(0) {}
~ResFile() { close(); }
void close();
uint8_t *fBytes;
const int32_t *fIndexes;
const char *fKeys;
int32_t fKeysLength;
int32_t fKeysCount;
PseudoListResource *fStrings;
int32_t fStringIndexLimit;
int32_t fChecksum;
};
struct SResource;
typedef struct KeyMapEntry {
int32_t oldpos, newpos;
} KeyMapEntry;
/* Resource bundle root table */
struct SRBRoot {
SRBRoot(const UString *comment, UBool isPoolBundle, UErrorCode &errorCode);
~SRBRoot();
void write(const char *outputDir, const char *outputPkg,
char *writtenFilename, int writtenFilenameLen, UErrorCode &errorCode);
void setLocale(char16_t *locale, UErrorCode &errorCode);
int32_t addTag(const char *tag, UErrorCode &errorCode);
const char *getKeyString(int32_t key) const;
const char *getKeyBytes(int32_t *pLength) const;
int32_t addKeyBytes(const char *keyBytes, int32_t length, UErrorCode &errorCode);
void compactKeys(UErrorCode &errorCode);
int32_t makeRes16(uint32_t resWord) const;
int32_t mapKey(int32_t oldpos) const;
private:
void compactStringsV2(UHashtable *stringSet, UErrorCode &errorCode);
public:
// TODO: private
SResource *fRoot; // Normally a TableResource.
char *fLocale;
int32_t fIndexLength;
int32_t fMaxTableLength;
UBool fNoFallback; /* see URES_ATT_NO_FALLBACK */
int8_t fStringsForm; /* default STRINGS_UTF16_V1 */
UBool fIsPoolBundle;
char *fKeys;
KeyMapEntry *fKeyMap;
int32_t fKeysBottom, fKeysTop;
int32_t fKeysCapacity;
int32_t fKeysCount;
int32_t fLocalKeyLimit; /* key offset < limit fits into URES_TABLE */
icu::UnicodeString f16BitUnits;
int32_t f16BitStringsLength;
const ResFile *fUsePoolBundle;
int32_t fPoolStringIndexLimit;
int32_t fPoolStringIndex16Limit;
int32_t fLocalStringIndexLimit;
SRBRoot *fWritePoolBundle;
};
/* write a java resource file */
// TODO: C++ify
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 */
// TODO: C++ify
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);
/* Various resource types */
/*
* Return a unique pointer to a dummy object,
* for use in non-error cases when no resource is to be added to the bundle.
* (nullptr is used in error cases.)
*/
struct SResource* res_none();
class ArrayResource;
class TableResource;
class IntVectorResource;
TableResource *table_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status);
ArrayResource *array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status);
struct SResource *string_open(struct SRBRoot *bundle, const char *tag, const char16_t *value, int32_t len, const struct UString* comment, UErrorCode *status);
struct SResource *alias_open(struct SRBRoot *bundle, const char *tag, char16_t *value, int32_t len, const struct UString* comment, UErrorCode *status);
IntVectorResource *intvector_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status);
struct SResource *int_open(struct SRBRoot *bundle, const char *tag, int32_t value, const struct UString* comment, UErrorCode *status);
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);
/* Resource place holder */
struct SResource {
SResource();
SResource(SRBRoot *bundle, const char *tag, int8_t type, const UString* comment,
UErrorCode &errorCode);
virtual ~SResource();
UBool isTable() const { return fType == URES_TABLE; }
UBool isString() const { return fType == URES_STRING; }
const char *getKeyString(const SRBRoot *bundle) const;
/**
* Preflights strings.
* Finds duplicates and counts the total number of string code units
* so that they can be written first to the 16-bit array,
* for minimal string and container storage.
*
* We walk the final parse tree, rather than collecting this information while building it,
* so that we need not deal with changes to the parse tree (especially removing resources).
*/
void preflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode);
virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode);
/**
* Writes resource values into f16BitUnits
* and determines the resource item word, if possible.
*/
void write16(SRBRoot *bundle);
virtual void handleWrite16(SRBRoot *bundle);
/**
* Calculates ("preflights") and advances the *byteOffset
* by the size of the resource's data in the binary file and
* determines the resource item word.
*
* Most handlePreWrite() functions may add any number of bytes, but preWrite()
* will always pad it to a multiple of 4.
* The resource item type may be a related subtype of the fType.
*
* The preWrite() and write() functions start and end at the same
* byteOffset values.
* Prewriting allows bundle.write() to determine the root resource item word,
* before actually writing the bundle contents to the file,
* which is necessary because the root item is stored at the beginning.
*/
void preWrite(uint32_t *byteOffset);
virtual void handlePreWrite(uint32_t *byteOffset);
/**
* Writes the resource's data to mem and updates the byteOffset
* in parallel.
*/
void write(UNewDataMemory *mem, uint32_t *byteOffset);
virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset);
/**
* Applies the given filter with the given base path to this resource.
* Removes child resources rejected by the filter recursively.
*
* @param bundle Needed in order to access the key for this and child resources.
*/
virtual void applyFilter(const PathFilter& filter, ResKeyPath& path, const SRBRoot* bundle);
/**
* Calls the given function for every key ID present in this tree.
*/
virtual void collectKeys(std::function<void(int32_t)> collector) const;
int8_t fType; /* nominal type: fRes (when != 0xffffffff) may use subtype */
UBool fWritten; /* res_write() can exit early */
uint32_t fRes; /* resource item word; RES_BOGUS=0xffffffff if not known yet */
int32_t fRes16; /* Res16 version of fRes for Table, Table16, Array16; -1 if it does not fit. */
int32_t fKey; /* Index into bundle->fKeys; -1 if no key. */
int32_t fKey16; /* Key16 version of fKey for Table & Table16; -1 if no key or it does not fit. */
int line; /* used internally to report duplicate keys in tables */
SResource *fNext; /* This is for internal chaining while building */
struct UString fComment;
};
class ContainerResource : public SResource {
public:
ContainerResource(SRBRoot *bundle, const char *tag, int8_t type,
const UString* comment, UErrorCode &errorCode)
: SResource(bundle, tag, type, comment, errorCode),
fCount(0), fFirst(nullptr) {}
virtual ~ContainerResource();
void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode) override;
void collectKeys(std::function<void(int32_t)> collector) const override;
protected:
void writeAllRes16(SRBRoot *bundle);
void preWriteAllRes(uint32_t *byteOffset);
void writeAllRes(UNewDataMemory *mem, uint32_t *byteOffset);
void writeAllRes32(UNewDataMemory *mem, uint32_t *byteOffset);
public:
// TODO: private with getter?
uint32_t fCount;
SResource *fFirst;
};
class TableResource : public ContainerResource {
public:
TableResource(SRBRoot *bundle, const char *tag,
const UString* comment, UErrorCode &errorCode)
: ContainerResource(bundle, tag, URES_TABLE, comment, errorCode),
fTableType(URES_TABLE), fRoot(bundle) {}
virtual ~TableResource();
void add(SResource *res, int linenumber, UErrorCode &errorCode);
void handleWrite16(SRBRoot *bundle) override;
void handlePreWrite(uint32_t *byteOffset) override;
void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override;
void applyFilter(const PathFilter& filter, ResKeyPath& path, const SRBRoot* bundle) override;
int8_t fTableType; // determined by table_write16() for table_preWrite() & table_write()
SRBRoot *fRoot;
};
class ArrayResource : public ContainerResource {
public:
ArrayResource(SRBRoot *bundle, const char *tag,
const UString* comment, UErrorCode &errorCode)
: ContainerResource(bundle, tag, URES_ARRAY, comment, errorCode),
fLast(nullptr) {}
virtual ~ArrayResource();
void add(SResource *res);
virtual void handleWrite16(SRBRoot *bundle) override;
virtual void handlePreWrite(uint32_t *byteOffset) override;
virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override;
SResource *fLast;
};
/**
* List of resources for a pool bundle.
* Writes an empty table resource, rather than a container structure.
*/
class PseudoListResource : public ContainerResource {
public:
PseudoListResource(SRBRoot *bundle, UErrorCode &errorCode)
: ContainerResource(bundle, nullptr, URES_TABLE, nullptr, errorCode) {}
virtual ~PseudoListResource();
void add(SResource *res);
virtual void handleWrite16(SRBRoot *bundle) override;
};
class StringBaseResource : public SResource {
public:
StringBaseResource(SRBRoot *bundle, const char *tag, int8_t type,
const char16_t *value, int32_t len,
const UString* comment, UErrorCode &errorCode);
StringBaseResource(SRBRoot *bundle, int8_t type,
const icu::UnicodeString &value, UErrorCode &errorCode);
StringBaseResource(int8_t type, const char16_t *value, int32_t len, UErrorCode &errorCode);
virtual ~StringBaseResource();
const char16_t *getBuffer() const { return icu::toUCharPtr(fString.getBuffer()); }
int32_t length() const { return fString.length(); }
virtual void handlePreWrite(uint32_t *byteOffset) override;
virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override;
// TODO: private with getter?
icu::UnicodeString fString;
};
class StringResource : public StringBaseResource {
public:
StringResource(SRBRoot *bundle, const char *tag, const char16_t *value, int32_t len,
const UString* comment, UErrorCode &errorCode)
: StringBaseResource(bundle, tag, URES_STRING, value, len, comment, errorCode),
fSame(nullptr), fSuffixOffset(0),
fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {}
StringResource(SRBRoot *bundle, const icu::UnicodeString &value, UErrorCode &errorCode)
: StringBaseResource(bundle, URES_STRING, value, errorCode),
fSame(nullptr), fSuffixOffset(0),
fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {}
StringResource(int32_t poolStringIndex, int8_t numCharsForLength,
const char16_t *value, int32_t length,
UErrorCode &errorCode)
: StringBaseResource(URES_STRING, value, length, errorCode),
fSame(nullptr), fSuffixOffset(0),
fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(numCharsForLength) {
// v3 pool string encoded as string-v2 with low offset
fRes = URES_MAKE_RESOURCE(URES_STRING_V2, poolStringIndex);
fWritten = true;
}
virtual ~StringResource();
int32_t get16BitStringsLength() const {
return fNumCharsForLength + length() + 1; // +1 for the NUL
}
virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode) override;
virtual void handleWrite16(SRBRoot *bundle) override;
void writeUTF16v2(int32_t base, icu::UnicodeString &dest);
StringResource *fSame; // used for duplicates
int32_t fSuffixOffset; // this string is a suffix of fSame at this offset
int32_t fNumCopies; // number of equal strings represented by one stringSet element
int32_t fNumUnitsSaved; // from not writing duplicates and suffixes
int8_t fNumCharsForLength;
};
class AliasResource : public StringBaseResource {
public:
AliasResource(SRBRoot *bundle, const char *tag, const char16_t *value, int32_t len,
const UString* comment, UErrorCode &errorCode)
: StringBaseResource(bundle, tag, URES_ALIAS, value, len, comment, errorCode) {}
virtual ~AliasResource();
};
class IntResource : public SResource {
public:
IntResource(SRBRoot *bundle, const char *tag, int32_t value,
const UString* comment, UErrorCode &errorCode);
virtual ~IntResource();
// TODO: private with getter?
int32_t fValue;
};
class IntVectorResource : public SResource {
public:
IntVectorResource(SRBRoot *bundle, const char *tag,
const UString* comment, UErrorCode &errorCode);
virtual ~IntVectorResource();
void add(int32_t value, UErrorCode &errorCode);
virtual void handlePreWrite(uint32_t *byteOffset) override;
virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override;
// TODO: UVector32
size_t fCount;
size_t fSize;
uint32_t *fArray;
};
class BinaryResource : public SResource {
public:
BinaryResource(SRBRoot *bundle, const char *tag,
uint32_t length, uint8_t *data, const char* fileName,
const UString* comment, UErrorCode &errorCode);
virtual ~BinaryResource();
virtual void handlePreWrite(uint32_t *byteOffset) override;
virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override;
// TODO: CharString?
uint32_t fLength;
uint8_t *fData;
// TODO: CharString
char* fFileName; // file name for binary or import binary tags if any
};
// TODO: use LocalPointer or delete
void res_close(struct SResource *res);
void setIncludeCopyright(UBool val);
UBool getIncludeCopyright();
void setFormatVersion(int32_t formatVersion);
int32_t getFormatVersion();
void setUsePoolBundle(UBool use);
/* in wrtxml.cpp */
uint32_t computeCRC(const char *ptr, uint32_t len, uint32_t lastcrc);
U_CDECL_END
#endif /* #ifndef RESLIST_H */

406
deps/icu-small/source/tools/genrb/rle.c vendored Normal file
View File

@ -0,0 +1,406 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* 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 <stdbool.h>
#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, status) UPRV_BLOCK_MACRO_BEGIN { \
if(buffer<bufLimit){ \
*buffer++=(value); \
}else{ \
*status = U_BUFFER_OVERFLOW_ERROR; \
} \
} UPRV_BLOCK_MACRO_END
/**
* 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) {
if (length < 4) {
int j=0;
for (; j<length; ++j) {
if (value == (int32_t) ESCAPE){
APPEND(buffer,bufLimit,ESCAPE, status);
}
APPEND(buffer,bufLimit,value,status);
}
}
else {
if (length == (int32_t) ESCAPE) {
if (value == (int32_t) ESCAPE){
APPEND(buffer,bufLimit,ESCAPE,status);
}
APPEND(buffer,bufLimit,value,status);
--length;
}
APPEND(buffer,bufLimit,ESCAPE,status);
APPEND(buffer,bufLimit,(uint16_t) length,status);
APPEND(buffer,bufLimit,(uint16_t)value, 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, runValue, runLength, status);
runValue = s;
runLength = 1;
}
}
buffer = encodeRunShort(buffer, bufLimit, 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;
}

74
deps/icu-small/source/tools/genrb/rle.h vendored Normal file
View File

@ -0,0 +1,74 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* 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

219
deps/icu-small/source/tools/genrb/ustr.c vendored Normal file
View File

@ -0,0 +1,219 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2012, 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"
#include "unicode/utf16.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))
U_CFUNC void
ustr_init(struct UString *s)
{
s->fChars = 0;
s->fLength = s->fCapacity = 0;
}
U_CFUNC 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
*/
}
}
U_CFUNC void
ustr_deinit(struct UString *s)
{
if (s) {
uprv_free(s->fChars);
s->fChars = 0;
s->fLength = s->fCapacity = 0;
}
}
U_CFUNC 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;
}
u_memcpy(dst->fChars, src->fChars, src->fLength);
dst->fLength = src->fLength;
dst->fChars[dst->fLength] = 0x0000;
}
U_CFUNC 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;
}
U_CFUNC void
ustr_cat(struct UString *dst,
const struct UString *src,
UErrorCode *status)
{
ustr_ncat(dst, src, src->fLength, status);
}
U_CFUNC 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;
}
U_CFUNC 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;
}
U_CFUNC 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);
}
}
U_CFUNC 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;
}

View File

@ -0,0 +1,81 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 1998-2012, 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) UPRV_BLOCK_MACRO_BEGIN { \
if (c <= 0xffff) \
{ \
*(target)++ = (UChar) c; \
len=1; \
} \
else \
{ \
target[0] = U16_LEAD(c); \
target[1] = U16_TRAIL(c); \
len=2; \
target +=2; \
} \
} UPRV_BLOCK_MACRO_END
#define U_APPEND_CHAR32_ONLY(c,target) UPRV_BLOCK_MACRO_BEGIN { \
if (c <= 0xffff) \
{ \
*(target)++ = (UChar) c; \
} \
else \
{ \
target[0] = U16_LEAD(c); \
target[1] = U16_TRAIL(c); \
target +=2; \
} \
} UPRV_BLOCK_MACRO_END
/* A C representation of a string "object" (to avoid realloc all the time) */
struct UString {
UChar *fChars;
int32_t fLength;
int32_t fCapacity;
};
U_CFUNC void ustr_init(struct UString *s);
U_CFUNC void
ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status);
U_CFUNC void ustr_deinit(struct UString *s);
U_CFUNC void ustr_setlen(struct UString *s, int32_t len, UErrorCode *status);
U_CFUNC void ustr_cpy(struct UString *dst, const struct UString *src,
UErrorCode *status);
U_CFUNC void ustr_cat(struct UString *dst, const struct UString *src,
UErrorCode *status);
U_CFUNC void ustr_ncat(struct UString *dst, const struct UString *src,
int32_t n, UErrorCode *status);
U_CFUNC void ustr_ucat(struct UString *dst, UChar c, UErrorCode *status);
U_CFUNC void ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status);
U_CFUNC void ustr_uscat(struct UString *dst, const UChar* src,int len,UErrorCode *status);
#endif

View File

@ -0,0 +1,698 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
* Copyright (C) 2000-2015, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File wrtjava.cpp
*
* Modification History:
*
* Date Name Description
* 01/11/02 Ram Creation.
* 02/12/08 Spieth Fix errant 'new Object[][]{' insertion
* 02/19/08 Spieth Removed ICUListResourceBundle dependency
*******************************************************************************
*/
#include <assert.h>
#include "unicode/unistr.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 "uhash.h"
#include "uresimp.h"
#include "unicode/ustring.h"
#include "unicode/utf8.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\n"
"public class ";
static const char* javaClass1= " extends ListResourceBundle {\n\n"
" /**\n"
" * Overrides ListResourceBundle \n"
" */\n"
" public final Object[][] getContents() { \n"
" return contents;\n"
" }\n\n"
" private static Object[][] contents = {\n";
/*static const char* javaClassICU= " extends ListResourceBundle {\n\n"
" public %s () {\n"
" super.contents = data;\n"
" }\n"
" static final Object[][] data = new Object[][] { \n";*/
static int tabCount = 3;
static FileStream* out=nullptr;
static struct SRBRoot* srBundle ;
/*static const char* outDir = nullptr;*/
static const char* bName=nullptr;
static const char* pName=nullptr;
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 = nullptr;
static int32_t
uCharsToChars(char *target, int32_t targetLen, const char16_t *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] = static_cast<char>(source[i]);
}
j+=2;
}else if(source[i-1]!='\\'){
if(j+2<targetLen){
uprv_strcat(target,"\\");
target[j + 1] = static_cast<char>(source[i]);
}
j+=2;
}else if(source[i-1]=='\\'){
target[j++] = static_cast<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] = static_cast<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] = static_cast<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 static_cast<uint32_t>(tSourceEnd - source);
}
tSourceEnd--;
}
return static_cast<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(const char16_t *src, int32_t srcLen, UBool printEndLine, UErrorCode *status) {
uint32_t length = srcLen*8;
uint32_t bufLen = 0;
uint32_t columnCount;
char* buf = static_cast<char*>(malloc(sizeof(char) * length));
if(buf == nullptr) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
}
columnCount = getColumnCount(srcLen);
memset(buf,0,length);
bufLen = uCharsToChars(buf,length,src,srcLen,status);
// buflen accounts for extra bytes added due to multi byte encoding of
// non ASCII characters
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 idx = strrch(current,add,'\\');
if (idx > add) {
idx = add;
} else {
int32_t num =idx-1;
uint32_t seqLen;
while(num>0){
if(current[num]=='\\'){
num--;
}else{
break;
}
}
if ((idx-num)%2==0) {
idx--;
}
seqLen = (current[idx+1]=='u') ? 6 : 2;
if ((add-idx) < seqLen) {
add = idx + seqLen;
}
}
}
T_FileStream_write(out,"\"",1);
uint32_t byteIndex = 0;
uint32_t trailBytes = 0;
if(len+add<bufLen){
// check the trail bytes to be added to the output line
while (byteIndex < add) {
if (U8_IS_LEAD(*(current + byteIndex))) {
trailBytes = U8_COUNT_TRAIL_BYTES(*(current + byteIndex));
add += trailBytes;
}
byteIndex++;
}
T_FileStream_write(out,current,add);
if (len + add < bufLen) {
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);
}
/* Writing Functions */
static void
string_write_java(const StringResource *res,UErrorCode *status) {
(void)res->getKeyString(srBundle);
str_write_java(res->getBuffer(), res->length(), true, status);
}
static void
array_write_java(const ArrayResource *res, UErrorCode *status) {
const char* arr ="new String[] { \n";
struct SResource *current = nullptr;
UBool allStrings = true;
if (U_FAILURE(*status)) {
return;
}
if (res->fCount > 0) {
current = res->fFirst;
while(current != nullptr){
if(!current->isString()){
allStrings = false;
break;
}
current= current->fNext;
}
current = res->fFirst;
if(allStrings==false){
const char* object = "new Object[]{\n";
write_tabs(out);
T_FileStream_write(out, object, static_cast<int32_t>(uprv_strlen(object)));
tabCount++;
}else{
write_tabs(out);
T_FileStream_write(out, arr, static_cast<int32_t>(uprv_strlen(arr)));
tabCount++;
}
while (current != nullptr) {
/*if(current->isString()){
write_tabs(out);
}*/
res_write_java(current, status);
if(U_FAILURE(*status)){
return;
}
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, static_cast<int32_t>(uprv_strlen(arr)));
write_tabs(out);
T_FileStream_write(out,"},\n",3);
}
}
static void
intvector_write_java(const IntVectorResource *res, UErrorCode * /*status*/) {
uint32_t i = 0;
const char* intArr = "new int[] {\n";
/* const char* intC = "new Integer("; */
const char* stringArr = "new String[]{\n";
const char *resname = res->getKeyString(srBundle);
char buf[100];
int len =0;
buf[0]=0;
write_tabs(out);
if(resname != nullptr && uprv_strcmp(resname,"DateTimeElements")==0){
T_FileStream_write(out, stringArr, static_cast<int32_t>(uprv_strlen(stringArr)));
tabCount++;
for(i = 0; i<res->fCount; i++) {
write_tabs(out);
len=itostr(buf,res->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, static_cast<int32_t>(uprv_strlen(intArr)));
tabCount++;
for(i = 0; i<res->fCount; i++) {
write_tabs(out);
/* T_FileStream_write(out, intC, (int32_t)uprv_strlen(intC)); */
len=itostr(buf,res->fArray[i],10,0);
T_FileStream_write(out,buf,len);
/* T_FileStream_write(out,"),",2); */
/* T_FileStream_write(out,"\n",1); */
T_FileStream_write(out,",\n",2);
}
}
tabCount--;
write_tabs(out);
T_FileStream_write(out,"},\n",3);
}
static void
int_write_java(const IntResource *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, static_cast<int32_t>(uprv_strlen(intC)));
len=itostr(buf, res->fValue, 10, 0);
T_FileStream_write(out,buf,len);
T_FileStream_write(out,"),\n",3 );
}
static void
bytes_write_java(const BinaryResource *res, UErrorCode * /*status*/) {
const char* type = "new byte[] {";
const char* byteDecl = "%i, ";
char byteBuffer[100] = { 0 };
uint8_t* byteArray = nullptr;
int byteIterator = 0;
int32_t srcLen=res->fLength;
if(srcLen>0 )
{
byteArray = res->fData;
write_tabs(out);
T_FileStream_write(out, type, static_cast<int32_t>(uprv_strlen(type)));
T_FileStream_write(out, "\n", 1);
tabCount++;
for (;byteIterator<srcLen;byteIterator++)
{
if (byteIterator%16 == 0)
{
write_tabs(out);
}
if (byteArray[byteIterator] < 128)
{
snprintf(byteBuffer, sizeof(byteBuffer), byteDecl, byteArray[byteIterator]);
}
else
{
snprintf(byteBuffer, sizeof(byteBuffer), byteDecl, (byteArray[byteIterator]-256));
}
T_FileStream_write(out, byteBuffer, static_cast<int32_t>(uprv_strlen(byteBuffer)));
if (byteIterator%16 == 15)
{
T_FileStream_write(out, "\n", 1);
}
}
if (((byteIterator-1)%16) != 15)
{
T_FileStream_write(out, "\n", 1);
}
tabCount--;
write_tabs(out);
T_FileStream_write(out, "},\n", 3);
}
else
{
/* Empty array */
write_tabs(out);
T_FileStream_write(out, type, static_cast<int32_t>(uprv_strlen(type)));
T_FileStream_write(out,"},\n",3);
}
}
static UBool start = true;
static void
table_write_java(const TableResource *res, UErrorCode *status) {
uint32_t i = 0;
struct SResource *current = nullptr;
const char* obj = "new Object[][]{\n";
if (U_FAILURE(*status)) {
return ;
}
if (res->fCount > 0) {
if(start==false){
write_tabs(out);
T_FileStream_write(out, obj, static_cast<int32_t>(uprv_strlen(obj)));
tabCount++;
}
start = false;
current = res->fFirst;
i = 0;
while (current != nullptr) {
const char *currentKeyString = current->getKeyString(srBundle);
assert(i < res->fCount);
write_tabs(out);
T_FileStream_write(out, openBrace, 2);
tabCount++;
write_tabs(out);
if(currentKeyString != nullptr) {
T_FileStream_write(out, "\"", 1);
T_FileStream_write(out, currentKeyString,
static_cast<int32_t>(uprv_strlen(currentKeyString)));
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, static_cast<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 != nullptr) {
switch (res->fType) {
case URES_STRING:
string_write_java (static_cast<const StringResource *>(res), status);
return;
case URES_ALIAS:
printf("Encountered unsupported resource type %d of alias\n", res->fType);
*status = U_UNSUPPORTED_ERROR;
return;
case URES_INT_VECTOR:
intvector_write_java (static_cast<const IntVectorResource *>(res), status);
return;
case URES_BINARY:
bytes_write_java (static_cast<const BinaryResource *>(res), status);
return;
case URES_INT:
int_write_java (static_cast<const IntResource *>(res), status);
return;
case URES_ARRAY:
array_write_java (static_cast<const ArrayResource *>(res), status);
return;
case URES_TABLE:
table_write_java (static_cast<const TableResource *>(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;*/
start = true; /* Reset the start indicator*/
bName = (bundleName==nullptr) ? "LocaleElements" : bundleName;
pName = (packageName==nullptr)? "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==nullptr){
*status = U_FILE_ACCESS_ERROR;
return;
}
if(getIncludeCopyright()){
T_FileStream_write(out, copyRight, static_cast<int32_t>(uprv_strlen(copyRight)));
T_FileStream_write(out, warningMsg, static_cast<int32_t>(uprv_strlen(warningMsg)));
}
T_FileStream_write(out, "package ", static_cast<int32_t>(uprv_strlen("package ")));
T_FileStream_write(out, pName, static_cast<int32_t>(uprv_strlen(pName)));
T_FileStream_write(out,";\n\n",3);
T_FileStream_write(out, javaClass, static_cast<int32_t>(uprv_strlen(javaClass)));
T_FileStream_write(out, className, static_cast<int32_t>(uprv_strlen(className)));
T_FileStream_write(out, javaClass1, static_cast<int32_t>(uprv_strlen(javaClass1)));
/* 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, static_cast<int32_t>(uprv_strlen(closeClass)));
T_FileStream_close(out);
ucnv_close(conv);
}

File diff suppressed because it is too large Load Diff