10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
56793Smuffin * Common Development and Distribution License (the "License").
66793Smuffin * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
216793Smuffin
220Sstevel@tonic-gate /*
236793Smuffin * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
29*6812Sraf #include "lint.h"
300Sstevel@tonic-gate #include "mtlib.h"
310Sstevel@tonic-gate #include <ctype.h>
320Sstevel@tonic-gate #include <stdio.h>
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <string.h>
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate #include <unistd.h>
370Sstevel@tonic-gate #include <sys/mman.h>
380Sstevel@tonic-gate #include <langinfo.h>
390Sstevel@tonic-gate #include "libc.h"
400Sstevel@tonic-gate #include "_loc_path.h"
410Sstevel@tonic-gate #include "msgfmt.h"
420Sstevel@tonic-gate #include "gettext.h"
430Sstevel@tonic-gate
440Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
450Sstevel@tonic-gate #include "plural_parser.h"
460Sstevel@tonic-gate #include <stdarg.h>
470Sstevel@tonic-gate #endif
480Sstevel@tonic-gate
490Sstevel@tonic-gate static const char *category_name[] = {
500Sstevel@tonic-gate "LC_CTYPE",
510Sstevel@tonic-gate "LC_NUMERIC",
520Sstevel@tonic-gate "LC_TIME",
530Sstevel@tonic-gate "LC_COLLATE",
540Sstevel@tonic-gate "LC_MONETARY",
550Sstevel@tonic-gate "LC_MESSAGES"
560Sstevel@tonic-gate };
570Sstevel@tonic-gate
580Sstevel@tonic-gate static const int category_name_len[] = {
590Sstevel@tonic-gate 8,
600Sstevel@tonic-gate 10,
610Sstevel@tonic-gate 7,
620Sstevel@tonic-gate 10,
630Sstevel@tonic-gate 11,
640Sstevel@tonic-gate 11
650Sstevel@tonic-gate };
660Sstevel@tonic-gate
670Sstevel@tonic-gate /*
680Sstevel@tonic-gate * mk_msgfile
690Sstevel@tonic-gate *
700Sstevel@tonic-gate * INPUT
710Sstevel@tonic-gate * mp - uses the following members:
720Sstevel@tonic-gate * msgfile - buffer to store the pathname to the message file
730Sstevel@tonic-gate * binding - directory pathname bound to specified domain
740Sstevel@tonic-gate * cblen - length of binding
750Sstevel@tonic-gate * locale - locale name
760Sstevel@tonic-gate * domain - domain name
770Sstevel@tonic-gate * category - category
780Sstevel@tonic-gate * domain_len - length of domain name
790Sstevel@tonic-gate *
800Sstevel@tonic-gate * OUTPUT
810Sstevel@tonic-gate * mp->msgfile - pathname to the message file is stored
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * RETURN
840Sstevel@tonic-gate * mp->msgfile is returned
850Sstevel@tonic-gate */
860Sstevel@tonic-gate char *
mk_msgfile(struct msg_pack * mp)870Sstevel@tonic-gate mk_msgfile(struct msg_pack *mp)
880Sstevel@tonic-gate {
890Sstevel@tonic-gate char *p, *q;
900Sstevel@tonic-gate const char *catstr;
916793Smuffin uint32_t cblen, loclen, catlen, totallen;
920Sstevel@tonic-gate
930Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
946793Smuffin gprintf(0, "*************** mk_msgfile(0x%p)\n", (void *)mp);
956793Smuffin printmp(mp, 1);
960Sstevel@tonic-gate #endif
970Sstevel@tonic-gate
980Sstevel@tonic-gate p = mp->msgfile;
990Sstevel@tonic-gate q = mp->binding;
1000Sstevel@tonic-gate while (*p = *q++)
1010Sstevel@tonic-gate p++;
1026793Smuffin cblen = (uint32_t)(p - mp->msgfile);
1030Sstevel@tonic-gate if (*(p - 1) != '/') {
1040Sstevel@tonic-gate /*
1050Sstevel@tonic-gate * if the last character of binding
1060Sstevel@tonic-gate * isn't a '/', adding '/'.
1070Sstevel@tonic-gate */
1080Sstevel@tonic-gate if (cblen + 1 >= MAXPATHLEN) {
1090Sstevel@tonic-gate /* MAXPATHLEN includes a null termination */
1100Sstevel@tonic-gate return (NULL);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate *p++ = '/';
1130Sstevel@tonic-gate cblen++;
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1166793Smuffin loclen = strlen(mp->locale);
1170Sstevel@tonic-gate catstr = category_name[mp->category];
1186793Smuffin catlen = (uint32_t)category_name_len[mp->category];
1190Sstevel@tonic-gate /*
1200Sstevel@tonic-gate * totallen is the length of the msgfile
1210Sstevel@tonic-gate * pathname excluding a null termination.
1220Sstevel@tonic-gate */
1230Sstevel@tonic-gate
1246793Smuffin totallen = cblen + loclen + 1 + catlen + 1 +
1256793Smuffin mp->domain_len + MSGFILESUFFIXLEN;
1260Sstevel@tonic-gate if (totallen >= MAXPATHLEN)
1270Sstevel@tonic-gate return (NULL);
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate q = mp->locale;
1300Sstevel@tonic-gate while (*p++ = *q++)
1310Sstevel@tonic-gate ;
1320Sstevel@tonic-gate *(p - 1) = '/';
1330Sstevel@tonic-gate while (*p++ = *catstr++)
1340Sstevel@tonic-gate ;
1350Sstevel@tonic-gate *(p - 1) = '/';
1360Sstevel@tonic-gate q = mp->domain;
1376793Smuffin while (*p = *q++)
1386793Smuffin p++;
1396793Smuffin q = MSGFILESUFFIX;
1400Sstevel@tonic-gate while (*p++ = *q++)
1410Sstevel@tonic-gate ;
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
1446793Smuffin gprintf(0, "*************** Exiting mk_msgfile\n");
1456793Smuffin gprintf(0, "mp->msgfile: \"%s\"\n", mp->msgfile);
1460Sstevel@tonic-gate #endif
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate return (mp->msgfile);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate /*
1520Sstevel@tonic-gate * check_cache
1530Sstevel@tonic-gate *
1540Sstevel@tonic-gate * INPUT
1550Sstevel@tonic-gate * mp - may use the following members:
1560Sstevel@tonic-gate * msgfile - pathname to the message catalog file
1576793Smuffin * hash_domain - hash id of this domain
1580Sstevel@tonic-gate *
1590Sstevel@tonic-gate * RETURN
1606793Smuffin * non-NULL
1616793Smuffin * pointer to the Msg_node object of the current message catalog
1626793Smuffin * found in the cache
1636793Smuffin *
1646793Smuffin * NULL
1656793Smuffin * this message catalog does not exist in the cache
1660Sstevel@tonic-gate */
1676793Smuffin Msg_node *
check_cache(struct msg_pack * mp)1686793Smuffin check_cache(struct msg_pack *mp)
1690Sstevel@tonic-gate {
1706793Smuffin Msg_node *cur_msg, *mnp;
1710Sstevel@tonic-gate Gettext_t *gt = global_gt;
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
1746793Smuffin gprintf(0, "*************** check_cache(0x%p)\n", mp);
1756793Smuffin printmp(mp, 1);
1760Sstevel@tonic-gate #endif
1770Sstevel@tonic-gate
1786793Smuffin cur_msg = gt->c_m_node; /* current Msg_node */
1790Sstevel@tonic-gate if (cur_msg &&
1806793Smuffin cur_msg->hashid == mp->hash_domain &&
1816793Smuffin strcmp(cur_msg->path, mp->msgfile) == 0) {
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate * msgfile is the same as the previous message file
1840Sstevel@tonic-gate */
1850Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
1866793Smuffin gprintf(0, "*** cache found\n");
1876793Smuffin gprintf(0, "************* exiting check_cache\n");
1886793Smuffin printmnp(cur_msg, 1);
1890Sstevel@tonic-gate #endif
1906793Smuffin return (cur_msg);
1910Sstevel@tonic-gate }
1926793Smuffin mnp = gt->m_node;
1936793Smuffin while (mnp) {
1940Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
1956793Smuffin gprintf(0, "========== descending the list\n");
1966793Smuffin gprintf(0, " hashid: %d, hash_domain: %d\n",
1976793Smuffin mnp->hashid, mp->hash_domain);
1986793Smuffin printmnp(mnp, 1);
1990Sstevel@tonic-gate #endif
2006793Smuffin if (mnp->hashid == mp->hash_domain &&
2016793Smuffin strcmp(mnp->path, mp->msgfile) == 0) {
2020Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
2036793Smuffin gprintf(0, "*** cache found\n");
2046793Smuffin gprintf(0, "******* exiting check_cache\n");
2056793Smuffin printmnp(mnp, 1);
2060Sstevel@tonic-gate #endif
2076793Smuffin gt->c_m_node = mnp;
2086793Smuffin return (mnp);
2090Sstevel@tonic-gate }
2106793Smuffin mnp = mnp->next;
2110Sstevel@tonic-gate }
2126793Smuffin
2130Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
2146793Smuffin gprintf(0, "*** cache not found\n");
2156793Smuffin gprintf(0, "******* exiting check_cache\n");
2160Sstevel@tonic-gate #endif
2176793Smuffin return (NULL);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate char *
get_codeset(const char * domain)2210Sstevel@tonic-gate get_codeset(const char *domain)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate char *codeset;
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
2266793Smuffin gprintf(0, "*************** get_codeset(\"%s\")\n",
2276793Smuffin domain ? domain : "(null)");
2280Sstevel@tonic-gate #endif
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate codeset = _real_bindtextdomain_u(domain, NULL, TP_CODESET);
2316793Smuffin if (codeset == NULL) {
2320Sstevel@tonic-gate /* no codeset is bound to this domain */
2330Sstevel@tonic-gate codeset = nl_langinfo(CODESET);
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
2366793Smuffin gprintf(0, "*************** existing get_codeset(\"%s\")\n",
2376793Smuffin domain ? domain : "(null)");
2386793Smuffin gprintf(0, " = \"%s\"\n", codeset);
2390Sstevel@tonic-gate #endif
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate return (codeset);
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate /*
2456793Smuffin * get_hashid (hashpjw)
2460Sstevel@tonic-gate *
2470Sstevel@tonic-gate * Calculates the hash value from the specified string.
2480Sstevel@tonic-gate * Actual hashid will be mod(hash value, PRIME_NUMBER).
2490Sstevel@tonic-gate *
2500Sstevel@tonic-gate * Ref: Compilers - Principles, Techniques, and Tools
2510Sstevel@tonic-gate * Aho, Sethi, and Ullman
2520Sstevel@tonic-gate */
2536793Smuffin uint32_t
get_hashid(const char * str,uint32_t * len)2546793Smuffin get_hashid(const char *str, uint32_t *len)
2550Sstevel@tonic-gate {
2566793Smuffin const unsigned char *p = (unsigned char *)str;
2576793Smuffin uint32_t h = 0;
2586793Smuffin uint32_t g;
2590Sstevel@tonic-gate
2606793Smuffin for (; *p; p++) {
2610Sstevel@tonic-gate h = (h << 4) + *p;
2620Sstevel@tonic-gate g = h & 0xf0000000;
2630Sstevel@tonic-gate if (g) {
2640Sstevel@tonic-gate h = h ^ (g >> 24);
2650Sstevel@tonic-gate h = h ^ g;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate }
2686793Smuffin
2690Sstevel@tonic-gate if (len)
2706793Smuffin *len = (uint32_t)(p - (unsigned char *)str);
2710Sstevel@tonic-gate return (h);
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate
2746793Smuffin uint32_t
doswap32(uint32_t n)2756793Smuffin doswap32(uint32_t n)
2760Sstevel@tonic-gate {
2776793Smuffin uint32_t r;
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate r = (n << 24) | ((n & 0xff00) << 8) |
2806793Smuffin ((n >> 8) & 0xff00) | (n >> 24);
2810Sstevel@tonic-gate return (r);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
2856793Smuffin static uint32_t
search_msg(Msg_g_node * p,const char * id,uint32_t hash_val,struct gnu_msg_ent * m)2866793Smuffin search_msg(Msg_g_node *p, const char *id, uint32_t hash_val,
2876793Smuffin struct gnu_msg_ent *m)
2886793Smuffin {
2896793Smuffin char *base = (char *)p->msg_file_info;
2906793Smuffin uint32_t hash_size, num_of_str, i, idx, inc;
2916793Smuffin char *ms;
2926793Smuffin
2936793Smuffin num_of_str = p->num_of_str;
2946793Smuffin hash_size = p->hash_size;
2956793Smuffin idx = hash_val % hash_size;
2966793Smuffin inc = 1 + (hash_val % (hash_size - 2));
2976793Smuffin
2986793Smuffin while ((i = p->hash_table[idx]) != 0) {
2996793Smuffin ms = (i <= num_of_str) ?
3006793Smuffin base + SWAP(p, m[i-1].offset) :
3016793Smuffin p->mchunk + p->d_msg[MSGID][i-num_of_str-1].offset;
3026793Smuffin if (strcmp(id, ms) == 0) {
3036793Smuffin /* found */
3046793Smuffin return (i);
3056793Smuffin }
3066793Smuffin idx = (idx + inc) % hash_size;
3076793Smuffin }
3086793Smuffin /* not found */
3096793Smuffin return (0);
3106793Smuffin }
3116793Smuffin
3126793Smuffin void
print_rev1_info(Msg_g_node * p)3136793Smuffin print_rev1_info(Msg_g_node *p)
3146793Smuffin {
3156793Smuffin char *base = (char *)p->msg_file_info;
3166793Smuffin struct gnu_msg_info *header = p->msg_file_info;
3176793Smuffin struct gnu_msg_ent *m;
3186793Smuffin uint32_t hv, hidx;
3196793Smuffin char *ms;
3206793Smuffin enum gnu_msgidstr v;
3216793Smuffin int x;
3226793Smuffin
3236793Smuffin #ifdef GETTEXT_DEBUG_DYMMSG
3246793Smuffin gprintf(0, "******** dynamic msgid/msgstr\n");
3256793Smuffin for (v = MSGID; v <= MSGSTR; v++) {
3266793Smuffin for (x = 0; x < p->num_of_d_str; x++) {
3276793Smuffin gprintf(0, "len: %u\n", p->d_msg[v][x].len);
3286793Smuffin gprintf(0, "str: \"%s\"\n",
3296793Smuffin p->mchunk + p->d_msg[v][x].offset);
3306793Smuffin }
3316793Smuffin }
3326793Smuffin #endif
3336793Smuffin #ifdef GETTEXT_DEBUG_HASHTBL
3346793Smuffin gprintf(0, "******** dynamic hash table\n");
3356793Smuffin for (x = 0; x < p->hash_size; x++) {
3366793Smuffin gprintf(0, "%d: %u\n", x, p->hash_table[x]);
3376793Smuffin }
3386793Smuffin #endif
3396793Smuffin #ifdef GETTEXT_DEBUG_CHECK_STMSGID
3406793Smuffin gprintf(0, "******** sanity check of static msgid\n");
3416793Smuffin m = (struct gnu_msg_ent *)(uintptr_t)
3426793Smuffin (base + SWAP(p, header->off_msgid_tbl));
3436793Smuffin for (x = 0; x < p->num_of_str; x++) {
3446793Smuffin ms = base + SWAP(p, m[x].offset);
3456793Smuffin gprintf(0, "\"%s\"\n", ms);
3466793Smuffin hv = get_hashid(ms, NULL);
3476793Smuffin hidx = search_msg(p, ms, hv, m);
3486793Smuffin if (hidx == 0) {
3496793Smuffin gprintf(0,
3506793Smuffin "failed to find this msg in the hash table\n");
3516793Smuffin } else {
3526793Smuffin if (hidx != x + 1) {
3536793Smuffin gprintf(0, "hash table mismatch\n");
3546793Smuffin }
3556793Smuffin }
3566793Smuffin }
3576793Smuffin #endif
3586793Smuffin #ifdef GETTEXT_DEBUG_CHECK_DYMMSGID
3596793Smuffin gprintf(0, "******* sanity check of dynamic msgid\n");
3606793Smuffin m = (struct gnu_msg_ent *)(uintptr_t)
3616793Smuffin (base + SWAP(p, header->off_msgid_tbl));
3626793Smuffin for (x = 0; x < p->num_of_d_str; x++) {
3636793Smuffin ms = p->mchunk + p->d_msg[MSGID][x].offset;
3646793Smuffin gprintf(0, "\"%s\"\n", ms);
3656793Smuffin hv = get_hashid(ms, NULL);
3666793Smuffin hidx = search_msg(p, ms, hv, m);
3676793Smuffin if (hidx == 0) {
3686793Smuffin gprintf(0,
3696793Smuffin "failed to find this msg in the hash table\n");
3706793Smuffin } else {
3716793Smuffin if (hidx != x + p->num_of_str + 1) {
3726793Smuffin gprintf(0, "hash table mismatch\n");
3736793Smuffin }
3746793Smuffin }
3756793Smuffin }
3766793Smuffin #endif
3776793Smuffin }
3786793Smuffin
3790Sstevel@tonic-gate void
gprintf(int level,const char * format,...)3800Sstevel@tonic-gate gprintf(int level, const char *format, ...)
3810Sstevel@tonic-gate {
3820Sstevel@tonic-gate va_list ap;
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate va_start(ap, format);
3850Sstevel@tonic-gate
3866793Smuffin while (level-- > 0) {
3870Sstevel@tonic-gate (void) fputs(" ", stdout);
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate (void) vprintf(format, ap);
3900Sstevel@tonic-gate va_end(ap);
3916793Smuffin
3926793Smuffin (void) fflush(stdout);
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate void
printlist(void)3960Sstevel@tonic-gate printlist(void)
3970Sstevel@tonic-gate {
3980Sstevel@tonic-gate struct domain_binding *ppp;
3990Sstevel@tonic-gate Gettext_t *gt = global_gt;
4000Sstevel@tonic-gate
4016793Smuffin gprintf(0, "=== Printing default list and regural list\n");
4026793Smuffin gprintf(0, " Default domain=<%s>, binding=<%s>\n",
4030Sstevel@tonic-gate DEFAULT_DOMAIN, defaultbind);
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate ppp = FIRSTBIND(gt);
4060Sstevel@tonic-gate while (ppp) {
4076793Smuffin gprintf(0, " domain=<%s>, binding=<%s>, codeset=<%s>\n",
4080Sstevel@tonic-gate ppp->domain ? ppp->domain : "(null)",
4096793Smuffin ppp->binding ? ppp->binding : "(null)",
4106793Smuffin ppp->codeset ? ppp->codeset : "(null)");
4110Sstevel@tonic-gate ppp = ppp->next;
4120Sstevel@tonic-gate }
4136793Smuffin (void) fflush(stdout);
4140Sstevel@tonic-gate }
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate void
printmp(struct msg_pack * mp,int level)4170Sstevel@tonic-gate printmp(struct msg_pack *mp, int level)
4180Sstevel@tonic-gate {
4190Sstevel@tonic-gate gprintf(level, "=== mp ===\n");
4200Sstevel@tonic-gate gprintf(level, " msgid1: \"%s\"\n",
4216793Smuffin mp->msgid1 ? mp->msgid1 : "(null)");
4220Sstevel@tonic-gate gprintf(level, " msgid2: \"%s\"\n",
4236793Smuffin mp->msgid2 ? mp->msgid2 : "(null)");
4246793Smuffin gprintf(level, " msgfile: \"%s\"\n",
4256793Smuffin mp->msgfile ? mp->msgfile : "(null)");
4260Sstevel@tonic-gate gprintf(level, " domain: \"%s\"\n",
4276793Smuffin mp->domain ? mp->domain : "(null)");
4280Sstevel@tonic-gate gprintf(level, " binding: \"%s\"\n",
4296793Smuffin mp->binding ? mp->binding : "(null)");
4300Sstevel@tonic-gate gprintf(level, " locale: \"%s\"\n",
4316793Smuffin mp->locale ? mp->locale : "(null)");
4320Sstevel@tonic-gate gprintf(level, " language: \"%s\"\n",
4336793Smuffin mp->language ? mp->language : "(null)");
4340Sstevel@tonic-gate gprintf(level, " addr: 0x%p\n", mp->addr);
4350Sstevel@tonic-gate gprintf(level, " fsz: %d\n", mp->fsz);
4366793Smuffin gprintf(level, " hash_domain: %d\n", mp->hash_domain);
4376793Smuffin gprintf(level, " domain_len: %d\n", mp->domain_len);
4386793Smuffin gprintf(level, " n: %d\n", mp->n);
4396793Smuffin gprintf(level, " category: \"%s\"\n",
4406793Smuffin category_name[mp->category]);
4416793Smuffin gprintf(level, " plural: %d\n", mp->plural);
4426793Smuffin gprintf(level, " nlsp: %d\n", mp->nlsp);
4430Sstevel@tonic-gate gprintf(level, " trusted: %d\n", mp->trusted);
4446793Smuffin gprintf(level, " status: %d\n", mp->status);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate void
printsunmsg(Msg_s_node * smnp,int level)4480Sstevel@tonic-gate printsunmsg(Msg_s_node *smnp, int level)
4490Sstevel@tonic-gate {
4500Sstevel@tonic-gate gprintf(level, "=== sunmsg ===\n");
4510Sstevel@tonic-gate gprintf(level, " msg_file_info: 0x%p\n",
4526793Smuffin (void *)smnp->msg_file_info);
4530Sstevel@tonic-gate gprintf(level, " msg_mid: %d\n",
4546793Smuffin smnp->msg_file_info->msg_mid);
4550Sstevel@tonic-gate gprintf(level, " msg_count: %d\n",
4566793Smuffin smnp->msg_file_info->msg_count);
4570Sstevel@tonic-gate gprintf(level, " str_count_msgid: %d\n",
4586793Smuffin smnp->msg_file_info->str_count_msgid);
4590Sstevel@tonic-gate gprintf(level, " str_count_msgstr: %d\n",
4606793Smuffin smnp->msg_file_info->str_count_msgstr);
4610Sstevel@tonic-gate gprintf(level, " msg_struct_size: %d\n",
4626793Smuffin smnp->msg_file_info->msg_struct_size);
4630Sstevel@tonic-gate gprintf(level, " msg_list: 0x%p\n",
4646793Smuffin (void *)smnp->msg_list);
4650Sstevel@tonic-gate gprintf(level, " msg_ids: 0x%p\n",
4666793Smuffin (void *)smnp->msg_ids);
4670Sstevel@tonic-gate gprintf(level, " msg_strs: 0x%p\n",
4686793Smuffin (void *)smnp->msg_strs);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate void
printgnumsg(Msg_g_node * gmnp,int level)4720Sstevel@tonic-gate printgnumsg(Msg_g_node *gmnp, int level)
4730Sstevel@tonic-gate {
4740Sstevel@tonic-gate gprintf(level, "=== gnumsg ===\n");
4756793Smuffin gprintf(level, " msg_file_info: 0x%p\n", gmnp->msg_file_info);
4760Sstevel@tonic-gate gprintf(level, " magic: 0x%x\n",
4776793Smuffin gmnp->msg_file_info->magic);
4780Sstevel@tonic-gate gprintf(level, " revision: %d\n",
4796793Smuffin SWAP(gmnp, gmnp->msg_file_info->revision));
4800Sstevel@tonic-gate gprintf(level, " num_of_str: %d\n",
4816793Smuffin SWAP(gmnp, gmnp->msg_file_info->num_of_str));
4820Sstevel@tonic-gate gprintf(level, " off_msgid_tbl: %d\n",
4836793Smuffin SWAP(gmnp, gmnp->msg_file_info->off_msgid_tbl));
4840Sstevel@tonic-gate gprintf(level, " off_msgstr_tbl: %d\n",
4856793Smuffin SWAP(gmnp, gmnp->msg_file_info->off_msgstr_tbl));
4860Sstevel@tonic-gate gprintf(level, " sz_hashtbl: %d\n",
4876793Smuffin SWAP(gmnp, gmnp->msg_file_info->sz_hashtbl));
4880Sstevel@tonic-gate gprintf(level, " off_hashtbl: %d\n",
4896793Smuffin SWAP(gmnp, gmnp->msg_file_info->off_hashtbl));
4906793Smuffin if (gmnp->flag & ST_REV1) {
4916793Smuffin struct gnu_msg_rev1_info *a =
4926793Smuffin (struct gnu_msg_rev1_info *)(uintptr_t)
4936793Smuffin ((char *)gmnp->msg_file_info +
4946793Smuffin sizeof (struct gnu_msg_info));
4956793Smuffin gprintf(level, " num_of_dynamic_macro: %d\n",
4966793Smuffin SWAP(gmnp, a->num_of_dynamic_macro));
4976793Smuffin gprintf(level, " off_dynamic_macro: %d\n",
4986793Smuffin SWAP(gmnp, a->off_dynamic_macro));
4996793Smuffin gprintf(level, " num_of_dynamic_str: %d\n",
5006793Smuffin SWAP(gmnp, a->num_of_dynamic_str));
5016793Smuffin gprintf(level, " off_dynamic_msgid_tbl: %d\n",
5026793Smuffin SWAP(gmnp, a->off_dynamic_msgid_tbl));
5036793Smuffin gprintf(level, " off_dynamic_msgstr_tbl: %d\n",
5046793Smuffin SWAP(gmnp, a->off_dynamic_msgstr_tbl));
5056793Smuffin }
5066793Smuffin gprintf(level, " fsize: %lu\n", gmnp->fsize);
5076793Smuffin gprintf(level, " flag: %08x\n", gmnp->flag);
5086793Smuffin gprintf(level, " num_of_str: %u\n", gmnp->num_of_str);
5096793Smuffin gprintf(level, " num_of_d_str: %u\n", gmnp->num_of_d_str);
5106793Smuffin gprintf(level, " hash_size: %u\n", gmnp->hash_size);
5116793Smuffin gprintf(level, " hash_table: 0x%p\n", (void *)gmnp->hash_table);
5126793Smuffin gprintf(level, " d_msgid: 0x%p\n", (void *)gmnp->d_msg[MSGID]);
5136793Smuffin gprintf(level, " d_msgstr: 0x%p\n", (void *)gmnp->d_msg[MSGSTR]);
5146793Smuffin gprintf(level, " mchunk: 0x%p\n", (void *)gmnp->mchunk);
5156793Smuffin
5160Sstevel@tonic-gate gprintf(level, " src_encoding: \"%s\"\n",
5176793Smuffin gmnp->src_encoding ? gmnp->src_encoding : "(null)");
5180Sstevel@tonic-gate gprintf(level, " dst_encoding: \"%s\"\n",
5196793Smuffin gmnp->dst_encoding ? gmnp->dst_encoding : "(null)");
5200Sstevel@tonic-gate gprintf(level, " nplurals: %d\n",
5216793Smuffin gmnp->nplurals);
5220Sstevel@tonic-gate gprintf(level, " plural: 0x%p\n",
5236793Smuffin (void *)gmnp->plural);
5240Sstevel@tonic-gate if (gmnp->plural)
5250Sstevel@tonic-gate printexpr(gmnp->plural, level+1);
5260Sstevel@tonic-gate gprintf(level, " fd: 0x%p\n", (void *)gmnp->fd);
5270Sstevel@tonic-gate gprintf(level, " conv_msgstr: 0x%p\n",
5286793Smuffin (void *)gmnp->conv_msgstr);
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate void
printexpr(struct expr * e,int level)5320Sstevel@tonic-gate printexpr(struct expr *e, int level)
5330Sstevel@tonic-gate {
5340Sstevel@tonic-gate static const char *op_name[] = {
5356793Smuffin "NULL", "INIT", "EXP",
5366793Smuffin "NUM", "VAR", "?", ":", "||",
5376793Smuffin "&&", "==", "!=", ">", "<",
5386793Smuffin ">=", "<=", "+", "-", "*", "/",
5396793Smuffin "%", "!", "(", ")", "ERR"
5400Sstevel@tonic-gate };
5410Sstevel@tonic-gate switch (GETOPNUM(e->op)) {
5420Sstevel@tonic-gate case 0:
5430Sstevel@tonic-gate switch (GETTYPE(e->op)) {
5440Sstevel@tonic-gate case T_NUM:
5450Sstevel@tonic-gate gprintf(level, "NUM(%d)\n", e->num);
5460Sstevel@tonic-gate break;
5470Sstevel@tonic-gate case T_VAR:
5480Sstevel@tonic-gate gprintf(level, "VAR(n)\n");
5490Sstevel@tonic-gate break;
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate break;
5520Sstevel@tonic-gate case 1:
5530Sstevel@tonic-gate gprintf(level, "OP: !\n");
5540Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5550Sstevel@tonic-gate break;
5560Sstevel@tonic-gate case 2:
5570Sstevel@tonic-gate gprintf(level, "OP: %s\n", op_name[GETTYPE(e->op)]);
5580Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5590Sstevel@tonic-gate printexpr(e->nodes[1], level+1);
5600Sstevel@tonic-gate break;
5610Sstevel@tonic-gate case 3:
5620Sstevel@tonic-gate gprintf(level, "OP: ?\n");
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5650Sstevel@tonic-gate printexpr(e->nodes[1], level+1);
5660Sstevel@tonic-gate printexpr(e->nodes[2], level+1);
5670Sstevel@tonic-gate break;
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate void
printmnp(Msg_node * mnp,int level)5730Sstevel@tonic-gate printmnp(Msg_node *mnp, int level)
5740Sstevel@tonic-gate {
5750Sstevel@tonic-gate gprintf(level, "=== mnp ===\n");
5760Sstevel@tonic-gate
5776793Smuffin gprintf(level, " hashid: %d\n", mnp->hashid);
5780Sstevel@tonic-gate gprintf(level, " type: \"%s\"\n",
5796793Smuffin mnp->type == T_ILL_MO ? "T_ILL_MO" :
5806793Smuffin mnp->type == T_SUN_MO ? "T_SUN_MO" :
5816793Smuffin mnp->type == T_GNU_MO ? "T_GNU_MO" :
5826793Smuffin "UNKNOWN TYPE");
5830Sstevel@tonic-gate gprintf(level, " path: \"%s\"\n",
5846793Smuffin mnp->path ? mnp->path : "(null)");
5850Sstevel@tonic-gate gprintf(level, " msg_file_trusted: %d\n",
5866793Smuffin mnp->trusted);
5870Sstevel@tonic-gate if (mnp->type == T_SUN_MO)
5880Sstevel@tonic-gate printsunmsg(mnp->msg.sunmsg, level+1);
5890Sstevel@tonic-gate else if (mnp->type == T_GNU_MO)
5900Sstevel@tonic-gate printgnumsg(mnp->msg.gnumsg, level+1);
5910Sstevel@tonic-gate gprintf(level, " next: 0x%p\n", (void *)mnp->next);
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate void
printnls(Nls_node * n,int level)5956793Smuffin printnls(Nls_node *n, int level)
5960Sstevel@tonic-gate {
5976793Smuffin gprintf(level, "=== nls ===\n");
5986793Smuffin gprintf(level, " domain: \"%s\"\n", n->domain ? n->domain : "NULL");
5996793Smuffin gprintf(level, " locale: \"%s\"\n", n->locale ? n->locale : "NULL");
6006793Smuffin gprintf(level, " nlspath: \"%s\"\n", n->nlspath ? n->nlspath :
6016793Smuffin "NULL");
6026793Smuffin gprintf(level, " next: 0x%p\n", n->next);
6036793Smuffin }
6040Sstevel@tonic-gate
6056793Smuffin void
printdbind(Dbinding * d,int level)6066793Smuffin printdbind(Dbinding *d, int level)
6076793Smuffin {
6086793Smuffin gprintf(level, "=== dbind ===\n");
6096793Smuffin gprintf(level, " domain: \"%s\"\n", d->domain ? d->domain : "NULL");
6106793Smuffin gprintf(level, " binding: \"%s\"\n", d->binding ? d->binding :
6116793Smuffin "NULL");
6126793Smuffin gprintf(level, " codeset: \"%s\"\n", d->codeset ? d->codeset :
6136793Smuffin "NULL");
6146793Smuffin gprintf(level, " next: 0x%p\n", d->next);
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate void
printgt(Gettext_t * gt,int level)6186793Smuffin printgt(Gettext_t *gt, int level)
6190Sstevel@tonic-gate {
6206793Smuffin gprintf(level, "=== gt ===\n");
6216793Smuffin gprintf(level, " cur_domain: \"%s\"\n", gt->cur_domain);
6226793Smuffin if (gt->dbind) {
6236793Smuffin printdbind(gt->dbind, level+1);
6246793Smuffin } else {
6256793Smuffin gprintf(level, " dbind: NULL\n");
6266793Smuffin }
6276793Smuffin if (gt->m_node) {
6286793Smuffin printmnp(gt->m_node, level + 1);
6296793Smuffin } else {
6306793Smuffin gprintf(level, " m_node: NULL\n");
6316793Smuffin }
6326793Smuffin if (gt->n_node) {
6336793Smuffin printnls(gt->n_node, level + 1);
6346793Smuffin } else {
6356793Smuffin gprintf(level, " n_node: NULL\n");
6366793Smuffin }
6376793Smuffin if (gt->c_m_node) {
6386793Smuffin printmnp(gt->c_m_node, level + 1);
6396793Smuffin } else {
6406793Smuffin gprintf(level, " c_m_node: NULL\n");
6416793Smuffin }
6426793Smuffin if (gt->c_n_node) {
6436793Smuffin printnls(gt->c_n_node, level + 1);
6446793Smuffin } else {
6456793Smuffin gprintf(level, " c_n_node: NULL\n");
6466793Smuffin }
6470Sstevel@tonic-gate }
6486793Smuffin
6490Sstevel@tonic-gate #endif
650