Changeset 1792


Ignore:
Timestamp:
Jan 28, 2005, 8:07:55 PM (21 years ago)
Author:
bird
Message:

fixes from Lorne.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/locale/setlocale.c

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r1791 r1792  
    7070                             && (s)[4] == 'X' \
    7171                             && (s)[5] == '\0' )
     72#define IS_EURO(s)         ((   (s)[0] == 'E' \
     73                             && (s)[1] == 'U' \
     74                             && (s)[2] == 'R' \
     75                             && (s)[3] == 'O' \
     76                             && (s)[4] == '\0' \
     77                            ) || ( \
     78                                (s)[0] == 'e' \
     79                             && (s)[1] == 'u' \
     80                             && (s)[2] == 'r' \
     81                             && (s)[3] == 'o' \
     82                             && (s)[4] == '\0') )
    7283/** Max lenght we anticipate of a codepage name. */
    7384#define CODEPAGE_MAX_LENGTH     64
     
    221232static void localeNumericFree(__LIBC_PLOCALELCONV pLconv);
    222233static void localeMonetaryFree(__LIBC_PLOCALELCONV pLconv);
    223 static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv);
    224 static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale);
     234static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv, const char *pszLocale);
     235static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale, const char *pszModifier);
    225236static void localeGlobalFree(__LIBC_PLOCALEGLOBAL pGlobal, int iCategory);
    226 static int localeParseLocale(char *pszLocale, const char **ppszCodepage);
    227 static int localeDoOne(struct temp_locale *pTemp, int iCategory, const char *pszLocale, const char *pszCodepage);
     237static int localeParseLocale(char *pszLocale, const char **ppszCodepage, const char **ppszModifier);
     238static int localeDoOne(struct temp_locale *pTemp, int iCategory, const char *pszLocale, const char *pszCodepage, const char *pszModifier);
    228239static int localeDo(struct temp_locale *pTemp, int iCategory, char *pszLocale, int fDefaultValue);
    229240static char *localeCommit(struct temp_locale *pTemp, int iCategory);
     
    822833    FREE(thousands_sep);
    823834    FREE(grouping);
    824                                                                                                                                                                                                                                                                 pLconv->fNumericConsts = 0;
     835
     836    pLconv->fNumericConsts = 0;
    825837#undef FREE
    826838}
     
    874886 * @param   uobj        The UconvObject to use.
    875887 * @param   pULconv     Pointer to the pULconv structure to get the data from.
    876  */
    877 static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv)
     888 * @param   pszLocale   Pointer to the locale base specifier.
     889 */
     890static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv, const char *pszLocale)
    878891{
    879892    int     rc;
     
    881894    localeNumericFree(pLconv);
    882895
    883     /*
    884      * Convert the stuff.
    885      */
     896    if (    !IS_C_LOCALE(pszLocale)
     897        &&  !IS_POSIX_LOCALE(pszLocale))
     898    {
     899        /*
     900         * Convert the stuff.
     901         */
    886902#define CONVERT_UCS(field) \
    887903    do  { rc = convert_ucs(uobj, pULconv->field, &pLconv->s.field); if (rc) return rc; } while (0)
    888     CONVERT_UCS(decimal_point);
    889     CONVERT_UCS(thousands_sep);
     904        CONVERT_UCS(decimal_point);
     905        CONVERT_UCS(thousands_sep);
    890906#undef CONVERT_UCS
    891907
    892     return localeConvertGrouping(pULconv->grouping, &pLconv->s.grouping);
     908        return localeConvertGrouping(pULconv->grouping, &pLconv->s.grouping);
     909    }
     910    else
     911    {
     912        /* the C/POSIX locale */
     913        LIBCLOG_MSG2("POSIX '%s'\n", pszLocale);
     914        pLconv->fNumericConsts        = 1;
     915        pLconv->s.decimal_point       = ".";
     916        pLconv->s.thousands_sep       = ",";
     917        pLconv->s.grouping            = "";
     918        return 0;
     919    }
    893920}
    894921
     
    902929 * @param   uobj        The UconvObject to use.
    903930 * @param   pULconv     Pointer to the pULconv structure to get the data from.
    904  * @param   pszLocale   The locale specifier.
    905  */
    906 static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale)
     931 * @param   pszLocale   The locale base specifier.
     932 * @param   pszModifier The locale modifier.
     933 */
     934static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale, const char *pszModifier)
    907935{
    908936    int rc;
     
    917945         */
    918946#define CONVERT_UCS(field) \
    919         do  { rc = convert_ucs(uobj, pULconv->field, &pLconv->s.field); if (rc) return rc; } while (0)
    920         CONVERT_UCS(int_curr_symbol);
    921         CONVERT_UCS(currency_symbol);
     947    do  { rc = convert_ucs(uobj, pULconv->field, &pLconv->s.field); if (rc) return rc; } while (0)
     948
     949        if (pszModifier && IS_EURO(pszModifier))
     950        {
     951            /** @todo check for specs on a standard EURO grouping and stuff. */
     952            pLconv->s.currency_symbol = strdup("EUR");
     953            pLconv->s.int_curr_symbol = strdup("EUR");
     954        }
     955        else
     956        {
     957            CONVERT_UCS(int_curr_symbol);
     958            CONVERT_UCS(currency_symbol);
     959        }
    922960        CONVERT_UCS(mon_decimal_point);
    923961        CONVERT_UCS(mon_thousands_sep);
     
    950988        pLconv->s.int_curr_symbol = pLconv->s.currency_symbol = pLconv->s.mon_decimal_point
    951989            = pLconv->s.mon_thousands_sep = pLconv->s.positive_sign = pLconv->s.negative_sign
    952             = pLconv->pszCrncyStr = "";
     990            = pLconv->pszCrncyStr = pLconv->s.mon_grouping = "";
    953991        pLconv->s.int_frac_digits   = -1;
    954992        pLconv->s.frac_digits       = -1;
     
    959997        pLconv->s.p_sign_posn       = -1;
    960998        pLconv->s.n_sign_posn       = -1;
    961         return 0;
     999
     1000        return 0;
    9621001    }
    9631002}
     
    9801019 * Parses out the locale spec and the code page spec.
    9811020 */
    982 static int localeParseLocale(char *pszLocale, const char **ppszCodepage)
    983 {
    984     /*
    985      * Strip of modifier.
     1021static int localeParseLocale(char *pszLocale, const char **ppszCodepage, const char **ppszModifier)
     1022{
     1023    /*
     1024     * Modifier.
    9861025     */
    9871026    char *psz = strchr(pszLocale, '@');
    9881027    if (psz)
    9891028    {
    990         LIBCLOG_MSG2("Ignoring locale modifier '%s'\n", psz);
    991         *psz = '\0';
    992     }
     1029        *psz++ = '\0';
     1030        LIBCLOG_MSG2("Using locale modifier '%s'\n", psz);
     1031    }
     1032    *ppszModifier = psz;
    9931033
    9941034    /*
     
    12031243
    12041244/**
    1205  * Performe the locale operation on one category.
    1206  */
    1207 static int localeDoOne(struct temp_locale *pTemp, int iCategory, const char *pszLocale, const char *pszCodepage)
    1208 {
    1209     LIBCLOG_ENTER("pTemp=%p iCategory=%d (%s) pszLocale=%p:{%s} pszCodepage=%p:{%s}\n",
    1210                   (void *)pTemp, iCategory, gaszCategories[iCategory + 1], pszLocale, pszLocale, pszCodepage, pszCodepage);
     1245 * Perform the locale operation on one category.
     1246 */
     1247static int localeDoOne(struct temp_locale *pTemp, int iCategory, const char *pszLocale, const char *pszCodepage, const char *pszModifier)
     1248{
     1249    LIBCLOG_ENTER("pTemp=%p iCategory=%d (%s) pszLocale=%p:{%s} pszCodepage=%p:{%s} pszModifier=%p:{%s}\n",
     1250                  (void *)pTemp, iCategory, gaszCategories[iCategory + 1], pszLocale, pszLocale, pszCodepage, pszCodepage, pszModifier, pszModifier);
    12111251    char            szCodepageActual[CODEPAGE_MAX_LENGTH];
    12121252    UconvObject     uobj;
     
    12551295            {
    12561296                if (iCategory == LC_NUMERIC)
    1257                     rc = localeNumericDo(&pTemp->Lconv, uobj, pULconv);
     1297                    rc = localeNumericDo(&pTemp->Lconv, uobj, pULconv, pszLocale);
    12581298                else
    1259                     rc = localeMonetaryDo(&pTemp->Lconv, uobj, lobj, pULconv, pszLocale);
     1299                    rc = localeMonetaryDo(&pTemp->Lconv, uobj, lobj, pULconv, pszLocale, pszModifier);
    12601300                UniFreeLocaleInfo(pULconv);
    12611301            }
     
    12921332         */
    12931333        localeGlobalFree(&pTemp->Global, iCategory);
    1294         if (!pszCodepage || !*pszCodepage)
    1295         {
    1296             /* (no codepage specified) */
    1297             if (IS_C_LOCALE(pszLocale))
    1298                 pTemp->Global.apszNames[iCategory + 1] = (char *)gszC;
    1299             else if (IS_POSIX_LOCALE(pszLocale))
    1300                 pTemp->Global.apszNames[iCategory + 1] = (char *)gszPOSIX;
    1301             else
    1302             {
    1303                 pTemp->Global.apszNames[iCategory + 1] = strdup(pszLocale);
    1304                 if (!pTemp->Global.apszNames[iCategory + 1])
    1305                     return -ENOMEM;
    1306             }
    1307         }
     1334        if ((!pszCodePage || !*pszCodePage) && IS_C_LOCALE(pszLocale))
     1335            pTemp->Global.apszNames[iCategory + 1] = (char *)gszC;
     1336        else if ((!pszCodePage || !*pszCodePage) && IS_POSIX_LOCALE(pszLocale))
     1337            pTemp->Global.apszNames[iCategory + 1] = (char *)gszPOSIX;
    13081338        else
    1309         {
    1310             /* pszLocale + "." + szCodepageActual. */
     1339        {
     1340            /* pszLocale + "." + szCodepageActual [+ "@" + pszModifier] */
    13111341            int     cch1 = strlen(pszLocale);
    13121342            int     cch2 = strlen(szCodepageActual);
    1313             char   *psz = malloc(cch1 + cch2 + 2);
     1343            int     cch3 = pszModifier ? strlen(pszModifier) : 0;
     1344            char   *psz = pTemp->Global.apszNames[iCategory + 1] = malloc(cch1 + cch2 + cch3 + !!cch3 + 2);
    13141345            if (!psz)
    13151346                return -ENOMEM;
    1316 
     1347            char   *psz = psz;
    13171348            memcpy(psz, pszLocale, cch1);
    1318             psz[cch1] = '.';
    1319             memcpy(psz + cch1 + 1, szCodepageActual, cch2);
    1320             psz[cch1 + 1 + cch2] = '\0';
    1321 
    1322             pTemp->Global.apszNames[iCategory + 1] = psz;
    1323         }
     1349            psz += cch1;
     1350
     1351            *psz++ = '.';
     1352            memcpy(psz, szCodepageActual, cch2);
     1353            psz += cch2;
     1354           
     1355            if (cch3)
     1356            {
     1357                *psz++ = '@';
     1358                memcpy(psz, pszModifier, cch3);
     1359                psz += cch3;
     1360            }
     1361            *psz = '\0';
     1362
     1363            LIBCLOG_MSG2("Setting iCategory='%d''%s' locale value to '%s'\n",
     1364                         iCategory, gaszCategories[iCategory + 1], pTemp->Global.apszNames[iCategory + 1]);
     1365        }
    13241366    }
    13251367
     
    13421384                  (void *)pTemp, iCategory, gaszCategories[iCategory + 1], pszLocale, pszLocale, fDefaultValue);
    13431385    const char *pszCodepage;
     1386    const char *pszModifier;
    13441387    char       *pszNext;
    13451388    int         rc;
     
    13501393    if (iCategory != LC_ALL)
    13511394    {
    1352         rc = localeParseLocale(pszLocale, &pszCodepage);
     1395        rc = localeParseLocale(pszLocale, &pszCodepage, &pszModifier);
    13531396        if (!rc)
    1354             rc = localeDoOne(pTemp, iCategory, pszLocale, pszCodepage);
     1397            rc = localeDoOne(pTemp, iCategory, pszLocale, pszCodepage, pszModifier);
    13551398    }
    13561399    else
     
    13611404         * form "CATEGORY1=value1;CATEGORY2=value2[;...]", where values are
    13621405         * also in XPG format: "language[_territory[.codeset]][@modifier]".
    1363          * Currently we're ignoring the modifier.
     1406         * Currently we're only handling the @EURO/@euro modifiers and ignoring the rest.
    13641407         */
    13651408        pszNext = strchr(pszLocale, ';');
     
    13831426                        char        *pszVal = &pszCur[cch + 1];
    13841427                        const char  *pszValCp;
     1428                        const char  *pszValQual;
    13851429                        /* parse the locale value. */
    1386                         rc = localeParseLocale(pszVal, &pszValCp);
     1430                        rc = localeParseLocale(pszVal, &pszValCp, &pszValQual);
    13871431                        if (!rc)
    13881432                        {
    13891433                            if (iCat != LC_ALL)
    1390                                 rc = localeDoOne(pTemp, iCat, pszVal, pszValCp);
     1434                                rc = localeDoOne(pTemp, iCat, pszVal, pszValCp, pszValQual);
    13911435                            else /* Iterate all categories except LC_ALL. */
    13921436                                for (iCat = LC_ALL + 1; !rc && iCat < _LC_LAST; iCat++)
    1393                                     rc = localeDoOne(pTemp, iCat, pszVal, pszValCp);
     1437                                    rc = localeDoOne(pTemp, iCat, pszVal, pszValCp, pszValQual);
    13941438                        }
    13951439                        break;
     
    14121456             * Parse it first to save time.
    14131457             */
    1414             rc = localeParseLocale(pszLocale, &pszCodepage);
     1458            rc = localeParseLocale(pszLocale, &pszCodepage, &pszModifier);
    14151459            if (!rc)
    14161460            {
     
    14251469                    {
    14261470                        const char *pszCodepageEnv;
     1471                        const char *pszModifierEnv;
    14271472                        char *pszCopy = alloca(strlen(pszEnv) + 1);
    14281473                        if (!pszCopy)
    14291474                            LIBCLOG_RETURN_INT(-ENOMEM);
    1430                         rc = localeParseLocale(strcpy(pszCopy, pszEnv), &pszCodepageEnv);
     1475                        rc = localeParseLocale(strcpy(pszCopy, pszEnv), &pszCodepageEnv, &pszModifierEnv);
    14311476                        if (!rc)
    1432                             rc = localeDoOne(pTemp, iCat, pszCopy, pszCodepageEnv);
     1477                            rc = localeDoOne(pTemp, iCat, pszCopy, pszCodepageEnv, pszModifierEnv);
    14331478                    }
    14341479                    else
    1435                         rc = localeDoOne(pTemp, iCat, pszLocale, pszCodepage);
     1480                        rc = localeDoOne(pTemp, iCat, pszLocale, pszCodepage, pszModifier);
    14361481                }
    14371482            }
     
    15211566    if (pTemp->afProcessed[LC_MESSAGES + 1])
    15221567    {
    1523         pTemp->afProcessed[LC_MONETARY + 1] = 0;
     1568        pTemp->afProcessed[LC_MESSAGES + 1] = 0;
    15241569        gLocale.apszNames[LC_MESSAGES + 1] = pTemp->Global.apszNames[LC_MESSAGES + 1];
    15251570    }
     
    16041649/**
    16051650 * This setlocale() implementation differs from the specs in that any
    1606  * options specified by '@...' is ignored.
     1651 * options specified by '@...' other than EURO/euro is ignored.
    16071652 */
    16081653char *_STD(setlocale)(int iCategory, const char *pszLocale)
     
    17281773                UconvObject     uobj;
    17291774                const char *pszCodepage;
    1730                 int     cch1 = strlen(gLocale.apszNames[LC_CTYPE + 1]);
    1731                 int     cch2 = strlen(gLocale.apszNames[LC_COLLATE + 1]);
    1732                 int     cch = cch1 > cch2 ? cch1 + 1 : cch2 + 1;
     1775                const char *pszModifier;
     1776                int     cch1 = strlen(gLocale.apszNames[LC_CTYPE + 1]) + 1;
     1777                int     cch2 = strlen(gLocale.apszNames[LC_COLLATE + 1]) + 1;
     1778                int     cch = cch1 > cch2 ? cch1 : cch2;
    17331779                char   *psz = alloca(cch);
    17341780                if (!psz)
     
    17381784                    ||  __libc_GLocaleCtype.uobj)
    17391785                {
    1740                     memcpy(psz, gLocale.apszNames[LC_CTYPE + 1], cch1 + 1);
    1741                     localeParseLocale(psz, &pszCodepage);
     1786                    memcpy(psz, gLocale.apszNames[LC_CTYPE + 1], cch);
     1787                    localeParseLocale(psz, &pszCodepage, &pszModifier);
    17421788                    rc = __libc_localeCreateObjects(psz, pszCodepage, NULL, &lobj, &uobj);
    17431789                    if (!rc)
     
    17581804                    ||  __libc_gLocaleCollate.uobj)
    17591805                {
    1760                     memcpy(psz, gLocale.apszNames[LC_COLLATE + 1], cch2 + 1);
    1761                     localeParseLocale(psz, &pszCodepage);
     1806                    memcpy(psz, gLocale.apszNames[LC_COLLATE + 1], cch);
     1807                    localeParseLocale(psz, &pszCodepage, &pszModifier);
    17621808                    rc = __libc_localeCreateObjects(psz, pszCodepage, NULL, &lobj, &uobj);
    17631809                    if (!rc)
Note: See TracChangeset for help on using the changeset viewer.