void TestMessageFormat::testClone() 
{
    UErrorCode success = U_ZERO_ERROR;
    MessageFormat *x = new MessageFormat("There are {0} files on {1}", success);
    MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success);
    MessageFormat *y = 0;
    y = (MessageFormat*)x->clone();
    if ( (*x == *y) && 
         (*x != *z) && 
         (*y != *z) )
        logln("First test (operator ==): Passed!");
    else {
        errln("TestMessageFormat::testClone failed #1");
        logln("First test (operator ==): Failed!");
    }
    if ( ((*x == *y) && (*y == *x)) &&
         ((*x != *z) && (*z != *x)) &&
         ((*y != *z) && (*z != *y)) )
        logln("Second test (equals): Passed!");
    else {
        errln("TestMessageFormat::testClone failed #2");
        logln("Second test (equals): Failed!");
    }

    delete x;
    delete y;
    delete z;
}
Example #2
0
// {sfb} doesn't apply in C++?
void MessageFormatRegressionTest::Test4114739()
{

    UErrorCode status = U_ZERO_ERROR;    
    MessageFormat *mf = new MessageFormat("<{0}>", status);
    failure(status, "new MessageFormat");

    Formattable *objs1 = NULL;
    //Formattable objs2 [] = {};
    //Formattable *objs3 [] = {NULL};
    //try {
    UnicodeString pat;
    UnicodeString res;
        logln("pattern: \"" + mf->toPattern(pat) + "\"");
        log("format(null) : ");
        FieldPosition pos(FieldPosition::DONT_CARE);
        logln("\"" + mf->format(objs1, 0, res, pos, status) + "\"");
        failure(status, "mf->format");
        /*log("format({})   : ");
        logln("\"" + mf->format(objs2, 0, res, FieldPosition(FieldPosition::DONT_CARE), status) + "\"");
        failure(status, "mf->format");
        log("format({null}) :");
        logln("\"" + mf->format(objs3, 0, res, FieldPosition(FieldPosition::DONT_CARE), status) + "\"");
        failure(status, "mf->format");*/
    /*} catch (Exception e) {
        errln("Exception thrown for null argument tests.");
    }*/

    delete mf;
}
Example #3
0
void MessageFormatRegressionTest::Test4120552()
{
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *mf = new MessageFormat("pattern", status);
    failure(status, "new MessageFormat");
    UnicodeString texts[] = {
        (UnicodeString)"pattern", 
            (UnicodeString)"pat", 
            (UnicodeString)"1234"
    };
    UnicodeString pat;
    logln("pattern: \"" + mf->toPattern(pat) + "\"");
    for (int i = 0; i < 3; i++) {
        ParsePosition pp(0);
        //Object[] objs = mf.parse(texts[i], pp);
        int32_t count = 0;
        Formattable *objs = mf->parse(texts[i], pp, count);
        log("  text for parsing: \"" + texts[i] + "\"");
        if (objs == NULL) {
            logln("  (incorrectly formatted string)");
            if (pp.getErrorIndex() == -1)
                errln(UnicodeString("Incorrect error index: ") + pp.getErrorIndex());
        } else {
            logln("  (correctly formatted string)");
            delete[] objs;
        }
    }
    delete mf;
}
void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale,
                     UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments.
                     UnicodeString &result)
{
    if(U_FAILURE(realStatus))
        return; // you messed up

    UnicodeString errString1(u_errorName(inStatus0));

    UnicodeString countryName2;
    inCountry2.getDisplayCountry(theLocale,countryName2);

    Formattable myArgs[] = {
        Formattable((int32_t)inStatus0),   // inStatus0      {0}
        Formattable(errString1), // statusString1 {1}
        Formattable(countryName2),  // inCountry2 {2}
        Formattable(currency3)// currency3  {3,number,currency}
    };

    MessageFormat *fmt = new MessageFormat("MessageFormat's API is broken!!!!!!!!!!!",realStatus);
    fmt->setLocale(theLocale);
    fmt->applyPattern(pattern, realStatus);
    
    if (U_FAILURE(realStatus)) {
        delete fmt;
        return;
    }

    FieldPosition ignore = 0;                      
    fmt->format(myArgs,4,result,ignore,realStatus);

    delete fmt;
}
Example #5
0
void MessageFormatRegressionTest::Test4116444()
{
    UnicodeString patterns [] = {
        (UnicodeString)"", 
        (UnicodeString)"one", 
        (UnicodeString) "{0,date,short}"
    };
    
    UErrorCode status = U_ZERO_ERROR;    
    MessageFormat *mf = new MessageFormat("", status);
    failure(status, "new MessageFormat");

    for (int i = 0; i < 3; i++) {
        UnicodeString pattern = patterns[i];
        mf->applyPattern(pattern, status);
        failure(status, "mf->applyPattern", TRUE);

        //try {
        int32_t count = 0;    
        ParsePosition pp(0);
        Formattable *array = mf->parse(UnicodeString(""), pp, count);
            logln("pattern: \"" + pattern + "\"");
            log(" parsedObjects: ");
            if (array != NULL) {
                log("{");
                for (int j = 0; j < count; j++) {
                    //if (array[j] != null)
                    UnicodeString dummy;
                    err("\"" + array[j].getString(dummy) + "\"");
                    //else
                     //   log("null");
                    if (j < count- 1) 
                        log(",");
                }
                log("}") ;
                delete[] array;
            } else {
                log("null");
            }
            logln("");
        /*} catch (Exception e) {
            errln("pattern: \"" + pattern + "\"");
            errln("  Exception: " + e.getMessage());
        }*/
    }

    delete mf;
}
Example #6
0
void MessageFormatRegressionTest::TestAPI() {
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *format = new MessageFormat("", status);
    failure(status, "new MessageFormat");
    
    // Test adoptFormat
    MessageFormat *fmt = new MessageFormat("",status);
    format->adoptFormat("",fmt,status);
    failure(status, "adoptFormat");

    // Test getFormat
    format->setFormat((int32_t)0,*fmt);
    format->getFormat("",status);
    failure(status, "getFormat");
    delete format;
}
void MessageFormatRegressionTest::TestAPI() {
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *format = new MessageFormat("", status);
    failure(status, "new MessageFormat");
    
    // Test adoptFormat
    MessageFormat *fmt = new MessageFormat("",status);
    format->adoptFormat("some_name",fmt,status);  // Must at least pass a valid identifier.
    failure(status, "adoptFormat");

    // Test getFormat
    format->setFormat((int32_t)0,*fmt);
    format->getFormat("some_other_name",status);  // Must at least pass a valid identifier.
    failure(status, "getFormat");
    delete format;
}
static void umsg_set_timezone(MessageFormatter_object *mfo,
							  intl_error& err)
{
	MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
	TimeZone	  *used_tz = NULL;
	const Format  **formats;
	int32_t		  count;

	/* Unfortanely, this cannot change the time zone for arguments that
	 * appear inside complex formats because ::getFormats() returns NULL
	 * for all uncached formats, which is the case for complex formats
	 * unless they were set via one of the ::setFormat() methods */

	if (mfo->mf_data.tz_set) {
		return; /* already done */
	}

	formats = mf->getFormats(count);

	if (formats == NULL) {
		intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
			"Out of memory retrieving subformats", 0);
	}

	for (int i = 0; U_SUCCESS(err.code) && i < count; i++) {
		DateFormat* df = dynamic_cast<DateFormat*>(
			const_cast<Format *>(formats[i]));
		if (df == NULL) {
			continue;
		}

		if (used_tz == NULL) {
			zval nullzv, *zvptr = &nullzv;
			ZVAL_NULL(zvptr);
			used_tz = timezone_process_timezone_argument(zvptr, &err, "msgfmt_format");
			if (used_tz == NULL) {
				continue;
			}
		}

		df->setTimeZone(*used_tz);
	}

	if (U_SUCCESS(err.code)) {
		mfo->mf_data.tz_set = 1;
	}
}
Example #9
0
void MessageFormatRegressionTest::Test4058973() 
{
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}", status);
    failure(status, "new MessageFormat");

    UnicodeString pat;
    pat = fmt->toPattern(pat);
    UnicodeString exp("{0,choice,0#no files|1#one file|1< {0,number,integer} files}");
    if (pat != exp) {
        errln("MessageFormat.toPattern failed");
        errln("Exp: " + exp);
        errln("Got: " + pat);
    }

    delete fmt;
}
Example #10
0
void MessageFormatRegressionTest::Test4114743()
{
    UnicodeString originalPattern("initial pattern");
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *mf = new MessageFormat(originalPattern, status);
    failure(status, "new MessageFormat");
    //try {
        UnicodeString illegalPattern("ab { '}' de");
        mf->applyPattern(illegalPattern, status);
        if( ! U_FAILURE(status))
            errln("illegal pattern: \"" + illegalPattern + "\"");
    /*} catch (IllegalArgumentException foo) {
        if (!originalPattern.equals(mf.toPattern()))
            errln("pattern after: \"" + mf.toPattern() + "\"");
    }*/
    delete mf;
}
Example #11
0
void MessageFormatRegressionTest::Test4052223()
{

    ParsePosition pos(0);
    if (pos.getErrorIndex() != -1) {
        errln("ParsePosition.getErrorIndex initialization failed.");
    }

    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *fmt = new MessageFormat("There are {0} apples growing on the {1} tree.", status);
    failure(status, "new MessageFormat");
    UnicodeString str("There is one apple growing on the peach tree.");
    
    int32_t count = 0;
    fmt->parse(str, pos, count);

    logln(UnicodeString("unparsable string , should fail at ") + pos.getErrorIndex());
    if (pos.getErrorIndex() == -1)
        errln("Bug 4052223 failed : parsing string " + str);
    pos.setErrorIndex(4);
    if (pos.getErrorIndex() != 4)
        errln(UnicodeString("setErrorIndex failed, got ") + pos.getErrorIndex() + " instead of 4");
    
    ChoiceFormat *f = new ChoiceFormat(
        "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.", status);
    failure(status, "new ChoiceFormat");
    pos.setIndex(0); 
    pos.setErrorIndex(-1);
    Formattable obj;
    f->parse("are negative", obj, pos);
    if (pos.getErrorIndex() != -1 && obj.getDouble() == -1.0)
        errln(UnicodeString("Parse with \"are negative\" failed, at ") + pos.getErrorIndex());
    pos.setIndex(0); 
    pos.setErrorIndex(-1);
    f->parse("are no or fraction ", obj, pos);
    if (pos.getErrorIndex() != -1 && obj.getDouble() == 0.0)
        errln(UnicodeString("Parse with \"are no or fraction\" failed, at ") + pos.getErrorIndex());
    pos.setIndex(0); 
    pos.setErrorIndex(-1);
    f->parse("go postal", obj, pos);
    if (pos.getErrorIndex() == -1 && ! uprv_isNaN(obj.getDouble()))
        errln(UnicodeString("Parse with \"go postal\" failed, at ") + pos.getErrorIndex());
    
    delete fmt;
    delete f;
}
void TestMessageFormat::testBug2()
{
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString result;
    // {sfb} use double format in pattern, so result will match (not strictly necessary)
    const UnicodeString pattern = "There {0,choice,0.0#are no files|1.0#is one file|1.0<are {0, number} files} on disk {1}. ";
    logln("The input pattern : " + pattern);
    MessageFormat *fmt = new MessageFormat(pattern, status);
    if (U_FAILURE(status)) {
        errln("MessageFormat pattern creation failed.");
        return;
    }
    logln("The output pattern is : " + fmt->toPattern(result));
    if (pattern != result) {
        errln("MessageFormat::toPattern() failed.");
    }
    delete fmt;
}
Example #13
0
void MessageFormatRegressionTest::Test4142938() 
{
    UnicodeString pat = CharsToUnicodeString("''Vous'' {0,choice,0#n''|1#}avez s\\u00E9lectionn\\u00E9 "
        "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} "
        "personnel{0,choice,0#s|1#|2#s}.");
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *mf = new MessageFormat(pat, status);
    failure(status, "new MessageFormat");

    UnicodeString PREFIX [] = {
        CharsToUnicodeString("'Vous' n'avez s\\u00E9lectionn\\u00E9 aucun clients personnels."),
        CharsToUnicodeString("'Vous' avez s\\u00E9lectionn\\u00E9 "),
        CharsToUnicodeString("'Vous' avez s\\u00E9lectionn\\u00E9 ")
    };  
    UnicodeString SUFFIX [] = {
        UnicodeString(),
        UNICODE_STRING(" client personnel.", 18),
        UNICODE_STRING(" clients personnels.", 20)
    };

    for (int i=0; i<3; i++) {
        UnicodeString out;
        //out = mf->format(new Object[]{new Integer(i)});
        Formattable objs [] = {
            Formattable((int32_t)i)
        };
        FieldPosition pos(FieldPosition::DONT_CARE);
        out = mf->format(objs, 1, out, pos, status);
        if (!failure(status, "mf->format", TRUE)) {
            if (SUFFIX[i] == "") {
                if (out != PREFIX[i])
                    errln((UnicodeString)"" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"");
            }
            else {
                if (!out.startsWith(PREFIX[i]) ||
                    !out.endsWith(SUFFIX[i]))
                    errln((UnicodeString)"" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
                          SUFFIX[i] + "\"");
            }
        }
    }

    delete mf;
}
Example #14
0
static HashTable *umsg_get_types(MessageFormatter_object *mfo,
								 intl_error& err)
{
	MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;

#ifdef HAS_MESSAGE_PATTERN
	const MessagePattern mp = MessageFormatAdapter::getMessagePattern(mf);

	return umsg_parse_format(mfo, mp, err);
#else
	if (mf->usesNamedArguments()) {
			intl_errors_set(&err, U_UNSUPPORTED_ERROR,
				"This extension supports named arguments only on ICU 4.8+",
				0);
		return NULL;
	}
	return umsg_get_numeric_types(mfo, err);
#endif
}
Example #15
0
void MessageFormatRegressionTest::Test4113018()
{
    UnicodeString originalPattern("initial pattern");
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *mf = new MessageFormat(originalPattern, status);
    failure(status, "new messageFormat");
    UnicodeString illegalPattern("format: {0, xxxYYY}");
    UnicodeString pat;
    logln("pattern before: \"" + mf->toPattern(pat) + "\"");
    logln("illegal pattern: \"" + illegalPattern + "\"");
    //try {
        mf->applyPattern(illegalPattern, status);
        if( ! U_FAILURE(status))
            errln("Should have thrown IllegalArgumentException for pattern : " + illegalPattern);
    /*} catch (IllegalArgumentException e) {
        if (!originalPattern.equals(mf.toPattern()))
            errln("pattern after: \"" + mf.toPattern() + "\"");
    }*/
    delete mf;
}
void TestMessageFormat::sample() 
{
    MessageFormat *form = 0;
    UnicodeString buffer1, buffer2;
    UErrorCode success = U_ZERO_ERROR;
    form = new MessageFormat("There are {0} files on {1}", success);
    if (U_FAILURE(success)) {
        errln("Err: Message format creation failed");
        logln("Sample message format creation failed.");
        return;
    }
    UnicodeString abc("abc");
    UnicodeString def("def");
    Formattable testArgs1[] = { abc, def };
    FieldPosition fieldpos(0);
    assertEquals("format",
                 "There are abc files on def",
                 form->format(testArgs1, 2, buffer2, fieldpos, success));
    assertSuccess("format", success);
    delete form;
}
void TestMessageFormat::testMsgFormatChoice(/* char* par */)
{
    logln("running TestMessageFormat::testMsgFormatChoice");

    UErrorCode err = U_ZERO_ERROR;

    MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", err);
    double filelimits[] = {0,1,2};
    UnicodeString filepart[] = {"no files","one file","{0,number} files"};
    ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3);
    form->setFormat(1,*fileform); // NOT zero, see below
        //is the format adopted?

    FieldPosition ignore(FieldPosition::DONT_CARE);
    UnicodeString string;
    Formattable testArgs1[] = {(int32_t)0, "MyDisk"};    
    form->format(testArgs1, 2, string, ignore, err);
    if (string != "The disk \"MyDisk\" contains no files.") {
        errln("TestMessageFormat::testMsgFormatChoice failed on test #1");
    }
 
    ignore.setField(FieldPosition::DONT_CARE);
    string.remove();
    Formattable testArgs2[] = {(int32_t)1, "MyDisk"};    
    form->format(testArgs2, 2, string, ignore, err);
    if (string != "The disk \"MyDisk\" contains one file.") {
        errln("TestMessageFormat::testMsgFormatChoice failed on test #2");
    }

    ignore.setField(FieldPosition::DONT_CARE);
    string.remove();
    Formattable testArgs3[] = {(int32_t)1273, "MyDisk"};    
    form->format(testArgs3, 2, string, ignore, err);
    if (string != "The disk \"MyDisk\" contains 1,273 files.") {
        errln("TestMessageFormat::testMsgFormatChoice failed on test #3");
    }

    delete form;
    delete fileform;
}
void TestMessageFormat::testSimpleFormat(/* char* par */)
{
    logln("running TestMessageFormat::testSimpleFormat");

    UErrorCode err = U_ZERO_ERROR;

    Formattable testArgs1[] = {(int32_t)0, "MyDisk"};
    Formattable testArgs2[] = {(int32_t)1, "MyDisk"};
    Formattable testArgs3[] = {(int32_t)12, "MyDisk"};
   
    MessageFormat* form = new MessageFormat(
        "The disk \"{1}\" contains {0} file(s).", err);
    
    UnicodeString string;
    FieldPosition ignore(FieldPosition::DONT_CARE);
    form->format(testArgs1, 2, string, ignore, err);
    if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") {
        errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #1"));
    }
 
    ignore.setField(FieldPosition::DONT_CARE);
    string.remove();
    form->format(testArgs2, 2, string, ignore, err);
    if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") {
        logln(string);
        errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #2")+string);
    }
 
    ignore.setField(FieldPosition::DONT_CARE);
    string.remove();
    form->format(testArgs3, 2, string, ignore, err);
    if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).") {
        errln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #3")+string);
    }

    delete form;
 }
