Example #1
0
	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;
	}
Example #2
0
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;
}
Example #3
0
 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);
}
Example #5
0
	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;
	}
Example #6
0
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;
}
Example #7
0
/**
 *  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));
}
Example #9
0
void
DigitList::appendDigitsTo(CharString &str, UErrorCode &status) const {
    str.append((const char *) fDecNumber->lsu, fDecNumber->digits, status);
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #13
0
// 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;
    }
}
Example #14
0
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);
}