示例#1
0
文件: capi.c 项目: MIPS/external-icu
void capi() {
    UNumberFormat *fmt;
    UErrorCode status = U_ZERO_ERROR;
    /* The string "987654321.123" as UChars */
    UChar str[] = { 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33,
                    0x32, 0x31, 0x30, 0x2E, 0x31, 0x32, 0x33, 0 };
    UChar buf[256];
    int32_t needed;
    double a;
    
    /* Create a formatter for the US locale */
    fmt = unum_open(
          UNUM_DECIMAL,      /* style         */
          0,                 /* pattern       */
          0,                 /* patternLength */
          "en_US",           /* locale        */
          0,                 /* parseErr      */
          &status);
    if (U_FAILURE(status)) {
        printf("FAIL: unum_open\n");
        exit(1);
    }

    /* Use the formatter to parse a number.  When using the C API,
       we have to specify whether we want a double or a long in advance.

       We pass in NULL for the position pointer in order to get the
       default behavior which is to parse from the start. */
    a = unum_parseDouble(fmt, str, u_strlen(str), NULL, &status);
    if (U_FAILURE(status)) {
        printf("FAIL: unum_parseDouble\n");
        exit(1);
    }

    /* Show the result */
    printf("unum_parseDouble(\"");
    uprintf(str);
    printf("\") => %g\n", a);

    /* Use the formatter to format the same number back into a string
       in the US locale.  The return value is the buffer size needed.
       We're pretty sure we have enough space, but in a production
       application one would check this value.

       We pass in NULL for the UFieldPosition pointer because we don't
       care to receive that data. */
    needed = unum_formatDouble(fmt, a, buf, 256, NULL, &status);
    if (U_FAILURE(status)) {
        printf("FAIL: format_parseDouble\n");
        exit(1);
    }

    /* Show the result */
    printf("unum_formatDouble(%g) => \"", a);
    uprintf(buf);
    printf("\"\n");

    /* Release the storage used by the formatter */
    unum_close(fmt);
}
示例#2
0
static Variant HHVM_METHOD(NumberFormatter, parse,
                           const String& value, int64_t type,
                           VRefParam position) {
  NUMFMT_GET(obj, this_, false);
  UErrorCode error = U_ZERO_ERROR;
  icu::UnicodeString val(u16(value, error));
  NUMFMT_CHECK(obj, error, false);
  Variant ret;
  int32_t pos = position.toInt64();
  error = U_ZERO_ERROR;
  switch (type) {
    case UNUM(TYPE_INT32):
      ret = unum_parse(obj->formatter(), val.getBuffer(), val.length(),
                       &pos, &error);
      break;
    case UNUM(TYPE_INT64):
      ret = unum_parseInt64(obj->formatter(), val.getBuffer(), val.length(),
                            &pos, &error);
      break;
    case UNUM(TYPE_DOUBLE):
      ret = unum_parseDouble(obj->formatter(), val.getBuffer(), val.length(),
                             &pos, &error);
      break;
    default:
      obj->setError(U_UNSUPPORTED_ERROR);
      return false;
  }
  NUMFMT_CHECK(obj, error, false);
  position = pos;
  return ret;
}
示例#3
0
文件: uscanf_p.c 项目: 119120119/node
static int32_t
u_scanf_spellout_handler(UFILE          *input,
                         u_scanf_spec_info *info,
                         ufmt_args      *args,
                         const UChar    *fmt,
                         int32_t        *fmtConsumed,
                         int32_t        *argConverted)
{
    int32_t         len;
    double          num;
    UNumberFormat   *format;
    int32_t         parsePos    = 0;
    int32_t         skipped;
    UErrorCode      status      = U_ZERO_ERROR;


    /* skip all ws in the input */
    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);

    /* fill the input's internal buffer */
    ufile_fill_uchar_buffer(input);

    /* determine the size of the input's buffer */
    len = (int32_t)(input->str.fLimit - input->str.fPos);

    /* truncate to the width, if specified */
    if(info->fWidth != -1)
        len = ufmt_min(len, info->fWidth);

    /* get the formatter */
    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SPELLOUT);

    /* handle error */
    if(format == 0)
        return 0;

    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
    /* This is not applicable to RBNF. */
    /*skipped += u_scanf_skip_leading_positive_sign(input, format, &status);*/

    /* parse the number */
    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);

    if (!info->fSkipArg) {
        *(double*)(args[0].ptrValue) = num;
    }

    /* mask off any necessary bits */
    /*  if(! info->fIsLong_double)
    num &= DBL_MAX;*/

    /* update the input's position to reflect consumed data */
    input->str.fPos += parsePos;

    /* we converted 1 arg */
    *argConverted = !info->fSkipArg;
    return parsePos + skipped;
}
JSValue IntlPluralRules::select(ExecState& exec, double value)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // 13.1.4 ResolvePlural (pluralRules, n)
    // https://tc39.github.io/ecma402/#sec-resolveplural
    if (!m_initializedPluralRules)
        return throwTypeError(&exec, scope, "Intl.PluralRules.prototype.select called on value that's not an object initialized as a PluralRules"_s);

    if (!std::isfinite(value))
        return jsNontrivialString(&exec, "other"_s);