Example #19
0
void MessageFormatRegressionTest::Test4118592()
{
    UErrorCode status = U_ZERO_ERROR;
    MessageFormat *mf = new MessageFormat("", status);
    failure(status, "new messageFormat");
    UnicodeString pattern("{0,choice,1#YES|2#NO}");
    UnicodeString prefix("");
    Formattable *objs = 0;

    for (int i = 0; i < 5; i++) {
        UnicodeString formatted;
        formatted = prefix + "YES";
        mf->applyPattern(prefix + pattern, status);
        failure(status, "mf->applyPattern");
        prefix += "x";
        //Object[] objs = mf.parse(formatted, new ParsePosition(0));
        int32_t count = 0;
        ParsePosition pp(0);
        objs = mf->parse(formatted, pp, count);
        UnicodeString pat;
        logln(UnicodeString("") + i + ". pattern :\"" + mf->toPattern(pat) + "\"");
        log(" \"" + formatted + "\" parsed as ");
        if (objs == NULL) 
            logln("  null");
        else {
            UnicodeString temp;
            if(objs[0].getType() == Formattable::kString)
                logln((UnicodeString)"  " + objs[0].getString(temp));
            else
                logln((UnicodeString)"  " + (objs[0].getType() == Formattable::kLong ? objs[0].getLong() : objs[0].getDouble()));
            delete[] objs;

        }
    }

    delete mf;
}
Example #20
0
UnicodeString& 
TimeUnitFormat::format(const Formattable& obj, UnicodeString& toAppendTo,
                       FieldPosition& pos, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return toAppendTo;
    }
    if (obj.getType() == Formattable::kObject) {
        const UObject* formatObj = obj.getObject();
        const TimeUnitAmount* amount = dynamic_cast<const TimeUnitAmount*>(formatObj);
        if (amount != NULL){
            Hashtable* countToPattern = fTimeUnitToCountToPatterns[amount->getTimeUnitField()];
            double number;
            const Formattable& amtNumber = amount->getNumber();
            if (amtNumber.getType() == Formattable::kDouble) {
                number = amtNumber.getDouble();
            } else if (amtNumber.getType() == Formattable::kLong) {
                number = amtNumber.getLong();
            } else {
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return toAppendTo;
            }
            UnicodeString count = fPluralRules->select(number);
#ifdef TMUTFMT_DEBUG
            char result[1000];
            count.extract(0, count.length(), result, "UTF-8");
            std::cout << "number: " << number << "; format plural count: " << result << "\n";           
#endif
            MessageFormat* pattern = ((MessageFormat**)countToPattern->get(count))[fStyle];
            Formattable formattable[1];
            formattable[0].setDouble(number);
            return pattern->format(formattable, 1, toAppendTo, pos, status);
        }
    }
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return toAppendTo;
}
Example #21
0
void MessageFormatRegressionTest::Test4118594()
{
    UErrorCode status = U_ZERO_ERROR;
    const UBool possibleDataError = TRUE;
    MessageFormat *mf = new MessageFormat("{0}, {0}, {0}", status);
    failure(status, "new MessageFormat");
    UnicodeString forParsing("x, y, z");
    //Object[] objs = mf.parse(forParsing, new ParsePosition(0));
    int32_t count = 0;
    ParsePosition pp(0);
    Formattable *objs = mf->parse(forParsing, pp, count);
    UnicodeString pat;
    logln("pattern: \"" + mf->toPattern(pat) + "\"");
    logln("text for parsing: \"" + forParsing + "\"");
    UnicodeString str;
    if (objs[0].getString(str) != "z")
        errln("argument0: \"" + objs[0].getString(str) + "\"");
    mf->applyPattern("{0,number,#.##}, {0,number,#.#}", status);
    failure(status, "mf->applyPattern", possibleDataError);
    //Object[] oldobjs = {new Double(3.1415)};
    Formattable oldobjs [] = {Formattable(3.1415)};
    UnicodeString result;
    FieldPosition pos(FieldPosition::DONT_CARE);
    result = mf->format( oldobjs, 1, result, pos, status );
    failure(status, "mf->format", possibleDataError);
    pat.remove();
    logln("pattern: \"" + mf->toPattern(pat) + "\"");
    logln("text for parsing: \"" + result + "\"");
    // result now equals "3.14, 3.1"
    if (result != "3.14, 3.1")
        dataerrln("result = " + result + " - " + u_errorName(status));
    //Object[] newobjs = mf.parse(result, new ParsePosition(0));
    int32_t count1 = 0;
    pp.setIndex(0);
    Formattable *newobjs = mf->parse(result, pp, count1);
    // newobjs now equals {new Double(3.1)}
    if (newobjs == NULL) {
        dataerrln("Error calling MessageFormat::parse");
    } else {
        if (newobjs[0].getDouble() != 3.1)
            errln( UnicodeString("newobjs[0] = ") + newobjs[0].getDouble());
    }

    delete [] objs;
    delete [] newobjs;
    delete mf;
}
Example #22
0
UnicodeString&
LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const {
    if (buffer.isEmpty()) {
        buffer.setTo(src);
    } else {
        UnicodeString combined;
        Formattable data[] = {
          buffer,
          src
        };
        FieldPosition fpos;
        UErrorCode status = U_ZERO_ERROR;
        separatorFormat->format(data, 2, combined, fpos, status);
        if (U_SUCCESS(status)) {
            buffer.setTo(combined);
        }
    }
    return buffer;
}
Example #23
0
/*
 * This method updates the cache and must be called with a lock
 */
