Changeset 1792
- Timestamp:
- Jan 28, 2005, 8:07:55 PM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/src/lib/locale/setlocale.c
-
Property cvs2svn:cvs-rev
changed from
1.12
to1.13
r1791 r1792 70 70 && (s)[4] == 'X' \ 71 71 && (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') ) 72 83 /** Max lenght we anticipate of a codepage name. */ 73 84 #define CODEPAGE_MAX_LENGTH 64 … … 221 232 static void localeNumericFree(__LIBC_PLOCALELCONV pLconv); 222 233 static 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 );234 static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv, const char *pszLocale); 235 static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale, const char *pszModifier); 225 236 static 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 );237 static int localeParseLocale(char *pszLocale, const char **ppszCodepage, const char **ppszModifier); 238 static int localeDoOne(struct temp_locale *pTemp, int iCategory, const char *pszLocale, const char *pszCodepage, const char *pszModifier); 228 239 static int localeDo(struct temp_locale *pTemp, int iCategory, char *pszLocale, int fDefaultValue); 229 240 static char *localeCommit(struct temp_locale *pTemp, int iCategory); … … 822 833 FREE(thousands_sep); 823 834 FREE(grouping); 824 pLconv->fNumericConsts = 0; 835 836 pLconv->fNumericConsts = 0; 825 837 #undef FREE 826 838 } … … 874 886 * @param uobj The UconvObject to use. 875 887 * @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 */ 890 static int localeNumericDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, struct UniLconv *pULconv, const char *pszLocale) 878 891 { 879 892 int rc; … … 881 894 localeNumericFree(pLconv); 882 895 883 /* 884 * Convert the stuff. 885 */ 896 if ( !IS_C_LOCALE(pszLocale) 897 && !IS_POSIX_LOCALE(pszLocale)) 898 { 899 /* 900 * Convert the stuff. 901 */ 886 902 #define CONVERT_UCS(field) \ 887 903 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); 890 906 #undef CONVERT_UCS 891 907 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 } 893 920 } 894 921 … … 902 929 * @param uobj The UconvObject to use. 903 930 * @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 */ 934 static int localeMonetaryDo(__LIBC_PLOCALELCONV pLconv, UconvObject uobj, LocaleObject lobj, struct UniLconv *pULconv, const char *pszLocale, const char *pszModifier) 907 935 { 908 936 int rc; … … 917 945 */ 918 946 #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 } 922 960 CONVERT_UCS(mon_decimal_point); 923 961 CONVERT_UCS(mon_thousands_sep); … … 950 988 pLconv->s.int_curr_symbol = pLconv->s.currency_symbol = pLconv->s.mon_decimal_point 951 989 = pLconv->s.mon_thousands_sep = pLconv->s.positive_sign = pLconv->s.negative_sign 952 = pLconv->pszCrncyStr = "";990 = pLconv->pszCrncyStr = pLconv->s.mon_grouping = ""; 953 991 pLconv->s.int_frac_digits = -1; 954 992 pLconv->s.frac_digits = -1; … … 959 997 pLconv->s.p_sign_posn = -1; 960 998 pLconv->s.n_sign_posn = -1; 961 return 0; 999 1000 return 0; 962 1001 } 963 1002 } … … 980 1019 * Parses out the locale spec and the code page spec. 981 1020 */ 982 static int localeParseLocale(char *pszLocale, const char **ppszCodepage )983 { 984 /* 985 * Strip of modifier.1021 static int localeParseLocale(char *pszLocale, const char **ppszCodepage, const char **ppszModifier) 1022 { 1023 /* 1024 * Modifier. 986 1025 */ 987 1026 char *psz = strchr(pszLocale, '@'); 988 1027 if (psz) 989 1028 { 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; 993 1033 994 1034 /* … … 1203 1243 1204 1244 /** 1205 * Perform ethe 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 */ 1247 static 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); 1211 1251 char szCodepageActual[CODEPAGE_MAX_LENGTH]; 1212 1252 UconvObject uobj; … … 1255 1295 { 1256 1296 if (iCategory == LC_NUMERIC) 1257 rc = localeNumericDo(&pTemp->Lconv, uobj, pULconv );1297 rc = localeNumericDo(&pTemp->Lconv, uobj, pULconv, pszLocale); 1258 1298 else 1259 rc = localeMonetaryDo(&pTemp->Lconv, uobj, lobj, pULconv, pszLocale );1299 rc = localeMonetaryDo(&pTemp->Lconv, uobj, lobj, pULconv, pszLocale, pszModifier); 1260 1300 UniFreeLocaleInfo(pULconv); 1261 1301 } … … 1292 1332 */ 1293 1333 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; 1308 1338 else 1309 1310 /* pszLocale + "." + szCodepageActual .*/1339 { 1340 /* pszLocale + "." + szCodepageActual [+ "@" + pszModifier] */ 1311 1341 int cch1 = strlen(pszLocale); 1312 1342 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); 1314 1345 if (!psz) 1315 1346 return -ENOMEM; 1316 1347 char *psz = psz; 1317 1348 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 } 1324 1366 } 1325 1367 … … 1342 1384 (void *)pTemp, iCategory, gaszCategories[iCategory + 1], pszLocale, pszLocale, fDefaultValue); 1343 1385 const char *pszCodepage; 1386 const char *pszModifier; 1344 1387 char *pszNext; 1345 1388 int rc; … … 1350 1393 if (iCategory != LC_ALL) 1351 1394 { 1352 rc = localeParseLocale(pszLocale, &pszCodepage );1395 rc = localeParseLocale(pszLocale, &pszCodepage, &pszModifier); 1353 1396 if (!rc) 1354 rc = localeDoOne(pTemp, iCategory, pszLocale, pszCodepage );1397 rc = localeDoOne(pTemp, iCategory, pszLocale, pszCodepage, pszModifier); 1355 1398 } 1356 1399 else … … 1361 1404 * form "CATEGORY1=value1;CATEGORY2=value2[;...]", where values are 1362 1405 * 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. 1364 1407 */ 1365 1408 pszNext = strchr(pszLocale, ';'); … … 1383 1426 char *pszVal = &pszCur[cch + 1]; 1384 1427 const char *pszValCp; 1428 const char *pszValQual; 1385 1429 /* parse the locale value. */ 1386 rc = localeParseLocale(pszVal, &pszValCp );1430 rc = localeParseLocale(pszVal, &pszValCp, &pszValQual); 1387 1431 if (!rc) 1388 1432 { 1389 1433 if (iCat != LC_ALL) 1390 rc = localeDoOne(pTemp, iCat, pszVal, pszValCp );1434 rc = localeDoOne(pTemp, iCat, pszVal, pszValCp, pszValQual); 1391 1435 else /* Iterate all categories except LC_ALL. */ 1392 1436 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); 1394 1438 } 1395 1439 break; … … 1412 1456 * Parse it first to save time. 1413 1457 */ 1414 rc = localeParseLocale(pszLocale, &pszCodepage );1458 rc = localeParseLocale(pszLocale, &pszCodepage, &pszModifier); 1415 1459 if (!rc) 1416 1460 { … … 1425 1469 { 1426 1470 const char *pszCodepageEnv; 1471 const char *pszModifierEnv; 1427 1472 char *pszCopy = alloca(strlen(pszEnv) + 1); 1428 1473 if (!pszCopy) 1429 1474 LIBCLOG_RETURN_INT(-ENOMEM); 1430 rc = localeParseLocale(strcpy(pszCopy, pszEnv), &pszCodepageEnv );1475 rc = localeParseLocale(strcpy(pszCopy, pszEnv), &pszCodepageEnv, &pszModifierEnv); 1431 1476 if (!rc) 1432 rc = localeDoOne(pTemp, iCat, pszCopy, pszCodepageEnv );1477 rc = localeDoOne(pTemp, iCat, pszCopy, pszCodepageEnv, pszModifierEnv); 1433 1478 } 1434 1479 else 1435 rc = localeDoOne(pTemp, iCat, pszLocale, pszCodepage );1480 rc = localeDoOne(pTemp, iCat, pszLocale, pszCodepage, pszModifier); 1436 1481 } 1437 1482 } … … 1521 1566 if (pTemp->afProcessed[LC_MESSAGES + 1]) 1522 1567 { 1523 pTemp->afProcessed[LC_M ONETARY+ 1] = 0;1568 pTemp->afProcessed[LC_MESSAGES + 1] = 0; 1524 1569 gLocale.apszNames[LC_MESSAGES + 1] = pTemp->Global.apszNames[LC_MESSAGES + 1]; 1525 1570 } … … 1604 1649 /** 1605 1650 * 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. 1607 1652 */ 1608 1653 char *_STD(setlocale)(int iCategory, const char *pszLocale) … … 1728 1773 UconvObject uobj; 1729 1774 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; 1733 1779 char *psz = alloca(cch); 1734 1780 if (!psz) … … 1738 1784 || __libc_GLocaleCtype.uobj) 1739 1785 { 1740 memcpy(psz, gLocale.apszNames[LC_CTYPE + 1], cch 1 + 1);1741 localeParseLocale(psz, &pszCodepage );1786 memcpy(psz, gLocale.apszNames[LC_CTYPE + 1], cch); 1787 localeParseLocale(psz, &pszCodepage, &pszModifier); 1742 1788 rc = __libc_localeCreateObjects(psz, pszCodepage, NULL, &lobj, &uobj); 1743 1789 if (!rc) … … 1758 1804 || __libc_gLocaleCollate.uobj) 1759 1805 { 1760 memcpy(psz, gLocale.apszNames[LC_COLLATE + 1], cch 2 + 1);1761 localeParseLocale(psz, &pszCodepage );1806 memcpy(psz, gLocale.apszNames[LC_COLLATE + 1], cch); 1807 localeParseLocale(psz, &pszCodepage, &pszModifier); 1762 1808 rc = __libc_localeCreateObjects(psz, pszCodepage, NULL, &lobj, &uobj); 1763 1809 if (!rc) -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.