Changeset 3915
- Timestamp:
- Oct 24, 2014, 8:27:59 PM (10 years ago)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified branches/libc-0.6/src/emx/src/lib/locale/setlocale.c ¶
r3788 r3915 84 84 #define CODEPAGE_MAX_LENGTH 64 85 85 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 86 116 /******************************************************************************* 87 117 * Structures and Typedefs * … … 482 512 483 513 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 */ 522 static 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)); 484 528 } 485 529 … … 721 765 } 722 766 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 */ 773 static 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 } 723 780 724 781 /** … … 841 898 842 899 /** 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 */ 905 static 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 /** 843 930 * Frees the CRT resources held up by a time structure. 844 931 * @param pTime The time structure. … … 853 940 char **ppsz = (char **)pTime; 854 941 char **ppszEnd = (char **)pTime->fConsts; 855 while ( ppsz <ppszEnd)942 while ((uintptr_t)ppsz < (uintptr_t)ppszEnd) 856 943 { 857 944 void *pv = *ppsz; … … 868 955 869 956 /** 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 */ 962 static 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 /** 870 972 * Frees all heap strings in the monetary part of the lconv structure. 871 973 * @param pLconv What to work on. … … 880 982 pLconv->fNumericConsts = 0; 881 983 #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 */ 992 static 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); 882 1018 } 883 1019 … … 1071 1207 1072 1208 /** 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 */ 1214 static 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 /** 1073 1225 * Frees all heap strings in the monetary part of the lconv structure. 1074 1226 * @param pLconv What to work on. … … 1126 1278 1127 1279 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 */ 1290 static void localeGlobalNameCommit(__LIBC_LOCALEGLOBAL volatile *pHot, __LIBC_PLOCALEGLOBAL pCold, int iCategory) 1291 { 1292 MAYBE_SWAP_STRING_MEMBERS(pHot, pCold, apszNames[iCategory + 1], 0); 1128 1293 } 1129 1294 … … 1644 1809 static char *localeCommit(struct temp_locale *pTemp, int iCategory) 1645 1810 { 1646 char *pszRet;1647 char *pszAll;1648 int cch;1649 int iCat;1811 char *pszRet; 1812 char *pszAll; 1813 int cch; 1814 int iCat; 1650 1815 1651 1816 /* … … 1655 1820 1656 1821 /* 1657 * Copy all the data.1822 * Swap all the data (caller frees the old data). 1658 1823 */ 1659 1824 if (pTemp->afProcessed[LC_COLLATE + 1]) 1660 1825 { 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); 1665 1828 } 1666 1829 1667 1830 if (pTemp->afProcessed[LC_CTYPE + 1]) 1668 1831 { 1669 localeCtypeFree(&__libc_GLocaleCtype);1670 memcpy(&__libc_GLocaleCtype, &pTemp->Ctype, sizeof(__libc_GLocaleCtype));1671 1832 MB_CUR_MAX = pTemp->Ctype.mbcs ? pTemp->Ctype.mbcs : 1; 1672 1833 if ( IS_C_LOCALE(pTemp->Global.apszNames[LC_CTYPE + 1]) … … 1675 1836 else 1676 1837 __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); 1679 1841 } 1680 1842 1681 1843 if (pTemp->afProcessed[LC_TIME + 1]) 1682 1844 { 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); 1687 1847 } 1688 1848 1689 1849 if (pTemp->afProcessed[LC_NUMERIC + 1]) 1690 1850 { 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); 1698 1853 } 1699 1854 1700 1855 if (pTemp->afProcessed[LC_MONETARY + 1]) 1701 1856 { 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); 1728 1859 } 1729 1860 if (pTemp->afProcessed[LC_MESSAGES + 1]) 1730 1861 { 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 } 1737 1865 1738 1866 /* … … 1770 1898 } 1771 1899 *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); 1774 1902 } 1775 1903 else if (strcmp(gLocale.apszNames[LC_ALL + 1], pszAll)) 1776 1904 { 1777 localeGlobalFree(&gLocale, LC_ALL);1905 pTemp->Global.apszNames[LC_ALL + 1] = gLocale.apszNames[LC_ALL + 1]; 1778 1906 gLocale.apszNames[LC_ALL + 1] = strdup(pszAll); 1779 1907 } … … 1808 1936 if (pTemp->afProcessed[LC_MESSAGES + 1]) 1809 1937 localeMessagesFree(&pTemp->Msg); 1938 localeGlobalFree(&pTemp->Global, LC_ALL); 1810 1939 for (iCat = 0; iCat < _LC_LAST; iCat++) 1811 1940 if (pTemp->afProcessed[iCat + 1]) … … 1816 1945 /** 1817 1946 * This setlocale() implementation differs from the specs in that any 1818 * options specified by '@...' other than EURO/euro isignored.1947 * options specified by '@...' other than EURO/euro are ignored. 1819 1948 */ 1820 1949 char *_STD(setlocale)(int iCategory, const char *pszLocale) -
TabularUnified trunk/libc/tests/libc/smoketests/setlocale-1.c ¶
r3897 r3915 61 61 { 62 62 char *psz1; 63 char *psz1Copy; 63 64 char *psz2; 64 65 int rc = 0; … … 66 67 setlocale(LC_ALL, "en_US"); 67 68 psz1 = setlocale(LC_CTYPE, "de_DE"); 69 psz1Copy = psz1 ? strdup(psz1) : NULL; 70 68 71 psz2 = setlocale(LC_CTYPE, "de_DE"); 69 if (psz1 && psz2 && !strcmp(psz1, psz2)) 70 printf("2nd setlocale returns the same. %s errno=%d\n", psz1, errno); 72 if (psz1 == psz2 && psz2 && !strcmp(psz1Copy, psz2)) 73 printf("2nd setlocale returns the same pointer, great (%s). errno=%d\n", psz1, errno); 74 else if (psz1 && psz2 && !strcmp(psz1Copy, psz2)) 75 { 76 #if 1 /* kLibC behaviour */ 77 printf("error: 2nd setlocale returns different points, but same value (%s): %p != %p errno=%d\n", 78 psz2, psz1, psz2, errno); 79 rc++; 80 #else 81 printf("2nd setlocale returns the same value. %s errno=%d\n", psz2, errno); 82 #endif 83 } 71 84 else 72 85 { 73 printf("error: 2nd setlocale returns differntly. %s != %s errno=%d\n", psz1, psz2, errno);86 printf("error: 2nd setlocale returns differntly. %s != %s (%p, %p) errno=%d\n", psz1, psz2, psz1, psz2, errno); 74 87 rc++; 75 88 } 89 free(psz1Copy); 76 90 77 91 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.