summaryrefslogtreecommitdiff
path: root/locale
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2013-12-20 09:29:29 +0100
committerThomas Schwinge <thomas@codesourcery.com>2013-12-20 09:29:29 +0100
commita65dd355fb80a05215e15ae97649de52aec885e3 (patch)
tree81701bb0c6b648630f2bf1729a85d7f5eb49e67b /locale
parent296a5732f94abe4d5699dc981e4ccfb950b48cee (diff)
parentb4578bab30f72cddd2cf38abfb39f9c8dc892249 (diff)
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'locale')
-rw-r--r--locale/C-address.c2
-rw-r--r--locale/C-monetary.c7
-rw-r--r--locale/categories.def1
-rw-r--r--locale/hashval.h2
-rw-r--r--locale/iso-3166.def12
-rw-r--r--locale/iso-4217.def24
-rw-r--r--locale/iso-639.def28
-rw-r--r--locale/loadarchive.c4
-rw-r--r--locale/loadlocale.c2
-rw-r--r--locale/localeconv.c44
-rw-r--r--locale/localeinfo.h10
-rw-r--r--locale/locarchive.h2
-rw-r--r--locale/programs/3level.h56
-rw-r--r--locale/programs/ld-address.c108
-rw-r--r--locale/programs/ld-collate.c247
-rw-r--r--locale/programs/ld-ctype.c525
-rw-r--r--locale/programs/ld-identification.c130
-rw-r--r--locale/programs/ld-measurement.c35
-rw-r--r--locale/programs/ld-messages.c52
-rw-r--r--locale/programs/ld-monetary.c310
-rw-r--r--locale/programs/ld-name.c65
-rw-r--r--locale/programs/ld-numeric.c68
-rw-r--r--locale/programs/ld-paper.c41
-rw-r--r--locale/programs/ld-telephone.c53
-rw-r--r--locale/programs/ld-time.c440
-rw-r--r--locale/programs/locale.c20
-rw-r--r--locale/programs/localedef.c14
-rw-r--r--locale/programs/localedef.h6
-rw-r--r--locale/programs/locarchive.c454
-rw-r--r--locale/programs/locfile.c181
-rw-r--r--locale/programs/locfile.h68
-rw-r--r--locale/setlocale.c2
-rw-r--r--locale/weight.h16
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;
}