#if HAVE(ICU_PLURALRULES_WITH_FORMAT)
    UErrorCode status = U_ZERO_ERROR;
    Vector<UChar, 8> result(8);
    auto length = uplrules_selectWithFormat(m_pluralRules.get(), value, m_numberFormat.get(), result.data(), result.size(), &status);
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to select plural value"_s);
#else
    UErrorCode status = U_ZERO_ERROR;
    Vector<UChar, 32> buffer(32);
    auto length = unum_formatDouble(m_numberFormat.get(), value, buffer.data(), buffer.size(), nullptr, &status);
    if (status == U_BUFFER_OVERFLOW_ERROR) {
        buffer.grow(length);
        status = U_ZERO_ERROR;
        unum_formatDouble(m_numberFormat.get(), value, buffer.data(), length, nullptr, &status);
    }
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to select plural value"_s);

    double formatted = unum_parseDouble(m_numberFormat.get(), buffer.data(), length, nullptr, &status);
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to select plural value"_s);

    // Can only be 'zero', 'one', 'two', 'few', 'many' or 'other'
    status = U_ZERO_ERROR;
    Vector<UChar, 8> result(8);
    length = uplrules_select(m_pluralRules.get(), formatted, result.data(), result.size(), &status);
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to select plural value"_s);
#endif

    return jsString(&exec, String(result.data(), length));
}
示例#5
0
文件: cnmdptst.c 项目: winlibs/icu4c
/* Test exponential pattern*/
static void TestExponential(void)
{
    int32_t pat_length, val_length, lval_length;
    int32_t ival, ilval, p, v, lneed;
    UNumberFormat *fmt;
    int32_t ppos;
    UChar *upat;
    UChar pattern[20];
    UChar *str=NULL;
    UChar uvalfor[20], ulvalfor[20];
    char tempMsgBug[256];
    double a;
    UErrorCode status = U_ZERO_ERROR;
#if U_PLATFORM == U_PF_OS390
    static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 };
#else
    static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
