CharString operator+(const CharString& str1, const CharString& str2){ CharString str; for(int i=0; i<str1.length(); i++){ str.append(str1[i]); } for(int i=0; i<str2.length(); i++){ str.append(str2[i]); } return str; }
static UnicodeString loadNumericDateFormatterPattern( const UResourceBundle *resource, const char *pattern, UErrorCode &status) { UnicodeString result; if (U_FAILURE(status)) { return result; } CharString chs; chs.append("durationUnits", status) .append("/", status).append(pattern, status); LocalUResourceBundlePointer patternBundle( ures_getByKeyWithFallback( resource, chs.data(), NULL, &status)); if (U_FAILURE(status)) { return result; } getString(patternBundle.getAlias(), result, status); // Replace 'h' with 'H' int32_t len = result.length(); UChar *buffer = result.getBuffer(len); for (int32_t i = 0; i < len; ++i) { if (buffer[i] == 0x68) { // 'h' buffer[i] = 0x48; // 'H' } } result.releaseBuffer(len); return result; }
void transform(const UnicodeString &word, CharString &buf, UErrorCode &errorCode) { UChar32 c = 0; int32_t len = word.length(); for (int32_t i = 0; i < len; i += U16_LENGTH(c)) { c = word.char32At(i); buf.append(transform(c, errorCode), errorCode); } }
static void load(const Locale& inLocale, CDFLocaleData* result, UErrorCode& status) { LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(inLocale, status)); if (U_FAILURE(status)) { return; } const char* nsName = ns->getName(); LocalUResourceBundlePointer resource(ures_open(NULL, inLocale.getName(), &status)); if (U_FAILURE(status)) { return; } CmptDecDataSink sink(*result); sink.isFallback = FALSE; // First load the number elements data if nsName is not Latin. if (uprv_strcmp(nsName, gLatnTag) != 0) { sink.isLatin = FALSE; CharString path; path.append(gNumberElementsTag, status) .append('/', status) .append(nsName, status); ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status); if (status == U_MISSING_RESOURCE_ERROR) { // Silently ignore and use Latin status = U_ZERO_ERROR; } else if (U_FAILURE(status)) { return; } sink.isFallback = TRUE; } // Now load Latin. sink.isLatin = TRUE; ures_getAllItemsWithFallback(resource.getAlias(), gLatnPath, sink, status); if (U_FAILURE(status)) return; // If longData is empty, default it to be equal to shortData if (result->longData.isEmpty()) { result->longData.setToBogus(); } // Check for "other" variants in each of the three data classes, and resolve missing elements. if (!result->longData.isBogus()) { checkForOtherVariants(&result->longData, status); if (U_FAILURE(status)) return; fillInMissing(&result->longData); } checkForOtherVariants(&result->shortData, status); if (U_FAILURE(status)) return; fillInMissing(&result->shortData); // TODO: Enable this statement when currency support is added // checkForOtherVariants(&result->shortCurrencyData, status); // if (U_FAILURE(status)) return; // fillInMissing(&result->shortCurrencyData); }
CharString CharString::subString(int start, int end) const{ if(end==-1 || end>length()) end = length(); if(start<0) start = 0; CharString str; for(int i=start; i<end; i++){ str.append(operator[](i)); } return str; }
static UBool thaiWordToBytes(const UChar *s, int32_t length, CharString &str, UErrorCode &errorCode) { for(int32_t i=0; i<length; ++i) { UChar c=s[i]; int32_t b=thaiCharToByte(c); if(b>=0) { str.append((char)b, errorCode); } else { fprintf(stderr, "thaiWordToBytes(): unable to encode U+%04X as a byte\n", c); return FALSE; } } return TRUE; }
/** * Return a string form of this number. * Format is as defined by the decNumber library, for interchange of * decimal numbers. */ void DigitList::getDecimal(CharString &str, UErrorCode &status) { if (U_FAILURE(status)) { return; } // A decimal number in string form can, worst case, be 14 characters longer // than the number of digits. So says the decNumber library doc. int32_t maxLength = fDecNumber->digits + 14; int32_t capacity = 0; char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status); if (U_FAILURE(status)) { return; // Memory allocation error on growing the string. } U_ASSERT(capacity >= maxLength); uprv_decNumberToString(this->fDecNumber, buffer); U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength); str.append(buffer, -1, status); }
void NamesPropsBuilder::setProps(const UniProps &props, const UnicodeSet &newValues, UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } if(!newValues.contains(UCHAR_NAME) && !newValues.contains(PPUCD_NAME_ALIAS)) { return; } U_ASSERT(props.start==props.end); const char *names[4]={ NULL, NULL, NULL, NULL }; int16_t lengths[4]={ 0, 0, 0, 0 }; /* get the character name */ if(props.name!=NULL) { names[0]=props.name; lengths[0]=(int16_t)uprv_strlen(props.name); parseName(names[0], lengths[0]); } CharString buffer; if(props.nameAlias!=NULL) { /* * Only use "correction" aliases for now, from Unicode 6.1 NameAliases.txt with 3 fields per line. * TODO: Work on ticket #8963 to deal with multiple type:alias pairs per character. */ const char *corr=uprv_strstr(props.nameAlias, "correction="); if(corr!=NULL) { corr+=11; // skip "correction=" const char *limit=uprv_strchr(corr, ','); if(limit!=NULL) { buffer.append(corr, limit-corr, errorCode); names[3]=buffer.data(); lengths[3]=(int16_t)(limit-corr); } else { names[3]=corr; lengths[3]=(int16_t)uprv_strlen(corr); } parseName(names[3], lengths[3]); } } addLine(props.start, names, lengths, LENGTHOF(names)); }
void DigitList::appendDigitsTo(CharString &str, UErrorCode &status) const { str.append((const char *) fDecNumber->lsu, fDecNumber->digits, status); }
int main(int argc, char* argv[]) { UErrorCode status = U_ZERO_ERROR; const char *arg = NULL; const char *outputDir = NULL; /* NULL = no output directory, use current */ const char *inputDir = NULL; const char *encoding = ""; int i; 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[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 of --destdir destination directory, followed by the path, defaults to %s\n" "\t-s or --sourcedir source directory for files followed by path, defaults to %s\n" "\t-i or --icudatadir directory for locating any needed intermediate data files,\n" "\t followed by path, defaults to %s\n", u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory()); fprintf(stderr, "\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n" "\t defaults to ASCII and \\uXXXX format.\n" "\t --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 write a pool.res file with all of the keys of all input bundles\n" "\t --usePoolBundle [path-to-pool.res] 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"); 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[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 != NULL){ xliffOutputFileName = options[WRITE_XLIFF].value; } } 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(NULL, 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 == NULL) { 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!=NULL) { 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 == NULL) { 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 == NULL) { 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 = (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 = (const int32_t *)( (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 = (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(NULL, status); if (poolBundle.fStrings == NULL) { 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 UChar *p = (const UChar *)(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 = ((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 == NULL) { 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 = NULL; } } T_FileStream_close(poolFile); setUsePoolBundle(TRUE); if (isVerbose() && poolBundle.fStrings != NULL) { printf("number of shared strings: %d\n", (int)poolBundle.fStrings->fCount); int32_t length = poolBundle.fStringIndexLimit + 1; // incl. last NUL printf("16-bit units for strings: %6d = %6d bytes\n", (int)length, (int)length * 2); } } if(!options[FORMAT_VERSION].doesOccur && getFormatVersion() == 3 && poolBundle.fStrings == NULL && !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, NULL, newPoolBundle.getAlias(), options[NO_BINARY_COLLATION].doesOccur, status); } poolBundle.close(); if(U_SUCCESS(status) && options[WRITE_POOL_BUNDLE].doesOccur) { char outputFileName[256]; newPoolBundle->write(outputDir, NULL, outputFileName, sizeof(outputFileName), status); if(U_FAILURE(status)) { fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName(status)); } } u_cleanup(); /* Dont return warnings as a failure */ if (U_SUCCESS(status)) { return 0; } return status; }
void DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData) { if (U_FAILURE(status)) { return; } *validLocale = *actualLocale = 0; currPattern = NULL; // First initialize all the symbols to the fallbacks for anything we can't find initialize(); // // Next get the numbering system for this locale and set zero digit // and the digit string based on the numbering system for the locale // LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(loc, status)); const char *nsName; if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) { nsName = ns->getName(); UnicodeString digitString(ns->getDescription()); int32_t digitIndex = 0; UChar32 digit = digitString.char32At(0); fSymbols[kZeroDigitSymbol].setTo(digit); for (int32_t i = kOneDigitSymbol; i <= kNineDigitSymbol; ++i) { digitIndex += U16_LENGTH(digit); digit = digitString.char32At(digitIndex); fSymbols[i].setTo(digit); } } else { nsName = gLatn; } // Open resource bundles const char* locStr = loc.getName(); LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status)); LocalUResourceBundlePointer numberElementsRes( ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status)); if (U_FAILURE(status)) { if ( useLastResortData ) { status = U_USING_DEFAULT_WARNING; initialize(); } return; } // Set locale IDs // TODO: Is there a way to do this without depending on the resource bundle instance? U_LOCALE_BASED(locBased, *this); locBased.setLocaleIDs( ures_getLocaleByType( numberElementsRes.getAlias(), ULOC_VALID_LOCALE, &status), ures_getLocaleByType( numberElementsRes.getAlias(), ULOC_ACTUAL_LOCALE, &status)); // Now load the rest of the data from the data sink. // Start with loading this nsName if it is not Latin. DecFmtSymDataSink sink(*this); if (uprv_strcmp(nsName, gLatn) != 0) { CharString path; path.append(gNumberElements, status) .append('/', status) .append(nsName, status) .append('/', status) .append(gSymbols, status); ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status); // If no symbols exist for the given nsName and resource bundle, silently ignore // and fall back to Latin. if (status == U_MISSING_RESOURCE_ERROR) { status = U_ZERO_ERROR; } else if (U_FAILURE(status)) { return; } } // Continue with Latin if necessary. if (!sink.seenAll()) { ures_getAllItemsWithFallback(resource.getAlias(), gNumberElementsLatnSymbols, sink, status); if (U_FAILURE(status)) { return; } } // Let the monetary number separators equal the default number separators if necessary. sink.resolveMissingMonetarySeparators(fSymbols); // Obtain currency data from the currency API. This is strictly // for backward compatibility; we don't use DecimalFormatSymbols // for currency data anymore. UErrorCode internalStatus = U_ZERO_ERROR; // don't propagate failures out UChar curriso[4]; UnicodeString tempStr; ucurr_forLocale(locStr, curriso, 4, &internalStatus); uprv_getStaticCurrencyName(curriso, locStr, tempStr, internalStatus); if (U_SUCCESS(internalStatus)) { fSymbols[kIntlCurrencySymbol].setTo(curriso, -1); fSymbols[kCurrencySymbol] = tempStr; } /* else use the default values. */ //load the currency data UChar ucc[4]={0}; //Currency Codes are always 3 chars long int32_t uccLen = 4; const char* locName = loc.getName(); UErrorCode localStatus = U_ZERO_ERROR; uccLen = ucurr_forLocale(locName, ucc, uccLen, &localStatus); if(U_SUCCESS(localStatus) && uccLen > 0) { char cc[4]={0}; u_UCharsToChars(ucc, cc, uccLen); /* An explicit currency was requested */ LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus)); LocalUResourceBundlePointer currency( ures_getByKeyWithFallback(currencyResource.getAlias(), "Currencies", NULL, &localStatus)); ures_getByKeyWithFallback(currency.getAlias(), cc, currency.getAlias(), &localStatus); if(U_SUCCESS(localStatus) && ures_getSize(currency.getAlias())>2) { // the length is 3 if more data is present ures_getByIndex(currency.getAlias(), 2, currency.getAlias(), &localStatus); int32_t currPatternLen = 0; currPattern = ures_getStringByIndex(currency.getAlias(), (int32_t)0, &currPatternLen, &localStatus); UnicodeString decimalSep = ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)1, &localStatus); UnicodeString groupingSep = ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)2, &localStatus); if(U_SUCCESS(localStatus)){ fSymbols[kMonetaryGroupingSeparatorSymbol] = groupingSep; fSymbols[kMonetarySeparatorSymbol] = decimalSep; //pattern.setTo(TRUE, currPattern, currPatternLen); status = localStatus; } } /* else An explicit currency was requested and is unknown or locale data is malformed. */ /* ucurr_* API will get the correct value later on. */ } // else ignore the error if no currency // Currency Spacing. localStatus = U_ZERO_ERROR; LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus)); LocalUResourceBundlePointer currencySpcRes( ures_getByKeyWithFallback(currencyResource.getAlias(), gCurrencySpacingTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { const char* keywords[UNUM_CURRENCY_SPACING_COUNT] = { gCurrencyMatchTag, gCurrencySudMatchTag, gCurrencyInsertBtnTag }; localStatus = U_ZERO_ERROR; LocalUResourceBundlePointer dataRes( ures_getByKeyWithFallback(currencySpcRes.getAlias(), gBeforeCurrencyTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { localStatus = U_ZERO_ERROR; for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { currencySpcBeforeSym[i] = ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); } } dataRes.adoptInstead( ures_getByKeyWithFallback(currencySpcRes.getAlias(), gAfterCurrencyTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { localStatus = U_ZERO_ERROR; for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { currencySpcAfterSym[i] = ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); } } } }
void NamesPropsBuilder::setAlgNamesRange(UChar32 start, UChar32 end, const char *type, const char *prefix, // number of hex digits UErrorCode &errorCode) { /* modulo factors, maximum 8 */ /* 3 factors: 19, 21, 28, most-to-least-significant */ static const uint16_t hangulFactors[3]={ 19, 21, 28 }; static const char jamo[]= "HANGUL SYLLABLE \0" "G\0GG\0N\0D\0DD\0R\0M\0B\0BB\0" "S\0SS\0\0J\0JJ\0C\0K\0T\0P\0H\0" "A\0AE\0YA\0YAE\0EO\0E\0YEO\0YE\0O\0" "WA\0WAE\0OE\0YO\0U\0WEO\0WE\0WI\0" "YU\0EU\0YI\0I\0" "\0G\0GG\0GS\0N\0NJ\0NH\0D\0L\0LG\0LM\0" "LB\0LS\0LT\0LP\0LH\0M\0B\0BS\0" "S\0SS\0NG\0J\0C\0K\0T\0P\0H"; int32_t prefixLength=0; AlgorithmicRange range; uprv_memset(&range, 0, sizeof(AlgorithmicRange)); int32_t rangeSize=(int32_t)sizeof(AlgorithmicRange); range.start=start; range.end=end; if(0==uprv_strcmp(type, "han")) { range.type=0; range.variant= end<=0xffff ? 4 : 5; prefixLength=uprv_strlen(prefix)+1; rangeSize+=prefixLength; } else if(0==uprv_strcmp(type, "hangul")) { range.type=1; range.variant=(uint8_t)LENGTHOF(hangulFactors); rangeSize+=(int32_t)sizeof(hangulFactors); rangeSize+=(int32_t)sizeof(jamo); } else { fprintf(stderr, "genprops error: unknown algnamesrange type '%s'\n", prefix); errorCode=U_ILLEGAL_ARGUMENT_ERROR; return; } int32_t paddingLength=paddingLength=rangeSize&3; if(paddingLength) { paddingLength=4-paddingLength; rangeSize+=paddingLength; } range.size=(uint16_t)rangeSize; algRanges.append((char *)&range, (int32_t)sizeof(AlgorithmicRange), errorCode); if(range.type==0) { // han algRanges.append(prefix, prefixLength, errorCode); } else /* type==1 */ { // hangul algRanges.append((char *)hangulFactors, (int32_t)sizeof(hangulFactors), errorCode); algRanges.append(jamo, (int32_t)sizeof(jamo), errorCode); } while(paddingLength) { algRanges.append((char)0xaa, errorCode); --paddingLength; } ++countAlgRanges; }
// Returns TRUE for "ok to continue parsing fields". UBool PreparsedUCD::parseProperty(UniProps &props, const char *field, UnicodeSet &newValues, UErrorCode &errorCode) { CharString pBuffer; const char *p=field; const char *v=strchr(p, '='); int binaryValue; if(*p=='-') { if(v!=NULL) { fprintf(stderr, "error in preparsed UCD: mix of binary-property-no and " "enum-property syntax '%s' on line %ld\n", field, (long)lineNumber); errorCode=U_PARSE_ERROR; return FALSE; } binaryValue=0; ++p; } else if(v==NULL) { binaryValue=1; } else { binaryValue=-1; // Copy out the property name rather than modifying the field (writing a NUL). pBuffer.append(p, (int32_t)(v-p), errorCode); p=pBuffer.data(); ++v; } int32_t prop=pnames->getPropertyEnum(p); if(prop<0) { for(int32_t i=0;; ++i) { if(i==UPRV_LENGTHOF(ppucdProperties)) { // Ignore unknown property names. return TRUE; } if(0==uprv_stricmp(p, ppucdProperties[i].name)) { prop=ppucdProperties[i].prop; U_ASSERT(prop>=0); break; } } } if(prop<UCHAR_BINARY_LIMIT) { if(binaryValue>=0) { props.binProps[prop]=(UBool)binaryValue; } else { // No binary value for a binary property. fprintf(stderr, "error in preparsed UCD: enum-property syntax '%s' " "for binary property on line %ld\n", field, (long)lineNumber); errorCode=U_PARSE_ERROR; } } else if(binaryValue>=0) { // Binary value for a non-binary property. fprintf(stderr, "error in preparsed UCD: binary-property syntax '%s' " "for non-binary property on line %ld\n", field, (long)lineNumber); errorCode=U_PARSE_ERROR; } else if (prop < UCHAR_INT_START) { fprintf(stderr, "error in preparsed UCD: prop value is invalid: '%d' for line %ld\n", prop, (long)lineNumber); errorCode=U_PARSE_ERROR; } else if(prop<UCHAR_INT_LIMIT) { int32_t value=pnames->getPropertyValueEnum(prop, v); if(value==UCHAR_INVALID_CODE && prop==UCHAR_CANONICAL_COMBINING_CLASS) { // TODO: Make getPropertyValueEnum(UCHAR_CANONICAL_COMBINING_CLASS, v) work. char *end; unsigned long ccc=uprv_strtoul(v, &end, 10); if(v<end && *end==0 && ccc<=254) { value=(int32_t)ccc; } } if(value==UCHAR_INVALID_CODE) { fprintf(stderr, "error in preparsed UCD: '%s' is not a valid value on line %ld\n", field, (long)lineNumber); errorCode=U_PARSE_ERROR; } else { props.intProps[prop-UCHAR_INT_START]=value; } } else if(*v=='<') { // Do not parse default values like <code point>, just set null values. switch(prop) { case UCHAR_BIDI_MIRRORING_GLYPH: props.bmg=U_SENTINEL; break; case UCHAR_BIDI_PAIRED_BRACKET: props.bpb=U_SENTINEL; break; case UCHAR_SIMPLE_CASE_FOLDING: props.scf=U_SENTINEL; break; case UCHAR_SIMPLE_LOWERCASE_MAPPING: props.slc=U_SENTINEL; break; case UCHAR_SIMPLE_TITLECASE_MAPPING: props.stc=U_SENTINEL; break; case UCHAR_SIMPLE_UPPERCASE_MAPPING: props.suc=U_SENTINEL; break; case UCHAR_CASE_FOLDING: props.cf.remove(); break; case UCHAR_LOWERCASE_MAPPING: props.lc.remove(); break; case UCHAR_TITLECASE_MAPPING: props.tc.remove(); break; case UCHAR_UPPERCASE_MAPPING: props.uc.remove(); break; case UCHAR_SCRIPT_EXTENSIONS: props.scx.clear(); break; default: fprintf(stderr, "error in preparsed UCD: '%s' is not a valid default value on line %ld\n", field, (long)lineNumber); errorCode=U_PARSE_ERROR; } } else { char c; switch(prop) { case UCHAR_NUMERIC_VALUE: props.numericValue=v; c=*v; if('0'<=c && c<='9' && v[1]==0) { props.digitValue=c-'0'; } else { props.digitValue=-1; } break; case UCHAR_NAME: props.name=v; break; case UCHAR_AGE: u_versionFromString(props.age, v); // Writes 0.0.0.0 if v is not numeric. break; case UCHAR_BIDI_MIRRORING_GLYPH: props.bmg=parseCodePoint(v, errorCode); break; case UCHAR_BIDI_PAIRED_BRACKET: props.bpb=parseCodePoint(v, errorCode); break; case UCHAR_SIMPLE_CASE_FOLDING: props.scf=parseCodePoint(v, errorCode); break; case UCHAR_SIMPLE_LOWERCASE_MAPPING: props.slc=parseCodePoint(v, errorCode); break; case UCHAR_SIMPLE_TITLECASE_MAPPING: props.stc=parseCodePoint(v, errorCode); break; case UCHAR_SIMPLE_UPPERCASE_MAPPING: props.suc=parseCodePoint(v, errorCode); break; case UCHAR_CASE_FOLDING: parseString(v, props.cf, errorCode); break; case UCHAR_LOWERCASE_MAPPING: parseString(v, props.lc, errorCode); break; case UCHAR_TITLECASE_MAPPING: parseString(v, props.tc, errorCode); break; case UCHAR_UPPERCASE_MAPPING: parseString(v, props.uc, errorCode); break; case PPUCD_NAME_ALIAS: props.nameAlias=v; break; case PPUCD_CONDITIONAL_CASE_MAPPINGS: case PPUCD_TURKIC_CASE_FOLDING: // No need to parse their values: They are hardcoded in the runtime library. break; case UCHAR_SCRIPT_EXTENSIONS: parseScriptExtensions(v, props.scx, errorCode); break; default: // Ignore unhandled properties. return TRUE; } } if(U_SUCCESS(errorCode)) { newValues.add((UChar32)prop); return TRUE; } else { return FALSE; } }
U_CAPI void U_EXPORT2 uplug_init(UErrorCode *status) { #if !U_ENABLE_DYLOAD (void)status; /* unused */ #elif !UCONFIG_NO_FILE_IO CharString plugin_dir; const char *env = getenv("ICU_PLUGINS"); if(U_FAILURE(*status)) return; if(env != NULL) { plugin_dir.append(env, -1, *status); } if(U_FAILURE(*status)) return; #if defined(DEFAULT_ICU_PLUGINS) if(plugin_dir.isEmpty()) { plugin_dir.append(DEFAULT_ICU_PLUGINS, -1, *status); } #endif #if UPLUG_TRACE DBG((stderr, "ICU_PLUGINS=%s\n", plugin_dir.data())); #endif if(!plugin_dir.isEmpty()) { FILE *f; CharString pluginFile; #ifdef OS390BATCH /* There are potentially a lot of ways to implement a plugin directory on OS390/zOS */ /* Keeping in mind that unauthorized file access is logged, monitored, and enforced */ /* I've chosen to open a DDNAME if BATCH and leave it alone for (presumably) UNIX */ /* System Services. Alternative techniques might be allocating a member in */ /* SYS1.PARMLIB or setting an environment variable "ICU_PLUGIN_PATH" (?). The */ /* DDNAME can be connected to a file in the HFS if need be. */ pluginFile.append("//DD:ICUPLUG", -1, *status); /* JAM 20 Oct 2011 */ #else pluginFile.append(plugin_dir, *status); pluginFile.append(U_FILE_SEP_STRING, -1, *status); pluginFile.append("icuplugins", -1, *status); pluginFile.append(U_ICU_VERSION_SHORT, -1, *status); pluginFile.append(".txt", -1, *status); #endif #if UPLUG_TRACE DBG((stderr, "status=%s\n", u_errorName(*status))); #endif if(U_FAILURE(*status)) { return; } if((size_t)pluginFile.length() > (sizeof(plugin_file)-1)) { *status = U_BUFFER_OVERFLOW_ERROR; #if UPLUG_TRACE DBG((stderr, "status=%s\n", u_errorName(*status))); #endif return; } /* plugin_file is not used for processing - it is only used so that uplug_getPluginFile() works (i.e. icuinfo) */ uprv_strncpy(plugin_file, pluginFile.data(), sizeof(plugin_file)); #if UPLUG_TRACE DBG((stderr, "pluginfile= %s len %d/%d\n", plugin_file, (int)strlen(plugin_file), (int)sizeof(plugin_file))); #endif #ifdef __MVS__ if (iscics()) /* 12 Nov 2011 JAM */ { f = NULL; } else #endif { f = fopen(pluginFile.data(), "r"); } if(f != NULL) { char linebuf[1024]; char *p, *libName=NULL, *symName=NULL, *config=NULL; int32_t line = 0; while(fgets(linebuf,1023,f)) { line++; if(!*linebuf || *linebuf=='#') { continue; } else { p = linebuf; while(*p&&isspace((int)*p)) p++; if(!*p || *p=='#') continue; libName = p; while(*p&&!isspace((int)*p)) { p++; } if(!*p || *p=='#') continue; /* no tab after libname */ *p=0; /* end of libname */ p++; while(*p&&isspace((int)*p)) { p++; } if(!*p||*p=='#') continue; /* no symname after libname +tab */ symName = p; while(*p&&!isspace((int)*p)) { p++; } if(*p) { /* has config */ *p=0; ++p; while(*p&&isspace((int)*p)) { p++; } if(*p) { config = p; } } /* chop whitespace at the end of the config */ if(config!=NULL&&*config!=0) { p = config+strlen(config); while(p>config&&isspace((int)*(--p))) { *p=0; } } /* OK, we're good. */ { UErrorCode subStatus = U_ZERO_ERROR; UPlugData *plug = uplug_initPlugFromLibrary(libName, symName, config, &subStatus); if(U_FAILURE(subStatus) && U_SUCCESS(*status)) { *status = subStatus; } #if UPLUG_TRACE DBG((stderr, "PLUGIN libName=[%s], sym=[%s], config=[%s]\n", libName, symName, config)); DBG((stderr, " -> %p, %s\n", (void*)plug, u_errorName(subStatus))); #else (void)plug; /* unused */ #endif } } } fclose(f); } else { #if UPLUG_TRACE DBG((stderr, "Can't open plugin file %s\n", plugin_file)); #endif } } uplug_loadWaitingPlugs(status); #endif /* U_ENABLE_DYLOAD */ ucln_registerCleanup(UCLN_UPLUG, uplug_cleanup); }