const UChar*
TZGNCore::getPartialLocationName(const UnicodeString& tzCanonicalID,
                        const UnicodeString& mzID, UBool isLong, const UnicodeString& mzDisplayName) {
    U_ASSERT(!tzCanonicalID.isEmpty());
    U_ASSERT(!mzID.isEmpty());
    U_ASSERT(!mzDisplayName.isEmpty());

    PartialLocationKey key;
    key.tzID = ZoneMeta::findTimeZoneID(tzCanonicalID);
    key.mzID = ZoneMeta::findMetaZoneID(mzID);
    key.isLong = isLong;
    U_ASSERT(key.tzID != NULL && key.mzID != NULL);

    const UChar* uplname = (const UChar*)uhash_get(fPartialLocationNamesMap, (void *)&key);
    if (uplname != NULL) {
        return uplname;
    }

    UnicodeString location;
    UnicodeString usCountryCode;
    ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode);
    if (!usCountryCode.isEmpty()) {
        char countryCode[ULOC_COUNTRY_CAPACITY];
        U_ASSERT(usCountryCode.length() < ULOC_COUNTRY_CAPACITY);
        int32_t ccLen = usCountryCode.extract(0, usCountryCode.length(), countryCode, sizeof(countryCode), US_INV);
        countryCode[ccLen] = 0;

        UnicodeString regionalGolden;
        fTimeZoneNames->getReferenceZoneID(mzID, countryCode, regionalGolden);
        if (tzCanonicalID == regionalGolden) {
            // Use country name
            fLocaleDisplayNames->regionDisplayName(countryCode, location);
        } else {
            // Otherwise, use exemplar city name
            fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location);
        }
    } else {
        fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location);
        if (location.isEmpty()) {
            // This could happen when the time zone is not associated with a country,
            // and its ID is not hierarchical, for example, CST6CDT.
            // We use the canonical ID itself as the location for this case.
            location.setTo(tzCanonicalID);
        }
    }

    UErrorCode status = U_ZERO_ERROR;
    UnicodeString name;

    FieldPosition fpos;
    Formattable param[] = {
        Formattable(location),
        Formattable(mzDisplayName)
    };
    fFallbackFormat->format(param, 2, name, fpos, status);
    if (U_FAILURE(status)) {
        return NULL;
    }

    uplname = fStringPool.get(name, status);
    if (U_SUCCESS(status)) {
        // Add the name to cache
        PartialLocationKey* cacheKey = (PartialLocationKey *)uprv_malloc(sizeof(PartialLocationKey));
        if (cacheKey != NULL) {
            cacheKey->tzID = key.tzID;
            cacheKey->mzID = key.mzID;
            cacheKey->isLong = key.isLong;
            uhash_put(fPartialLocationNamesMap, (void *)cacheKey, (void *)uplname, &status);
            if (U_FAILURE(status)) {
                uprv_free(cacheKey);
            } else {
                // put the name to the local trie as well
                GNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(GNameInfo));
                if (nameinfo != NULL) {
                    nameinfo->type = isLong ? UTZGNM_LONG : UTZGNM_SHORT;
                    nameinfo->tzID = key.tzID;
                    fGNamesTrie.put(uplname, nameinfo, status);
                }
            }
        }
    }
    return uplname;
}
Example #24
0
void
TimeUnitFormat::parseObject(const UnicodeString& source,
                            Formattable& result,
                            ParsePosition& pos) const {
    Formattable resultNumber(0.0);
    UBool withNumberFormat = false;
    TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
    int32_t oldPos = pos.getIndex();
    int32_t newPos = -1;
    int32_t longestParseDistance = 0;
    UnicodeString* countOfLongestMatch = NULL;
#ifdef TMUTFMT_DEBUG
    char res[1000];
    source.extract(0, source.length(), res, "UTF-8");
    std::cout << "parse source: " << res << "\n";
#endif
    // parse by iterating through all available patterns
    // and looking for the longest match.
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
        int32_t elemPos = UHASH_FIRST;
        const UHashElement* elem = NULL;
        while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
            const UHashTok keyTok = elem->key;
            UnicodeString* count = (UnicodeString*)keyTok.pointer;
#ifdef TMUTFMT_DEBUG
            count->extract(0, count->length(), res, "UTF-8");
            std::cout << "parse plural count: " << res << "\n";
#endif
            const UHashTok valueTok = elem->value;
            // the value is a pair of MessageFormat*
            MessageFormat** patterns = (MessageFormat**)valueTok.pointer;
            for (UTimeUnitFormatStyle style = UTMUTFMT_FULL_STYLE; style < UTMUTFMT_FORMAT_STYLE_COUNT;
                 style = (UTimeUnitFormatStyle)(style + 1)) {
                MessageFormat* pattern = patterns[style];
                pos.setErrorIndex(-1);
                pos.setIndex(oldPos);
                // see if we can parse
                Formattable parsed;
                pattern->parseObject(source, parsed, pos);
                if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
                    continue;
                }
    #ifdef TMUTFMT_DEBUG
                std::cout << "parsed.getType: " << parsed.getType() << "\n";
    #endif
                Formattable tmpNumber(0.0);
                if (pattern->getArgTypeCount() != 0) {
                    Formattable& temp = parsed[0];
                    if (temp.getType() == Formattable::kString) {
                        UnicodeString tmpString;
                        UErrorCode pStatus = U_ZERO_ERROR;
                        getNumberFormat().parse(temp.getString(tmpString), tmpNumber, pStatus);
                        if (U_FAILURE(pStatus)) {
                            continue;
                        }
                    } else if (temp.isNumeric()) {
                        tmpNumber = temp;
                    } else {
                        continue;
                    }
                }
                int32_t parseDistance = pos.getIndex() - oldPos;
                if (parseDistance > longestParseDistance) {
                    if (pattern->getArgTypeCount() != 0) {
                        resultNumber = tmpNumber;
                        withNumberFormat = true;
                    } else {
                        withNumberFormat = false;
                    }
                    resultTimeUnit = i;
                    newPos = pos.getIndex();
                    longestParseDistance = parseDistance;
                    countOfLongestMatch = count;
                }
            }
        }
    }
    /* After find the longest match, parse the number.
     * Result number could be null for the pattern without number pattern.
     * such as unit pattern in Arabic.
     * When result number is null, use plural rule to set the number.
     */
    if (withNumberFormat == false && longestParseDistance != 0) {
        // set the number using plurrual count
        if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
            resultNumber = Formattable(0.0);
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
            resultNumber = Formattable(1.0);
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
            resultNumber = Formattable(2.0);
        } else {
            // should not happen.
            // TODO: how to handle?
            resultNumber = Formattable(3.0);
        }
    }
    if (longestParseDistance == 0) {
        pos.setIndex(oldPos);
        pos.setErrorIndex(0);
    } else {
        UErrorCode status = U_ZERO_ERROR;
        TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUnit, status);
        if (U_SUCCESS(status)) {
            result.adoptObject(tmutamt);
            pos.setIndex(newPos);
            pos.setErrorIndex(-1);
        } else {
            pos.setIndex(oldPos);
            pos.setErrorIndex(0);
        }
    }
}
Example #25
0
void
TestChoiceFormat::TestComplexExample( void )
{
    UErrorCode status = U_ZERO_ERROR;
    const double filelimits[] = {-1, 0,1,2};
    const UnicodeString filepart[] = {"are corrupted files", "are no files","is one file","are {2} files"};

    ChoiceFormat* fileform = new ChoiceFormat( filelimits, filepart, 4);

    if (!fileform) { 
        it_errln("***  test_complex_example fileform"); 
        return; 
    }

    Format* filenumform = NumberFormat::createInstance( status );
    if (!filenumform) { 
        dataerrln((UnicodeString)"***  test_complex_example filenumform - " + u_errorName(status)); 
        delete fileform;
        return; 
    }
    if (!chkstatus( status, "***  test_simple_example filenumform" )) {
        delete fileform;
        delete filenumform;
        return;
    }

    //const Format* testFormats[] = { fileform, NULL, filenumform };
    //pattform->setFormats( testFormats, 3 );

    MessageFormat* pattform = new MessageFormat("There {0} on {1}", status );
    if (!pattform) { 
        it_errln("***  test_complex_example pattform"); 
        delete fileform;
        delete filenumform;
        return; 
    }
    if (!chkstatus( status, "***  test_complex_example pattform" )) {
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }

    pattform->setFormat( 0, *fileform );
    pattform->setFormat( 2, *filenumform );


    Formattable testArgs[] = {(int32_t)0, "Disk_A", (int32_t)0};
    UnicodeString str;
    UnicodeString res1, res2;
    pattform->toPattern( res1 );
    it_logln("MessageFormat toPattern: " + res1);
    fileform->toPattern( res1 );
    it_logln("ChoiceFormat toPattern: " + res1);
    if (res1 == "-1#are corrupted files|0#are no files|1#is one file|2#are {2} files") {
        it_logln("toPattern tested!");
    }else{
        it_errln("***  ChoiceFormat to Pattern result!");
    }

    FieldPosition fpos(FieldPosition::DONT_CARE);

    UnicodeString checkstr[] = { 
        "There are corrupted files on Disk_A",
        "There are no files on Disk_A",
        "There is one file on Disk_A",
        "There are 2 files on Disk_A",
        "There are 3 files on Disk_A"
    };

    // if (status != U_ZERO_ERROR) return; // TODO: analyze why we have such a bad bail out here!

    if (U_FAILURE(status)) { 
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }


    int32_t i;
    int32_t start = -1;
    for (i = start; i < 4; ++i) {
        str = "";
        status = U_ZERO_ERROR;
        testArgs[0] = Formattable((int32_t)i);
        testArgs[2] = testArgs[0];
        res2 = pattform->format(testArgs, 3, str, fpos, status );
        if (!chkstatus( status, "***  test_complex_example format" )) {
            delete fileform;
            delete filenumform;
            delete pattform;
            return;
        }
        it_logln(i + UnicodeString(" -> ") + res2);
        if (res2 != checkstr[i - start]) {
            it_errln("***  test_complex_example res string");
            it_errln(UnicodeString("*** ") + i + UnicodeString(" -> '") + res2 + UnicodeString("' unlike '") + checkstr[i] + UnicodeString("' ! "));
        }
    }
    it_logln();

    it_logln("------ additional testing in complex test ------");
    it_logln();
    //
#if 0  // ICU 4.8 deprecates and disables the ChoiceFormat getters.
    int32_t retCount;
    const double* retLimits = fileform->getLimits( retCount );
    if ((retCount == 4) && (retLimits)
    && (retLimits[0] == -1.0)
    && (retLimits[1] == 0.0)
    && (retLimits[2] == 1.0)
    && (retLimits[3] == 2.0)) {
        it_logln("getLimits tested!");
    }else{
        it_errln("***  getLimits unexpected result!");
    }

    const UnicodeString* retFormats = fileform->getFormats( retCount );
    if ((retCount == 4) && (retFormats)
    && (retFormats[0] == "are corrupted files") 
    && (retFormats[1] == "are no files") 
    && (retFormats[2] == "is one file")
    && (retFormats[3] == "are {2} files")) {
        it_logln("getFormats tested!");
    }else{
        it_errln("***  getFormats unexpected result!");
    }
#endif

    UnicodeString checkstr2[] = { 
        "There is no folder on Disk_A",
        "There is one folder on Disk_A",
        "There are many folders on Disk_A",
        "There are many folders on Disk_A"
    };

    fileform->applyPattern("0#is no folder|1#is one folder|2#are many folders", status );
    if (status == U_ZERO_ERROR)
        it_logln("status applyPattern OK!");
    if (!chkstatus( status, "***  test_complex_example pattform" )) {
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }
    pattform->setFormat( 0, *fileform );
    fpos = 0;
    for (i = 0; i < 4; ++i) {
        str = "";
        status = U_ZERO_ERROR;
        testArgs[0] = Formattable((int32_t)i);
        testArgs[2] = testArgs[0];
        res2 = pattform->format(testArgs, 3, str, fpos, status );
        if (!chkstatus( status, "***  test_complex_example format 2" )) {
            delete fileform;
            delete filenumform;
            delete pattform;
            return;
        }
        it_logln(UnicodeString() + i + UnicodeString(" -> ") + res2);
        if (res2 != checkstr2[i]) {
            it_errln("***  test_complex_example res string");
            it_errln(UnicodeString("*** ") + i + UnicodeString(" -> '") + res2 + UnicodeString("' unlike '") + checkstr2[i] + UnicodeString("' ! "));
        }
    }

    const double limits_A[] = {1,2,3,4,5,6,7};
    const UnicodeString monthNames_A[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
    ChoiceFormat* form_A = new ChoiceFormat(limits_A, monthNames_A, 7);
    ChoiceFormat* form_A2 = new ChoiceFormat(limits_A, monthNames_A, 7);
    const double limits_B[] = {1,2,3,4,5,6,7};
    const UnicodeString monthNames_B[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat_BBB"};
    ChoiceFormat* form_B = new ChoiceFormat(limits_B, monthNames_B, 7);
    if (!form_A || !form_B || !form_A2) {
        it_errln("***  test-choiceFormat not allocatable!");
    }else{
        if (*form_A == *form_A2) {
            it_logln("operator== tested.");
        }else{
            it_errln("***  operator==");
        }

        if (*form_A != *form_B) {
            it_logln("operator!= tested.");
        }else{
            it_errln("***  operator!=");
        }

        ChoiceFormat* form_A3 = (ChoiceFormat*) form_A->clone();
        if (!form_A3) {
            it_errln("***  ChoiceFormat->clone is nil.");
        }else{
            if ((*form_A3 == *form_A) && (*form_A3 != *form_B)) {
                it_logln("method clone tested.");
            }else{
                it_errln("***  ChoiceFormat clone or operator==, or operator!= .");
            }
        }

        ChoiceFormat form_Assigned( *form_A );
        UBool ok = (form_Assigned == *form_A) && (form_Assigned != *form_B);
        form_Assigned = *form_B;
        ok = ok && (form_Assigned != *form_A) && (form_Assigned == *form_B);
        if (ok) {
            it_logln("copy constructor and operator= tested.");
        }else{
            it_errln("***  copy constructor or operator= or operator == or operator != .");
        }
        delete form_A3;
    }
    

    delete form_A; delete form_A2; delete form_B; 

    const char* testPattern = "0#none|1#one|2#many";
    ChoiceFormat form_pat( testPattern, status );
    if (!chkstatus( status, "***  ChoiceFormat contructor( newPattern, status)" )) {
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }

    form_pat.toPattern( res1 );
    if (res1 == "0#none|1#one|2#many") {
        it_logln("ChoiceFormat contructor( newPattern, status) tested");
    }else{
        it_errln("***  ChoiceFormat contructor( newPattern, status) or toPattern result!");
    }

    double d_a2[] = { 3.0, 4.0 };
    UnicodeString s_a2[] = { "third", "forth" };

    form_pat.setChoices( d_a2, s_a2, 2 );
    form_pat.toPattern( res1 );
    it_logln(UnicodeString("ChoiceFormat adoptChoices toPattern: ") + res1);
    if (res1 == "3#third|4#forth") {
        it_logln("ChoiceFormat adoptChoices tested");
    }else{
        it_errln("***  ChoiceFormat adoptChoices result!");
    }

    str = "";
    fpos = 0;
    status = U_ZERO_ERROR;
    double arg_double = 3.0;
    res1 = form_pat.format( arg_double, str, fpos );
    it_logln(UnicodeString("ChoiceFormat format:") + res1);
    if (res1 != "third") it_errln("***  ChoiceFormat format (double, ...) result!");

    str = "";
    fpos = 0;
    status = U_ZERO_ERROR;
    int64_t arg_64 = 3;
    res1 = form_pat.format( arg_64, str, fpos );
    it_logln(UnicodeString("ChoiceFormat format:") + res1);
    if (res1 != "third") it_errln("***  ChoiceFormat format (int64_t, ...) result!");

    str = "";
    fpos = 0;
    status = U_ZERO_ERROR;
    int32_t arg_long = 3;
    res1 = form_pat.format( arg_long, str, fpos );
    it_logln(UnicodeString("ChoiceFormat format:") + res1);
    if (res1 != "third") it_errln("***  ChoiceFormat format (int32_t, ...) result!");

    Formattable ft( (int32_t)3 );
    str = "";
    fpos = 0;
    status = U_ZERO_ERROR;
    res1 = form_pat.format( ft, str, fpos, status );
    if (!chkstatus( status, "***  test_complex_example format (int32_t, ...)" )) {
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }
    it_logln(UnicodeString("ChoiceFormat format:") + res1);
    if (res1 != "third") it_errln("***  ChoiceFormat format (Formattable, ...) result!");

    Formattable fta[] = { (int32_t)3 };
    str = "";
    fpos = 0;
    status = U_ZERO_ERROR;
    res1 = form_pat.format( fta, 1, str, fpos, status );
    if (!chkstatus( status, "***  test_complex_example format (int32_t, ...)" )) {
        delete fileform;
        delete filenumform;
        delete pattform;
        return;
    }
    it_logln(UnicodeString("ChoiceFormat format:") + res1);
    if (res1 != "third") it_errln("***  ChoiceFormat format (Formattable[], cnt, ...) result!");

    ParsePosition parse_pos = 0;
    Formattable result;
    UnicodeString parsetext("third");
    form_pat.parse( parsetext, result, parse_pos );
    double rd = (result.getType() == Formattable::kLong) ? result.getLong() : result.getDouble();
    if (rd == 3.0) {
        it_logln("parse( ..., ParsePos ) tested.");
    }else{
        it_errln("*** ChoiceFormat parse( ..., ParsePos )!");
    }

    form_pat.parse( parsetext, result, status );
    rd = (result.getType() == Formattable::kLong) ? result.getLong() : result.getDouble();
    if (rd == 3.0) {
        it_logln("parse( ..., UErrorCode ) tested.");
    }else{
        it_errln("*** ChoiceFormat parse( ..., UErrorCode )!");
    }

    /*
    UClassID classID = ChoiceFormat::getStaticClassID();
    if (classID == form_pat.getDynamicClassID()) {
        it_out << "getStaticClassID and getDynamicClassID tested." << endl;
    }else{
        it_errln("*** getStaticClassID and getDynamicClassID!");
    }
    */

    it_logln();

    delete fileform; 
    delete filenumform;
    delete pattform;
}
Example #26
0
static void umsg_set_timezone(MessageFormatter_object *mfo,
							  intl_error& err)
{
	MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
	TimeZone	  *used_tz = NULL;
	const Format  **formats;
	int32_t		  count;

	/* Unfortanely, this cannot change the time zone for arguments that
	 * appear inside complex formats because ::getFormats() returns NULL
	 * for all uncached formats, which is the case for complex formats
	 * unless they were set via one of the ::setFormat() methods */

	if (mfo->mf_data.tz_set) {
		return; /* already done */
	}

	/* There is a bug in ICU which prevents MessageFormatter::getFormats()
	   to handle more than 10 formats correctly. The enumerator could be
	   used to walk through the present formatters using getFormat(), which
	   however seems to provide just a readonly access. This workaround
	   prevents crash when there are > 10 formats but doesn't set any error.
	   As a result, only DateFormatters with > 10 subformats are affected.
	   This workaround should be ifdef'd out, when the bug has been fixed
	   in ICU. */
	icu::StringEnumeration* fnames = mf->getFormatNames(err.code);
	if (!fnames || U_FAILURE(err.code)) {
		return;
	}
	count = fnames->count(err.code);
	delete fnames;
	if (count > 10) {
		return;
	}

	formats = mf->getFormats(count);

	if (formats == NULL) {
		intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
			"Out of memory retrieving subformats", 0);
	}

	for (int i = 0; U_SUCCESS(err.code) && i < count; i++) {
		DateFormat* df = dynamic_cast<DateFormat*>(
			const_cast<Format *>(formats[i]));
		if (df == NULL) {
			continue;
		}

		if (used_tz == NULL) {
			zval nullzv, *zvptr = &nullzv;
			ZVAL_NULL(zvptr);
			used_tz = timezone_process_timezone_argument(zvptr, &err, "msgfmt_format");
			if (used_tz == NULL) {
				continue;
			}
		}

		df->setTimeZone(*used_tz);
	}

	if (U_SUCCESS(err.code)) {
		mfo->mf_data.tz_set = 1;
	}
}
Example #27
0
UnicodeString&
LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
                                          UnicodeString& result) const {
  UnicodeString resultName;

  const char* lang = locale.getLanguage();
  if (uprv_strlen(lang) == 0) {
    lang = "root";
  }
  const char* script = locale.getScript();
  const char* country = locale.getCountry();
  const char* variant = locale.getVariant();

  UBool hasScript = uprv_strlen(script) > 0;
  UBool hasCountry = uprv_strlen(country) > 0;
  UBool hasVariant = uprv_strlen(variant) > 0;

  if (dialectHandling == ULDN_DIALECT_NAMES) {
    char buffer[ULOC_FULLNAME_CAPACITY];
    do { // loop construct is so we can break early out of search
      if (hasScript && hasCountry) {
        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
        localeIdName(buffer, resultName);
        if (!resultName.isBogus()) {
          hasScript = FALSE;
          hasCountry = FALSE;
          break;
        }
      }
      if (hasScript) {
        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
        localeIdName(buffer, resultName);
        if (!resultName.isBogus()) {
          hasScript = FALSE;
          break;
        }
      }
      if (hasCountry) {
        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
        localeIdName(buffer, resultName);
        if (!resultName.isBogus()) {
          hasCountry = FALSE;
          break;
        }
      }
    } while (FALSE);
  }
  if (resultName.isBogus() || resultName.isEmpty()) {
    localeIdName(lang, resultName);
  }

  UnicodeString resultRemainder;
  UnicodeString temp;
  StringEnumeration *e = NULL;
  UErrorCode status = U_ZERO_ERROR;

  if (hasScript) {
    resultRemainder.append(scriptDisplayName(script, temp));
  }
  if (hasCountry) {
    appendWithSep(resultRemainder, regionDisplayName(country, temp));
  }
  if (hasVariant) {
    appendWithSep(resultRemainder, variantDisplayName(variant, temp));
  }
  resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
  resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);

  e = locale.createKeywords(status);
  if (e && U_SUCCESS(status)) {
    UnicodeString temp2;
    char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY
    const char* key;
    while ((key = e->next((int32_t *)0, status)) != NULL) {
      locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status);
      keyDisplayName(key, temp);
      temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
      temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
      keyValueDisplayName(key, value, temp2);
      temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen);
      temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen);
      if (temp2 != UnicodeString(value, -1, US_INV)) {
        appendWithSep(resultRemainder, temp2);
      } else if (temp != UnicodeString(key, -1, US_INV)) {
        UnicodeString temp3;
        Formattable data[] = {
          temp,
          temp2
        };
        FieldPosition fpos;
        status = U_ZERO_ERROR;
        keyTypeFormat->format(data, 2, temp3, fpos, status);
        appendWithSep(resultRemainder, temp3);
      } else {
        appendWithSep(resultRemainder, temp)
          .append((UChar)0x3d /* = */)
          .append(temp2);
      }
    }
    delete e;
  }

  if (!resultRemainder.isEmpty()) {
    Formattable data[] = {
      resultName,
      resultRemainder
    };
    FieldPosition fpos;
    status = U_ZERO_ERROR;
    format->format(data, 2, result, fpos, status);
    return adjustForUsageAndContext(kCapContextUsageLanguage, result);
  }

  result = resultName;
  return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
