diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:29:29 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:29:29 +0100 |
commit | a65dd355fb80a05215e15ae97649de52aec885e3 (patch) | |
tree | 81701bb0c6b648630f2bf1729a85d7f5eb49e67b /locale | |
parent | 296a5732f94abe4d5699dc981e4ccfb950b48cee (diff) | |
parent | b4578bab30f72cddd2cf38abfb39f9c8dc892249 (diff) |
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'locale')
33 files changed, 1125 insertions, 1904 deletions
diff --git a/locale/C-address.c b/locale/C-address.c index 060a956f36..fe6e69e8ba 100644 --- a/locale/C-address.c +++ b/locale/C-address.c @@ -38,7 +38,7 @@ const struct __locale_data _nl_C_LC_ADDRESS attribute_hidden = { .string = "" }, { .string = "" }, { .string = "" }, - { .string = "" }, + { .word = 0 }, { .string = "" }, { .string = "" }, { .string = "" }, diff --git a/locale/C-monetary.c b/locale/C-monetary.c index b4ffb16e61..9c36c761fe 100644 --- a/locale/C-monetary.c +++ b/locale/C-monetary.c @@ -21,11 +21,8 @@ /* This table's entries are taken from POSIX.2 Table 2-9 ``LC_MONETARY Category Definition in the POSIX Locale'', with additions from ISO 14652, section 4.4. */ -#ifdef __CHAR_UNSIGNED__ static const char not_available[] = "\377"; -#else -static const char not_available[] = "\177"; -#endif +static const uint32_t conversion_rate[] = { 1, 1 }; const struct __locale_data _nl_C_LC_MONETARY attribute_hidden = { @@ -78,7 +75,7 @@ const struct __locale_data _nl_C_LC_MONETARY attribute_hidden = { .word = 99991231 }, { .word = 10101 }, { .word = 99991231 }, - { .word = 1 }, + { .string = (const char *) conversion_rate }, { .word = (unsigned int) L'\0' }, { .word = (unsigned int) L'\0' }, { .string = _nl_C_codeset } diff --git a/locale/categories.def b/locale/categories.def index 8c2537842a..e1172e99c5 100644 --- a/locale/categories.def +++ b/locale/categories.def @@ -156,6 +156,7 @@ DEFINE_CATEGORY DEFINE_ELEMENT (N_SEP_BY_SPACE, "n_sep_by_space", std, byte, 0, 2) DEFINE_ELEMENT (P_SIGN_POSN, "p_sign_posn", std, byte, 0, 4) DEFINE_ELEMENT (N_SIGN_POSN, "n_sign_posn", std, byte, 0, 4) + DEFINE_ELEMENT (_NL_MONETARY_CRNCYSTR, "crncystr", std, string) DEFINE_ELEMENT (__INT_P_CS_PRECEDES, "int_p_cs_precedes", std, byte, 0, 1) DEFINE_ELEMENT (__INT_P_SEP_BY_SPACE, "int_p_sep_by_space", std, byte, 0, 2) DEFINE_ELEMENT (__INT_N_CS_PRECEDES, "int_n_cs_precedes", std, byte, 0, 1) diff --git a/locale/hashval.h b/locale/hashval.h index 737162f6b8..88e7839386 100644 --- a/locale/hashval.h +++ b/locale/hashval.h @@ -37,7 +37,7 @@ compute_hashval (const void *key, size_t keylen) while (cnt < keylen) { hval = (hval << 9) | (hval >> (sizeof hval * CHAR_BIT - 9)); - hval += (hashval_t) *(((char *) key) + cnt++); + hval += (hashval_t) ((const unsigned char *) key)[cnt++]; } return hval != 0 ? hval : ~((hashval_t) 0); } diff --git a/locale/iso-3166.def b/locale/iso-3166.def index a9e1422cba..52997b4bf0 100644 --- a/locale/iso-3166.def +++ b/locale/iso-3166.def @@ -33,6 +33,7 @@ DEFINE_COUNTRY_CODE ("BENIN", BJ, BEN, 204) DEFINE_COUNTRY_CODE ("BERMUDA", BM, BMU, 60) DEFINE_COUNTRY_CODE ("BHUTAN", BT, BTN, 64) DEFINE_COUNTRY_CODE ("BOLIVIA", BO, BOL, 68) +DEFINE_COUNTRY_CODE ("BONAIRE, SINT EUSTATIUS AND SABA", BQ, BES, 535) DEFINE_COUNTRY_CODE ("BOSNIA AND HERZEGOVINA", BA, BIH, 70) DEFINE_COUNTRY_CODE ("BOTSWANA", BW, BWA, 72) DEFINE_COUNTRY_CODE ("BOUVET ISLAND", BV, BVT, 74) @@ -62,13 +63,13 @@ DEFINE_COUNTRY_CODE ("COSTA RICA", CR, CRI, 188) DEFINE_COUNTRY_CODE ("COTE D'IVOIRE", CI, CIV, 384) DEFINE_COUNTRY_CODE ("CROATIA", HR, HRV, 191) DEFINE_COUNTRY_CODE ("CUBA", CU, CUB, 192) +DEFINE_COUNTRY_CODE ("CURACAO", CW, CUW, 531) DEFINE_COUNTRY_CODE ("CYPRUS", CY, CYP, 196) DEFINE_COUNTRY_CODE ("CZECH REPUBLIC", CZ, CZE, 203) DEFINE_COUNTRY_CODE ("DENMARK", DK, DNK, 208) DEFINE_COUNTRY_CODE ("DJIBOUTI", DJ, DJI, 262) DEFINE_COUNTRY_CODE ("DOMINICA", DM, DMA, 212) DEFINE_COUNTRY_CODE ("DOMINICAN REPUBLIC", DO, DOM, 214) -DEFINE_COUNTRY_CODE ("EAST TIMOR", TP, TMP, 626) DEFINE_COUNTRY_CODE ("ECUADOR", EC, ECU, 218) DEFINE_COUNTRY_CODE ("EGYPT", EG, EGY, 818) DEFINE_COUNTRY_CODE ("EL SALVADOR", SV, SLV, 222) @@ -175,7 +176,7 @@ DEFINE_COUNTRY_CODE ("NORWAY", NO, NOR, 578) DEFINE_COUNTRY_CODE ("OMAN", OM, OMN, 512) DEFINE_COUNTRY_CODE ("PAKISTAN", PK, PAK, 586) DEFINE_COUNTRY_CODE ("PALAU", PW, PLW, 585) -DEFINE_COUNTRY_CODE ("PALESTINIAN TERRITORY, OCCUPIED", PS, PSE, 275) +DEFINE_COUNTRY_CODE ("PALESTINE, STATE OF", PS, PSE, 275) DEFINE_COUNTRY_CODE ("PANAMA", PA, PAN, 591) DEFINE_COUNTRY_CODE ("PAPUA NEW GUINEA", PG, PNG, 598) DEFINE_COUNTRY_CODE ("PARAGUAY", PY, PRY, 600) @@ -190,9 +191,11 @@ DEFINE_COUNTRY_CODE ("REUNION", RE, REU, 638) DEFINE_COUNTRY_CODE ("ROMANIA", RO, ROU, 642) DEFINE_COUNTRY_CODE ("RUSSIAN FEDERATION", RU, RUS, 643) DEFINE_COUNTRY_CODE ("RWANDA", RW, RWA, 646) +DEFINE_COUNTRY_CODE ("SAINT BARTHELEMY", BL, BLM, 652) DEFINE_COUNTRY_CODE ("SAINT HELENA", SH, SHN, 654) DEFINE_COUNTRY_CODE ("SAINT KITTS AND NEVIS", KN, KNA, 659) DEFINE_COUNTRY_CODE ("SAINT LUCIA", LC, LCA, 662) +DEFINE_COUNTRY_CODE ("SAINT MARTIN (FRENCH PART)", MF, MAF, 663) DEFINE_COUNTRY_CODE ("SAINT PIERRE AND MIQUELON", PM, SPM, 666) DEFINE_COUNTRY_CODE ("SAINT VINCENT AND THE GRENADINES", VC, VCT, 670) DEFINE_COUNTRY_CODE ("SAMOA", WS, WSM, 882) @@ -204,15 +207,17 @@ DEFINE_COUNTRY_CODE ("SERBIA", RS, SRB, 688) DEFINE_COUNTRY_CODE ("SEYCHELLES", SC, SYC, 690) DEFINE_COUNTRY_CODE ("SIERRA LEONE", SL, SLE, 694) DEFINE_COUNTRY_CODE ("SINGAPORE", SG, SGP, 702) +DEFINE_COUNTRY_CODE ("SINT MAARTEN (DUTCH PART)", SX, SXM, 534) DEFINE_COUNTRY_CODE ("SLOVAKIA", SK, SVK, 703) DEFINE_COUNTRY_CODE ("SLOVENIA", SI, SVN, 705) DEFINE_COUNTRY_CODE ("SOLOMON ISLANDS", SB, SLB, 90) DEFINE_COUNTRY_CODE ("SOMALIA", SO, SOM, 706) DEFINE_COUNTRY_CODE ("SOUTH AFRICA", ZA, ZAF, 710) DEFINE_COUNTRY_CODE ("SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", GS, SGS, 239) +DEFINE_COUNTRY_CODE ("SOUTH SUDAN", SS, SSD, 728) DEFINE_COUNTRY_CODE ("SPAIN", ES, ESP, 724) DEFINE_COUNTRY_CODE ("SRI LANKA", LK, LKA, 144) -DEFINE_COUNTRY_CODE ("SUDAN", SD, SDN, 736) +DEFINE_COUNTRY_CODE ("SUDAN", SD, SDN, 729) DEFINE_COUNTRY_CODE ("SURINAME", SR, SUR, 740) DEFINE_COUNTRY_CODE ("SVALBARD AND JAN MAYEN", SJ, SJM, 744) DEFINE_COUNTRY_CODE ("SWAZILAND", SZ, SWZ, 748) @@ -223,6 +228,7 @@ DEFINE_COUNTRY_CODE ("TAIWAN, PROVINCE OF CHINA", TW, TWN, 158) DEFINE_COUNTRY_CODE ("TAJIKISTAN", TJ, TJK, 762) DEFINE_COUNTRY_CODE ("TANZANIA, UNITED REPUBLIC OF", TZ, TZA, 834) DEFINE_COUNTRY_CODE ("THAILAND", TH, THA, 764) +DEFINE_COUNTRY_CODE ("TIMOR-LESTE", TL, TLS, 626) DEFINE_COUNTRY_CODE ("TOGO", TG, TGO, 768) DEFINE_COUNTRY_CODE ("TOKELAU", TK, TKL, 772) DEFINE_COUNTRY_CODE ("TONGA", TO, TON, 776) diff --git a/locale/iso-4217.def b/locale/iso-4217.def index ee0133959c..bcc170bfb3 100644 --- a/locale/iso-4217.def +++ b/locale/iso-4217.def @@ -17,7 +17,7 @@ DEFINE_INT_CURR("AOA") /* Angolan Kwanza */ DEFINE_INT_CURR("ARS") /* Argentine Peso */ DEFINE_INT_CURR("AUD") /* Australian Dollar */ DEFINE_INT_CURR("AWG") /* Aruba Guilder */ -DEFINE_INT_CURR("AZM") /* Azerbaijan Manat */ +DEFINE_INT_CURR("AZN") /* Azerbaijan Manat */ DEFINE_INT_CURR("BAM") /* Bosnian and Herzegovina Convertible Mark */ DEFINE_INT_CURR("BBD") /* Barbados Dollar */ DEFINE_INT_CURR("BDT") /* Bangladesh Taka */ @@ -27,7 +27,7 @@ DEFINE_INT_CURR("BIF") /* Burundi Franc */ DEFINE_INT_CURR("BMD") /* Burmudian Dollar */ DEFINE_INT_CURR("BND") /* Brunei Dollar */ DEFINE_INT_CURR("BOB") /* Bolivian Boliviano */ -DEFINE_INT_CURR("BRL") /* Brazil Cruzeiro */ +DEFINE_INT_CURR("BRL") /* Brazil Real */ DEFINE_INT_CURR("BSD") /* Bahamas Dollar */ DEFINE_INT_CURR("BTN") /* Bhutan Ngultrum */ DEFINE_INT_CURR("BWP") /* Botswana Pula */ @@ -57,7 +57,7 @@ DEFINE_INT_CURR("FJD") /* Fiji Dollar */ DEFINE_INT_CURR("FKP") /* Falkland Islands Pound (Malvinas) */ DEFINE_INT_CURR("GBP") /* British Pound */ DEFINE_INT_CURR("GEL") /* Georgia Lari */ -DEFINE_INT_CURR("GHC") /* Ghana Cedi */ +DEFINE_INT_CURR("GHS") /* Ghana Cedi */ DEFINE_INT_CURR("GIP") /* Gibraltar Pound */ DEFINE_INT_CURR("GMD") /* Gambian Dalasi */ DEFINE_INT_CURR("GNF") /* Guinea Franc */ @@ -70,12 +70,10 @@ DEFINE_INT_CURR("HTG") /* Haiti Gourde */ DEFINE_INT_CURR("HUF") /* Hungarian Forint */ DEFINE_INT_CURR("IDR") /* Indonesia Rupiah */ DEFINE_INT_CURR("ILS") /* Israeli Shekel */ -DEFINE_INT_CURR("IMP") /* Isle of Man Pounds */ DEFINE_INT_CURR("INR") /* Indian Rupee (Bhutan) */ DEFINE_INT_CURR("IQD") /* Iraqi Dinar */ DEFINE_INT_CURR("IRR") /* Iranian Rial */ DEFINE_INT_CURR("ISK") /* Iceland Krona */ -DEFINE_INT_CURR("JEP") /* Jersey Pound */ DEFINE_INT_CURR("JMD") /* Jamaican Dollar */ DEFINE_INT_CURR("JOD") /* Jordanian Dinar */ DEFINE_INT_CURR("JPY") /* Japanese Yen */ @@ -106,11 +104,11 @@ DEFINE_INT_CURR("MOP") /* Macau Pataca */ DEFINE_INT_CURR("MRO") /* Mauritania Ouguiya */ DEFINE_INT_CURR("MTL") /* Maltese Lira */ DEFINE_INT_CURR("MUR") /* Mauritius Rupee */ -DEFINE_INT_CURR("MVR") /* Maldives Rupee */ +DEFINE_INT_CURR("MVR") /* Maldives Rufiyaa */ DEFINE_INT_CURR("MWK") /* Malawi Kwacha */ DEFINE_INT_CURR("MXN") /* Mexican Peso */ DEFINE_INT_CURR("MYR") /* Malaysian Ringgit */ -DEFINE_INT_CURR("MZM") /* Mozambique Metical */ +DEFINE_INT_CURR("MZN") /* Mozambique Metical */ DEFINE_INT_CURR("NAD") /* Namibia Dollar */ DEFINE_INT_CURR("NGN") /* Nigeria Naira */ DEFINE_INT_CURR("NIO") /* Nicaragua Cordoba Oro */ @@ -126,7 +124,6 @@ DEFINE_INT_CURR("PKR") /* Pakistan Rupee */ DEFINE_INT_CURR("PLN") /* Polish Zloty */ DEFINE_INT_CURR("PYG") /* Paraguay Guarani */ DEFINE_INT_CURR("QAR") /* Qatar Rial */ -DEFINE_INT_CURR("ROL") /* Romanian Leu */ DEFINE_INT_CURR("RON") /* Romanian New Leu */ DEFINE_INT_CURR("RSD") /* Serbian Dinars */ DEFINE_INT_CURR("RUB") /* Russian Ruble */ @@ -134,16 +131,13 @@ DEFINE_INT_CURR("RWF") /* Rwanda Franc */ DEFINE_INT_CURR("SAR") /* Saudi Arabia Riyal */ DEFINE_INT_CURR("SBD") /* Solomon Islands Dollar */ DEFINE_INT_CURR("SCR") /* Seychelles Rupee */ -DEFINE_INT_CURR("SDD") /* Sudanese Dinars */ +DEFINE_INT_CURR("SDG") /* Sudanese Pound */ DEFINE_INT_CURR("SEK") /* Swedish Krona */ DEFINE_INT_CURR("SGD") /* Singapore Dollar */ DEFINE_INT_CURR("SHP") /* St. Helena Pound */ -DEFINE_INT_CURR("SIT") /* Slovenian Tolar */ -DEFINE_INT_CURR("SKK") /* Slovakian Koruna */ DEFINE_INT_CURR("SLL") /* Sierra Leone Leone */ DEFINE_INT_CURR("SOS") /* Somalia Schilling */ -DEFINE_INT_CURR("SPL") /* Seborga Luigini */ -DEFINE_INT_CURR("SRG") /* Suriname Guilder */ +DEFINE_INT_CURR("SRD") /* Suriname Dollar */ DEFINE_INT_CURR("STD") /* Sao Tome and Principe Dobra */ DEFINE_INT_CURR("SVC") /* El Salvador Colon */ DEFINE_INT_CURR("SYP") /* Syrian Arab Republic Pound */ @@ -155,7 +149,6 @@ DEFINE_INT_CURR("TND") /* Tunisian Dinar */ DEFINE_INT_CURR("TOP") /* Tonga Pa'Anga */ DEFINE_INT_CURR("TRY") /* New Turkish Lira */ DEFINE_INT_CURR("TTD") /* Trinidad and Tobago */ -DEFINE_INT_CURR("TVD") /* Tuvalu Dollars */ DEFINE_INT_CURR("TWD") /* Taiwan, Province of China Dollar */ DEFINE_INT_CURR("TZS") /* United Republic of Tanzania Shilling */ DEFINE_INT_CURR("UAH") /* Ukraine Hryvna */ @@ -163,13 +156,12 @@ DEFINE_INT_CURR("UGX") /* Ugandan Shilling */ DEFINE_INT_CURR("USD") /* United States Dollar */ DEFINE_INT_CURR("UYU") /* Uruguay Peso Uruguayo */ DEFINE_INT_CURR("UZS") /* Uzbekistan Sum */ -DEFINE_INT_CURR("VEB") /* Venezuelan Bolivar */ +DEFINE_INT_CURR("VEF") /* Venezuelan Bolivar Fuerte */ DEFINE_INT_CURR("VND") /* Viet Nam Dong */ DEFINE_INT_CURR("VUV") /* Vanuatu Vatu */ DEFINE_INT_CURR("WST") /* Samoa Tala */ DEFINE_INT_CURR("XAF") /* Central African Franc (United Republic of Cameroon, Central African Republic, Chad, Congo, Gabon) */ DEFINE_INT_CURR("XCD") /* East Caribbean Dollar (Antiqua, Dominica, Grenada, Montserrat, St. Kitts-Nevis-Anguilla, Saint Lucia, Saint Vincent and the Grenadines) */ -DEFINE_INT_CURR("XDR") /* International Monetary Fund */ DEFINE_INT_CURR("XOF") /* West African Franc (Benin, Ivory Coast, Niger, Senegal, Togo, Upper Volta) */ DEFINE_INT_CURR("XPF") /* French polynesia, New Caledonia, Wallis and Futuna Islands */ DEFINE_INT_CURR("YER") /* Yemeni Rial */ diff --git a/locale/iso-639.def b/locale/iso-639.def index 50b5a52f57..994792e085 100644 --- a/locale/iso-639.def +++ b/locale/iso-639.def @@ -46,6 +46,7 @@ DEFINE_LANGUAGE_CODE3 ("Austronesian (Other)", map, map) DEFINE_LANGUAGE_CODE ("Avaric", av, ava, ava) DEFINE_LANGUAGE_CODE ("Avestan", ae, ave, ave) DEFINE_LANGUAGE_CODE3 ("Awadhi", awa, awa) +DEFINE_LANGUAGE_CODE ("Aymara, Southern", ay, ayc, ayc) DEFINE_LANGUAGE_CODE ("Aymara", ay, aym, aym) DEFINE_LANGUAGE_CODE ("Azerbaijani", az, aze, aze) DEFINE_LANGUAGE_CODE3 ("Balinese", ban, ban) @@ -85,6 +86,7 @@ DEFINE_LANGUAGE_CODE3 ("Caucasian (Other)", cau, cau) DEFINE_LANGUAGE_CODE3 ("Cebuano", ceb, ceb) DEFINE_LANGUAGE_CODE3 ("Celtic (Other)", cel, cel) DEFINE_LANGUAGE_CODE3 ("Central American Indian (Other)", cai, cai) +DEFINE_LANGUAGE_CODE3 ("Central Nahuatl", nhn, nhn) DEFINE_LANGUAGE_CODE3 ("Central Sama", sml, sml) DEFINE_LANGUAGE_CODE3 ("Chagatai", chg, chg) DEFINE_LANGUAGE_CODE3 ("Chamic languages", cmc, cmc) @@ -95,6 +97,7 @@ DEFINE_LANGUAGE_CODE3 ("Cheyenne", chy, chy) DEFINE_LANGUAGE_CODE2 ("Chhattisgarhi", hne) /* ISO 639-3 */ DEFINE_LANGUAGE_CODE3 ("Chibcha", chb, chb) DEFINE_LANGUAGE_CODE ("Chichewa; Chewa; Nyanja", ny, nya, nya) +DEFINE_LANGUAGE_CODE3 ("Chiga", cgg, cgg) DEFINE_LANGUAGE_CODE ("Chinese", zh, zho, chi) DEFINE_LANGUAGE_CODE3 ("Chinook jargon", chn, chn) DEFINE_LANGUAGE_CODE3 ("Chipewyan", chp, chp) @@ -161,6 +164,7 @@ DEFINE_LANGUAGE_CODE3 ("Friulian", fur, fur) DEFINE_LANGUAGE_CODE ("Fulah", ff, ful, ful) DEFINE_LANGUAGE_CODE ("Gaelic; Scottish Gaelic", gd, gla, gla) DEFINE_LANGUAGE_CODE ("Galician", gl, glg, glg) +DEFINE_LANGUAGE_CODE3 ("Gan Chinese", gan, gan) DEFINE_LANGUAGE_CODE ("Ganda", lg, lug, lug) DEFINE_LANGUAGE_CODE3 ("Gayo", gay, gay) DEFINE_LANGUAGE_CODE3 ("Ga", gaa, gaa) @@ -184,6 +188,7 @@ DEFINE_LANGUAGE_CODE ("Gujarati", gu, guj, guj) DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi) DEFINE_LANGUAGE_CODE3 ("Haida", hai, hai) DEFINE_LANGUAGE_CODE ("Haitian; Haitian Creole", ht, hat, hat) +DEFINE_LANGUAGE_CODE3 ("Hakka Chinese", hak, hak) DEFINE_LANGUAGE_CODE ("Hausa", ha, hau, hau) DEFINE_LANGUAGE_CODE3 ("Hawaiian", haw, haw) DEFINE_LANGUAGE_CODE ("Hebrew", he, heb, heb) @@ -194,6 +199,7 @@ DEFINE_LANGUAGE_CODE ("Hindi", hi, hin, hin) DEFINE_LANGUAGE_CODE ("Hiri Motu", ho, hmo, hmo) DEFINE_LANGUAGE_CODE3 ("Hittite", hit, hit) DEFINE_LANGUAGE_CODE3 ("Hmong", hmn, hmn) +DEFINE_LANGUAGE_CODE3 ("Huizhou Chinese", czh, czh) DEFINE_LANGUAGE_CODE ("Hungarian", hu, hun, hun) DEFINE_LANGUAGE_CODE3 ("Hupa", hup, hup) DEFINE_LANGUAGE_CODE3 ("Iban", iba, iba) @@ -219,6 +225,7 @@ DEFINE_LANGUAGE_CODE3 ("Iroquoian languages", iro, iro) DEFINE_LANGUAGE_CODE ("Italian", it, ita, ita) DEFINE_LANGUAGE_CODE ("Japanese", ja, jpn, jpn) DEFINE_LANGUAGE_CODE ("Javanese", jv, jav, jav) +DEFINE_LANGUAGE_CODE3 ("Jinyu Chinese", cjy, cjy) DEFINE_LANGUAGE_CODE3 ("Judeo-Arabic", jrb, jrb) DEFINE_LANGUAGE_CODE3 ("Judeo-Persian", jpr, jpr) DEFINE_LANGUAGE_CODE3 ("Kabardian", kbd, kbd) @@ -265,8 +272,10 @@ DEFINE_LANGUAGE_CODE ("Lao", lo, lao, lao) DEFINE_LANGUAGE_CODE ("Latin", la, lat, lat) DEFINE_LANGUAGE_CODE ("Latvian", lv, lav, lav) DEFINE_LANGUAGE_CODE3 ("Lezghian", lez, lez) +DEFINE_LANGUAGE_CODE3 ("Ligurian", lij, lij) DEFINE_LANGUAGE_CODE ("Limburgan; Limburger; Limburgish", li, lim, lim) DEFINE_LANGUAGE_CODE ("Lingala", ln, lin, lin) +DEFINE_LANGUAGE_CODE3 ("Literary Chinese", lzh, lzh) DEFINE_LANGUAGE_CODE ("Lithuanian", lt, lit, lit) DEFINE_LANGUAGE_CODE3 ("Lojban", jbo, jbo) DEFINE_LANGUAGE_CODE3 ("Low German; Low Saxon; German, Low; Saxon, Low", nds, nds) @@ -290,6 +299,7 @@ DEFINE_LANGUAGE_CODE ("Malayalam", ml, mal, mal) DEFINE_LANGUAGE_CODE ("Malay", ms, msa, may) DEFINE_LANGUAGE_CODE ("Maltese", mt, mlt, mlt) DEFINE_LANGUAGE_CODE3 ("Manchu", mnc, mnc) +DEFINE_LANGUAGE_CODE3 ("Mandarin Chinese", cmn, cmn) DEFINE_LANGUAGE_CODE3 ("Mandar", mdr, mdr) DEFINE_LANGUAGE_CODE3 ("Mandingo", man, man) DEFINE_LANGUAGE_CODE3 ("Manipuri", mni, mni) @@ -302,10 +312,14 @@ DEFINE_LANGUAGE_CODE ("Marshallese", mh, mah, mah) DEFINE_LANGUAGE_CODE3 ("Marwari", mwr, mwr) DEFINE_LANGUAGE_CODE3 ("Masai", mas, mas) DEFINE_LANGUAGE_CODE3 ("Mayan languages", myn, myn) +DEFINE_LANGUAGE_CODE3 ("Meadow Mari", mhr, mhr) DEFINE_LANGUAGE_CODE3 ("Mende", men, men) DEFINE_LANGUAGE_CODE3 ("Mi'kmaq; Micmac", mic, mic) DEFINE_LANGUAGE_CODE3 ("Minangkabau", min, min) -DEFINE_LANGUAGE_CODE3 ("Min Nan", nan, nan) +DEFINE_LANGUAGE_CODE3 ("Min Bei Chinese", mnp, mnp) +DEFINE_LANGUAGE_CODE3 ("Min Dong Chinese", cdo, cdo) +DEFINE_LANGUAGE_CODE3 ("Min Nan Chinese", nan, nan) +DEFINE_LANGUAGE_CODE3 ("Min Zhong Chinese", czo, czo) DEFINE_LANGUAGE_CODE3 ("Mirandese", mwl, mwl) DEFINE_LANGUAGE_CODE3 ("Miscellaneous languages", mis, mis) DEFINE_LANGUAGE_CODE3 ("Mohawk", moh, moh) @@ -347,7 +361,7 @@ DEFINE_LANGUAGE_CODE3 ("Nyoro", nyo, nyo) DEFINE_LANGUAGE_CODE3 ("Nzima", nzi, nzi) DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Provençal", oc, oci, oci) DEFINE_LANGUAGE_CODE ("Ojibwa", oj, oji, oji) -DEFINE_LANGUAGE_CODE ("Oriya", or, ori, ori) +DEFINE_LANGUAGE_CODE ("Odia", or, ori, ori) DEFINE_LANGUAGE_CODE ("Oromo", om, orm, orm) DEFINE_LANGUAGE_CODE3 ("Osage", osa, osa) DEFINE_LANGUAGE_CODE ("Ossetian; Ossetic", os, oss, oss) @@ -369,8 +383,10 @@ DEFINE_LANGUAGE_CODE ("Polish", pl, pol, pol) DEFINE_LANGUAGE_CODE ("Portuguese", pt, por, por) DEFINE_LANGUAGE_CODE3 ("Prakrit languages", pra, pra) DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro) +DEFINE_LANGUAGE_CODE3 ("Pu-Xian Chinese", cpx, cpx) DEFINE_LANGUAGE_CODE ("Pushto", ps, pus, pus) DEFINE_LANGUAGE_CODE ("Quechua", qu, que, que) +DEFINE_LANGUAGE_CODE3 ("Quechua, Southern", quz, quz) DEFINE_LANGUAGE_CODE ("Raeto-Romance", rm, roh, roh) DEFINE_LANGUAGE_CODE3 ("Rajasthani", raj, raj) DEFINE_LANGUAGE_CODE3 ("Rapanui", rap, rap) @@ -403,6 +419,7 @@ DEFINE_LANGUAGE_CODE3 ("Sicilian", scn, scn) DEFINE_LANGUAGE_CODE3 ("Sidamo", sid, sid) DEFINE_LANGUAGE_CODE3 ("Sign Languages", sgn, sgn) DEFINE_LANGUAGE_CODE3 ("Siksika", bla, bla) +DEFINE_LANGUAGE_CODE3 ("Silesian", szl, szl) DEFINE_LANGUAGE_CODE ("Sindhi", sd, snd, snd) DEFINE_LANGUAGE_CODE ("Sinhala; Sinhalese", si, sin, sin) DEFINE_LANGUAGE_CODE3 ("Sino-Tibetan (Other)", sit, sit) @@ -443,6 +460,7 @@ DEFINE_LANGUAGE_CODE ("Telugu", te, tel, tel) DEFINE_LANGUAGE_CODE3 ("Tereno", ter, ter) DEFINE_LANGUAGE_CODE3 ("Tetum", tet, tet) DEFINE_LANGUAGE_CODE ("Thai", th, tha, tha) +DEFINE_LANGUAGE_CODE3 ("Tharu, Chitwani", the, the) DEFINE_LANGUAGE_CODE ("Tibetan", bo, bod, tib) DEFINE_LANGUAGE_CODE3 ("Tigre", tig, tig) DEFINE_LANGUAGE_CODE ("Tigrinya", ti, tir, tir) @@ -469,6 +487,7 @@ DEFINE_LANGUAGE_CODE3 ("Ugaritic", uga, uga) DEFINE_LANGUAGE_CODE ("Uighur; Uyghur", ug, uig, uig) DEFINE_LANGUAGE_CODE ("Ukrainian", uk, ukr, ukr) DEFINE_LANGUAGE_CODE3 ("Umbundu", umb, umb) +DEFINE_LANGUAGE_CODE3 ("Unami Delaware", unm, unm) DEFINE_LANGUAGE_CODE3 ("Undetermined", und, und) DEFINE_LANGUAGE_CODE3 ("Upper Sorbian", hsb, hsb) DEFINE_LANGUAGE_CODE ("Urdu", ur, urd, urd) @@ -480,18 +499,21 @@ DEFINE_LANGUAGE_CODE ("Volapük", vo, vol, vol) DEFINE_LANGUAGE_CODE3 ("Votic", vot, vot) DEFINE_LANGUAGE_CODE3 ("Wakashan languages", wak, wak) DEFINE_LANGUAGE_CODE3 ("Walser", wae, wae) -DEFINE_LANGUAGE_CODE3 ("Walamo", wal, wal) +DEFINE_LANGUAGE_CODE3 ("Walaita", wal, wal) DEFINE_LANGUAGE_CODE ("Walloon", wa, wln, wln) DEFINE_LANGUAGE_CODE3 ("Waray", war, war) DEFINE_LANGUAGE_CODE3 ("Washo", was, was) DEFINE_LANGUAGE_CODE ("Welsh", cy, cym, wel) DEFINE_LANGUAGE_CODE ("Wolof", wo, wol, wol) +DEFINE_LANGUAGE_CODE3 ("Wu Chinese", wuu, wuu) DEFINE_LANGUAGE_CODE ("Xhosa", xh, xho, xho) +DEFINE_LANGUAGE_CODE3 ("Xiang Chinese", hsn, hsn) DEFINE_LANGUAGE_CODE3 ("Yakut", sah, sah) DEFINE_LANGUAGE_CODE3 ("Yao", yao, yao) DEFINE_LANGUAGE_CODE3 ("Yapese", yap, yap) DEFINE_LANGUAGE_CODE ("Yiddish", yi, yid, yid) DEFINE_LANGUAGE_CODE ("Yoruba", yo, yor, yor) +DEFINE_LANGUAGE_CODE3 ("Yue Chinese", yue, yue) DEFINE_LANGUAGE_CODE3 ("Yupik languages", ypk, ypk) DEFINE_LANGUAGE_CODE3 ("Zande", znd, znd) DEFINE_LANGUAGE_CODE3 ("Zapotec", zap, zap) diff --git a/locale/loadarchive.c b/locale/loadarchive.c index 70136dcf95..f723780ce1 100644 --- a/locale/loadarchive.c +++ b/locale/loadarchive.c @@ -274,6 +274,10 @@ _nl_load_locale_from_archive (int category, const char **namep) namehashtab = (struct namehashent *) ((char *) head + head->namehash_offset); + /* Avoid division by 0 if the file is corrupted. */ + if (__glibc_unlikely (head->namehash_size == 0)) + goto close_and_out; + idx = hval % head->namehash_size; incr = 1 + hval % (head->namehash_size - 2); diff --git a/locale/loadlocale.c b/locale/loadlocale.c index de7e3d01da..45162f1364 100644 --- a/locale/loadlocale.c +++ b/locale/loadlocale.c @@ -148,7 +148,7 @@ _nl_intern_locale_data (int category, const void *data, size_t datasize) newdata->values[cnt].string = newdata->filedata + idx; else { - if (idx % __alignof__ (u_int32_t) != 0) + if (!LOCFILE_ALIGNED_P (idx)) goto puntdata; newdata->values[cnt].word = *((const u_int32_t *) (newdata->filedata + idx)); diff --git a/locale/localeconv.c b/locale/localeconv.c index 71ba4c6ab3..98e82a5cf0 100644 --- a/locale/localeconv.c +++ b/locale/localeconv.c @@ -28,7 +28,7 @@ __localeconv (void) result.decimal_point = (char *) _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); result.thousands_sep = (char *) _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); result.grouping = (char *) _NL_CURRENT (LC_NUMERIC, GROUPING); - if (*result.grouping == CHAR_MAX || *result.grouping == (char) -1) + if (*result.grouping == '\177' || *result.grouping == '\377') result.grouping = (char *) ""; result.int_curr_symbol = (char *) _NL_CURRENT (LC_MONETARY, INT_CURR_SYMBOL); @@ -38,31 +38,29 @@ __localeconv (void) result.mon_thousands_sep = (char *) _NL_CURRENT (LC_MONETARY, MON_THOUSANDS_SEP); result.mon_grouping = (char *) _NL_CURRENT (LC_MONETARY, MON_GROUPING); - if (*result.mon_grouping == CHAR_MAX || *result.mon_grouping == (char) -1) + if (*result.mon_grouping == '\177' || *result.mon_grouping == '\377') result.mon_grouping = (char *) ""; result.positive_sign = (char *) _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN); result.negative_sign = (char *) _NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN); - result.int_frac_digits = *(char *) _NL_CURRENT (LC_MONETARY, - INT_FRAC_DIGITS); - result.frac_digits = *(char *) _NL_CURRENT (LC_MONETARY, FRAC_DIGITS); - result.p_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, P_CS_PRECEDES); - result.p_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE); - result.n_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, N_CS_PRECEDES); - result.n_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE); - result.p_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, P_SIGN_POSN); - result.n_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, N_SIGN_POSN); - result.int_p_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, - INT_P_CS_PRECEDES); - result.int_p_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, - INT_P_SEP_BY_SPACE); - result.int_n_cs_precedes = *(char *) _NL_CURRENT (LC_MONETARY, - INT_N_CS_PRECEDES); - result.int_n_sep_by_space = *(char *) _NL_CURRENT (LC_MONETARY, - INT_N_SEP_BY_SPACE); - result.int_p_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, - INT_P_SIGN_POSN); - result.int_n_sign_posn = *(char *) _NL_CURRENT (LC_MONETARY, - INT_N_SIGN_POSN); + +#define INT_ELEM(member, element) \ + result.member = *(char *) _NL_CURRENT (LC_MONETARY, element); \ + if (result.member == '\377') result.member = CHAR_MAX + + INT_ELEM (int_frac_digits, INT_FRAC_DIGITS); + INT_ELEM (frac_digits, FRAC_DIGITS); + INT_ELEM (p_cs_precedes, P_CS_PRECEDES); + INT_ELEM (p_sep_by_space, P_SEP_BY_SPACE); + INT_ELEM (n_cs_precedes, N_CS_PRECEDES); + INT_ELEM (n_sep_by_space, N_SEP_BY_SPACE); + INT_ELEM (p_sign_posn, P_SIGN_POSN); + INT_ELEM (n_sign_posn, N_SIGN_POSN); + INT_ELEM (int_p_cs_precedes, INT_P_CS_PRECEDES); + INT_ELEM (int_p_sep_by_space, INT_P_SEP_BY_SPACE); + INT_ELEM (int_n_cs_precedes, INT_N_CS_PRECEDES); + INT_ELEM (int_n_sep_by_space, INT_N_SEP_BY_SPACE); + INT_ELEM (int_p_sign_posn, INT_P_SIGN_POSN); + INT_ELEM (int_n_sign_posn, INT_N_SIGN_POSN); return &result; } diff --git a/locale/localeinfo.h b/locale/localeinfo.h index 3142726605..8d2c1665c2 100644 --- a/locale/localeinfo.h +++ b/locale/localeinfo.h @@ -87,6 +87,16 @@ struct __locale_data values __flexarr; /* Items, usually pointers into `filedata'. */ }; +/* This alignment is used for 32-bit integers in locale files, both + those that are explicitly int32_t or uint32_t and those that are + wchar_t, regardless of the (possibly smaller) alignment required + for such integers on a particular host. */ +#define LOCFILE_ALIGN sizeof (int32_t) +#define LOCFILE_ALIGN_MASK (LOCFILE_ALIGN - 1) +#define LOCFILE_ALIGN_UP(x) (((x) + LOCFILE_ALIGN - 1) \ + & ~LOCFILE_ALIGN_MASK) +#define LOCFILE_ALIGNED_P(x) (((x) & LOCFILE_ALIGN_MASK) == 0) + /* We know three kinds of collation sorting rules. */ enum coll_sort_rule { diff --git a/locale/locarchive.h b/locale/locarchive.h index f2d84771ab..fec3b1a4f7 100644 --- a/locale/locarchive.h +++ b/locale/locarchive.h @@ -80,6 +80,8 @@ struct locrecent struct locarhandle { + /* Full path to the locale archive file. */ + const char *fname; int fd; void *addr; size_t mmaped; diff --git a/locale/programs/3level.h b/locale/programs/3level.h index 9b8b1b96ad..c5f024fe35 100644 --- a/locale/programs/3level.h +++ b/locale/programs/3level.h @@ -26,7 +26,8 @@ ELEMENT to the type of every entry DEFAULT to the default value for empty entries ITERATE if you want the TABLE_iterate function to be defined - NO_FINALIZE if you don't want the TABLE_finalize function to be defined + NO_ADD_LOCALE if you don't want the add_locale_TABLE function + to be defined This will define @@ -36,7 +37,7 @@ void TABLE_add (struct TABLE *t, uint32_t wc, ELEMENT value); void TABLE_iterate (struct TABLE *t, void (*fn) (uint32_t wc, ELEMENT value)); - void TABLE_finalize (struct TABLE *t); + void add_locale_TABLE (struct locale_file *file, struct TABLE *t); */ #define CONCAT(a,b) CONCAT1(a,b) @@ -57,9 +58,8 @@ struct TABLE size_t level3_alloc; size_t level3_size; ELEMENT *level3; - /* Compressed representation. */ + /* Size of compressed representation. */ size_t result_size; - char *result; }; /* Initialize. Assumes t->p and t->q have already been set. */ @@ -206,15 +206,15 @@ CONCAT(TABLE,_iterate) (struct TABLE *t, } #endif -#ifndef NO_FINALIZE +#ifndef NO_ADD_LOCALE /* Finalize and shrink. */ static void -CONCAT(TABLE,_finalize) (struct TABLE *t) +CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t) { size_t i, j, k; uint32_t reorder3[t->level3_size]; uint32_t reorder2[t->level2_size]; - uint32_t level1_offset, level2_offset, level3_offset, last_offset; + uint32_t level2_offset, level3_offset, last_offset; /* Uniquify level3 blocks. */ k = 0; @@ -270,11 +270,8 @@ CONCAT(TABLE,_finalize) (struct TABLE *t) + t->level1_size * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t) + (t->level3_size << t->p) * sizeof (ELEMENT); - t->result_size = (last_offset + 3) & ~3ul; - t->result = (char *) xmalloc (t->result_size); + t->result_size = LOCFILE_ALIGN_UP (last_offset); - level1_offset = - 5 * sizeof (uint32_t); level2_offset = 5 * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t); @@ -283,29 +280,36 @@ CONCAT(TABLE,_finalize) (struct TABLE *t) + t->level1_size * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t); - ((uint32_t *) t->result)[0] = t->q + t->p; - ((uint32_t *) t->result)[1] = t->level1_size; - ((uint32_t *) t->result)[2] = t->p; - ((uint32_t *) t->result)[3] = (1 << t->q) - 1; - ((uint32_t *) t->result)[4] = (1 << t->p) - 1; + start_locale_structure (file); + add_locale_uint32 (file, t->q + t->p); + add_locale_uint32 (file, t->level1_size); + add_locale_uint32 (file, t->p); + add_locale_uint32 (file, (1 << t->q) - 1); + add_locale_uint32 (file, (1 << t->p) - 1); for (i = 0; i < t->level1_size; i++) - ((uint32_t *) (t->result + level1_offset))[i] = - (t->level1[i] == EMPTY + add_locale_uint32 + (file, + t->level1[i] == EMPTY ? 0 : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset); for (i = 0; i < (t->level2_size << t->q); i++) - ((uint32_t *) (t->result + level2_offset))[i] = - (t->level2[i] == EMPTY + add_locale_uint32 + (file, + t->level2[i] == EMPTY ? 0 : (t->level2[i] << t->p) * sizeof (ELEMENT) + level3_offset); - for (i = 0; i < (t->level3_size << t->p); i++) - ((ELEMENT *) (t->result + level3_offset))[i] = t->level3[i]; - - if (last_offset < t->result_size) - memset (t->result + last_offset, 0, t->result_size - last_offset); + if (sizeof (ELEMENT) == 1) + add_locale_raw_data (file, t->level3, t->level3_size << t->p); + else if (sizeof (ELEMENT) == sizeof (uint32_t)) + add_locale_uint32_array (file, (uint32_t *) t->level3, + t->level3_size << t->p); + else + abort (); + align_locale_data (file, LOCFILE_ALIGN); + end_locale_structure (file); if (t->level1_alloc > 0) free (t->level1); @@ -321,4 +325,4 @@ CONCAT(TABLE,_finalize) (struct TABLE *t) #undef ELEMENT #undef DEFAULT #undef ITERATE -#undef NO_FINALIZE +#undef NO_ADD_LOCALE diff --git a/locale/programs/ld-address.c b/locale/programs/ld-address.c index 39b9a836f4..291e7b787f 100644 --- a/locale/programs/ld-address.c +++ b/locale/programs/ld-address.c @@ -349,97 +349,23 @@ address_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { struct locale_address_t *address = locale->categories[LC_ADDRESS].address; - struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_ADDRESS); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) address->postal_fmt; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_post; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_ab2; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_ab3; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_car; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - - /* Align following data */ - iov[cnt].iov_base = (void *) "\0\0"; - iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2]; - idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3; - ++cnt; - - iov[cnt].iov_base = (void *) &address->country_num; - iov[cnt].iov_len = sizeof (uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->country_isbn; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->lang_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->lang_ab; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->lang_term; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) address->lang_lib; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)); - - write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", - 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)); + add_locale_string (&file, address->postal_fmt); + add_locale_string (&file, address->country_name); + add_locale_string (&file, address->country_post); + add_locale_string (&file, address->country_ab2); + add_locale_string (&file, address->country_ab3); + add_locale_string (&file, address->country_car); + add_locale_uint32 (&file, address->country_num); + add_locale_string (&file, address->country_isbn); + add_locale_string (&file, address->lang_name); + add_locale_string (&file, address->lang_ab); + add_locale_string (&file, address->lang_term); + add_locale_string (&file, address->lang_lib); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", &file); } diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c index e58c8f7020..f7ae09792a 100644 --- a/locale/programs/ld-collate.c +++ b/locale/programs/ld-collate.c @@ -44,6 +44,8 @@ static inline void __attribute ((always_inline)) obstack_int32_grow (struct obstack *obstack, int32_t data) { + assert (LOCFILE_ALIGNED_P (obstack_object_size (obstack))); + data = maybe_swap_uint32 (data); if (sizeof (int32_t) == sizeof (int)) obstack_int_grow (obstack, data); else @@ -54,6 +56,8 @@ static inline void __attribute ((always_inline)) obstack_int32_grow_fast (struct obstack *obstack, int32_t data) { + assert (LOCFILE_ALIGNED_P (obstack_object_size (obstack))); + data = maybe_swap_uint32 (data); if (sizeof (int32_t) == sizeof (int)) obstack_int_grow_fast (obstack, data); else @@ -165,7 +169,7 @@ struct symbol_t #define ELEMENT struct element_t * #define DEFAULT NULL #define ITERATE -#define NO_FINALIZE +#define NO_ADD_LOCALE #include "3level.h" /* Sparse table of int32_t. */ @@ -348,6 +352,9 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen, { size_t nwcs = wcslen ((wchar_t *) wcs); uint32_t zero = 0; + /* Handle <U0000> as a single character. */ + if (nwcs == 0) + nwcs = 1; obstack_grow (&collate->mempool, wcs, nwcs * sizeof (uint32_t)); obstack_grow (&collate->mempool, &zero, sizeof (uint32_t)); newp->wcs = (uint32_t *) obstack_finish (&collate->mempool); @@ -1813,8 +1820,6 @@ symbol `%s' has the same encoding as"), (*eptr)->name); runp = runp->next; } - collseq_table_finalize (&collate->wcseqorder); - /* Now determine whether the UNDEFINED entry is needed and if yes, whether it was defined. */ collate->undefined.used_in_level = need_undefined ? ~0ul : 0; @@ -1957,6 +1962,7 @@ output_weightwc (struct obstack *pool, struct locale_collate_t *collate, obstack_int32_grow (pool, j); obstack_grow (pool, buf, j * sizeof (int32_t)); + maybe_swap_uint32_obstack (pool, j); } return retval | ((elem->section->ruleidx & 0x7f) << 24); @@ -2075,6 +2081,7 @@ add_to_tablewc (uint32_t ch, struct element_t *runp) weightidx = output_weightwc (atwc.weightpool, atwc.collate, runp); + assert (runp->nwcs > 0); added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t); if (sizeof (int) == sizeof (int32_t)) obstack_make_room (atwc.extrapool, added); @@ -2098,10 +2105,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, { struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate; const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE); - struct iovec iov[2 + nelems]; - struct locale_file data; - uint32_t idx[nelems]; - size_t cnt; + struct locale_file file; size_t ch; int32_t tablemb[256]; struct obstack weightpool; @@ -2114,51 +2118,22 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, int i; struct element_t *runp; - data.magic = LIMAGIC (LC_COLLATE); - data.n = nelems; - iov[0].iov_base = (void *) &data; - iov[0].iov_len = sizeof (data); - - iov[1].iov_base = (void *) idx; - iov[1].iov_len = sizeof (idx); - - idx[0] = iov[0].iov_len + iov[1].iov_len; - cnt = 0; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_NRULES)); - iov[2 + cnt].iov_base = &nrules; - iov[2 + cnt].iov_len = sizeof (uint32_t); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + init_locale_data (&file, nelems); + add_locale_uint32 (&file, nrules); /* If we have no LC_COLLATE data emit only the number of rules as zero. */ if (collate == NULL) { - int32_t dummy = 0; - - while (cnt < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)) + size_t idx; + for (idx = 1; idx < nelems; idx++) { /* The words have to be handled specially. */ - if (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) - { - iov[2 + cnt].iov_base = &dummy; - iov[2 + cnt].iov_len = sizeof (int32_t); - } + if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) + add_locale_uint32 (&file, 0); else - { - iov[2 + cnt].iov_base = NULL; - iov[2 + cnt].iov_len = 0; - } - - if (cnt + 1 < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)) - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + add_locale_empty (&file); } - - assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)); - - write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov); - + write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file); return; } @@ -2185,17 +2160,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, ++i; } /* And align the output. */ - i = (nrules * i) % __alignof__ (int32_t); + i = (nrules * i) % LOCFILE_ALIGN; if (i > 0) do obstack_1grow (&weightpool, '\0'); - while (++i < __alignof__ (int32_t)); + while (++i < LOCFILE_ALIGN); - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_RULESETS)); - iov[2 + cnt].iov_len = obstack_object_size (&weightpool); - iov[2 + cnt].iov_base = obstack_finish (&weightpool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + add_locale_raw_obstack (&file, &weightpool); /* Generate the 8-bit table. Walk through the lists of sequences starting with the same byte and add them one after the other to @@ -2239,8 +2210,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, struct element_t *runp = collate->mbheads[ch]; struct element_t *lastp; - assert ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) == 0); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); tablemb[ch] = -obstack_object_size (&extrapool); @@ -2265,11 +2235,9 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, struct element_t *curp; /* Compute how much space we will need. */ - added = ((sizeof (int32_t) + 1 + 2 * (runp->nmbs - 1) - + __alignof__ (int32_t) - 1) - & ~(__alignof__ (int32_t) - 1)); - assert ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) == 0); + added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + + 2 * (runp->nmbs - 1)); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); obstack_make_room (&extrapool, added); /* More than one consecutive entry. We mark this by having @@ -2326,11 +2294,9 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, /* Output the weight info. */ weightidx = output_weight (&weightpool, collate, runp); - added = ((sizeof (int32_t) + 1 + runp->nmbs - 1 - + __alignof__ (int32_t) - 1) - & ~(__alignof__ (int32_t) - 1)); - assert ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) == 0); + added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + + runp->nmbs - 1); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); obstack_make_room (&extrapool, added); obstack_int32_grow_fast (&extrapool, weightidx); @@ -2342,8 +2308,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, } /* Add alignment bytes if necessary. */ - while ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))) obstack_1grow_fast (&extrapool, '\0'); /* Next entry. */ @@ -2352,15 +2317,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, } while (runp != NULL); - assert ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) == 0); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); /* If the final entry in the list is not a single character we add an UNDEFINED entry here. */ if (lastp->nmbs != 1) { - int added = ((sizeof (int32_t) + 1 + 1 + __alignof__ (int32_t) - 1) - & ~(__alignof__ (int32_t) - 1)); + int added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + 1); obstack_make_room (&extrapool, added); obstack_int32_grow_fast (&extrapool, 0); @@ -2370,67 +2333,26 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, obstack_1grow_fast (&extrapool, 0); /* Add alignment bytes if necessary. */ - while ((obstack_object_size (&extrapool) - & (__alignof__ (int32_t) - 1)) != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))) obstack_1grow_fast (&extrapool, '\0'); } } /* Add padding to the tables if necessary. */ - while ((obstack_object_size (&weightpool) & (__alignof__ (int32_t) - 1)) - != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&weightpool))) obstack_1grow (&weightpool, 0); /* Now add the four tables. */ - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB)); - iov[2 + cnt].iov_base = tablemb; - iov[2 + cnt].iov_len = sizeof (tablemb); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTMB)); - iov[2 + cnt].iov_len = obstack_object_size (&weightpool); - iov[2 + cnt].iov_base = obstack_finish (&weightpool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAMB)); - iov[2 + cnt].iov_len = obstack_object_size (&extrapool); - iov[2 + cnt].iov_base = obstack_finish (&extrapool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTMB)); - iov[2 + cnt].iov_len = obstack_object_size (&indirectpool); - iov[2 + cnt].iov_base = obstack_finish (&indirectpool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0); - ++cnt; - + add_locale_uint32_array (&file, (const uint32_t *) tablemb, 256); + add_locale_raw_obstack (&file, &weightpool); + add_locale_raw_obstack (&file, &extrapool); + add_locale_raw_obstack (&file, &indirectpool); /* Now the same for the wide character table. We need to store some more information here. */ - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP1)); - iov[2 + cnt].iov_base = NULL; - iov[2 + cnt].iov_len = 0; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP2)); - iov[2 + cnt].iov_base = NULL; - iov[2 + cnt].iov_len = 0; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP3)); - iov[2 + cnt].iov_base = NULL; - iov[2 + cnt].iov_len = 0; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; + add_locale_empty (&file); + add_locale_empty (&file); + add_locale_empty (&file); /* Since we are using the sign of an integer to mark indirection the offsets in the arrays we are indirectly referring to must not be @@ -2462,41 +2384,11 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, memset (&atwc, 0, sizeof (atwc)); - collidx_table_finalize (&tablewc); - /* Now add the four tables. */ - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC)); - iov[2 + cnt].iov_base = tablewc.result; - iov[2 + cnt].iov_len = tablewc.result_size; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0); - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTWC)); - iov[2 + cnt].iov_len = obstack_object_size (&weightpool); - iov[2 + cnt].iov_base = obstack_finish (&weightpool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0); - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAWC)); - iov[2 + cnt].iov_len = obstack_object_size (&extrapool); - iov[2 + cnt].iov_base = obstack_finish (&extrapool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0); - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTWC)); - iov[2 + cnt].iov_len = obstack_object_size (&indirectpool); - iov[2 + cnt].iov_base = obstack_finish (&indirectpool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0); - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - + add_locale_collidx_table (&file, &tablewc); + add_locale_raw_obstack (&file, &weightpool); + add_locale_raw_obstack (&file, &extrapool); + add_locale_raw_obstack (&file, &indirectpool); /* Finally write the table with collation element names out. It is a hash table with a simple function which gets the name of the @@ -2586,6 +2478,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, obstack_int32_grow (&extrapool, runp->nwcs); obstack_grow (&extrapool, runp->wcs, runp->nwcs * sizeof (uint32_t)); + maybe_swap_uint32_obstack (&extrapool, runp->nwcs); obstack_int32_grow (&extrapool, runp->wcseqorder); } @@ -2594,47 +2487,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, } /* Prepare to write out this data. */ - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)); - iov[2 + cnt].iov_base = &elem_size; - iov[2 + cnt].iov_len = sizeof (int32_t); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_TABLEMB)); - iov[2 + cnt].iov_base = elem_table; - iov[2 + cnt].iov_len = elem_size * 2 * sizeof (int32_t); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_EXTRAMB)); - iov[2 + cnt].iov_len = obstack_object_size (&extrapool); - iov[2 + cnt].iov_base = obstack_finish (&extrapool); - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB)); - iov[2 + cnt].iov_base = collate->mbseqorder; - iov[2 + cnt].iov_len = 256; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC)); - iov[2 + cnt].iov_base = collate->wcseqorder.result; - iov[2 + cnt].iov_len = collate->wcseqorder.result_size; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - assert (idx[cnt] % __alignof__ (int32_t) == 0); - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_CODESET)); - iov[2 + cnt].iov_base = (void *) charmap->code_set_name; - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - ++cnt; - - assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE)); - - write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov); + add_locale_uint32 (&file, elem_size); + add_locale_uint32_array (&file, elem_table, 2 * elem_size); + add_locale_raw_obstack (&file, &extrapool); + add_locale_raw_data (&file, collate->mbseqorder, 256); + add_locale_collseq_table (&file, &collate->wcseqorder); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file); obstack_free (&weightpool, NULL); obstack_free (&extrapool, NULL); diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index 8be7fce887..e7e17b86f9 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -119,9 +119,51 @@ struct translit_include_t #define TABLE idx_table #define ELEMENT uint32_t #define DEFAULT ((uint32_t) ~0) -#define NO_FINALIZE +#define NO_ADD_LOCALE #include "3level.h" +#define TABLE wcwidth_table +#define ELEMENT uint8_t +#define DEFAULT 0xff +#include "3level.h" + +#define TABLE wctrans_table +#define ELEMENT int32_t +#define DEFAULT 0 +#define wctrans_table_add wctrans_table_add_internal +#include "3level.h" +#undef wctrans_table_add +/* The wctrans_table must actually store the difference between the + desired result and the argument. */ +static inline void +wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc) +{ + wctrans_table_add_internal (t, wc, mapped_wc - wc); +} + +/* Construction of sparse 3-level tables. + See wchar-lookup.h for their structure and the meaning of p and q. */ + +struct wctype_table +{ + /* Parameters. */ + unsigned int p; + unsigned int q; + /* Working representation. */ + size_t level1_alloc; + size_t level1_size; + uint32_t *level1; + size_t level2_alloc; + size_t level2_size; + uint32_t *level2; + size_t level3_alloc; + size_t level3_size; + uint32_t *level3; + size_t result_size; +}; + +static void add_locale_wctype_table (struct locale_file *file, + struct wctype_table *t); /* The real definition of the struct for the LC_CTYPE locale. */ struct locale_ctype_t @@ -189,11 +231,11 @@ struct locale_ctype_t uint32_t **map_b; uint32_t **map32_b; uint32_t **class_b; - struct iovec *class_3level; - struct iovec *map_3level; + struct wctype_table *class_3level; + struct wctrans_table *map_3level; uint32_t *class_name_ptr; uint32_t *map_name_ptr; - struct iovec width; + struct wcwidth_table width; uint32_t mb_cur_max; const char *codeset_name; uint32_t *translit_from_idx; @@ -228,7 +270,7 @@ static void ctype_map_new (struct linereader *lr, struct locale_ctype_t *ctype, const char *name, const struct charmap_t *charmap); static uint32_t *find_idx (struct locale_ctype_t *ctype, uint32_t **table, - size_t *max, size_t *act, unsigned int idx); + size_t *max, size_t *act, uint32_t idx); static void set_class_defaults (struct locale_ctype_t *ctype, const struct charmap_t *charmap, struct repertoire_t *repertoire); @@ -269,9 +311,8 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale, /* We have seen no names yet. */ ctype->charnames_max = charmap->mb_cur_max == 1 ? 256 : 512; - ctype->charnames = - (unsigned int *) xmalloc (ctype->charnames_max - * sizeof (unsigned int)); + ctype->charnames = (uint32_t *) xmalloc (ctype->charnames_max + * sizeof (uint32_t)); for (cnt = 0; cnt < 256; ++cnt) ctype->charnames[cnt] = cnt; ctype->charnames_act = 256; @@ -905,33 +946,21 @@ void ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { - static const char nulbytes[4] = { 0, 0, 0, 0 }; struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype; const size_t nelems = (_NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1) + ctype->nr_charclass + ctype->map_collection_nr); - struct iovec *iov = alloca (sizeof *iov - * (2 + nelems + 2 * ctype->nr_charclass - + ctype->map_collection_nr + 4)); - struct locale_file data; - uint32_t *idx = alloca (sizeof *idx * (nelems + 1)); + struct locale_file file; uint32_t default_missing_len; - size_t elem, cnt, offset, total; - char *cp; + size_t elem, cnt; /* Now prepare the output: Find the sizes of the table we can use. */ allocate_arrays (ctype, charmap, ctype->repertoire); - data.magic = LIMAGIC (LC_CTYPE); - data.n = nelems; - iov[0].iov_base = (void *) &data; - iov[0].iov_len = sizeof (data); - - iov[1].iov_base = (void *) idx; - iov[1].iov_len = nelems * sizeof (uint32_t); - - idx[0] = iov[0].iov_len + iov[1].iov_len; - offset = 0; + default_missing_len = (ctype->default_missing + ? wcslen ((wchar_t *) ctype->default_missing) + : 0); + init_locale_data (&file, nelems); for (elem = 0; elem < nelems; ++elem) { if (elem < _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1)) @@ -939,9 +968,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, { #define CTYPE_EMPTY(name) \ case name: \ - iov[2 + elem + offset].iov_base = NULL; \ - iov[2 + elem + offset].iov_len = 0; \ - idx[elem + 1] = idx[elem]; \ + add_locale_empty (&file); \ break CTYPE_EMPTY(_NL_CTYPE_GAP1); @@ -951,273 +978,156 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, CTYPE_EMPTY(_NL_CTYPE_GAP5); CTYPE_EMPTY(_NL_CTYPE_GAP6); -#define CTYPE_DATA(name, base, len) \ +#define CTYPE_RAW_DATA(name, base, size) \ case _NL_ITEM_INDEX (name): \ - iov[2 + elem + offset].iov_base = (base); \ - iov[2 + elem + offset].iov_len = (len); \ - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; \ + add_locale_raw_data (&file, base, size); \ break - CTYPE_DATA (_NL_CTYPE_CLASS, - ctype->ctype_b, - (256 + 128) * sizeof (char_class_t)); + CTYPE_RAW_DATA (_NL_CTYPE_CLASS, + ctype->ctype_b, + (256 + 128) * sizeof (char_class_t)); - CTYPE_DATA (_NL_CTYPE_TOUPPER, - ctype->map_b[0], - (256 + 128) * sizeof (uint32_t)); - CTYPE_DATA (_NL_CTYPE_TOLOWER, - ctype->map_b[1], - (256 + 128) * sizeof (uint32_t)); - - CTYPE_DATA (_NL_CTYPE_TOUPPER32, - ctype->map32_b[0], - 256 * sizeof (uint32_t)); - CTYPE_DATA (_NL_CTYPE_TOLOWER32, - ctype->map32_b[1], - 256 * sizeof (uint32_t)); - - CTYPE_DATA (_NL_CTYPE_CLASS32, - ctype->ctype32_b, - 256 * sizeof (char_class32_t)); +#define CTYPE_UINT32_ARRAY(name, base, n_elems) \ + case _NL_ITEM_INDEX (name): \ + add_locale_uint32_array (&file, base, n_elems); \ + break - CTYPE_DATA (_NL_CTYPE_CLASS_OFFSET, - &ctype->class_offset, sizeof (uint32_t)); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER, ctype->map_b[0], 256 + 128); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER, ctype->map_b[1], 256 + 128); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER32, ctype->map32_b[0], 256); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER32, ctype->map32_b[1], 256); + CTYPE_RAW_DATA (_NL_CTYPE_CLASS32, + ctype->ctype32_b, + 256 * sizeof (char_class32_t)); - CTYPE_DATA (_NL_CTYPE_MAP_OFFSET, - &ctype->map_offset, sizeof (uint32_t)); +#define CTYPE_UINT32(name, value) \ + case _NL_ITEM_INDEX (name): \ + add_locale_uint32 (&file, value); \ + break - CTYPE_DATA (_NL_CTYPE_TRANSLIT_TAB_SIZE, - &ctype->translit_idx_size, sizeof (uint32_t)); + CTYPE_UINT32 (_NL_CTYPE_CLASS_OFFSET, ctype->class_offset); + CTYPE_UINT32 (_NL_CTYPE_MAP_OFFSET, ctype->map_offset); + CTYPE_UINT32 (_NL_CTYPE_TRANSLIT_TAB_SIZE, ctype->translit_idx_size); - CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_IDX, - ctype->translit_from_idx, - ctype->translit_idx_size * sizeof (uint32_t)); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_IDX, + ctype->translit_from_idx, + ctype->translit_idx_size); - CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_TBL, - ctype->translit_from_tbl, - ctype->translit_from_tbl_size); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_TBL, + ctype->translit_from_tbl, + ctype->translit_from_tbl_size + / sizeof (uint32_t)); - CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_IDX, - ctype->translit_to_idx, - ctype->translit_idx_size * sizeof (uint32_t)); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_IDX, + ctype->translit_to_idx, + ctype->translit_idx_size); - CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_TBL, - ctype->translit_to_tbl, ctype->translit_to_tbl_size); + CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_TBL, + ctype->translit_to_tbl, + ctype->translit_to_tbl_size / sizeof (uint32_t)); case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES): /* The class name array. */ - total = 0; - for (cnt = 0; cnt < ctype->nr_charclass; ++cnt, ++offset) - { - iov[2 + elem + offset].iov_base - = (void *) ctype->classnames[cnt]; - iov[2 + elem + offset].iov_len - = strlen (ctype->classnames[cnt]) + 1; - total += iov[2 + elem + offset].iov_len; - } - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = 4 - (total % 4); - total += 4 - (total % 4); - - idx[elem + 1] = idx[elem] + total; + start_locale_structure (&file); + for (cnt = 0; cnt < ctype->nr_charclass; ++cnt) + add_locale_string (&file, ctype->classnames[cnt]); + add_locale_char (&file, 0); + align_locale_data (&file, LOCFILE_ALIGN); + end_locale_structure (&file); break; case _NL_ITEM_INDEX (_NL_CTYPE_MAP_NAMES): /* The class name array. */ - total = 0; - for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt, ++offset) - { - iov[2 + elem + offset].iov_base - = (void *) ctype->mapnames[cnt]; - iov[2 + elem + offset].iov_len - = strlen (ctype->mapnames[cnt]) + 1; - total += iov[2 + elem + offset].iov_len; - } - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = 4 - (total % 4); - total += 4 - (total % 4); - - idx[elem + 1] = idx[elem] + total; + start_locale_structure (&file); + for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt) + add_locale_string (&file, ctype->mapnames[cnt]); + add_locale_char (&file, 0); + align_locale_data (&file, LOCFILE_ALIGN); + end_locale_structure (&file); break; - CTYPE_DATA (_NL_CTYPE_WIDTH, - ctype->width.iov_base, - ctype->width.iov_len); + case _NL_ITEM_INDEX (_NL_CTYPE_WIDTH): + add_locale_wcwidth_table (&file, &ctype->width); + break; - CTYPE_DATA (_NL_CTYPE_MB_CUR_MAX, - &ctype->mb_cur_max, sizeof (uint32_t)); + CTYPE_UINT32 (_NL_CTYPE_MB_CUR_MAX, ctype->mb_cur_max); case _NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME): - total = strlen (ctype->codeset_name) + 1; - if (total % 4 == 0) - iov[2 + elem + offset].iov_base = (char *) ctype->codeset_name; - else - { - iov[2 + elem + offset].iov_base = alloca ((total + 3) & ~3); - memset (mempcpy (iov[2 + elem + offset].iov_base, - ctype->codeset_name, total), - '\0', 4 - (total & 3)); - total = (total + 3) & ~3; - } - iov[2 + elem + offset].iov_len = total; - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_string (&file, ctype->codeset_name); break; + CTYPE_UINT32 (_NL_CTYPE_MAP_TO_NONASCII, ctype->to_nonascii); - CTYPE_DATA (_NL_CTYPE_MAP_TO_NONASCII, - &ctype->to_nonascii, sizeof (uint32_t)); - - CTYPE_DATA (_NL_CTYPE_NONASCII_CASE, - &ctype->nonascii_case, sizeof (uint32_t)); + CTYPE_UINT32 (_NL_CTYPE_NONASCII_CASE, ctype->nonascii_case); case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN): - iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t)); - iov[2 + elem + offset].iov_len = sizeof (uint32_t); - *(uint32_t *) iov[2 + elem + offset].iov_base = - ctype->mbdigits_act / 10; - idx[elem + 1] = idx[elem] + sizeof (uint32_t); + add_locale_uint32 (&file, ctype->mbdigits_act / 10); break; case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_WC_LEN): - /* Align entries. */ - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4; - idx[elem] += iov[2 + elem + offset].iov_len; - ++offset; - - iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t)); - iov[2 + elem + offset].iov_len = sizeof (uint32_t); - *(uint32_t *) iov[2 + elem + offset].iov_base = - ctype->wcdigits_act / 10; - idx[elem + 1] = idx[elem] + sizeof (uint32_t); + add_locale_uint32 (&file, ctype->wcdigits_act / 10); break; case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_MB): - /* Compute the length of all possible characters. For INDIGITS - there might be more than one. We simply concatenate all of - them with a NUL byte following. The NUL byte wouldn't be - necessary but it makes it easier for the user. */ - total = 0; - - for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB); - cnt < ctype->mbdigits_act; cnt += 10) - total += ctype->mbdigits[cnt]->nbytes + 1; - iov[2 + elem + offset].iov_base = (char *) alloca (total); - iov[2 + elem + offset].iov_len = total; - - cp = iov[2 + elem + offset].iov_base; + start_locale_structure (&file); for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB); cnt < ctype->mbdigits_act; cnt += 10) { - cp = mempcpy (cp, ctype->mbdigits[cnt]->bytes, - ctype->mbdigits[cnt]->nbytes); - *cp++ = '\0'; + add_locale_raw_data (&file, ctype->mbdigits[cnt]->bytes, + ctype->mbdigits[cnt]->nbytes); + add_locale_char (&file, 0); } - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + end_locale_structure (&file); break; case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_MB): - /* Compute the length of all possible characters. For INDIGITS - there might be more than one. We simply concatenate all of - them with a NUL byte following. The NUL byte wouldn't be - necessary but it makes it easier for the user. */ + start_locale_structure (&file); cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB); - total = ctype->mboutdigits[cnt]->nbytes + 1; - iov[2 + elem + offset].iov_base = (char *) alloca (total); - iov[2 + elem + offset].iov_len = total; - - *(char *) mempcpy (iov[2 + elem + offset].iov_base, - ctype->mboutdigits[cnt]->bytes, - ctype->mboutdigits[cnt]->nbytes) = '\0'; - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_raw_data (&file, ctype->mboutdigits[cnt]->bytes, + ctype->mboutdigits[cnt]->nbytes); + add_locale_char (&file, 0); + end_locale_structure (&file); break; case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_WC): - total = ctype->wcdigits_act / 10; - - iov[2 + elem + offset].iov_base = - (uint32_t *) alloca (total * sizeof (uint32_t)); - iov[2 + elem + offset].iov_len = total * sizeof (uint32_t); - + start_locale_structure (&file); for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC); cnt < ctype->wcdigits_act; cnt += 10) - ((uint32_t *) iov[2 + elem + offset].iov_base)[cnt / 10] - = ctype->wcdigits[cnt]; - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_uint32 (&file, ctype->wcdigits[cnt]); + end_locale_structure (&file); break; - case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC): - /* Align entries. */ - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4; - idx[elem] += iov[2 + elem + offset].iov_len; - ++offset; - /* FALLTRHOUGH */ - - case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT1_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC): + case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC): cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC); - iov[2 + elem + offset].iov_base = &ctype->wcoutdigits[cnt]; - iov[2 + elem + offset].iov_len = sizeof (uint32_t); - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_uint32 (&file, ctype->wcoutdigits[cnt]); break; case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN): - /* Align entries. */ - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4; - idx[elem] += iov[2 + elem + offset].iov_len; - ++offset; - - default_missing_len = (ctype->default_missing - ? wcslen ((wchar_t *)ctype->default_missing) - : 0); - iov[2 + elem + offset].iov_base = &default_missing_len; - iov[2 + elem + offset].iov_len = sizeof (uint32_t); - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_uint32 (&file, default_missing_len); break; case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING): - iov[2 + elem + offset].iov_base = - ctype->default_missing ?: (uint32_t *) L""; - iov[2 + elem + offset].iov_len = - wcslen (iov[2 + elem + offset].iov_base) * sizeof (uint32_t); - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_uint32_array (&file, ctype->default_missing, + default_missing_len); break; case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE_LEN): - /* Align entries. */ - iov[2 + elem + offset].iov_base = (void *) nulbytes; - iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4; - idx[elem] += iov[2 + elem + offset].iov_len; - ++offset; - - iov[2 + elem + offset].iov_base = &ctype->ntranslit_ignore; - iov[2 + elem + offset].iov_len = sizeof (uint32_t); - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + add_locale_uint32 (&file, ctype->ntranslit_ignore); break; case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE): + start_locale_structure (&file); { - uint32_t *ranges = (uint32_t *) alloca (ctype->ntranslit_ignore - * 3 * sizeof (uint32_t)); struct translit_ignore_t *runp; - - iov[2 + elem + offset].iov_base = ranges; - iov[2 + elem + offset].iov_len = (ctype->ntranslit_ignore - * 3 * sizeof (uint32_t)); - for (runp = ctype->translit_ignore; runp != NULL; runp = runp->next) { - *ranges++ = runp->from; - *ranges++ = runp->to; - *ranges++ = runp->step; + add_locale_uint32 (&file, runp->from); + add_locale_uint32 (&file, runp->to); + add_locale_uint32 (&file, runp->step); } } - /* Remove the following line in case a new entry is added - after _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN. */ - if (elem < nelems) - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; + end_locale_structure (&file); break; default: @@ -1229,28 +1139,21 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, size_t nr = elem - _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1); if (nr < ctype->nr_charclass) { - iov[2 + elem + offset].iov_base = ctype->class_b[nr]; - iov[2 + elem + offset].iov_len = 256 / 32 * sizeof (uint32_t); - idx[elem] += iov[2 + elem + offset].iov_len; - ++offset; - - iov[2 + elem + offset] = ctype->class_3level[nr]; + start_locale_prelude (&file); + add_locale_uint32_array (&file, ctype->class_b[nr], 256 / 32); + end_locale_prelude (&file); + add_locale_wctype_table (&file, &ctype->class_3level[nr]); } else { nr -= ctype->nr_charclass; assert (nr < ctype->map_collection_nr); - iov[2 + elem + offset] = ctype->map_3level[nr]; + add_locale_wctrans_table (&file, &ctype->map_3level[nr]); } - idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len; } } - assert (2 + elem + offset == (nelems + 2 * ctype->nr_charclass - + ctype->map_collection_nr + 4 + 2)); - - write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", 2 + elem + offset, - iov); + write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", &file); } @@ -3529,29 +3432,6 @@ no output digits defined and none of the standard names in the charmap"))); } -/* Construction of sparse 3-level tables. - See wchar-lookup.h for their structure and the meaning of p and q. */ - -struct wctype_table -{ - /* Parameters. */ - unsigned int p; - unsigned int q; - /* Working representation. */ - size_t level1_alloc; - size_t level1_size; - uint32_t *level1; - size_t level2_alloc; - size_t level2_size; - uint32_t *level2; - size_t level3_alloc; - size_t level3_size; - uint32_t *level3; - /* Compressed representation. */ - size_t result_size; - char *result; -}; - /* Initialize. Assumes t->p and t->q have already been set. */ static inline void wctype_table_init (struct wctype_table *t) @@ -3657,12 +3537,12 @@ wctype_table_add (struct wctype_table *t, uint32_t wc) /* Finalize and shrink. */ static void -wctype_table_finalize (struct wctype_table *t) +add_locale_wctype_table (struct locale_file *file, struct wctype_table *t) { size_t i, j, k; uint32_t reorder3[t->level3_size]; uint32_t reorder2[t->level2_size]; - uint32_t level1_offset, level2_offset, level3_offset; + uint32_t level2_offset, level3_offset; /* Uniquify level3 blocks. */ k = 0; @@ -3712,16 +3592,12 @@ wctype_table_finalize (struct wctype_table *t) if (t->level1[i] != EMPTY) t->level1[i] = reorder2[t->level1[i]]; - /* Create and fill the resulting compressed representation. */ t->result_size = 5 * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t) + (t->level3_size << t->p) * sizeof (uint32_t); - t->result = (char *) xmalloc (t->result_size); - level1_offset = - 5 * sizeof (uint32_t); level2_offset = 5 * sizeof (uint32_t) + t->level1_size * sizeof (uint32_t); @@ -3730,26 +3606,29 @@ wctype_table_finalize (struct wctype_table *t) + t->level1_size * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t); - ((uint32_t *) t->result)[0] = t->q + t->p + 5; - ((uint32_t *) t->result)[1] = t->level1_size; - ((uint32_t *) t->result)[2] = t->p + 5; - ((uint32_t *) t->result)[3] = (1 << t->q) - 1; - ((uint32_t *) t->result)[4] = (1 << t->p) - 1; + start_locale_structure (file); + add_locale_uint32 (file, t->q + t->p + 5); + add_locale_uint32 (file, t->level1_size); + add_locale_uint32 (file, t->p + 5); + add_locale_uint32 (file, (1 << t->q) - 1); + add_locale_uint32 (file, (1 << t->p) - 1); for (i = 0; i < t->level1_size; i++) - ((uint32_t *) (t->result + level1_offset))[i] = - (t->level1[i] == EMPTY + add_locale_uint32 + (file, + t->level1[i] == EMPTY ? 0 : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset); for (i = 0; i < (t->level2_size << t->q); i++) - ((uint32_t *) (t->result + level2_offset))[i] = - (t->level2[i] == EMPTY + add_locale_uint32 + (file, + t->level2[i] == EMPTY ? 0 : (t->level2[i] << t->p) * sizeof (uint32_t) + level3_offset); - for (i = 0; i < (t->level3_size << t->p); i++) - ((uint32_t *) (t->result + level3_offset))[i] = t->level3[i]; + add_locale_uint32_array (file, t->level3, t->level3_size << t->p); + end_locale_structure (file); if (t->level1_alloc > 0) free (t->level1); @@ -3759,26 +3638,6 @@ wctype_table_finalize (struct wctype_table *t) free (t->level3); } -#define TABLE wcwidth_table -#define ELEMENT uint8_t -#define DEFAULT 0xff -#include "3level.h" - -#define TABLE wctrans_table -#define ELEMENT int32_t -#define DEFAULT 0 -#define wctrans_table_add wctrans_table_add_internal -#include "3level.h" -#undef wctrans_table_add -/* The wctrans_table must actually store the difference between the - desired result and the argument. */ -static inline void -wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc) -{ - wctrans_table_add_internal (t, wc, mapped_wc - wc); -} - - /* Flattens the included transliterations into a translit list. Inserts them in the list at `cursor', and returns the new cursor. */ static struct translit_t ** @@ -3855,8 +3714,8 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, ctype->ctype32_b = (char_class32_t *) xcalloc (256, sizeof (char_class32_t)); ctype->class_b = (uint32_t **) xmalloc (ctype->nr_charclass * sizeof (uint32_t *)); - ctype->class_3level = (struct iovec *) - xmalloc (ctype->nr_charclass * sizeof (struct iovec)); + ctype->class_3level = (struct wctype_table *) + xmalloc (ctype->nr_charclass * sizeof (struct wctype_table)); /* This is the array accessed using the multibyte string elements. */ for (idx = 0; idx < 256; ++idx) @@ -3888,34 +3747,30 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, for (nr = 0; nr < ctype->nr_charclass; nr++) { - struct wctype_table t; + struct wctype_table *t; - t.p = 4; /* or: 5 */ - t.q = 7; /* or: 6 */ - wctype_table_init (&t); + t = &ctype->class_3level[nr]; + t->p = 4; /* or: 5 */ + t->q = 7; /* or: 6 */ + wctype_table_init (t); for (idx = 0; idx < ctype->class_collection_act; ++idx) if (ctype->class_collection[idx] & _ISwbit (nr)) - wctype_table_add (&t, ctype->charnames[idx]); - - wctype_table_finalize (&t); + wctype_table_add (t, ctype->charnames[idx]); if (verbose) WITH_CUR_LOCALE (fprintf (stderr, _("\ %s: table for class \"%s\": %lu bytes\n"), "LC_CTYPE", ctype->classnames[nr], - (unsigned long int) t.result_size)); - - ctype->class_3level[nr].iov_base = t.result; - ctype->class_3level[nr].iov_len = t.result_size; + (unsigned long int) t->result_size)); } /* Room for table of mappings. */ ctype->map_b = (uint32_t **) xmalloc (2 * sizeof (uint32_t *)); ctype->map32_b = (uint32_t **) xmalloc (ctype->map_collection_nr * sizeof (uint32_t *)); - ctype->map_3level = (struct iovec *) - xmalloc (ctype->map_collection_nr * sizeof (struct iovec)); + ctype->map_3level = (struct wctrans_table *) + xmalloc (ctype->map_collection_nr * sizeof (struct wctrans_table)); /* Fill in all mappings. */ for (idx = 0; idx < 2; ++idx) @@ -3956,27 +3811,23 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, for (nr = 0; nr < ctype->map_collection_nr; nr++) { - struct wctrans_table t; + struct wctrans_table *t; - t.p = 7; - t.q = 9; - wctrans_table_init (&t); + t = &ctype->map_3level[nr]; + t->p = 7; + t->q = 9; + wctrans_table_init (t); for (idx = 0; idx < ctype->map_collection_act[nr]; ++idx) if (ctype->map_collection[nr][idx] != 0) - wctrans_table_add (&t, ctype->charnames[idx], + wctrans_table_add (t, ctype->charnames[idx], ctype->map_collection[nr][idx]); - wctrans_table_finalize (&t); - if (verbose) WITH_CUR_LOCALE (fprintf (stderr, _("\ %s: table for map \"%s\": %lu bytes\n"), "LC_CTYPE", ctype->mapnames[nr], - (unsigned long int) t.result_size)); - - ctype->map_3level[nr].iov_base = t.result; - ctype->map_3level[nr].iov_len = t.result_size; + (unsigned long int) t->result_size)); } /* Extra array for class and map names. */ @@ -3996,11 +3847,12 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, saves a run-time check. But we put L'\0' in the table. This again saves a run-time check. */ { - struct wcwidth_table t; + struct wcwidth_table *t; - t.p = 7; - t.q = 9; - wcwidth_table_init (&t); + t = &ctype->width; + t->p = 7; + t->q = 9; + wcwidth_table_init (t); /* First set all the printable characters of the character set to the default width. */ @@ -4020,7 +3872,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, &ctype->class_collection_act, data->ucs4); if (class_bits != NULL && (*class_bits & BITw (tok_print))) - wcwidth_table_add (&t, data->ucs4, charmap->width_default); + wcwidth_table_add (t, data->ucs4, charmap->width_default); } } @@ -4068,7 +3920,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, &ctype->class_collection_act, wch); if (class_bits != NULL && (*class_bits & BITw (tok_print))) - wcwidth_table_add (&t, wch, + wcwidth_table_add (t, wch, charmap->width_rules[cnt].width); } @@ -4098,16 +3950,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap, } /* Set the width of L'\0' to 0. */ - wcwidth_table_add (&t, 0, 0); - - wcwidth_table_finalize (&t); + wcwidth_table_add (t, 0, 0); if (verbose) WITH_CUR_LOCALE (fprintf (stderr, _("%s: table for width: %lu bytes\n"), - "LC_CTYPE", (unsigned long int) t.result_size)); - - ctype->width.iov_base = t.result; - ctype->width.iov_len = t.result_size; + "LC_CTYPE", (unsigned long int) t->result_size)); } /* Set MB_CUR_MAX. */ diff --git a/locale/programs/ld-identification.c b/locale/programs/ld-identification.c index 4b03fb6987..5487aae7ce 100644 --- a/locale/programs/ld-identification.c +++ b/locale/programs/ld-identification.c @@ -182,116 +182,32 @@ identification_output (struct localedef_t *locale, { struct locale_identification_t *identification = locale->categories[LC_IDENTIFICATION].identification; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - + (__LC_LAST - 2)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)]; - size_t cnt = 0; + struct locale_file file; size_t num; - size_t last_idx; - - data.magic = LIMAGIC (LC_IDENTIFICATION); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) identification->title; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->source; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->address; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->contact; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->email; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->tel; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->fax; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->language; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->territory; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->audience; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->application; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->abbreviation; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->revision; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) identification->date; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - last_idx = cnt - 1; - idx[last_idx] = idx[cnt - 2]; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)); + add_locale_string (&file, identification->title); + add_locale_string (&file, identification->source); + add_locale_string (&file, identification->address); + add_locale_string (&file, identification->contact); + add_locale_string (&file, identification->email); + add_locale_string (&file, identification->tel); + add_locale_string (&file, identification->fax); + add_locale_string (&file, identification->language); + add_locale_string (&file, identification->territory); + add_locale_string (&file, identification->audience); + add_locale_string (&file, identification->application); + add_locale_string (&file, identification->abbreviation); + add_locale_string (&file, identification->revision); + add_locale_string (&file, identification->date); + start_locale_structure (&file); for (num = 0; num < __LC_LAST; ++num) if (num != LC_ALL) - { - iov[cnt].iov_base = (void *) identification->category[num]; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - idx[last_idx] += iov[cnt].iov_len; - ++cnt; - } - - assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - 1); - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == (2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - + (__LC_LAST - 2))); - - write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION", cnt, - iov); + add_locale_string (&file, identification->category[num]); + end_locale_structure (&file); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION", + &file); } diff --git a/locale/programs/ld-measurement.c b/locale/programs/ld-measurement.c index 4aa0ea99a7..5be54e739d 100644 --- a/locale/programs/ld-measurement.c +++ b/locale/programs/ld-measurement.c @@ -122,35 +122,12 @@ measurement_output (struct localedef_t *locale, { struct locale_measurement_t *measurement = locale->categories[LC_MEASUREMENT].measurement; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_MEASUREMENT); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = &measurement->measurement; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)); - - write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT", - 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)); + add_locale_char (&file, measurement->measurement); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT", &file); } diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c index f1b9f93f26..116f3a2bb6 100644 --- a/locale/programs/ld-messages.c +++ b/locale/programs/ld-messages.c @@ -184,49 +184,15 @@ messages_output (struct localedef_t *locale, const struct charmap_t *charmap, { struct locale_messages_t *messages = locale->categories[LC_MESSAGES].messages; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_MESSAGES); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (char *) messages->yesexpr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (char *) messages->noexpr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (char *) messages->yesstr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (char *) messages->nostr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (char *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - - assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)); - - write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES", - 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)); + add_locale_string (&file, messages->yesexpr); + add_locale_string (&file, messages->noexpr); + add_locale_string (&file, messages->yesstr); + add_locale_string (&file, messages->nostr); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES", &file); } diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c index 4dfca3dd7b..c88275f1cc 100644 --- a/locale/programs/ld-monetary.c +++ b/locale/programs/ld-monetary.c @@ -364,262 +364,57 @@ monetary_output (struct localedef_t *locale, const struct charmap_t *charmap, { struct locale_monetary_t *monetary = locale->categories[LC_MONETARY].monetary; - struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_MONETARY); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) monetary->int_curr_symbol; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->currency_symbol; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->mon_decimal_point; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->mon_thousands_sep; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = monetary->mon_grouping; - iov[cnt].iov_len = monetary->mon_grouping_len; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->positive_sign; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->negative_sign; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_frac_digits; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->frac_digits; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->p_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->p_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->n_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->n_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->p_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->n_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->crncystr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_p_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_p_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_n_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_n_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_p_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->int_n_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->duo_int_curr_symbol; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->duo_currency_symbol; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_frac_digits; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_frac_digits; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_p_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_p_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_n_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_n_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_p_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_p_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_n_cs_precedes; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_n_sep_by_space; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_p_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_n_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_p_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_int_n_sign_posn; - iov[cnt].iov_len = 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - - /* Align following data */ - iov[cnt].iov_base = (void *) "\0\0"; - iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2]; - idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3; - ++cnt; - - iov[cnt].iov_base = (void *) &monetary->uno_valid_from; - iov[cnt].iov_len = sizeof(uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->uno_valid_to; - iov[cnt].iov_len = sizeof(uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_valid_from; - iov[cnt].iov_len = sizeof(uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->duo_valid_to; - iov[cnt].iov_len = sizeof(uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) monetary->conversion_rate; - iov[cnt].iov_len = 2 * sizeof(uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->mon_decimal_point_wc; - iov[cnt].iov_len = sizeof (uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &monetary->mon_thousands_sep_wc; - iov[cnt].iov_len = sizeof (uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)); - - write_locale_data (output_path, LC_MONETARY, "LC_MONETARY", - 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)); + add_locale_string (&file, monetary->int_curr_symbol); + add_locale_string (&file, monetary->currency_symbol); + add_locale_string (&file, monetary->mon_decimal_point); + add_locale_string (&file, monetary->mon_thousands_sep); + add_locale_raw_data (&file, monetary->mon_grouping, + monetary->mon_grouping_len); + add_locale_string (&file, monetary->positive_sign); + add_locale_string (&file, monetary->negative_sign); + add_locale_char (&file, monetary->int_frac_digits); + add_locale_char (&file, monetary->frac_digits); + add_locale_char (&file, monetary->p_cs_precedes); + add_locale_char (&file, monetary->p_sep_by_space); + add_locale_char (&file, monetary->n_cs_precedes); + add_locale_char (&file, monetary->n_sep_by_space); + add_locale_char (&file, monetary->p_sign_posn); + add_locale_char (&file, monetary->n_sign_posn); + add_locale_string (&file, monetary->crncystr); + add_locale_char (&file, monetary->int_p_cs_precedes); + add_locale_char (&file, monetary->int_p_sep_by_space); + add_locale_char (&file, monetary->int_n_cs_precedes); + add_locale_char (&file, monetary->int_n_sep_by_space); + add_locale_char (&file, monetary->int_p_sign_posn); + add_locale_char (&file, monetary->int_n_sign_posn); + add_locale_string (&file, monetary->duo_int_curr_symbol); + add_locale_string (&file, monetary->duo_currency_symbol); + add_locale_char (&file, monetary->duo_int_frac_digits); + add_locale_char (&file, monetary->duo_frac_digits); + add_locale_char (&file, monetary->duo_p_cs_precedes); + add_locale_char (&file, monetary->duo_p_sep_by_space); + add_locale_char (&file, monetary->duo_n_cs_precedes); + add_locale_char (&file, monetary->duo_n_sep_by_space); + add_locale_char (&file, monetary->duo_int_p_cs_precedes); + add_locale_char (&file, monetary->duo_int_p_sep_by_space); + add_locale_char (&file, monetary->duo_int_n_cs_precedes); + add_locale_char (&file, monetary->duo_int_n_sep_by_space); + add_locale_char (&file, monetary->duo_p_sign_posn); + add_locale_char (&file, monetary->duo_n_sign_posn); + add_locale_char (&file, monetary->duo_int_p_sign_posn); + add_locale_char (&file, monetary->duo_int_n_sign_posn); + add_locale_uint32 (&file, monetary->uno_valid_from); + add_locale_uint32 (&file, monetary->uno_valid_to); + add_locale_uint32 (&file, monetary->duo_valid_from); + add_locale_uint32 (&file, monetary->duo_valid_to); + add_locale_uint32_array (&file, monetary->conversion_rate, 2); + add_locale_uint32 (&file, monetary->mon_decimal_point_wc); + add_locale_uint32 (&file, monetary->mon_thousands_sep_wc); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_MONETARY, "LC_MONETARY", &file); } @@ -882,6 +677,9 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, if (!ignore_content) { + /* A single -1 means no grouping. */ + if (act == 1 && grouping[0] == '\177') + act--; grouping[act++] = '\0'; monetary->mon_grouping = xrealloc (grouping, act); diff --git a/locale/programs/ld-name.c b/locale/programs/ld-name.c index 207bf0194e..efc541e47d 100644 --- a/locale/programs/ld-name.c +++ b/locale/programs/ld-name.c @@ -157,60 +157,17 @@ name_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { struct locale_name_t *name = locale->categories[LC_NAME].name; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NAME)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_NAME); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NAME); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) name->name_fmt; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) name->name_gen; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) name->name_mr; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) name->name_mrs; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) name->name_miss; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) name->name_ms; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)); - - write_locale_data (output_path, LC_NAME, "LC_NAME", - 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NAME)); + add_locale_string (&file, name->name_fmt); + add_locale_string (&file, name->name_gen); + add_locale_string (&file, name->name_mr); + add_locale_string (&file, name->name_mrs); + add_locale_string (&file, name->name_miss); + add_locale_string (&file, name->name_ms); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_NAME, "LC_NAME", &file); } diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c index 929409cb7a..f759947de4 100644 --- a/locale/programs/ld-numeric.c +++ b/locale/programs/ld-numeric.c @@ -133,61 +133,16 @@ numeric_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric; - struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_NUMERIC); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) (numeric->decimal_point ?: ""); - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) (numeric->thousands_sep ?: ""); - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = numeric->grouping; - iov[cnt].iov_len = numeric->grouping_len; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - - /* Align following data */ - iov[cnt].iov_base = (void *) "\0\0"; - iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2]; - idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3; - ++cnt; - - iov[cnt].iov_base = (void *) &numeric->decimal_point_wc; - iov[cnt].iov_len = sizeof (uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) &numeric->thousands_sep_wc; - iov[cnt].iov_len = sizeof (uint32_t); - ++cnt; - - idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - - assert (cnt + 1 == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)); - - write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC", - 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)); + add_locale_string (&file, numeric->decimal_point ?: ""); + add_locale_string (&file, numeric->thousands_sep ?: ""); + add_locale_raw_data (&file, numeric->grouping, numeric->grouping_len); + add_locale_uint32 (&file, numeric->decimal_point_wc); + add_locale_uint32 (&file, numeric->thousands_sep_wc); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC", &file); } @@ -350,6 +305,9 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result, if (now->tok != tok_eol) goto err_label; + /* A single -1 means no grouping. */ + if (act == 1 && grouping[0] == '\177') + act--; grouping[act++] = '\0'; numeric->grouping = xrealloc (grouping, act); diff --git a/locale/programs/ld-paper.c b/locale/programs/ld-paper.c index c6239dfd9d..595a600543 100644 --- a/locale/programs/ld-paper.c +++ b/locale/programs/ld-paper.c @@ -121,40 +121,13 @@ paper_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { struct locale_paper_t *paper = locale->categories[LC_PAPER].paper; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_PAPER)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_PAPER); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_PAPER); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[cnt - 2].iov_len + iov[cnt - 1].iov_len; - iov[cnt].iov_base = &paper->height; - iov[cnt].iov_len = 4; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = &paper->width; - iov[cnt].iov_len = 4; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)); - - write_locale_data (output_path, LC_PAPER, "LC_PAPER", - 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)); + add_locale_uint32 (&file, paper->height); + add_locale_uint32 (&file, paper->width); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_PAPER, "LC_PAPER", &file); } diff --git a/locale/programs/ld-telephone.c b/locale/programs/ld-telephone.c index 4452750921..3e71a36eb8 100644 --- a/locale/programs/ld-telephone.c +++ b/locale/programs/ld-telephone.c @@ -175,50 +175,15 @@ telephone_output (struct localedef_t *locale, const struct charmap_t *charmap, { struct locale_telephone_t *telephone = locale->categories[LC_TELEPHONE].telephone; - struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)]; - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)]; - size_t cnt = 0; - - data.magic = LIMAGIC (LC_TELEPHONE); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE); - iov[cnt].iov_base = (void *) &data; - iov[cnt].iov_len = sizeof (data); - ++cnt; - - iov[cnt].iov_base = (void *) idx; - iov[cnt].iov_len = sizeof (idx); - ++cnt; - - idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) telephone->tel_int_fmt; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) telephone->tel_dom_fmt; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) telephone->int_select; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) telephone->int_prefix; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) charmap->code_set_name;; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - - assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)); - - write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE", - 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE), iov); + struct locale_file file; + + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)); + add_locale_string (&file, telephone->tel_int_fmt); + add_locale_string (&file, telephone->tel_dom_fmt); + add_locale_string (&file, telephone->int_select); + add_locale_string (&file, telephone->int_prefix); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE", &file); } diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c index d3646b8717..5956cb32cf 100644 --- a/locale/programs/ld-time.c +++ b/locale/programs/ld-time.c @@ -539,394 +539,116 @@ time_output (struct localedef_t *locale, const struct charmap_t *charmap, const char *output_path) { struct locale_time_t *time = locale->categories[LC_TIME].time; - struct iovec *iov = alloca (sizeof *iov - * (2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME) - + time->num_era - 1 - + 2 * 99 - + 2 + time->num_era * 10)); - struct locale_file data; - uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)]; - size_t cnt, last_idx, num, n; + struct locale_file file; + size_t num, n; - data.magic = LIMAGIC (LC_TIME); - data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TIME); - iov[0].iov_base = (void *) &data; - iov[0].iov_len = sizeof (data); - - iov[1].iov_base = (void *) idx; - iov[1].iov_len = sizeof (idx); - - idx[0] = iov[0].iov_len + iov[1].iov_len; + init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TIME)); /* The ab'days. */ - for (cnt = 0; cnt <= _NL_ITEM_INDEX (ABDAY_7); ++cnt) - { - iov[2 + cnt].iov_base = - (void *) (time->abday[cnt - _NL_ITEM_INDEX (ABDAY_1)] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 7; ++n) + add_locale_string (&file, time->abday[n] ?: ""); /* The days. */ - for (; cnt <= _NL_ITEM_INDEX (DAY_7); ++cnt) - { - iov[2 + cnt].iov_base = - (void *) (time->day[cnt - _NL_ITEM_INDEX (DAY_1)] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 7; ++n) + add_locale_string (&file, time->day[n] ?: ""); /* The ab'mons. */ - for (; cnt <= _NL_ITEM_INDEX (ABMON_12); ++cnt) - { - iov[2 + cnt].iov_base = - (void *) (time->abmon[cnt - _NL_ITEM_INDEX (ABMON_1)] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 12; ++n) + add_locale_string (&file, time->abmon[n] ?: ""); /* The mons. */ - for (; cnt <= _NL_ITEM_INDEX (MON_12); ++cnt) - { - iov[2 + cnt].iov_base = - (void *) (time->mon[cnt - _NL_ITEM_INDEX (MON_1)] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 12; ++n) + add_locale_string (&file, time->mon[n] ?: ""); /* AM/PM. */ - for (; cnt <= _NL_ITEM_INDEX (PM_STR); ++cnt) - { - iov[2 + cnt].iov_base = - (void *) (time->am_pm[cnt - _NL_ITEM_INDEX (AM_STR)] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 2; ++n) + add_locale_string (&file, time->am_pm[n]); - iov[2 + cnt].iov_base = (void *) (time->d_t_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + add_locale_string (&file, time->d_t_fmt ?: ""); + add_locale_string (&file, time->d_fmt ?: ""); + add_locale_string (&file, time->t_fmt ?: ""); + add_locale_string (&file, time->t_fmt_ampm ?: ""); - iov[2 + cnt].iov_base = (void *) (time->d_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + start_locale_structure (&file); + for (num = 0; num < time->num_era; ++num) + add_locale_string (&file, time->era[num]); + end_locale_structure (&file); - iov[2 + cnt].iov_base = (void *) (time->t_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - ++cnt; + add_locale_string (&file, time->era_year ?: ""); + add_locale_string (&file, time->era_d_fmt ?: ""); - iov[2 + cnt].iov_base = (void *) (time->t_fmt_ampm ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len; - last_idx = ++cnt; + start_locale_structure (&file); + for (num = 0; num < 100; ++num) + add_locale_string (&file, time->alt_digits[num] ?: ""); + end_locale_structure (&file); - idx[1 + last_idx] = idx[last_idx]; - for (num = 0; num < time->num_era; ++num, ++cnt) - { - iov[2 + cnt].iov_base = (void *) time->era[num]; - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] += iov[2 + cnt].iov_len; - } - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->era_year ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->era_d_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - idx[1 + last_idx] = idx[last_idx]; - for (num = 0; num < 100; ++num, ++cnt) - { - iov[2 + cnt].iov_base = (void *) (time->alt_digits[num] ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] += iov[2 + cnt].iov_len; - } - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->era_d_t_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->era_t_fmt ?: ""); - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - - /* We must align the following data. */ - iov[2 + cnt].iov_base = (void *) "\0\0"; - iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx]; - idx[last_idx] = (idx[last_idx] + 3) & ~3; - ++cnt; - - /* The `era' data in usable form. */ - iov[2 + cnt].iov_base = (void *) &time->num_era; - iov[2 + cnt].iov_len = sizeof (uint32_t); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - idx[1 + last_idx] = idx[last_idx]; + add_locale_string (&file, time->era_d_t_fmt ?: ""); + add_locale_string (&file, time->era_t_fmt ?: ""); + add_locale_uint32 (&file, time->num_era); + + start_locale_structure (&file); for (num = 0; num < time->num_era; ++num) { - size_t l, l2; - - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].direction; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].offset; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[0]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[1]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[2]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[0]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[1]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[2]; - iov[2 + cnt].iov_len = sizeof (int32_t); - ++cnt; - - l = ((char *) rawmemchr (time->era_entries[num].format, '\0') - - time->era_entries[num].name) + 1; - l2 = (l + 3) & ~3; - iov[2 + cnt].iov_base = alloca (l2); - memset (mempcpy (iov[2 + cnt].iov_base, time->era_entries[num].name, l), - '\0', l2 - l); - iov[2 + cnt].iov_len = l2; - ++cnt; - - idx[1 + last_idx] += 8 * sizeof (int32_t) + l2; - - assert (idx[1 + last_idx] % 4 == 0); - - iov[2 + cnt].iov_base = (void *) time->era_entries[num].wname; - iov[2 + cnt].iov_len = ((wcschr ((wchar_t *) time->era_entries[num].wformat, L'\0') - - (wchar_t *) time->era_entries[num].wname + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] += iov[2 + cnt].iov_len; - ++cnt; + add_locale_uint32 (&file, time->era_entries[num].direction); + add_locale_uint32 (&file, time->era_entries[num].offset); + add_locale_uint32 (&file, time->era_entries[num].start_date[0]); + add_locale_uint32 (&file, time->era_entries[num].start_date[1]); + add_locale_uint32 (&file, time->era_entries[num].start_date[2]); + add_locale_uint32 (&file, time->era_entries[num].stop_date[0]); + add_locale_uint32 (&file, time->era_entries[num].stop_date[1]); + add_locale_uint32 (&file, time->era_entries[num].stop_date[2]); + add_locale_string (&file, time->era_entries[num].name); + add_locale_string (&file, time->era_entries[num].format); + add_locale_wstring (&file, time->era_entries[num].wname); + add_locale_wstring (&file, time->era_entries[num].wformat); } - ++last_idx; + end_locale_structure (&file); /* The wide character ab'days. */ - for (n = 0; n < 7; ++n, ++cnt, ++last_idx) - { - iov[2 + cnt].iov_base = - (void *) (time->wabday[n] ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 7; ++n) + add_locale_wstring (&file, time->wabday[n] ?: empty_wstr); /* The wide character days. */ - for (n = 0; n < 7; ++n, ++cnt, ++last_idx) - { - iov[2 + cnt].iov_base = - (void *) (time->wday[n] ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 7; ++n) + add_locale_wstring (&file, time->wday[n] ?: empty_wstr); /* The wide character ab'mons. */ - for (n = 0; n < 12; ++n, ++cnt, ++last_idx) - { - iov[2 + cnt].iov_base = - (void *) (time->wabmon[n] ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 12; ++n) + add_locale_wstring (&file, time->wabmon[n] ?: empty_wstr); /* The wide character mons. */ - for (n = 0; n < 12; ++n, ++cnt, ++last_idx) - { - iov[2 + cnt].iov_base = - (void *) (time->wmon[n] ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - } + for (n = 0; n < 12; ++n) + add_locale_wstring (&file, time->wmon[n] ?: empty_wstr); /* Wide character AM/PM. */ - for (n = 0; n < 2; ++n, ++cnt, ++last_idx) - { - iov[2 + cnt].iov_base = - (void *) (time->wam_pm[n] ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - } - - iov[2 + cnt].iov_base = (void *) (time->wd_t_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wd_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wt_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wt_fmt_ampm ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wera_year ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wera_d_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - idx[1 + last_idx] = idx[last_idx]; - for (num = 0; num < 100; ++num, ++cnt) - { - iov[2 + cnt].iov_base = (void *) (time->walt_digits[num] - ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] += iov[2 + cnt].iov_len; - } - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wera_d_t_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) (time->wera_t_fmt ?: empty_wstr); - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) &time->week_ndays; - iov[2 + cnt].iov_len = 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - /* We must align the following data. */ - iov[2 + cnt].iov_base = (void *) "\0\0"; - iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx]; - idx[last_idx] = (idx[last_idx] + 3) & ~3; - ++cnt; - - iov[2 + cnt].iov_base = (void *) &time->week_1stday; - iov[2 + cnt].iov_len = sizeof(uint32_t); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) &time->week_1stweek; - iov[2 + cnt].iov_len = 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) &time->first_weekday; - iov[2 + cnt].iov_len = 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) &time->first_workday; - iov[2 + cnt].iov_len = 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) &time->cal_direction; - iov[2 + cnt].iov_len = 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) time->timezone; - iov[2 + cnt].iov_len = strlen (time->timezone) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) time->date_fmt; - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - /* We must align the following data. */ - iov[2 + cnt].iov_base = (void *) "\0\0"; - iov[2 + cnt].iov_len = -idx[last_idx] & 3; - idx[last_idx] += -idx[last_idx] & 3; - ++cnt; - - iov[2 + cnt].iov_base = (void *) time->wdate_fmt; - iov[2 + cnt].iov_len = ((wcslen (iov[2 + cnt].iov_base) + 1) - * sizeof (uint32_t)); - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; - ++cnt; - ++last_idx; - - iov[2 + cnt].iov_base = (void *) charmap->code_set_name; - iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; - ++cnt; - ++last_idx; - - assert (cnt == (_NL_ITEM_INDEX (_NL_NUM_LC_TIME) - + time->num_era - 1 - + 2 * 99 - + 2 + time->num_era * 10)); - assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_TIME)); - - write_locale_data (output_path, LC_TIME, "LC_TIME", 2 + cnt, iov); + for (n = 0; n < 2; ++n) + add_locale_wstring (&file, time->wam_pm[n] ?: empty_wstr); + + add_locale_wstring (&file, time->wd_t_fmt ?: empty_wstr); + add_locale_wstring (&file, time->wd_fmt ?: empty_wstr); + add_locale_wstring (&file, time->wt_fmt ?: empty_wstr); + add_locale_wstring (&file, time->wt_fmt_ampm ?: empty_wstr); + add_locale_wstring (&file, time->wera_year ?: empty_wstr); + add_locale_wstring (&file, time->wera_d_fmt ?: empty_wstr); + + start_locale_structure (&file); + for (num = 0; num < 100; ++num) + add_locale_wstring (&file, time->walt_digits[num] ?: empty_wstr); + end_locale_structure (&file); + + add_locale_wstring (&file, time->wera_d_t_fmt ?: empty_wstr); + add_locale_wstring (&file, time->wera_t_fmt ?: empty_wstr); + add_locale_char (&file, time->week_ndays); + add_locale_uint32 (&file, time->week_1stday); + add_locale_char (&file, time->week_1stweek); + add_locale_char (&file, time->first_weekday); + add_locale_char (&file, time->first_workday); + add_locale_char (&file, time->cal_direction); + add_locale_string (&file, time->timezone); + add_locale_string (&file, time->date_fmt); + add_locale_wstring (&file, time->wdate_fmt); + add_locale_string (&file, charmap->code_set_name); + write_locale_data (output_path, LC_TIME, "LC_TIME", &file); } diff --git a/locale/programs/locale.c b/locale/programs/locale.c index 14d34e693d..d2b28d08f8 100644 --- a/locale/programs/locale.c +++ b/locale/programs/locale.c @@ -895,7 +895,7 @@ show_info (const char *name) printf ("%s=", item->name); if (val != NULL) - printf ("%d", *val == '\177' ? -1 : *val); + printf ("%d", *val == '\377' ? -1 : *val); putchar ('\n'); } break; @@ -927,6 +927,24 @@ show_info (const char *name) printf ("%d\n", val.word); } break; + case wordarray: + { + int first = 1; + union { unsigned int *wordarray; char *string; } val; + int cnt; + + val.string = nl_langinfo (item->item_id); + if (show_keyword_name) + printf ("%s=", item->name); + + for (cnt = 0; cnt < item->max; ++cnt) + { + printf ("%s%d", first ? "" : ";", val.wordarray[cnt]); + first = 0; + } + putchar ('\n'); + } + break; case wstring: case wstringarray: case wstringlist: diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c index 5a14f2ce32..d664232473 100644 --- a/locale/programs/localedef.c +++ b/locale/programs/localedef.c @@ -112,6 +112,8 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; #define OPT_REPLACE 307 #define OPT_DELETE_FROM_ARCHIVE 308 #define OPT_LIST_ARCHIVE 309 +#define OPT_LITTLE_ENDIAN 400 +#define OPT_BIG_ENDIAN 401 /* Definitions of arguments for argp functions. */ static const struct argp_option options[] = @@ -144,6 +146,10 @@ static const struct argp_option options[] = { "list-archive", OPT_LIST_ARCHIVE, NULL, 0, N_("List content of archive") }, { "alias-file", 'A', N_("FILE"), 0, N_("locale.alias file to consult when making archive")}, + { "little-endian", OPT_LITTLE_ENDIAN, NULL, 0, + N_("Generate little-endian output") }, + { "big-endian", OPT_BIG_ENDIAN, NULL, 0, + N_("Generate big-endian output") }, { NULL, 0, NULL, 0, NULL } }; @@ -203,7 +209,7 @@ main (int argc, char *argv[]) /* Handle a few special cases. */ if (list_archive) - show_archive_content (verbose); + show_archive_content (remaining > 1 ? argv[remaining] : NULL, verbose); if (add_to_archive) return add_locales_to_archive (argc - remaining, &argv[remaining], replace_archive); @@ -326,6 +332,12 @@ parse_opt (int key, char *arg, struct argp_state *state) case OPT_LIST_ARCHIVE: list_archive = true; break; + case OPT_LITTLE_ENDIAN: + set_big_endian (false); + break; + case OPT_BIG_ENDIAN: + set_big_endian (true); + break; case 'c': force_output = 1; break; diff --git a/locale/programs/localedef.h b/locale/programs/localedef.h index e010c72983..5a05a2e382 100644 --- a/locale/programs/localedef.h +++ b/locale/programs/localedef.h @@ -170,7 +170,9 @@ extern int add_locales_to_archive (size_t nlist, char *list[], bool replace); /* Removed named locales from archive. */ extern int delete_locales_from_archive (size_t nlist, char *list[]); -/* List content of locale archive. */ -extern void show_archive_content (int verbose) __attribute__ ((noreturn)); +/* List content of locale archive. If FNAME is non-null use that as + the locale archive to list, otherwise the default. */ +extern void show_archive_content (const char *fname, + int verbose) __attribute__ ((noreturn)); #endif /* localedef.h */ diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c index f7225b8bea..4ec24d611e 100644 --- a/locale/programs/locarchive.c +++ b/locale/programs/locarchive.c @@ -46,6 +46,7 @@ #include "../localeinfo.h" #include "../locarchive.h" #include "localedef.h" +#include "locfile.h" /* Define the hash function. We define the function as static inline. We must change the name so as not to conflict with simple-hash.h. */ @@ -74,6 +75,13 @@ static const char *locnames[] = #define INITIAL_NUM_SUMS 2000 +/* Get and set values (possibly endian-swapped) in structures mapped + from or written directly to locale archives. */ +#define GET(FIELD) maybe_swap_uint32 (FIELD) +#define SET(FIELD, VALUE) ((FIELD) = maybe_swap_uint32 (VALUE)) +#define INC(FIELD, INCREMENT) SET (FIELD, GET (FIELD) + (INCREMENT)) + + /* Size of the reserved address space area. */ #define RESERVE_MMAP_SIZE 512 * 1024 * 1024 @@ -125,27 +133,31 @@ create_archive (const char *archivefname, struct locarhandle *ah) error (EXIT_FAILURE, errno, _("cannot create temporary file: %s"), fname); /* Create the initial content of the archive. */ - head.magic = AR_MAGIC; - head.serial = 0; - head.namehash_offset = sizeof (struct locarhead); - head.namehash_used = 0; - head.namehash_size = next_prime (INITIAL_NUM_NAMES); - - head.string_offset = (head.namehash_offset - + head.namehash_size * sizeof (struct namehashent)); - head.string_used = 0; - head.string_size = INITIAL_SIZE_STRINGS; - - head.locrectab_offset = head.string_offset + head.string_size; - head.locrectab_used = 0; - head.locrectab_size = INITIAL_NUM_LOCREC; - - head.sumhash_offset = (head.locrectab_offset - + head.locrectab_size * sizeof (struct locrecent)); - head.sumhash_used = 0; - head.sumhash_size = next_prime (INITIAL_NUM_SUMS); - - total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent); + SET (head.magic, AR_MAGIC); + SET (head.serial, 0); + SET (head.namehash_offset, sizeof (struct locarhead)); + SET (head.namehash_used, 0); + SET (head.namehash_size, next_prime (INITIAL_NUM_NAMES)); + + SET (head.string_offset, + (GET (head.namehash_offset) + + GET (head.namehash_size) * sizeof (struct namehashent))); + SET (head.string_used, 0); + SET (head.string_size, INITIAL_SIZE_STRINGS); + + SET (head.locrectab_offset, + GET (head.string_offset) + GET (head.string_size)); + SET (head.locrectab_used, 0); + SET (head.locrectab_size, INITIAL_NUM_LOCREC); + + SET (head.sumhash_offset, + (GET (head.locrectab_offset) + + GET (head.locrectab_size) * sizeof (struct locrecent))); + SET (head.sumhash_used, 0); + SET (head.sumhash_size, next_prime (INITIAL_NUM_SUMS)); + + total = (GET (head.sumhash_offset) + + GET (head.sumhash_size) * sizeof (struct sumhashent)); /* Write out the header and create room for the other data structures. */ if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head)) @@ -211,6 +223,7 @@ create_archive (const char *archivefname, struct locarhandle *ah) _("cannot change mode of new locale archive")); } + ah->fname = NULL; ah->fd = fd; ah->mmap_base = mmap_base; ah->mmap_len = mmap_len; @@ -240,10 +253,10 @@ oldlocrecentcmp (const void *a, const void *b) for (cnt = 0; cnt < __LC_LAST; ++cnt) if (cnt != LC_ALL) { - if (la->record[cnt].offset < start_a) - start_a = la->record[cnt].offset; - if (la->record[cnt].offset + la->record[cnt].len > end_a) - end_a = la->record[cnt].offset + la->record[cnt].len; + if (GET (la->record[cnt].offset) < start_a) + start_a = GET (la->record[cnt].offset); + if (GET (la->record[cnt].offset) + GET (la->record[cnt].len) > end_a) + end_a = GET (la->record[cnt].offset) + GET (la->record[cnt].len); } assert (start_a != (uint32_t)-1); assert (end_a != 0); @@ -251,10 +264,10 @@ oldlocrecentcmp (const void *a, const void *b) for (cnt = 0; cnt < __LC_LAST; ++cnt) if (cnt != LC_ALL) { - if (lb->record[cnt].offset < start_b) - start_b = lb->record[cnt].offset; - if (lb->record[cnt].offset + lb->record[cnt].len > end_b) - end_b = lb->record[cnt].offset + lb->record[cnt].len; + if (GET (lb->record[cnt].offset) < start_b) + start_b = GET (lb->record[cnt].offset); + if (GET (lb->record[cnt].offset) + GET (lb->record[cnt].len) > end_b) + end_b = GET (lb->record[cnt].offset) + GET (lb->record[cnt].len); } assert (start_b != (uint32_t)-1); assert (end_b != 0); @@ -371,38 +384,42 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) /* Create the new archive header. The sizes of the various tables should be double from what is currently used. */ - newhead.namehash_size = MAX (next_prime (2 * newhead.namehash_used), - newhead.namehash_size); + SET (newhead.namehash_size, + MAX (next_prime (2 * GET (newhead.namehash_used)), + GET (newhead.namehash_size))); if (verbose) printf ("name: size: %u, used: %d, new: size: %u\n", - head->namehash_size, head->namehash_used, newhead.namehash_size); + GET (head->namehash_size), + GET (head->namehash_used), GET (newhead.namehash_size)); - newhead.string_offset = (newhead.namehash_offset - + (newhead.namehash_size - * sizeof (struct namehashent))); + SET (newhead.string_offset, (GET (newhead.namehash_offset) + + (GET (newhead.namehash_size) + * sizeof (struct namehashent)))); /* Keep the string table size aligned to 4 bytes, so that all the struct { uint32_t } types following are happy. */ - newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4, - newhead.string_size); + SET (newhead.string_size, MAX ((2 * GET (newhead.string_used) + 3) & -4, + GET (newhead.string_size))); - newhead.locrectab_offset = newhead.string_offset + newhead.string_size; - newhead.locrectab_size = MAX (2 * newhead.locrectab_used, - newhead.locrectab_size); + SET (newhead.locrectab_offset, + GET (newhead.string_offset) + GET (newhead.string_size)); + SET (newhead.locrectab_size, MAX (2 * GET (newhead.locrectab_used), + GET (newhead.locrectab_size))); - newhead.sumhash_offset = (newhead.locrectab_offset - + (newhead.locrectab_size - * sizeof (struct locrecent))); - newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used), - newhead.sumhash_size); + SET (newhead.sumhash_offset, (GET (newhead.locrectab_offset) + + (GET (newhead.locrectab_size) + * sizeof (struct locrecent)))); + SET (newhead.sumhash_size, + MAX (next_prime (2 * GET (newhead.sumhash_used)), + GET (newhead.sumhash_size))); - total = (newhead.sumhash_offset - + newhead.sumhash_size * sizeof (struct sumhashent)); + total = (GET (newhead.sumhash_offset) + + GET (newhead.sumhash_size) * sizeof (struct sumhashent)); /* The new file is empty now. */ - newhead.namehash_used = 0; - newhead.string_used = 0; - newhead.locrectab_used = 0; - newhead.sumhash_used = 0; + SET (newhead.namehash_used, 0); + SET (newhead.string_used, 0); + SET (newhead.locrectab_used, 0); + SET (newhead.sumhash_used, 0); /* Write out the header and create room for the other data structures. */ if (TEMP_FAILURE_RETRY (write (fd, &newhead, sizeof (newhead))) @@ -462,17 +479,17 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) /* Walk through the hash name hash table to find out what data is still referenced and transfer it into the new file. */ oldnamehashtab = (struct namehashent *) ((char *) ah->addr - + head->namehash_offset); + + GET (head->namehash_offset)); /* Sort the old locrec table in order of data position. */ - struct oldlocrecent oldlocrecarray[head->namehash_size]; - for (cnt = 0, loccnt = 0; cnt < head->namehash_size; ++cnt) - if (oldnamehashtab[cnt].locrec_offset != 0) + struct oldlocrecent oldlocrecarray[GET (head->namehash_size)]; + for (cnt = 0, loccnt = 0; cnt < GET (head->namehash_size); ++cnt) + if (GET (oldnamehashtab[cnt].locrec_offset) != 0) { oldlocrecarray[loccnt].cnt = cnt; oldlocrecarray[loccnt++].locrec = (struct locrecent *) ((char *) ah->addr - + oldnamehashtab[cnt].locrec_offset); + + GET (oldnamehashtab[cnt].locrec_offset)); } qsort (oldlocrecarray, loccnt, sizeof (struct oldlocrecent), oldlocrecentcmp); @@ -488,9 +505,9 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) for (idx = 0; idx < __LC_LAST; ++idx) if (idx != LC_ALL) { - old_data[idx].size = oldlocrec->record[idx].len; + old_data[idx].size = GET (oldlocrec->record[idx].len); old_data[idx].addr - = ((char *) ah->addr + oldlocrec->record[idx].offset); + = ((char *) ah->addr + GET (oldlocrec->record[idx].offset)); __md5_buffer (old_data[idx].addr, old_data[idx].size, old_data[idx].sum); @@ -500,20 +517,23 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) { const char *oldname = ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt - 1].cnt].name_offset); - - add_alias (&new_ah, - ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset), - 0, oldname, &last_locrec_offset); + + GET (oldnamehashtab[oldlocrecarray[cnt + - 1].cnt].name_offset)); + + add_alias + (&new_ah, + ((char *) ah->addr + + GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)), + 0, oldname, &last_locrec_offset); continue; } last_locrec_offset = - add_locale (&new_ah, - ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset), - old_data, 0); + add_locale + (&new_ah, + ((char *) ah->addr + + GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)), + old_data, 0); if (last_locrec_offset == 0) error (EXIT_FAILURE, 0, _("cannot extend locale archive file")); } @@ -552,11 +572,17 @@ open_archive (struct locarhandle *ah, bool readonly) struct locarhead head; int retry = 0; size_t prefix_len = output_prefix ? strlen (output_prefix) : 0; - char archivefname[prefix_len + sizeof (ARCHIVE_NAME)]; + char default_fname[prefix_len + sizeof (ARCHIVE_NAME)]; + const char *archivefname = ah->fname; - if (output_prefix) - memcpy (archivefname, output_prefix, prefix_len); - strcpy (archivefname + prefix_len, ARCHIVE_NAME); + /* If ah has a non-NULL fname open that otherwise open the default. */ + if (archivefname == NULL) + { + archivefname = default_fname; + if (output_prefix) + memcpy (default_fname, output_prefix, prefix_len); + strcpy (default_fname + prefix_len, ARCHIVE_NAME); + } while (1) { @@ -564,8 +590,11 @@ open_archive (struct locarhandle *ah, bool readonly) fd = open64 (archivefname, readonly ? O_RDONLY : O_RDWR); if (fd == -1) { - /* Maybe the file does not yet exist. */ - if (errno == ENOENT) + /* Maybe the file does not yet exist? If we are opening + the default locale archive we ignore the failure and + list an empty archive, otherwise we print an error + and exit. */ + if (errno == ENOENT && archivefname == default_fname) { if (readonly) { @@ -690,26 +719,28 @@ insert_name (struct locarhandle *ah, { const struct locarhead *const head = ah->addr; struct namehashent *namehashtab - = (struct namehashent *) ((char *) ah->addr + head->namehash_offset); + = (struct namehashent *) ((char *) ah->addr + + GET (head->namehash_offset)); unsigned int insert_idx, idx, incr; /* Hash value of the locale name. */ uint32_t hval = archive_hashval (name, name_len); insert_idx = -1; - idx = hval % head->namehash_size; - incr = 1 + hval % (head->namehash_size - 2); + idx = hval % GET (head->namehash_size); + incr = 1 + hval % (GET (head->namehash_size) - 2); /* If the name_offset field is zero this means this is a deleted entry and therefore no entry can be found. */ - while (namehashtab[idx].name_offset != 0) + while (GET (namehashtab[idx].name_offset) != 0) { - if (namehashtab[idx].hashval == hval - && strcmp (name, - (char *) ah->addr + namehashtab[idx].name_offset) == 0) + if (GET (namehashtab[idx].hashval) == hval + && (strcmp (name, + (char *) ah->addr + GET (namehashtab[idx].name_offset)) + == 0)) { /* Found the entry. */ - if (namehashtab[idx].locrec_offset != 0 && ! replace) + if (GET (namehashtab[idx].locrec_offset) != 0 && ! replace) { if (! be_quiet) error (0, 0, _("locale '%s' already exists"), name); @@ -719,26 +750,27 @@ insert_name (struct locarhandle *ah, break; } - if (namehashtab[idx].hashval == hval && ! be_quiet) + if (GET (namehashtab[idx].hashval) == hval && ! be_quiet) { error (0, 0, "hash collision (%u) %s, %s", - hval, name, (char *) ah->addr + namehashtab[idx].name_offset); + hval, name, + (char *) ah->addr + GET (namehashtab[idx].name_offset)); } /* Remember the first place we can insert the new entry. */ - if (namehashtab[idx].locrec_offset == 0 && insert_idx == -1) + if (GET (namehashtab[idx].locrec_offset) == 0 && insert_idx == -1) insert_idx = idx; idx += incr; - if (idx >= head->namehash_size) - idx -= head->namehash_size; + if (idx >= GET (head->namehash_size)) + idx -= GET (head->namehash_size); } /* Add as early as possible. */ if (insert_idx != -1) idx = insert_idx; - namehashtab[idx].hashval = hval; /* no-op if replacing an old entry. */ + SET (namehashtab[idx].hashval, hval); /* no-op if replacing an old entry. */ return &namehashtab[idx]; } @@ -754,12 +786,13 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, if (namehashent == NULL && ! replace) return; - if (namehashent->name_offset == 0) + if (GET (namehashent->name_offset) == 0) { /* We are adding a new hash entry for this alias. Determine whether we have to resize the file. */ - if (head->string_used + name_len + 1 > head->string_size - || 100 * head->namehash_used > 75 * head->namehash_size) + if (GET (head->string_used) + name_len + 1 > GET (head->string_size) + || (100 * GET (head->namehash_used) + > 75 * GET (head->namehash_size))) { /* The current archive is not large enough. */ enlarge_archive (ah, head); @@ -767,9 +800,9 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, /* The locrecent might have moved, so we have to look up the old name afresh. */ namehashent = insert_name (ah, oldname, strlen (oldname), true); - assert (namehashent->name_offset != 0); - assert (namehashent->locrec_offset != 0); - *locrec_offset_p = namehashent->locrec_offset; + assert (GET (namehashent->name_offset) != 0); + assert (GET (namehashent->locrec_offset) != 0); + *locrec_offset_p = GET (namehashent->locrec_offset); /* Tail call to try the whole thing again. */ add_alias (ah, alias, replace, oldname, locrec_offset_p); @@ -777,26 +810,27 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, } /* Add the name string. */ - memcpy (ah->addr + head->string_offset + head->string_used, + memcpy (ah->addr + GET (head->string_offset) + GET (head->string_used), alias, name_len + 1); - namehashent->name_offset = head->string_offset + head->string_used; - head->string_used += name_len + 1; + SET (namehashent->name_offset, + GET (head->string_offset) + GET (head->string_used)); + INC (head->string_used, name_len + 1); - ++head->namehash_used; + INC (head->namehash_used, 1); } - if (namehashent->locrec_offset != 0) + if (GET (namehashent->locrec_offset) != 0) { /* Replacing an existing entry. Mark that we are no longer using the old locrecent. */ struct locrecent *locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - --locrecent->refs; + + GET (namehashent->locrec_offset)); + INC (locrecent->refs, -1); } /* Point this entry at the locrecent installed for the main name. */ - namehashent->locrec_offset = locrec_offset; + SET (namehashent->locrec_offset, locrec_offset); } static int /* qsort comparator used below */ @@ -832,12 +866,17 @@ add_locale (struct locarhandle *ah, off64_t lastoffset; char *ptr; struct locale_category_data *size_order[__LC_LAST]; - const size_t pagesz = getpagesize (); + /* Page size alignment is a minor optimization for locality; use a + common value here rather than making the localedef output depend + on the page size of the system on which localedef is run. See + <https://sourceware.org/glibc/wiki/Development_Todo/Master#Locale_archive_alignment> + for more discussion. */ + const size_t pagesz = 4096; int small_mask; head = ah->addr; sumhashtab = (struct sumhashent *) ((char *) ah->addr - + head->sumhash_offset); + + GET (head->sumhash_offset)); memset (file_offsets, 0, sizeof (file_offsets)); @@ -895,10 +934,10 @@ add_locale (struct locarhandle *ah, table. */ hval = archive_hashval (data[cnt].sum, 16); - idx = hval % head->sumhash_size; - incr = 1 + hval % (head->sumhash_size - 2); + idx = hval % GET (head->sumhash_size); + incr = 1 + hval % (GET (head->sumhash_size) - 2); - while (sumhashtab[idx].file_offset != 0) + while (GET (sumhashtab[idx].file_offset) != 0) { if (memcmp (data[cnt].sum, sumhashtab[idx].sum, 16) == 0) { @@ -908,40 +947,42 @@ add_locale (struct locarhandle *ah, Unfortunately the sumhashent record does not include the size of the stored data. So we have to search for it. */ - locrecent = (struct locrecent *) ((char *) ah->addr - + head->locrectab_offset); + locrecent + = (struct locrecent *) ((char *) ah->addr + + GET (head->locrectab_offset)); size_t iloc; - for (iloc = 0; iloc < head->locrectab_used; ++iloc) - if (locrecent[iloc].refs != 0 - && (locrecent[iloc].record[cnt].offset - == sumhashtab[idx].file_offset)) + for (iloc = 0; iloc < GET (head->locrectab_used); ++iloc) + if (GET (locrecent[iloc].refs) != 0 + && (GET (locrecent[iloc].record[cnt].offset) + == GET (sumhashtab[idx].file_offset))) break; - if (iloc != head->locrectab_used - && data[cnt].size == locrecent[iloc].record[cnt].len + if (iloc != GET (head->locrectab_used) + && data[cnt].size == GET (locrecent[iloc].record[cnt].len) /* We have to compare the content. Either we can have the data mmaped or we have to read from the file. */ - && (file_data_available_p (ah, sumhashtab[idx].file_offset, - data[cnt].size) + && (file_data_available_p + (ah, GET (sumhashtab[idx].file_offset), + data[cnt].size) ? memcmp (data[cnt].addr, (char *) ah->addr - + sumhashtab[idx].file_offset, + + GET (sumhashtab[idx].file_offset), data[cnt].size) == 0 : compare_from_file (ah, data[cnt].addr, - sumhashtab[idx].file_offset, + GET (sumhashtab[idx].file_offset), data[cnt].size) == 0)) { /* Found it. */ - file_offsets[cnt] = sumhashtab[idx].file_offset; + file_offsets[cnt] = GET (sumhashtab[idx].file_offset); --num_new_offsets; break; } } idx += incr; - if (idx >= head->sumhash_size) - idx -= head->sumhash_size; + if (idx >= GET (head->sumhash_size)) + idx -= GET (head->sumhash_size); } } @@ -951,11 +992,14 @@ add_locale (struct locarhandle *ah, return 0; /* Determine whether we have to resize the file. */ - if (100 * (head->sumhash_used + num_new_offsets) > 75 * head->sumhash_size - || (namehashent->locrec_offset == 0 - && (head->locrectab_used == head->locrectab_size - || head->string_used + name_len + 1 > head->string_size - || 100 * head->namehash_used > 75 * head->namehash_size))) + if ((100 * (GET (head->sumhash_used) + num_new_offsets) + > 75 * GET (head->sumhash_size)) + || (GET (namehashent->locrec_offset) == 0 + && (GET (head->locrectab_used) == GET (head->locrectab_size) + || (GET (head->string_used) + name_len + 1 + > GET (head->string_size)) + || (100 * GET (head->namehash_used) + > 75 * GET (head->namehash_size))))) { /* The current archive is not large enough. */ enlarge_archive (ah, head); @@ -1018,20 +1062,20 @@ add_locale (struct locarhandle *ah, /* Add the hash value to the hash table. */ md5hval = archive_hashval (data[cnt].sum, 16); - idx = md5hval % head->sumhash_size; - incr = 1 + md5hval % (head->sumhash_size - 2); + idx = md5hval % GET (head->sumhash_size); + incr = 1 + md5hval % (GET (head->sumhash_size) - 2); - while (sumhashtab[idx].file_offset != 0) + while (GET (sumhashtab[idx].file_offset) != 0) { idx += incr; - if (idx >= head->sumhash_size) - idx -= head->sumhash_size; + if (idx >= GET (head->sumhash_size)) + idx -= GET (head->sumhash_size); } memcpy (sumhashtab[idx].sum, data[cnt].sum, 16); - sumhashtab[idx].file_offset = file_offsets[cnt]; + SET (sumhashtab[idx].file_offset, file_offsets[cnt]); - ++head->sumhash_used; + INC (head->sumhash_used, 1); } lastoffset = file_offsets[LC_ALL]; @@ -1042,25 +1086,28 @@ add_locale (struct locarhandle *ah, lastoffset += (data[cnt].size + 15) & -16; } - if (namehashent->name_offset == 0) + if (GET (namehashent->name_offset) == 0) { /* Add the name string. */ - memcpy ((char *) ah->addr + head->string_offset + head->string_used, + memcpy ((char *) ah->addr + GET (head->string_offset) + + GET (head->string_used), name, name_len + 1); - namehashent->name_offset = head->string_offset + head->string_used; - head->string_used += name_len + 1; - ++head->namehash_used; + SET (namehashent->name_offset, + GET (head->string_offset) + GET (head->string_used)); + INC (head->string_used, name_len + 1); + INC (head->namehash_used, 1); } - if (namehashent->locrec_offset == 0) + if (GET (namehashent->locrec_offset == 0)) { /* Allocate a name location record. */ - namehashent->locrec_offset = (head->locrectab_offset - + (head->locrectab_used++ - * sizeof (struct locrecent))); + SET (namehashent->locrec_offset, (GET (head->locrectab_offset) + + (GET (head->locrectab_used) + * sizeof (struct locrecent)))); + INC (head->locrectab_used, 1); locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - locrecent->refs = 1; + + GET (namehashent->locrec_offset)); + SET (locrecent->refs, 1); } else { @@ -1068,27 +1115,29 @@ add_locale (struct locarhandle *ah, we still need a new one. If not, reuse the old one. */ locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - if (locrecent->refs > 1) + + GET (namehashent->locrec_offset)); + if (GET (locrecent->refs) > 1) { - --locrecent->refs; - namehashent->locrec_offset = (head->locrectab_offset - + (head->locrectab_used++ - * sizeof (struct locrecent))); - locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - locrecent->refs = 1; + INC (locrecent->refs, -1); + SET (namehashent->locrec_offset, (GET (head->locrectab_offset) + + (GET (head->locrectab_used) + * sizeof (struct locrecent)))); + INC (head->locrectab_used, 1); + locrecent + = (struct locrecent *) ((char *) ah->addr + + GET (namehashent->locrec_offset)); + SET (locrecent->refs, 1); } } /* Fill in the table with the locations of the locale data. */ for (cnt = 0; cnt < __LC_LAST; ++cnt) { - locrecent->record[cnt].offset = file_offsets[cnt]; - locrecent->record[cnt].len = data[cnt].size; + SET (locrecent->record[cnt].offset, file_offsets[cnt]); + SET (locrecent->record[cnt].len, data[cnt].size); } - return namehashent->locrec_offset; + return GET (namehashent->locrec_offset); } @@ -1147,7 +1196,8 @@ add_locale_to_archive (ah, name, data, replace) unsigned int strindex[0]; } *filedata = data[LC_CTYPE].addr; codeset = (char *) filedata - + filedata->strindex[_NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME)]; + + maybe_swap_uint32 (filedata->strindex[_NL_ITEM_INDEX + (_NL_CTYPE_CODESET_NAME)]); char *normalized_codeset_name = NULL; normalized_codeset = _nl_normalize_codeset (codeset, strlen (codeset)); @@ -1307,6 +1357,7 @@ add_locales_to_archive (nlist, list, replace) /* Open the archive. This call never returns if we cannot successfully open the archive. */ + ah.fname = NULL; open_archive (&ah, false); while (nlist-- > 0) @@ -1506,11 +1557,12 @@ delete_locales_from_archive (nlist, list) /* Open the archive. This call never returns if we cannot successfully open the archive. */ + ah.fname = NULL; open_archive (&ah, false); head = ah.addr; namehashtab = (struct namehashent *) ((char *) ah.addr - + head->namehash_offset); + + GET (head->namehash_offset)); while (nlist-- > 0) { @@ -1522,30 +1574,31 @@ delete_locales_from_archive (nlist, list) /* Search for this locale in the archive. */ hval = archive_hashval (locname, strlen (locname)); - idx = hval % head->namehash_size; - incr = 1 + hval % (head->namehash_size - 2); + idx = hval % GET (head->namehash_size); + incr = 1 + hval % (GET (head->namehash_size) - 2); /* If the name_offset field is zero this means this is no deleted entry and therefore no entry can be found. */ - while (namehashtab[idx].name_offset != 0) + while (GET (namehashtab[idx].name_offset) != 0) { - if (namehashtab[idx].hashval == hval + if (GET (namehashtab[idx].hashval) == hval && (strcmp (locname, - (char *) ah.addr + namehashtab[idx].name_offset) + ((char *) ah.addr + + GET (namehashtab[idx].name_offset))) == 0)) { /* Found the entry. Now mark it as removed by zero-ing the reference to the locale record. */ - namehashtab[idx].locrec_offset = 0; + SET (namehashtab[idx].locrec_offset, 0); break; } idx += incr; - if (idx >= head->namehash_size) - idx -= head->namehash_size; + if (idx >= GET (head->namehash_size)) + idx -= GET (head->namehash_size); } - if (namehashtab[idx].name_offset == 0 && ! be_quiet) + if (GET (namehashtab[idx].name_offset) == 0 && ! be_quiet) error (0, 0, _("locale \"%s\" not in archive"), locname); } @@ -1594,7 +1647,7 @@ dataentcmp (const void *a, const void *b) void -show_archive_content (int verbose) +show_archive_content (const char *fname, int verbose) { struct locarhandle ah; struct locarhead *head; @@ -1604,21 +1657,22 @@ show_archive_content (int verbose) /* Open the archive. This call never returns if we cannot successfully open the archive. */ + ah.fname = fname; open_archive (&ah, true); head = ah.addr; - names = (struct nameent *) xmalloc (head->namehash_used + names = (struct nameent *) xmalloc (GET (head->namehash_used) * sizeof (struct nameent)); namehashtab = (struct namehashent *) ((char *) ah.addr - + head->namehash_offset); - for (cnt = used = 0; cnt < head->namehash_size; ++cnt) - if (namehashtab[cnt].locrec_offset != 0) + + GET (head->namehash_offset)); + for (cnt = used = 0; cnt < GET (head->namehash_size); ++cnt) + if (GET (namehashtab[cnt].locrec_offset) != 0) { - assert (used < head->namehash_used); - names[used].name = ah.addr + namehashtab[cnt].name_offset; - names[used++].locrec_offset = namehashtab[cnt].locrec_offset; + assert (used < GET (head->namehash_used)); + names[used].name = ah.addr + GET (namehashtab[cnt].name_offset); + names[used++].locrec_offset = GET (namehashtab[cnt].locrec_offset); } /* Sort the names. */ @@ -1630,17 +1684,17 @@ show_archive_content (int verbose) struct sumhashent *sumhashtab; int sumused; - files = (struct dataent *) xmalloc (head->sumhash_used + files = (struct dataent *) xmalloc (GET (head->sumhash_used) * sizeof (struct dataent)); sumhashtab = (struct sumhashent *) ((char *) ah.addr - + head->sumhash_offset); - for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt) - if (sumhashtab[cnt].file_offset != 0) + + GET (head->sumhash_offset)); + for (cnt = sumused = 0; cnt < GET (head->sumhash_size); ++cnt) + if (GET (sumhashtab[cnt].file_offset) != 0) { - assert (sumused < head->sumhash_used); + assert (sumused < GET (head->sumhash_used)); files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum; - files[sumused].file_offset = sumhashtab[cnt].file_offset; + files[sumused].file_offset = GET (sumhashtab[cnt].file_offset); files[sumused++].nlink = 0; } @@ -1656,18 +1710,19 @@ show_archive_content (int verbose) locrec = (struct locrecent *) ((char *) ah.addr + names[cnt].locrec_offset); for (idx = 0; idx < __LC_LAST; ++idx) - if (locrec->record[LC_ALL].offset != 0 + if (GET (locrec->record[LC_ALL].offset) != 0 ? (idx == LC_ALL - || (locrec->record[idx].offset - < locrec->record[LC_ALL].offset) - || (locrec->record[idx].offset + locrec->record[idx].len - > (locrec->record[LC_ALL].offset - + locrec->record[LC_ALL].len))) + || (GET (locrec->record[idx].offset) + < GET (locrec->record[LC_ALL].offset)) + || ((GET (locrec->record[idx].offset) + + GET (locrec->record[idx].len)) + > (GET (locrec->record[LC_ALL].offset) + + GET (locrec->record[LC_ALL].len)))) : idx != LC_ALL) { struct dataent *data, dataent; - dataent.file_offset = locrec->record[idx].offset; + dataent.file_offset = GET (locrec->record[idx].offset); data = (struct dataent *) bsearch (&dataent, files, sumused, sizeof (struct dataent), dataentcmp); @@ -1689,21 +1744,24 @@ show_archive_content (int verbose) { struct dataent *data, dataent; - dataent.file_offset = locrec->record[idx].offset; - if (locrec->record[LC_ALL].offset != 0 - && dataent.file_offset >= locrec->record[LC_ALL].offset - && (dataent.file_offset + locrec->record[idx].len - <= (locrec->record[LC_ALL].offset - + locrec->record[LC_ALL].len))) - dataent.file_offset = locrec->record[LC_ALL].offset; + dataent.file_offset = GET (locrec->record[idx].offset); + if (GET (locrec->record[LC_ALL].offset) != 0 + && (dataent.file_offset + >= GET (locrec->record[LC_ALL].offset)) + && (dataent.file_offset + GET (locrec->record[idx].len) + <= (GET (locrec->record[LC_ALL].offset) + + GET (locrec->record[LC_ALL].len)))) + dataent.file_offset = GET (locrec->record[LC_ALL].offset); data = (struct dataent *) bsearch (&dataent, files, sumused, sizeof (struct dataent), dataentcmp); printf ("%6d %7x %3d%c ", - locrec->record[idx].len, locrec->record[idx].offset, + GET (locrec->record[idx].len), + GET (locrec->record[idx].offset), data->nlink, - dataent.file_offset == locrec->record[LC_ALL].offset + (dataent.file_offset + == GET (locrec->record[LC_ALL].offset)) ? '+' : ' '); for (i = 0; i < 16; i += 4) printf ("%02x%02x%02x%02x", diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c index 3cbd6f1314..ef7adbff8d 100644 --- a/locale/programs/locfile.c +++ b/locale/programs/locfile.c @@ -22,19 +22,25 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/param.h> #include <sys/stat.h> +#include <assert.h> +#include <wchar.h> #include "../../crypt/md5.h" #include "localedef.h" +#include "localeinfo.h" #include "locfile.h" #include "simple-hash.h" #include "locfile-kw.h" +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free /* Temporary storage of the locale data before writing it to the archive. */ static locale_data_t to_archive; @@ -337,6 +343,7 @@ write_all_categories (struct localedef_t *definitions, /* Open the archive. This call never returns if we cannot successfully open the archive. */ + ah.fname = NULL; open_archive (&ah, false); if (add_locale_to_archive (&ah, locname, to_archive, true) != 0) @@ -533,17 +540,185 @@ compare_files (const char *filename1, const char *filename2, size_t size, return ret; } +/* True if the locale files use the opposite endianness to the + machine running localedef. */ +bool swap_endianness_p; + +/* When called outside a start_locale_structure/end_locale_structure + or start_locale_prelude/end_locale_prelude block, record that the + next byte in FILE's obstack will be the first byte of a new element. + Do likewise for the first call inside a start_locale_structure/ + end_locale_structure block. */ +static void +record_offset (struct locale_file *file) +{ + if (file->structure_stage < 2) + { + assert (file->next_element < file->n_elements); + file->offsets[file->next_element++] + = (obstack_object_size (&file->data) + + (file->n_elements + 2) * sizeof (uint32_t)); + if (file->structure_stage == 1) + file->structure_stage = 2; + } +} + +/* Initialize FILE for a new output file. N_ELEMENTS is the number + of elements in the file. */ +void +init_locale_data (struct locale_file *file, size_t n_elements) +{ + file->n_elements = n_elements; + file->next_element = 0; + file->offsets = xmalloc (sizeof (uint32_t) * n_elements); + obstack_init (&file->data); + file->structure_stage = 0; +} + +/* Align the size of FILE's obstack object to BOUNDARY bytes. */ +void +align_locale_data (struct locale_file *file, size_t boundary) +{ + size_t size = -obstack_object_size (&file->data) & (boundary - 1); + obstack_blank (&file->data, size); + memset (obstack_next_free (&file->data) - size, 0, size); +} + +/* Record that FILE's next element contains no data. */ +void +add_locale_empty (struct locale_file *file) +{ + record_offset (file); +} -/* Write a locale file, with contents given by N_ELEM and VEC. */ +/* Record that FILE's next element consists of SIZE bytes starting at DATA. */ +void +add_locale_raw_data (struct locale_file *file, const void *data, size_t size) +{ + record_offset (file); + obstack_grow (&file->data, data, size); +} + +/* Finish the current object on OBSTACK and use it as the data for FILE's + next element. */ +void +add_locale_raw_obstack (struct locale_file *file, struct obstack *obstack) +{ + size_t size = obstack_object_size (obstack); + record_offset (file); + obstack_grow (&file->data, obstack_finish (obstack), size); +} + +/* Use STRING as FILE's next element. */ +void +add_locale_string (struct locale_file *file, const char *string) +{ + record_offset (file); + obstack_grow (&file->data, string, strlen (string) + 1); +} + +/* Likewise for wide strings. */ +void +add_locale_wstring (struct locale_file *file, const uint32_t *string) +{ + add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1); +} + +/* Record that FILE's next element is the 32-bit integer VALUE. */ +void +add_locale_uint32 (struct locale_file *file, uint32_t value) +{ + align_locale_data (file, LOCFILE_ALIGN); + record_offset (file); + value = maybe_swap_uint32 (value); + obstack_grow (&file->data, &value, sizeof (value)); +} + +/* Record that FILE's next element is an array of N_ELEMS integers + starting at DATA. */ +void +add_locale_uint32_array (struct locale_file *file, + const uint32_t *data, size_t n_elems) +{ + align_locale_data (file, LOCFILE_ALIGN); + record_offset (file); + obstack_grow (&file->data, data, n_elems * sizeof (uint32_t)); + maybe_swap_uint32_obstack (&file->data, n_elems); +} + +/* Record that FILE's next element is the single byte given by VALUE. */ +void +add_locale_char (struct locale_file *file, char value) +{ + record_offset (file); + obstack_1grow (&file->data, value); +} + +/* Start building an element that contains several different pieces of data. + Subsequent calls to add_locale_* will add data to the same element up + till the next call to end_locale_structure. The element's alignment + is dictated by the first piece of data added to it. */ +void +start_locale_structure (struct locale_file *file) +{ + assert (file->structure_stage == 0); + file->structure_stage = 1; +} + +/* Finish a structure element that was started by start_locale_structure. + Empty structures are OK and behave like add_locale_empty. */ +void +end_locale_structure (struct locale_file *file) +{ + record_offset (file); + assert (file->structure_stage == 2); + file->structure_stage = 0; +} + +/* Start building data that goes before the next element's recorded offset. + Subsequent calls to add_locale_* will add data to the file without + treating any of it as the start of a new element. Calling + end_locale_prelude switches back to the usual behavior. */ +void +start_locale_prelude (struct locale_file *file) +{ + assert (file->structure_stage == 0); + file->structure_stage = 3; +} + +/* End a block started by start_locale_prelude. */ +void +end_locale_prelude (struct locale_file *file) +{ + assert (file->structure_stage == 3); + file->structure_stage = 0; +} + +/* Write a locale file, with contents given by FILE. */ void write_locale_data (const char *output_path, int catidx, const char *category, - size_t n_elem, struct iovec *vec) + struct locale_file *file) { size_t cnt, step, maxiov; int fd; char *fname; const char **other_paths; - + uint32_t header[2]; + size_t n_elem; + struct iovec vec[3]; + + assert (file->n_elements == file->next_element); + header[0] = LIMAGIC (catidx); + header[1] = file->n_elements; + vec[0].iov_len = sizeof (header); + vec[0].iov_base = header; + vec[1].iov_len = sizeof (uint32_t) * file->n_elements; + vec[1].iov_base = file->offsets; + vec[2].iov_len = obstack_object_size (&file->data); + vec[2].iov_base = obstack_finish (&file->data); + maybe_swap_uint32_array (vec[0].iov_base, 2); + maybe_swap_uint32_array (vec[1].iov_base, file->n_elements); + n_elem = 3; if (! no_archive) { /* The data will be added to the archive. For now we simply diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h index 83bf421ece..cb3e22fd87 100644 --- a/locale/programs/locfile.h +++ b/locale/programs/locfile.h @@ -18,18 +18,22 @@ #ifndef _LOCFILE_H #define _LOCFILE_H 1 +#include <byteswap.h> +#include <stdbool.h> #include <stdint.h> #include <sys/uio.h> +#include "obstack.h" #include "linereader.h" #include "localedef.h" - -/* Header of the locale data files. */ +/* Structure for storing the contents of a category file. */ struct locale_file { - int magic; - int n; + size_t n_elements, next_element; + uint32_t *offsets; + struct obstack data; + int structure_stage; }; @@ -65,10 +69,62 @@ extern void write_all_categories (struct localedef_t *definitions, const char *locname, const char *output_path); +extern bool swap_endianness_p; + +/* Change the output to be big-endian if BIG_ENDIAN is true and + little-endian otherwise. */ +static inline void +set_big_endian (bool big_endian) +{ + swap_endianness_p = (big_endian != (__BYTE_ORDER == __BIG_ENDIAN)); +} + +/* Munge VALUE so that, when stored, it has the correct byte order + for the output files. */ +static inline uint32_t +maybe_swap_uint32 (uint32_t value) +{ + return swap_endianness_p ? bswap_32 (value) : value; +} + +/* Likewise, but munge an array of N uint32_ts starting at ARRAY. */ +static inline void +maybe_swap_uint32_array (uint32_t *array, size_t n) +{ + if (swap_endianness_p) + while (n-- > 0) + array[n] = bswap_32 (array[n]); +} + +/* Like maybe_swap_uint32_array, but the array of N elements is at + the end of OBSTACK's current object. */ +static inline void +maybe_swap_uint32_obstack (struct obstack *obstack, size_t n) +{ + maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n); +} + /* Write out the data. */ +extern void init_locale_data (struct locale_file *file, size_t n_elements); +extern void align_locale_data (struct locale_file *file, size_t boundary); +extern void add_locale_empty (struct locale_file *file); +extern void add_locale_raw_data (struct locale_file *file, const void *data, + size_t size); +extern void add_locale_raw_obstack (struct locale_file *file, + struct obstack *obstack); +extern void add_locale_string (struct locale_file *file, const char *string); +extern void add_locale_wstring (struct locale_file *file, + const uint32_t *string); +extern void add_locale_uint32 (struct locale_file *file, uint32_t value); +extern void add_locale_uint32_array (struct locale_file *file, + const uint32_t *data, size_t n_elems); +extern void add_locale_char (struct locale_file *file, char value); +extern void start_locale_structure (struct locale_file *file); +extern void end_locale_structure (struct locale_file *file); +extern void start_locale_prelude (struct locale_file *file); +extern void end_locale_prelude (struct locale_file *file); extern void write_locale_data (const char *output_path, int catidx, - const char *category, size_t n_elem, - struct iovec *vec); + const char *category, struct locale_file *file); /* Entrypoints for the parsers of the individual categories. */ diff --git a/locale/setlocale.c b/locale/setlocale.c index be95519e9f..e83a156267 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -412,7 +412,7 @@ setlocale (int category, const char *locale) /* We must not simply free a global locale since we have no control over the usage. So we mark it as un-deletable. - Note: do not remove the `if', it's necessary to copy with + Note: do not remove the `if', it's necessary to cope with the builtin locale data. */ if (newdata->usage_count != UNDELETABLE) newdata->usage_count = UNDELETABLE; diff --git a/locale/weight.h b/locale/weight.h index 645eda2fe9..b097aaca0b 100644 --- a/locale/weight.h +++ b/locale/weight.h @@ -69,8 +69,8 @@ findidx (const unsigned char **cpp, size_t len) /* Up to the next entry. */ cp += nhere; - if ((1 + nhere) % __alignof__ (int32_t) != 0) - cp += __alignof__ (int32_t) - (1 + nhere) % __alignof__ (int32_t); + if (!LOCFILE_ALIGNED_P (1 + nhere)) + cp += LOCFILE_ALIGN - (1 + nhere) % LOCFILE_ALIGN; } else { @@ -89,9 +89,9 @@ findidx (const unsigned char **cpp, size_t len) { /* Cannot be in this range. */ cp += 2 * nhere; - if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0) - cp += (__alignof__ (int32_t) - - (1 + 2 * nhere) % __alignof__ (int32_t)); + if (!LOCFILE_ALIGNED_P (1 + 2 * nhere)) + cp += (LOCFILE_ALIGN + - (1 + 2 * nhere) % LOCFILE_ALIGN); continue; } @@ -104,9 +104,9 @@ findidx (const unsigned char **cpp, size_t len) { /* Cannot be in this range. */ cp += 2 * nhere; - if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0) - cp += (__alignof__ (int32_t) - - (1 + 2 * nhere) % __alignof__ (int32_t)); + if (!LOCFILE_ALIGNED_P (1 + 2 * nhere)) + cp += (LOCFILE_ALIGN + - (1 + 2 * nhere) % LOCFILE_ALIGN); continue; } |