#endif
    static const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
    static const int32_t lval[] = { 0, -1, 1, 123456789 };

    static const char* valFormat[] =
    {
        "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
        "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
        "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
        "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
    };
    static const char* lvalFormat[] =
    {
        "0E0", "-1E0", "1E0", "1.2346E8",
        "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
        "0E000", "-1E000", "1E000", "123.4568E006",
        "0E0", "[1E0]", "1E0", "1.235E8"
    };
    static const double valParse[] =
    {
#if U_PLATFORM == U_PF_OS390
        0.01234, 123460000, 1.23E75, -3.1416E-78,
        0.01234, 123460000, 1.23E75, -3.1416E-78,
        0.01234, 123456800, 1.23E75, -3.141593E-78,
        0.01234, 123500000, 1.23E75, -3.142E-78
#else
        /* We define the whole IEEE 754 number in the 4th column because
        Visual Age 7 has a bug in rounding numbers. */
        0.01234, 123460000, 1.23E300, -3.1415999999999999E-271,
        0.01234, 123460000, 1.23E300, -3.1415999999999999E-271,
        0.01234, 123456800, 1.23E300, -3.1415929999999999E-271,
        0.01234, 123500000, 1.23E300, -3.1420000000000001E-271
#endif
    };
    static const int32_t lvalParse[] =
    {
        0, -1, 1, 123460000,
            0, -1, 1, 123460000,
            0, -1, 1, 123456800,
            0, -1, 1, 123500000
    };


    pat_length = UPRV_LENGTHOF(pat);
    val_length = UPRV_LENGTHOF(val);
    lval_length = UPRV_LENGTHOF(lval);
    ival = 0;
    ilval = 0;
    for (p=0; p < pat_length; ++p)
    {
        upat=(UChar*)malloc(sizeof(UChar) * (strlen(pat[p])+1) );
        u_uastrcpy(upat, pat[p]);
        fmt=unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status);
        if (U_FAILURE(status)) {
            log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status));
            continue;
        }
        lneed= u_strlen(upat) + 1;
        unum_toPattern(fmt, FALSE, pattern, lneed, &status);
        log_verbose("Pattern \" %s \" -toPattern-> \" %s \" \n", upat, u_austrcpy(tempMsgBug, pattern) );
        for (v=0; v<val_length; ++v)
        {
            /*format*/
            lneed=0;
            lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status);
            if(status==U_BUFFER_OVERFLOW_ERROR){
                status=U_ZERO_ERROR;
                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
                unum_formatDouble(fmt, val[v], str, lneed+1,  NULL, &status);
            }
            if(U_FAILURE(status)) {
                log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
            }



            u_uastrcpy(uvalfor, valFormat[v+ival]);
            if(u_strcmp(str, uvalfor) != 0)
                log_verbose("FAIL: Expected %s ( %s )\n", valFormat[v+ival], u_austrcpy(tempMsgBug, uvalfor) );

            /*parsing*/
            ppos=0;
            a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
            if (ppos== u_strlen(str)) {
                if (a != valParse[v+ival])
                    log_err("FAIL: Expected: %e, Got: %g\n", valParse[v+ival], a);
            }
            else
                log_err(" FAIL: Partial parse (  %d  chars ) ->  %e\n",  ppos, a);

            free(str);
        }
        for (v=0; v<lval_length; ++v)
        {
            /*format*/
            lneed=0;
            lneed=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status);
            if(status==U_BUFFER_OVERFLOW_ERROR){
                status=U_ZERO_ERROR;
                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
                unum_formatDouble(fmt, lval[v], str, lneed+1,  NULL, &status);
            }
            if(U_FAILURE(status)) {
                log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
            }
            /*printf(" Format %e -> %s\n",  lval[v], austrdup(str) );*/
            u_uastrcpy(ulvalfor, lvalFormat[v+ilval]);
            if(u_strcmp(str, ulvalfor) != 0)
                log_err("FAIL: Expected %s ( %s )\n", valFormat[v+ilval], austrdup(ulvalfor) );

            /*parsing*/
            ppos=0;
            a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
            if (ppos== u_strlen(str)) {
                /*printf(" Parse -> %e\n",  a);*/
                if (a != lvalParse[v+ilval])
                    log_err("FAIL: Expected : %e\n", valParse[v+ival]);
            }
            else
                log_err(" FAIL: Partial parse (  %d  chars ) ->  %e\n",  ppos, a);

            free(str);

        }
        ival += val_length;
        ilval += lval_length;
        unum_close(fmt);
        free(upat);
    }
}
示例#6
0
文件: uscanf_p.c 项目: 119120119/node
static int32_t
u_scanf_scidbl_handler(UFILE        *input,
                       u_scanf_spec_info *info,
                       ufmt_args    *args,
                       const UChar  *fmt,
                       int32_t      *fmtConsumed,
                       int32_t      *argConverted)
{
    int32_t       len;
    double        num;
    UNumberFormat *scientificFormat, *genericFormat;
    /*int32_t       scientificResult, genericResult;*/
    double        scientificResult, genericResult;
    int32_t       scientificParsePos = 0, genericParsePos = 0, parsePos = 0;
    int32_t       skipped;
    UErrorCode    scientificStatus = U_ZERO_ERROR;
    UErrorCode    genericStatus = U_ZERO_ERROR;


    /* since we can't determine by scanning the characters whether */
    /* a number was formatted in the 'f' or 'g' styles, parse the */
    /* string with both formatters, and assume whichever one */
    /* parsed the most is the correct formatter to use */


    /* skip all ws in the input */
    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);

    /* fill the input's internal buffer */
    ufile_fill_uchar_buffer(input);

    /* determine the size of the input's buffer */
    len = (int32_t)(input->str.fLimit - input->str.fPos);

    /* truncate to the width, if specified */
    if(info->fWidth != -1)
        len = ufmt_min(len, info->fWidth);

    /* get the formatters */
    scientificFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC);
    genericFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL);

    /* handle error */
    if(scientificFormat == 0 || genericFormat == 0)
        return 0;

    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
    skipped += u_scanf_skip_leading_positive_sign(input, genericFormat, &genericStatus);

    /* parse the number using each format*/

    scientificResult = unum_parseDouble(scientificFormat, input->str.fPos, len,
        &scientificParsePos, &scientificStatus);

    genericResult = unum_parseDouble(genericFormat, input->str.fPos, len,
        &genericParsePos, &genericStatus);

    /* determine which parse made it farther */
    if(scientificParsePos > genericParsePos) {
        /* stash the result in num */
        num = scientificResult;
        /* update the input's position to reflect consumed data */
        parsePos += scientificParsePos;
    }
    else {
        /* stash the result in num */
        num = genericResult;
        /* update the input's position to reflect consumed data */
        parsePos += genericParsePos;
    }
    input->str.fPos += parsePos;

    if (!info->fSkipArg) {
        if (info->fIsLong)
            *(double*)(args[0].ptrValue) = num;
        else if (info->fIsLongDouble)
            *(long double*)(args[0].ptrValue) = num;
        else
            *(float*)(args[0].ptrValue) = (float)num;
    }

    /* mask off any necessary bits */
    /*  if(! info->fIsLong_double)
    num &= DBL_MAX;*/

    /* we converted 1 arg */
    *argConverted = !info->fSkipArg;
    return parsePos + skipped;
}
示例#7
0
文件: uscanf_p.c 项目: 119120119/node
static int32_t
u_scanf_scientific_handler(UFILE        *input,
                           u_scanf_spec_info *info,
                           ufmt_args    *args,
                           const UChar  *fmt,
                           int32_t      *fmtConsumed,
                           int32_t      *argConverted)
{
    int32_t         len;
    double          num;
    UNumberFormat   *format;
    int32_t         parsePos    = 0;
    int32_t         skipped;
    UErrorCode      status      = U_ZERO_ERROR;
    UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
    int32_t srcLen, expLen;
    UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE];


    /* skip all ws in the input */
    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);

    /* fill the input's internal buffer */
    ufile_fill_uchar_buffer(input);

    /* determine the size of the input's buffer */
    len = (int32_t)(input->str.fLimit - input->str.fPos);

    /* truncate to the width, if specified */
    if(info->fWidth != -1)
        len = ufmt_min(len, info->fWidth);

    /* get the formatter */
    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC);

    /* handle error */
    if(format == 0)
        return 0;

    /* set the appropriate flags on the formatter */

    srcLen = unum_getSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        srcExpBuf,
        sizeof(srcExpBuf),
        &status);

    /* Upper/lower case the e */
    if (info->fSpec == (UChar)0x65 /* e */) {
        expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            input->str.fBundle.fLocale,
            &status);
    }
    else {
        expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            input->str.fBundle.fLocale,
            &status);
    }

    unum_setSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        expBuf,
        expLen,
        &status);




    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
    skipped += u_scanf_skip_leading_positive_sign(input, format, &status);

    /* parse the number */
    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);

    if (!info->fSkipArg) {
        if (info->fIsLong)
            *(double*)(args[0].ptrValue) = num;
        else if (info->fIsLongDouble)
            *(long double*)(args[0].ptrValue) = num;
        else
            *(float*)(args[0].ptrValue) = (float)num;
    }

    /* mask off any necessary bits */
    /*  if(! info->fIsLong_double)
    num &= DBL_MAX;*/

    /* update the input's position to reflect consumed data */
    input->str.fPos += parsePos;

    /* we converted 1 arg */
    *argConverted = !info->fSkipArg;
    return parsePos + skipped;
}