Example #28
0
/*
 * This method updates the cache and must be called with a lock
 */
const UChar*
TZGNCore::getGenericLocationName(const UnicodeString& tzCanonicalID) {
    U_ASSERT(!tzCanonicalID.isEmpty());
    if (tzCanonicalID.length() > ZID_KEY_MAX) {
        return NULL;
    }

    UErrorCode status = U_ZERO_ERROR;
    UChar tzIDKey[ZID_KEY_MAX + 1];
    int32_t tzIDKeyLen = tzCanonicalID.extract(tzIDKey, ZID_KEY_MAX + 1, status);
    U_ASSERT(status == U_ZERO_ERROR);   // already checked length above
    tzIDKey[tzIDKeyLen] = 0;

    const UChar *locname = (const UChar *)uhash_get(fLocationNamesMap, tzIDKey);

    if (locname != NULL) {
        // gEmpty indicate the name is not available
        if (locname == gEmpty) {
            return NULL;
        }
        return locname;
    }

    // Construct location name
    UnicodeString name;
    UnicodeString usCountryCode;
    UBool isPrimary = FALSE;

    ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode, &isPrimary);

    if (!usCountryCode.isEmpty()) {
        FieldPosition fpos;

        if (isPrimary) {
            // If this is the primary zone in the country, use the country name.
            char countryCode[ULOC_COUNTRY_CAPACITY];
            U_ASSERT(usCountryCode.length() < ULOC_COUNTRY_CAPACITY);
            int32_t ccLen = usCountryCode.extract(0, usCountryCode.length(), countryCode, sizeof(countryCode), US_INV);
            countryCode[ccLen] = 0;

            UnicodeString country;
            fLocaleDisplayNames->regionDisplayName(countryCode, country);

            Formattable param[] = {
                Formattable(country)
            };

            fRegionFormat->format(param, 1, name, fpos, status);
        } else {
            // If this is not the primary zone in the country,
            // use the exemplar city name.

            // getExemplarLocationName should retur non-empty string
            // if the time zone is associated with a region

            UnicodeString city;
            fTimeZoneNames->getExemplarLocationName(tzCanonicalID, city);

            Formattable param[] = {
                Formattable(city),
            };

            fRegionFormat->format(param, 1, name, fpos, status);
        }
        if (U_FAILURE(status)) {
            return NULL;
        }
    }

    locname = name.isEmpty() ? NULL : fStringPool.get(name, status);
    if (U_SUCCESS(status)) {
        // Cache the result
        const UChar* cacheID = ZoneMeta::findTimeZoneID(tzCanonicalID);
        U_ASSERT(cacheID != NULL);
        if (locname == NULL) {
            // gEmpty to indicate - no location name available
            uhash_put(fLocationNamesMap, (void *)cacheID, (void *)gEmpty, &status);
        } else {
            uhash_put(fLocationNamesMap, (void *)cacheID, (void *)locname, &status);
            if (U_FAILURE(status)) {
                locname = NULL;
            } else {
                // put the name info into the trie
                GNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(GNameInfo));
                if (nameinfo != NULL) {
                    nameinfo->type = UTZGNM_LOCATION;
                    nameinfo->tzID = cacheID;
                    fGNamesTrie.put(locname, nameinfo, status);
                }
            }
        }
    }

    return locname;
}
// test RBNF extensions to message format
void TestMessageFormat::TestRBNF(void) {
    // WARNING: this depends on the RBNF formats for en_US
    Locale locale("en", "US", "");

    UErrorCode ec = U_ZERO_ERROR;

    UnicodeString values[] = {
        // decimal values do not format completely for ordinal or duration, and 
        // do not always parse, so do not include them
        "0", "1", "12", "100", "123", "1001", "123,456", "-17",
    };
    int32_t values_count = sizeof(values)/sizeof(values[0]);

    UnicodeString formats[] = {
        "There are {0,spellout} files to search.",
        "There are {0,spellout,%simplified} files to search.",
        "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.",
        "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse
        "Searching this file will take {0,duration} to complete.",
        "Searching this file will take {0,duration,%with-words} to complete.",
    };
    int32_t formats_count = sizeof(formats)/sizeof(formats[0]);

    Formattable args[1];

    NumberFormat* numFmt = NumberFormat::createInstance(locale, ec);
    if (U_FAILURE(ec)) {
        dataerrln("Error calling NumberFormat::createInstance()");
        return;
    }

    for (int i = 0; i < formats_count; ++i) {
        MessageFormat* fmt = new MessageFormat(formats[i], locale, ec);
        logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'");

        for (int j = 0; j < values_count; ++j) {
            ec = U_ZERO_ERROR;
            numFmt->parse(values[j], args[0], ec);
            if (U_FAILURE(ec)) {
                errln((UnicodeString)"Failed to parse test argument " + values[j]);
            } else {
                FieldPosition fp(0);
                UnicodeString result;
                fmt->format(args, 1, result, fp, ec);
                logln((UnicodeString)"value: " + toString(args[0]) + " --> " + result + UnicodeString(" ec: ") + u_errorName(ec));
               
                if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3)
                    int32_t count = 0;
                    Formattable* parseResult = fmt->parse(result, count, ec);
                    if (count != 1) {
                        errln((UnicodeString)"parse returned " + count + " args");
                    } else if (parseResult[0] != args[0]) {
                        errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0]));
                    }
                    delete []parseResult;
                }
            }
        }
        delete fmt;
    }
    delete numFmt;
}
void TestMessageFormat::PatternTest() 
{
    Formattable testArgs[] = {
        Formattable(double(1)), Formattable(double(3456)),
            Formattable("Disk"), Formattable(UDate((int32_t)1000000000L), Formattable::kIsDate)
    };
    UnicodeString testCases[] = {
       "Quotes '', '{', 'a' {0} '{0}'",
       "Quotes '', '{', 'a' {0,number} '{0}'",
       "'{'1,number,'#',##} {1,number,'#',##}",
       "There are {1} files on {2} at {3}.",
       "On {2}, there are {1} files, with {0,number,currency}.",
       "'{1,number,percent}', {1,number,percent},",
       "'{1,date,full}', {1,date,full},",
       "'{3,date,full}', {3,date,full},",
       "'{1,number,#,##}' {1,number,#,##}",
    };

    UnicodeString testResultPatterns[] = {
        "Quotes '', '{', a {0} '{'0}",
        "Quotes '', '{', a {0,number} '{'0}",
        "'{'1,number,#,##} {1,number,'#'#,##}",
        "There are {1} files on {2} at {3}.",
        "On {2}, there are {1} files, with {0,number,currency}.",
        "'{'1,number,percent}, {1,number,percent},",
        "'{'1,date,full}, {1,date,full},",
        "'{'3,date,full}, {3,date,full},",
        "'{'1,number,#,##} {1,number,#,##}"
    };

    UnicodeString testResultStrings[] = {
        "Quotes ', {, a 1 {0}",
        "Quotes ', {, a 1 {0}",
        "{1,number,#,##} #34,56",
        "There are 3,456 files on Disk at 1/12/70 5:46 AM.",
        "On Disk, there are 3,456 files, with $1.00.",
        "{1,number,percent}, 345,600%,",
        "{1,date,full}, Wednesday, December 31, 1969,",
        "{3,date,full}, Monday, January 12, 1970,",
        "{1,number,#,##} 34,56"
    };


    for (int32_t i = 0; i < 9; ++i) {
        //it_out << "\nPat in:  " << testCases[i]);

        MessageFormat *form = 0;
        UErrorCode success = U_ZERO_ERROR;
        UnicodeString buffer;
        form = new MessageFormat(testCases[i], Locale::getUS(), success);
        if (U_FAILURE(success)) {
            errln("MessageFormat creation failed.#1");
            logln(((UnicodeString)"MessageFormat for ") + testCases[i] + " creation failed.\n");
            continue;
        }
        if (form->toPattern(buffer) != testResultPatterns[i]) {
            errln(UnicodeString("TestMessageFormat::PatternTest failed test #2, i = ") + i);
            //form->toPattern(buffer);
            errln(((UnicodeString)" Orig: ") + testCases[i]);
            errln(((UnicodeString)" Exp:  ") + testResultPatterns[i]);
            errln(((UnicodeString)" Got:  ") + buffer);
        }

        //it_out << "Pat out: " << form->toPattern(buffer));
        UnicodeString result;
        int32_t count = 4;
        FieldPosition fieldpos(0);
        form->format(testArgs, count, result, fieldpos, success);
        if (U_FAILURE(success)) {
            errln("MessageFormat failed test #3");
            logln("TestMessageFormat::PatternTest failed test #3");
            continue;
        }
        if (result != testResultStrings[i]) {
            errln("TestMessageFormat::PatternTest failed test #4");
            logln("TestMessageFormat::PatternTest failed #4.");
            logln(UnicodeString("    Result: ") + result );
            logln(UnicodeString("  Expected: ") + testResultStrings[i] );
        }
        

        //it_out << "Result:  " << result);
#if 0
        /* TODO: Look at this test and see if this is still a valid test */
        logln("---------------- test parse ----------------");

        form->toPattern(buffer);
        logln("MSG pattern for parse: " + buffer);

        int32_t parseCount = 0;
        Formattable* values = form->parse(result, parseCount, success);
        if (U_FAILURE(success)) {
            errln("MessageFormat failed test #5");
            logln(UnicodeString("MessageFormat failed test #5 with error code ")+(int32_t)success);
        } else if (parseCount != count) {
            errln("MSG count not %d as expected. Got %d", count, parseCount);
        }
        UBool failed = FALSE;
        for (int32_t j = 0; j < parseCount; ++j) {
             if (values == 0 || testArgs[j] != values[j]) {
                errln(((UnicodeString)"MSG testargs[") + j + "]: " + toString(testArgs[j]));
                errln(((UnicodeString)"MSG values[") + j + "]  : " + toString(values[j]));
                failed = TRUE;
             }
        }
        if (failed)
            errln("MessageFormat failed test #6");
#endif
        delete form;
    }
}