Changeset 3916


Ignore:
Timestamp:
Oct 24, 2014, 8:40:23 PM (11 years ago)
Author:
bird
Message:

trunk,0.6: Forwardported r3915 (setlocale tweaks), see #292.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/src/lib/locale/setlocale.c

    r3915 r3916  
    548548
    549549static inline unsigned char Transform(LocaleObject lobj, UconvObject uobj,
    550                                       UniChar (* APIENTRY pfnTransFunc) (LocaleObject, UniChar),
     550                                      UniChar (APIENTRY *pfnTransFunc) (const LocaleObject, UniChar),
    551551                                      UniChar uc, unsigned char uchFallback)
    552552{
     
    13771377                    ULONG       cb;
    13781378                    int         rc;
    1379                     FS_VAR()
     1379                    FS_VAR();
    13801380
    13811381                    FS_SAVE_LOAD();
     
    14651465            ULONG   cb;
    14661466            int     rc;
    1467             FS_VAR()
     1467            FS_VAR();
    14681468
    14691469            FS_SAVE_LOAD();
     
    20432043
    20442044
    2045 _FORK_CHILD1(0xffffff00, setlocalForkChild1)
     2045_FORK_CHILD1(0xffffff00, setlocalForkChild1);
    20462046
    20472047/**
  • trunk/libc/src/libc/locale/os2/setlocale.c

    r3871 r3916  
    8484#define CODEPAGE_MAX_LENGTH     64
    8585
     86/** Macro for swapping generic struct field. */
     87#define SWAP_SIMPLE_MEMBERS(a_pHot, a_pCold, a_Type, a_Member) \
     88    do { \
     89        a_Type const Tmp    = (a_pHot)->a_Member; \
     90        (a_pHot)->a_Member  = (a_pCold)->a_Member; \
     91        (a_pCold)->a_Member = Tmp; \
     92    } while (0)
     93
     94/** Macro for swapping a string pointer if the new value differs or differs in
     95 *  it's readonlyness. */
     96#define MAYBE_SWAP_STRING_MEMBERS(a_pHot, a_pCold, a_Member, a_fOverride) \
     97    do { \
     98        char *pszTmp = (a_pHot)->a_Member; \
     99        if ((a_fOverride) || strcmp(pszTmp, (a_pCold)->a_Member) != 0) \
     100        { \
     101            (a_pHot)->a_Member  = (a_pCold)->a_Member; \
     102            (a_pCold)->a_Member = pszTmp; \
     103        } \
     104    } while (0)
     105
     106/** Macro for swapping a fixed array of string pointer if the new value differs
     107 *  or differs in it's readonlyness. */
     108#define MAYBE_SWAP_STRING_ARRAY_MEMBERS(a_pHot, a_pCold, a_apszMember, a_fOverride) \
     109    do { \
     110        unsigned iMember = sizeof((a_pHot)->a_apszMember) / sizeof((a_pHot)->a_apszMember[0]); \
     111        while (iMember-- > 0) \
     112            MAYBE_SWAP_STRING_MEMBERS(a_pHot, a_pCold, a_apszMember[iMember], a_fOverride); \
     113    } while (0)
     114
     115
    86116/*******************************************************************************
    87117*   Structures and Typedefs                                                    *
     
    482512
    483513    return 0;
     514}
     515
     516/**
     517 * Swaps the content of two locale collate structures.
     518 *
     519 * @param   pHot        The hot structure (target).
     520 * @param   pCold       The cold structure (source, will be freed).
     521 */
     522static void localeCollateSwap(__LIBC_LOCALECOLLATE *pHot, __LIBC_PLOCALECOLLATE pCold)
     523{
     524    __LIBC_LOCALECOLLATE Tmp;
     525    memcpy(&Tmp, pHot, sizeof(Tmp));
     526    memcpy(pHot, pCold, sizeof(Tmp));
     527    memcpy(pCold, &Tmp, sizeof(Tmp));
    484528}
    485529
     
    721765}
    722766
     767/**
     768 * Swaps the content of two locale Ctype structures.
     769 *
     770 * @param   pHot        The hot structure (target).
     771 * @param   pCold       The cold structure (source, will be freed).
     772 */
     773static void localeCtypeSwap(__LIBC_LOCALECTYPE *pHot, __LIBC_PLOCALECTYPE pCold)
     774{
     775    __LIBC_LOCALECTYPE Tmp;
     776    memcpy(&Tmp, pHot, sizeof(Tmp));
     777    memcpy(pHot, pCold, sizeof(Tmp));
     778    memcpy(pCold, &Tmp, sizeof(Tmp));
     779}
    723780
    724781/**
     
    841898
    842899/**
     900 * Commits the changed LC_TIME locale attributes.
     901 *
     902 * @param   pHot        The hot structure (target).
     903 * @param   pCold       The cold structure (source, will be freed).
     904 */
     905static void localeTimeCommit(__LIBC_LOCALETIME *pHot, __LIBC_PLOCALETIME pCold)
     906{
     907    int const fOverride = pHot->fConsts != pCold->fConsts;
     908    SWAP_SIMPLE_MEMBERS(pHot, pCold, int, fConsts);
     909    MAYBE_SWAP_STRING_ARRAY_MEMBERS(pHot, pCold, smonths, fOverride);
     910    MAYBE_SWAP_STRING_ARRAY_MEMBERS(pHot, pCold, lmonths, fOverride);
     911    MAYBE_SWAP_STRING_ARRAY_MEMBERS(pHot, pCold, swdays, fOverride);
     912    MAYBE_SWAP_STRING_ARRAY_MEMBERS(pHot, pCold, lwdays, fOverride);
     913    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, date_time_fmt, fOverride);
     914    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, date_fmt, fOverride);
     915    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, time_fmt, fOverride);
     916    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, am, fOverride);
     917    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, pm, fOverride);
     918    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, ampm_fmt, fOverride);
     919    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, era, fOverride);
     920    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, era_date_fmt, fOverride);
     921    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, era_date_time_fmt, fOverride);
     922    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, era_time_fmt, fOverride);
     923    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, alt_digits, fOverride);
     924    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, datesep, fOverride);
     925    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, timesep, fOverride);
     926    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, listsep, fOverride);
     927}
     928
     929/**
    843930 * Frees the CRT resources held up by a time structure.
    844931 * @param   pTime   The time structure.
     
    853940        char **ppsz = (char **)pTime;
    854941        char **ppszEnd = (char **)pTime->fConsts;
    855         while (ppsz < ppszEnd)
     942        while ((uintptr_t)ppsz < (uintptr_t)ppszEnd)
    856943        {
    857944            void *pv = *ppsz;
     
    868955
    869956/**
     957 * Commits the changed LC_NUMERIC locale attributes.
     958 *
     959 * @param   pHot        The hot structure (target).
     960 * @param   pCold       The cold structure (source, will be freed).
     961 */
     962static void localeNumericCommit(__LIBC_LOCALELCONV volatile *pHot, __LIBC_PLOCALELCONV pCold)
     963{
     964    int const fOverride = pHot->fNumericConsts != pCold->fNumericConsts;
     965    SWAP_SIMPLE_MEMBERS(pHot, pCold, int, fNumericConsts);
     966    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, s.decimal_point, fOverride);
     967    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, s.thousands_sep, fOverride);
     968    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, s.grouping, fOverride);
     969}
     970
     971/**
    870972 * Frees all heap strings in the monetary part of the lconv structure.
    871973 * @param   pLconv  What to work on.
     
    880982    pLconv->fNumericConsts = 0;
    881983#undef FREE
     984}
     985
     986/**
     987 * Commits the changed LC_MONETARY locale attributes.
     988 *
     989 * @param   pHot        The hot structure (target).
     990 * @param   pCold       The cold structure (source, will be freed).
     991 */
     992static void localeMonetaryCommit(__LIBC_LOCALELCONV volatile *pHot, __LIBC_PLOCALELCONV pCold)
     993{
     994    int const fOverride = pHot->fMonetaryConsts != pCold->fMonetaryConsts;
     995    SWAP_SIMPLE_MEMBERS(pHot, pCold, int,    fMonetaryConsts);
     996    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.int_curr_symbol, fOverride);
     997    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.currency_symbol, fOverride);
     998    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.mon_decimal_point, fOverride);
     999    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.mon_thousands_sep, fOverride);
     1000    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.mon_grouping, fOverride);
     1001    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.positive_sign, fOverride);
     1002    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   s.negative_sign, fOverride);
     1003    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_frac_digits);
     1004    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.frac_digits);
     1005    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.p_cs_precedes);
     1006    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.p_sep_by_space);
     1007    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.n_cs_precedes);
     1008    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.n_sep_by_space);
     1009    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.p_sign_posn);
     1010    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.n_sign_posn);
     1011    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_p_cs_precedes);
     1012    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_n_cs_precedes);
     1013    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_p_sep_by_space);
     1014    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_n_sep_by_space);
     1015    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_p_sign_posn);
     1016    SWAP_SIMPLE_MEMBERS(pHot, pCold, char,   s.int_n_sign_posn);
     1017    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold,   pszCrncyStr, fOverride);
    8821018}
    8831019
     
    10711207
    10721208/**
     1209 * Commits the changed LC_MESSAGES locale attributes.
     1210 *
     1211 * @param   pHot        The hot structure (target).
     1212 * @param   pCold       The cold structure (source, will be freed).
     1213 */
     1214static void localeMessagesCommit(__LIBC_LOCALEMSG *pHot, __LIBC_PLOCALEMSG pCold)
     1215{
     1216    int const fOverride = pHot->fConsts != pCold->fConsts;
     1217    SWAP_SIMPLE_MEMBERS(pHot, pCold, int, fConsts);
     1218    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, pszYesExpr, fOverride);
     1219    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, pszNoExpr, fOverride);
     1220    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, pszYesStr, fOverride);
     1221    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, pszNoStr, fOverride);
     1222}
     1223
     1224/**
    10731225 * Frees all heap strings in the monetary part of the lconv structure.
    10741226 * @param   pLconv  What to work on.
     
    11261278
    11271279    return 0;
     1280}
     1281
     1282
     1283/**
     1284 * Swaps the locate name between two locale instances unless they are equal.
     1285 *
     1286 * @param   pHot        The hot structure (target).
     1287 * @param   pCold       The cold structure (source, will be freed).
     1288 * @param   iCategory   The cateogry which name shall be swapped.
     1289 */
     1290static void localeGlobalNameCommit(__LIBC_LOCALEGLOBAL volatile *pHot, __LIBC_PLOCALEGLOBAL pCold, int iCategory)
     1291{
     1292    MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, apszNames[iCategory + 1], 0);
    11281293}
    11291294
     
    16551820
    16561821    /*
    1657      * Copy all the data.
     1822     * Swap all the data (caller frees the old data).
    16581823     */
    16591824    if (pTemp->afProcessed[LC_COLLATE + 1])
    16601825    {
    1661         localeCollateFree(&__libc_gLocaleCollate);
    1662         memcpy(&__libc_gLocaleCollate, &pTemp->Collate, sizeof(__libc_gLocaleCollate));
    1663         pTemp->afProcessed[LC_COLLATE + 1] = 0;
    1664         gLocale.apszNames[LC_COLLATE + 1] = pTemp->Global.apszNames[LC_COLLATE + 1];
     1826        localeCollateSwap(&__libc_gLocaleCollate, &pTemp->Collate);
     1827        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_COLLATE);
    16651828    }
    16661829
    16671830    if (pTemp->afProcessed[LC_CTYPE + 1])
    16681831    {
    1669         localeCtypeFree(&__libc_GLocaleCtype);
    1670         memcpy(&__libc_GLocaleCtype, &pTemp->Ctype, sizeof(__libc_GLocaleCtype));
    16711832        MB_CUR_MAX = pTemp->Ctype.mbcs ? pTemp->Ctype.mbcs : 1;
    16721833        if (    IS_C_LOCALE(pTemp->Global.apszNames[LC_CTYPE + 1])
     
    16751836        else
    16761837            __libc_GLocaleWCtype.uMask = ~0xffU;
    1677         pTemp->afProcessed[LC_CTYPE + 1] = 0;
    1678         gLocale.apszNames[LC_CTYPE + 1] = pTemp->Global.apszNames[LC_CTYPE + 1];
     1838
     1839        localeCtypeSwap(&__libc_GLocaleCtype, &pTemp->Ctype);
     1840        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_CTYPE);
    16791841    }
    16801842
    16811843    if (pTemp->afProcessed[LC_TIME + 1])
    16821844    {
    1683         localeTimeFree(&__libc_gLocaleTime);
    1684         memcpy(&__libc_gLocaleTime, &pTemp->Time, sizeof(__libc_gLocaleTime));
    1685         pTemp->afProcessed[LC_TIME + 1] = 0;
    1686         gLocale.apszNames[LC_TIME + 1] = pTemp->Global.apszNames[LC_TIME + 1];
     1845        localeTimeCommit(&__libc_gLocaleTime, &pTemp->Time);
     1846        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_TIME);
    16871847    }
    16881848
    16891849    if (pTemp->afProcessed[LC_NUMERIC + 1])
    16901850    {
    1691         localeNumericFree(&__libc_gLocaleLconv);
    1692         __libc_gLocaleLconv.fNumericConsts   = pTemp->Lconv.fNumericConsts;
    1693         __libc_gLocaleLconv.s.decimal_point  = pTemp->Lconv.s.decimal_point;
    1694         __libc_gLocaleLconv.s.thousands_sep  = pTemp->Lconv.s.thousands_sep;
    1695         __libc_gLocaleLconv.s.grouping       = pTemp->Lconv.s.grouping;
    1696         pTemp->afProcessed[LC_NUMERIC + 1] = 0;
    1697         gLocale.apszNames[LC_NUMERIC + 1] = pTemp->Global.apszNames[LC_NUMERIC + 1];
     1851        localeNumericCommit(&__libc_gLocaleLconv, &pTemp->Lconv);
     1852        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_NUMERIC);
    16981853    }
    16991854
    17001855    if (pTemp->afProcessed[LC_MONETARY + 1])
    17011856    {
    1702         localeMonetaryFree(&__libc_gLocaleLconv);
    1703         __libc_gLocaleLconv.fMonetaryConsts      = pTemp->Lconv.fMonetaryConsts;
    1704         __libc_gLocaleLconv.s.int_curr_symbol    = pTemp->Lconv.s.int_curr_symbol;
    1705         __libc_gLocaleLconv.s.currency_symbol    = pTemp->Lconv.s.currency_symbol;
    1706         __libc_gLocaleLconv.s.mon_decimal_point  = pTemp->Lconv.s.mon_decimal_point;
    1707         __libc_gLocaleLconv.s.mon_thousands_sep  = pTemp->Lconv.s.mon_thousands_sep;
    1708         __libc_gLocaleLconv.s.mon_grouping       = pTemp->Lconv.s.mon_grouping;
    1709         __libc_gLocaleLconv.s.positive_sign      = pTemp->Lconv.s.positive_sign;
    1710         __libc_gLocaleLconv.s.negative_sign      = pTemp->Lconv.s.negative_sign;
    1711         __libc_gLocaleLconv.s.int_frac_digits    = pTemp->Lconv.s.int_frac_digits;
    1712         __libc_gLocaleLconv.s.frac_digits        = pTemp->Lconv.s.frac_digits;
    1713         __libc_gLocaleLconv.s.p_cs_precedes      = pTemp->Lconv.s.p_cs_precedes;
    1714         __libc_gLocaleLconv.s.p_sep_by_space     = pTemp->Lconv.s.p_sep_by_space;
    1715         __libc_gLocaleLconv.s.n_cs_precedes      = pTemp->Lconv.s.n_cs_precedes;
    1716         __libc_gLocaleLconv.s.n_sep_by_space     = pTemp->Lconv.s.n_sep_by_space;
    1717         __libc_gLocaleLconv.s.p_sign_posn        = pTemp->Lconv.s.p_sign_posn;
    1718         __libc_gLocaleLconv.s.n_sign_posn        = pTemp->Lconv.s.n_sign_posn;
    1719         __libc_gLocaleLconv.s.int_p_cs_precedes  = pTemp->Lconv.s.int_p_cs_precedes;
    1720         __libc_gLocaleLconv.s.int_n_cs_precedes  = pTemp->Lconv.s.int_n_cs_precedes;
    1721         __libc_gLocaleLconv.s.int_p_sep_by_space = pTemp->Lconv.s.int_p_sep_by_space;
    1722         __libc_gLocaleLconv.s.int_n_sep_by_space = pTemp->Lconv.s.int_n_sep_by_space;
    1723         __libc_gLocaleLconv.s.int_p_sign_posn    = pTemp->Lconv.s.int_p_sign_posn;
    1724         __libc_gLocaleLconv.s.int_n_sign_posn    = pTemp->Lconv.s.int_n_sign_posn;
    1725         __libc_gLocaleLconv.pszCrncyStr          = pTemp->Lconv.pszCrncyStr;
    1726         pTemp->afProcessed[LC_MONETARY + 1] = 0;
    1727         gLocale.apszNames[LC_MONETARY + 1] = pTemp->Global.apszNames[LC_MONETARY + 1];
     1857        localeMonetaryCommit(&__libc_gLocaleLconv, &pTemp->Lconv);
     1858        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_MONETARY);
    17281859    }
    17291860    if (pTemp->afProcessed[LC_MESSAGES + 1])
    17301861    {
    1731         localeMessagesFree(&__libc_gLocaleMsg);
    1732         memcpy(&__libc_gLocaleMsg, &pTemp->Msg, sizeof(__libc_gLocaleMsg));
    1733         pTemp->afProcessed[LC_MESSAGES + 1] = 0;
    1734         gLocale.apszNames[LC_MESSAGES + 1] = pTemp->Global.apszNames[LC_MESSAGES + 1];
    1735     }
    1736 
     1862        localeMessagesCommit(&__libc_gLocaleMsg, &pTemp->Msg);
     1863        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_MESSAGES);
     1864    }
    17371865
    17381866    /*
     
    17701898        }
    17711899        *psz = '\0';
    1772         localeGlobalFree(&gLocale, LC_ALL);
    1773         gLocale.apszNames[LC_ALL + 1] = pszAll;
     1900        pTemp->Global.apszNames[LC_ALL + 1] = pszAll;
     1901        localeGlobalNameCommit(&gLocale, &pTemp->Global, LC_ALL);
    17741902    }
    17751903    else if (strcmp(gLocale.apszNames[LC_ALL + 1], pszAll))
    17761904    {
    1777         localeGlobalFree(&gLocale, LC_ALL);
     1905        pTemp->Global.apszNames[LC_ALL + 1] = gLocale.apszNames[LC_ALL + 1];
    17781906        gLocale.apszNames[LC_ALL + 1] = strdup(pszAll);
    17791907    }
     
    18081936    if (pTemp->afProcessed[LC_MESSAGES + 1])
    18091937        localeMessagesFree(&pTemp->Msg);
     1938    localeGlobalFree(&pTemp->Global, LC_ALL);
    18101939    for (iCat = 0; iCat < _LC_LAST; iCat++)
    18111940        if (pTemp->afProcessed[iCat + 1])
     
    18161945/**
    18171946 * This setlocale() implementation differs from the specs in that any
    1818  * options specified by '@...' other than EURO/euro is ignored.
     1947 * options specified by '@...' other than EURO/euro are ignored.
    18191948 */
    18201949char *_STD(setlocale)(int iCategory, const char *pszLocale)
Note: See TracChangeset for help on using the changeset viewer.