1c3d0cca4SAndrey A. Chernov /*- 2c3d0cca4SAndrey A. Chernov * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 3c3d0cca4SAndrey A. Chernov * at Electronni Visti IA, Kiev, Ukraine. 4c3d0cca4SAndrey A. Chernov * All rights reserved. 5c3d0cca4SAndrey A. Chernov * 6*3c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation 7*3c87aa1dSDavid Chisnall * All rights reserved. 8*3c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall 9*3c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation. 10*3c87aa1dSDavid Chisnall * 11*3c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation 12*3c87aa1dSDavid Chisnall * All rights reserved. 13*3c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall 14*3c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation. 15*3c87aa1dSDavid Chisnall * 16c3d0cca4SAndrey A. Chernov * Redistribution and use in source and binary forms, with or without 17c3d0cca4SAndrey A. Chernov * modification, are permitted provided that the following conditions 18c3d0cca4SAndrey A. Chernov * are met: 19c3d0cca4SAndrey A. Chernov * 1. Redistributions of source code must retain the above copyright 20c3d0cca4SAndrey A. Chernov * notice, this list of conditions and the following disclaimer. 21c3d0cca4SAndrey A. Chernov * 2. Redistributions in binary form must reproduce the above copyright 22c3d0cca4SAndrey A. Chernov * notice, this list of conditions and the following disclaimer in the 23c3d0cca4SAndrey A. Chernov * documentation and/or other materials provided with the distribution. 24c3d0cca4SAndrey A. Chernov * 25c3d0cca4SAndrey A. Chernov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 26c3d0cca4SAndrey A. Chernov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27c3d0cca4SAndrey A. Chernov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28c3d0cca4SAndrey A. Chernov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 29c3d0cca4SAndrey A. Chernov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30c3d0cca4SAndrey A. Chernov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31c3d0cca4SAndrey A. Chernov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32c3d0cca4SAndrey A. Chernov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33c3d0cca4SAndrey A. Chernov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34c3d0cca4SAndrey A. Chernov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35c3d0cca4SAndrey A. Chernov * SUCH DAMAGE. 36c3d0cca4SAndrey A. Chernov */ 37c3d0cca4SAndrey A. Chernov 38333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 39333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 40333fc21eSDavid E. O'Brien 41d201fe46SDaniel Eischen #include "namespace.h" 42c1417061SAndrey A. Chernov #include <arpa/inet.h> 43c3d0cca4SAndrey A. Chernov #include <stdio.h> 44c3d0cca4SAndrey A. Chernov #include <stdlib.h> 45c3d0cca4SAndrey A. Chernov #include <string.h> 46926f20c9SAndrey A. Chernov #include <errno.h> 47926f20c9SAndrey A. Chernov #include <unistd.h> 48c3d0cca4SAndrey A. Chernov #include <sysexits.h> 49d201fe46SDaniel Eischen #include "un-namespace.h" 50d201fe46SDaniel Eischen 51c3d0cca4SAndrey A. Chernov #include "collate.h" 5263407d34SAndrey A. Chernov #include "setlocale.h" 5376692b80SAndrey A. Chernov #include "ldpart.h" 54c3d0cca4SAndrey A. Chernov 554cd01193SMark Murray #include "libc_private.h" 564cd01193SMark Murray 57*3c87aa1dSDavid Chisnall /* 58*3c87aa1dSDavid Chisnall * To avoid modifying the original (single-threaded) code too much, we'll just 59*3c87aa1dSDavid Chisnall * define the old globals as fields inside the table. 60*3c87aa1dSDavid Chisnall * 61*3c87aa1dSDavid Chisnall * We also modify the collation table test functions to search the thread-local 62*3c87aa1dSDavid Chisnall * table first and the global table second. 63*3c87aa1dSDavid Chisnall */ 64*3c87aa1dSDavid Chisnall #define __collate_load_error (table->__collate_load_error) 65*3c87aa1dSDavid Chisnall #define __collate_substitute_nontrivial (table->__collate_substitute_nontrivial) 66*3c87aa1dSDavid Chisnall #define __collate_substitute_table_ptr (table->__collate_substitute_table_ptr) 67*3c87aa1dSDavid Chisnall #define __collate_char_pri_table_ptr (table->__collate_char_pri_table_ptr) 68*3c87aa1dSDavid Chisnall #define __collate_chain_pri_table (table->__collate_chain_pri_table) 6976692b80SAndrey A. Chernov 70*3c87aa1dSDavid Chisnall 71*3c87aa1dSDavid Chisnall struct xlocale_collate __xlocale_global_collate = { 72*3c87aa1dSDavid Chisnall {{0}, "C"}, 1, 0 73*3c87aa1dSDavid Chisnall }; 74*3c87aa1dSDavid Chisnall 75*3c87aa1dSDavid Chisnall struct xlocale_collate __xlocale_C_collate = { 76*3c87aa1dSDavid Chisnall {{0}, "C"}, 1, 0 77*3c87aa1dSDavid Chisnall }; 78c3d0cca4SAndrey A. Chernov 79eaa86f9dSBruce Evans void __collate_err(int ex, const char *f) __dead2; 80926f20c9SAndrey A. Chernov 81c3d0cca4SAndrey A. Chernov int 82*3c87aa1dSDavid Chisnall __collate_load_tables_l(const char *encoding, struct xlocale_collate *table); 83*3c87aa1dSDavid Chisnall 84*3c87aa1dSDavid Chisnall static void 85*3c87aa1dSDavid Chisnall destruct_collate(void *t) 86*3c87aa1dSDavid Chisnall { 87*3c87aa1dSDavid Chisnall struct xlocale_collate *table = t; 88*3c87aa1dSDavid Chisnall if (__collate_chain_pri_table) { 89*3c87aa1dSDavid Chisnall free(__collate_chain_pri_table); 90*3c87aa1dSDavid Chisnall } 91*3c87aa1dSDavid Chisnall free(t); 92*3c87aa1dSDavid Chisnall } 93*3c87aa1dSDavid Chisnall 94*3c87aa1dSDavid Chisnall void * 95*3c87aa1dSDavid Chisnall __collate_load(const char *encoding, locale_t unused) 96*3c87aa1dSDavid Chisnall { 97*3c87aa1dSDavid Chisnall if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { 98*3c87aa1dSDavid Chisnall return &__xlocale_C_collate; 99*3c87aa1dSDavid Chisnall } 100*3c87aa1dSDavid Chisnall struct xlocale_collate *table = calloc(sizeof(struct xlocale_collate), 1); 101*3c87aa1dSDavid Chisnall table->header.header.destructor = destruct_collate; 102*3c87aa1dSDavid Chisnall // FIXME: Make sure that _LDP_CACHE is never returned. We should be doing 103*3c87aa1dSDavid Chisnall // the caching outside of this section 104*3c87aa1dSDavid Chisnall if (__collate_load_tables_l(encoding, table) != _LDP_LOADED) { 105*3c87aa1dSDavid Chisnall xlocale_release(table); 106*3c87aa1dSDavid Chisnall return NULL; 107*3c87aa1dSDavid Chisnall } 108*3c87aa1dSDavid Chisnall return table; 109*3c87aa1dSDavid Chisnall } 110*3c87aa1dSDavid Chisnall 111*3c87aa1dSDavid Chisnall /** 112*3c87aa1dSDavid Chisnall * Load the collation tables for the specified encoding into the global table. 113*3c87aa1dSDavid Chisnall */ 114*3c87aa1dSDavid Chisnall int 11576692b80SAndrey A. Chernov __collate_load_tables(const char *encoding) 116c3d0cca4SAndrey A. Chernov { 117*3c87aa1dSDavid Chisnall return __collate_load_tables_l(encoding, &__xlocale_global_collate); 118*3c87aa1dSDavid Chisnall } 119*3c87aa1dSDavid Chisnall 120*3c87aa1dSDavid Chisnall int 121*3c87aa1dSDavid Chisnall __collate_load_tables_l(const char *encoding, struct xlocale_collate *table) 122*3c87aa1dSDavid Chisnall { 123c3d0cca4SAndrey A. Chernov FILE *fp; 1248e52da4dSAndrey A. Chernov int i, saverr, chains; 125c1417061SAndrey A. Chernov uint32_t u32; 1268e52da4dSAndrey A. Chernov char strbuf[STR_LEN], buf[PATH_MAX]; 127a2a26d0aSAndrey A. Chernov void *TMP_substitute_table, *TMP_char_pri_table, *TMP_chain_pri_table; 128c3d0cca4SAndrey A. Chernov 12976692b80SAndrey A. Chernov /* 'encoding' must be already checked. */ 13076692b80SAndrey A. Chernov if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { 131c3d0cca4SAndrey A. Chernov __collate_load_error = 1; 13276692b80SAndrey A. Chernov return (_LDP_CACHE); 133377da8e8SAndrey A. Chernov } 13476692b80SAndrey A. Chernov 13576692b80SAndrey A. Chernov /* 'PathLocale' must be already set & checked. */ 136d81a0916SAndrey A. Chernov /* Range checking not needed, encoding has fixed size */ 137af155bdfSAndrey A. Chernov (void)strcpy(buf, _PathLocale); 138af155bdfSAndrey A. Chernov (void)strcat(buf, "/"); 139af155bdfSAndrey A. Chernov (void)strcat(buf, encoding); 140af155bdfSAndrey A. Chernov (void)strcat(buf, "/LC_COLLATE"); 14176692b80SAndrey A. Chernov if ((fp = fopen(buf, "r")) == NULL) 14276692b80SAndrey A. Chernov return (_LDP_ERROR); 14376692b80SAndrey A. Chernov 1448e52da4dSAndrey A. Chernov if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) { 1458e52da4dSAndrey A. Chernov saverr = errno; 1468e52da4dSAndrey A. Chernov (void)fclose(fp); 1478e52da4dSAndrey A. Chernov errno = saverr; 1488e52da4dSAndrey A. Chernov return (_LDP_ERROR); 1498e52da4dSAndrey A. Chernov } 1508e52da4dSAndrey A. Chernov chains = -1; 1518e52da4dSAndrey A. Chernov if (strcmp(strbuf, COLLATE_VERSION) == 0) 1528e52da4dSAndrey A. Chernov chains = 0; 153edc43112SRuslan Ermilov else if (strcmp(strbuf, COLLATE_VERSION1_2) == 0) 1548e52da4dSAndrey A. Chernov chains = 1; 1558e52da4dSAndrey A. Chernov if (chains < 0) { 1568e52da4dSAndrey A. Chernov (void)fclose(fp); 1578e52da4dSAndrey A. Chernov errno = EFTYPE; 1588e52da4dSAndrey A. Chernov return (_LDP_ERROR); 1598e52da4dSAndrey A. Chernov } 1608e52da4dSAndrey A. Chernov if (chains) { 161c1417061SAndrey A. Chernov if (fread(&u32, sizeof(u32), 1, fp) != 1) { 1628e52da4dSAndrey A. Chernov saverr = errno; 1638e52da4dSAndrey A. Chernov (void)fclose(fp); 1648e52da4dSAndrey A. Chernov errno = saverr; 1658e52da4dSAndrey A. Chernov return (_LDP_ERROR); 1668e52da4dSAndrey A. Chernov } 167c1417061SAndrey A. Chernov if ((chains = (int)ntohl(u32)) < 1) { 1688e52da4dSAndrey A. Chernov (void)fclose(fp); 1698e52da4dSAndrey A. Chernov errno = EFTYPE; 1708e52da4dSAndrey A. Chernov return (_LDP_ERROR); 1718e52da4dSAndrey A. Chernov } 1728e52da4dSAndrey A. Chernov } else 1738e52da4dSAndrey A. Chernov chains = TABLE_SIZE; 1748e52da4dSAndrey A. Chernov 17576692b80SAndrey A. Chernov if ((TMP_substitute_table = 17676692b80SAndrey A. Chernov malloc(sizeof(__collate_substitute_table))) == NULL) { 177e34fe8a4SAndrey A. Chernov saverr = errno; 1786892b144SAndrey A. Chernov (void)fclose(fp); 179e34fe8a4SAndrey A. Chernov errno = saverr; 18076692b80SAndrey A. Chernov return (_LDP_ERROR); 1811642f84dSAndrey A. Chernov } 18276692b80SAndrey A. Chernov if ((TMP_char_pri_table = 18376692b80SAndrey A. Chernov malloc(sizeof(__collate_char_pri_table))) == NULL) { 184e34fe8a4SAndrey A. Chernov saverr = errno; 18576692b80SAndrey A. Chernov free(TMP_substitute_table); 1866892b144SAndrey A. Chernov (void)fclose(fp); 187e34fe8a4SAndrey A. Chernov errno = saverr; 18876692b80SAndrey A. Chernov return (_LDP_ERROR); 18976692b80SAndrey A. Chernov } 19076692b80SAndrey A. Chernov if ((TMP_chain_pri_table = 1918e52da4dSAndrey A. Chernov malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { 192e34fe8a4SAndrey A. Chernov saverr = errno; 19376692b80SAndrey A. Chernov free(TMP_substitute_table); 19476692b80SAndrey A. Chernov free(TMP_char_pri_table); 19576692b80SAndrey A. Chernov (void)fclose(fp); 196e34fe8a4SAndrey A. Chernov errno = saverr; 19776692b80SAndrey A. Chernov return (_LDP_ERROR); 19876692b80SAndrey A. Chernov } 19976692b80SAndrey A. Chernov 20076692b80SAndrey A. Chernov #define FREAD(a, b, c, d) \ 20176692b80SAndrey A. Chernov { \ 20276692b80SAndrey A. Chernov if (fread(a, b, c, d) != c) { \ 20376692b80SAndrey A. Chernov saverr = errno; \ 20476692b80SAndrey A. Chernov free(TMP_substitute_table); \ 20576692b80SAndrey A. Chernov free(TMP_char_pri_table); \ 20676692b80SAndrey A. Chernov free(TMP_chain_pri_table); \ 20776692b80SAndrey A. Chernov (void)fclose(d); \ 20876692b80SAndrey A. Chernov errno = saverr; \ 20976692b80SAndrey A. Chernov return (_LDP_ERROR); \ 21076692b80SAndrey A. Chernov } \ 21176692b80SAndrey A. Chernov } 21276692b80SAndrey A. Chernov 21376692b80SAndrey A. Chernov FREAD(TMP_substitute_table, sizeof(__collate_substitute_table), 1, fp); 21476692b80SAndrey A. Chernov FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); 2158e52da4dSAndrey A. Chernov FREAD(TMP_chain_pri_table, 216cbc98d05SAndrey A. Chernov sizeof(*__collate_chain_pri_table), chains, fp); 21776692b80SAndrey A. Chernov (void)fclose(fp); 21876692b80SAndrey A. Chernov 219a2a26d0aSAndrey A. Chernov if (__collate_substitute_table_ptr != NULL) 220a2a26d0aSAndrey A. Chernov free(__collate_substitute_table_ptr); 221a2a26d0aSAndrey A. Chernov __collate_substitute_table_ptr = TMP_substitute_table; 222a2a26d0aSAndrey A. Chernov if (__collate_char_pri_table_ptr != NULL) 223a2a26d0aSAndrey A. Chernov free(__collate_char_pri_table_ptr); 224a2a26d0aSAndrey A. Chernov __collate_char_pri_table_ptr = TMP_char_pri_table; 225edc43112SRuslan Ermilov for (i = 0; i < UCHAR_MAX + 1; i++) { 226edc43112SRuslan Ermilov __collate_char_pri_table[i].prim = 227edc43112SRuslan Ermilov ntohl(__collate_char_pri_table[i].prim); 228edc43112SRuslan Ermilov __collate_char_pri_table[i].sec = 229edc43112SRuslan Ermilov ntohl(__collate_char_pri_table[i].sec); 230edc43112SRuslan Ermilov } 2318e52da4dSAndrey A. Chernov if (__collate_chain_pri_table != NULL) 2328e52da4dSAndrey A. Chernov free(__collate_chain_pri_table); 2338e52da4dSAndrey A. Chernov __collate_chain_pri_table = TMP_chain_pri_table; 234edc43112SRuslan Ermilov for (i = 0; i < chains; i++) { 235edc43112SRuslan Ermilov __collate_chain_pri_table[i].prim = 236edc43112SRuslan Ermilov ntohl(__collate_chain_pri_table[i].prim); 237edc43112SRuslan Ermilov __collate_chain_pri_table[i].sec = 238edc43112SRuslan Ermilov ntohl(__collate_chain_pri_table[i].sec); 239edc43112SRuslan Ermilov } 240e755fb76SDmitrij Tejblum __collate_substitute_nontrivial = 0; 241e755fb76SDmitrij Tejblum for (i = 0; i < UCHAR_MAX + 1; i++) { 242e755fb76SDmitrij Tejblum if (__collate_substitute_table[i][0] != i || 243e755fb76SDmitrij Tejblum __collate_substitute_table[i][1] != 0) { 244e755fb76SDmitrij Tejblum __collate_substitute_nontrivial = 1; 245e755fb76SDmitrij Tejblum break; 246e755fb76SDmitrij Tejblum } 247e755fb76SDmitrij Tejblum } 24876692b80SAndrey A. Chernov __collate_load_error = 0; 249e755fb76SDmitrij Tejblum 25076692b80SAndrey A. Chernov return (_LDP_LOADED); 251c3d0cca4SAndrey A. Chernov } 252c3d0cca4SAndrey A. Chernov 253c3d0cca4SAndrey A. Chernov u_char * 254*3c87aa1dSDavid Chisnall __collate_substitute(struct xlocale_collate *table, const u_char *s) 255c3d0cca4SAndrey A. Chernov { 25603a7efc2SDmitrij Tejblum int dest_len, len, nlen; 257c3d0cca4SAndrey A. Chernov int delta = strlen(s); 258926f20c9SAndrey A. Chernov u_char *dest_str = NULL; 259c3d0cca4SAndrey A. Chernov 260926f20c9SAndrey A. Chernov if (s == NULL || *s == '\0') 2616892b144SAndrey A. Chernov return (__collate_strdup("")); 26203a7efc2SDmitrij Tejblum delta += delta / 8; 26303a7efc2SDmitrij Tejblum dest_str = malloc(dest_len = delta); 26403a7efc2SDmitrij Tejblum if (dest_str == NULL) 265e60b9f51SStefan Farfeleder __collate_err(EX_OSERR, __func__); 26603a7efc2SDmitrij Tejblum len = 0; 267c3d0cca4SAndrey A. Chernov while (*s) { 26803a7efc2SDmitrij Tejblum nlen = len + strlen(__collate_substitute_table[*s]); 26903a7efc2SDmitrij Tejblum if (dest_len <= nlen) { 27003a7efc2SDmitrij Tejblum dest_str = reallocf(dest_str, dest_len = nlen + delta); 271926f20c9SAndrey A. Chernov if (dest_str == NULL) 272e60b9f51SStefan Farfeleder __collate_err(EX_OSERR, __func__); 273c3d0cca4SAndrey A. Chernov } 2746892b144SAndrey A. Chernov (void)strcpy(dest_str + len, __collate_substitute_table[*s++]); 27503a7efc2SDmitrij Tejblum len = nlen; 276c3d0cca4SAndrey A. Chernov } 2776892b144SAndrey A. Chernov return (dest_str); 278c3d0cca4SAndrey A. Chernov } 279c3d0cca4SAndrey A. Chernov 280c3d0cca4SAndrey A. Chernov void 281*3c87aa1dSDavid Chisnall __collate_lookup(struct xlocale_collate *table, const u_char *t, int *len, int *prim, int *sec) 282c3d0cca4SAndrey A. Chernov { 283c3d0cca4SAndrey A. Chernov struct __collate_st_chain_pri *p2; 284c3d0cca4SAndrey A. Chernov 285c3d0cca4SAndrey A. Chernov *len = 1; 286c3d0cca4SAndrey A. Chernov *prim = *sec = 0; 2878e52da4dSAndrey A. Chernov for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { 2888e52da4dSAndrey A. Chernov if (*t == p2->str[0] && 2898e52da4dSAndrey A. Chernov strncmp(t, p2->str, strlen(p2->str)) == 0) { 290c3d0cca4SAndrey A. Chernov *len = strlen(p2->str); 291c3d0cca4SAndrey A. Chernov *prim = p2->prim; 292c3d0cca4SAndrey A. Chernov *sec = p2->sec; 293c3d0cca4SAndrey A. Chernov return; 294c3d0cca4SAndrey A. Chernov } 295c3d0cca4SAndrey A. Chernov } 296c3d0cca4SAndrey A. Chernov *prim = __collate_char_pri_table[*t].prim; 297c3d0cca4SAndrey A. Chernov *sec = __collate_char_pri_table[*t].sec; 298c3d0cca4SAndrey A. Chernov } 299c3d0cca4SAndrey A. Chernov 300c3d0cca4SAndrey A. Chernov u_char * 301f9b5e461SAlexey Zelkin __collate_strdup(u_char *s) 302c3d0cca4SAndrey A. Chernov { 303926f20c9SAndrey A. Chernov u_char *t = strdup(s); 304c3d0cca4SAndrey A. Chernov 305926f20c9SAndrey A. Chernov if (t == NULL) 306e60b9f51SStefan Farfeleder __collate_err(EX_OSERR, __func__); 3076892b144SAndrey A. Chernov return (t); 308c3d0cca4SAndrey A. Chernov } 309c3d0cca4SAndrey A. Chernov 310eaa86f9dSBruce Evans void 311eaa86f9dSBruce Evans __collate_err(int ex, const char *f) 312926f20c9SAndrey A. Chernov { 313926f20c9SAndrey A. Chernov const char *s; 314926f20c9SAndrey A. Chernov int serrno = errno; 315926f20c9SAndrey A. Chernov 3164cd01193SMark Murray s = _getprogname(); 3179233c4d9SJason Evans _write(STDERR_FILENO, s, strlen(s)); 3189233c4d9SJason Evans _write(STDERR_FILENO, ": ", 2); 319926f20c9SAndrey A. Chernov s = f; 3209233c4d9SJason Evans _write(STDERR_FILENO, s, strlen(s)); 3219233c4d9SJason Evans _write(STDERR_FILENO, ": ", 2); 322926f20c9SAndrey A. Chernov s = strerror(serrno); 3239233c4d9SJason Evans _write(STDERR_FILENO, s, strlen(s)); 3249233c4d9SJason Evans _write(STDERR_FILENO, "\n", 1); 325926f20c9SAndrey A. Chernov exit(ex); 326926f20c9SAndrey A. Chernov } 327926f20c9SAndrey A. Chernov 328c3d0cca4SAndrey A. Chernov #ifdef COLLATE_DEBUG 329c3d0cca4SAndrey A. Chernov void 330c3d0cca4SAndrey A. Chernov __collate_print_tables() 331c3d0cca4SAndrey A. Chernov { 332c3d0cca4SAndrey A. Chernov int i; 333c3d0cca4SAndrey A. Chernov struct __collate_st_chain_pri *p2; 334c3d0cca4SAndrey A. Chernov 335c3d0cca4SAndrey A. Chernov printf("Substitute table:\n"); 336c3d0cca4SAndrey A. Chernov for (i = 0; i < UCHAR_MAX + 1; i++) 337967a5cb1SAndrey A. Chernov if (i != *__collate_substitute_table[i]) 338c3d0cca4SAndrey A. Chernov printf("\t'%c' --> \"%s\"\n", i, 339c3d0cca4SAndrey A. Chernov __collate_substitute_table[i]); 340c3d0cca4SAndrey A. Chernov printf("Chain priority table:\n"); 341cbc98d05SAndrey A. Chernov for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) 342cbc98d05SAndrey A. Chernov printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); 343c3d0cca4SAndrey A. Chernov printf("Char priority table:\n"); 344c3d0cca4SAndrey A. Chernov for (i = 0; i < UCHAR_MAX + 1; i++) 345c3d0cca4SAndrey A. Chernov printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 346c3d0cca4SAndrey A. Chernov __collate_char_pri_table[i].sec); 347c3d0cca4SAndrey A. Chernov } 348c3d0cca4SAndrey A. Chernov #endif 349