17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5f13ac639Smuffin * Common Development and Distribution License (the "License").
6f13ac639Smuffin * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21f13ac639Smuffin
227c478bd9Sstevel@tonic-gate /*
23f13ac639Smuffin * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277257d1b4Sraf #include "lint.h"
287c478bd9Sstevel@tonic-gate #include "mtlib.h"
297c478bd9Sstevel@tonic-gate #include <ctype.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <string.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <unistd.h>
357c478bd9Sstevel@tonic-gate #include <sys/mman.h>
367c478bd9Sstevel@tonic-gate #include <langinfo.h>
377c478bd9Sstevel@tonic-gate #include "libc.h"
387c478bd9Sstevel@tonic-gate #include "_loc_path.h"
397c478bd9Sstevel@tonic-gate #include "msgfmt.h"
407c478bd9Sstevel@tonic-gate #include "gettext.h"
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
437c478bd9Sstevel@tonic-gate #include "plural_parser.h"
447c478bd9Sstevel@tonic-gate #include <stdarg.h>
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate static const char *category_name[] = {
487c478bd9Sstevel@tonic-gate "LC_CTYPE",
497c478bd9Sstevel@tonic-gate "LC_NUMERIC",
507c478bd9Sstevel@tonic-gate "LC_TIME",
517c478bd9Sstevel@tonic-gate "LC_COLLATE",
527c478bd9Sstevel@tonic-gate "LC_MONETARY",
537c478bd9Sstevel@tonic-gate "LC_MESSAGES"
547c478bd9Sstevel@tonic-gate };
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate static const int category_name_len[] = {
577c478bd9Sstevel@tonic-gate 8,
587c478bd9Sstevel@tonic-gate 10,
597c478bd9Sstevel@tonic-gate 7,
607c478bd9Sstevel@tonic-gate 10,
617c478bd9Sstevel@tonic-gate 11,
627c478bd9Sstevel@tonic-gate 11
637c478bd9Sstevel@tonic-gate };
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate * mk_msgfile
677c478bd9Sstevel@tonic-gate *
687c478bd9Sstevel@tonic-gate * INPUT
697c478bd9Sstevel@tonic-gate * mp - uses the following members:
70*00ae5933SToomas Soome * msgfile - buffer to store the pathname to the message file
717c478bd9Sstevel@tonic-gate * binding - directory pathname bound to specified domain
727c478bd9Sstevel@tonic-gate * cblen - length of binding
737c478bd9Sstevel@tonic-gate * locale - locale name
747c478bd9Sstevel@tonic-gate * domain - domain name
757c478bd9Sstevel@tonic-gate * category - category
767c478bd9Sstevel@tonic-gate * domain_len - length of domain name
777c478bd9Sstevel@tonic-gate *
787c478bd9Sstevel@tonic-gate * OUTPUT
797c478bd9Sstevel@tonic-gate * mp->msgfile - pathname to the message file is stored
807c478bd9Sstevel@tonic-gate *
817c478bd9Sstevel@tonic-gate * RETURN
827c478bd9Sstevel@tonic-gate * mp->msgfile is returned
837c478bd9Sstevel@tonic-gate */
847c478bd9Sstevel@tonic-gate char *
mk_msgfile(struct msg_pack * mp)857c478bd9Sstevel@tonic-gate mk_msgfile(struct msg_pack *mp)
867c478bd9Sstevel@tonic-gate {
87b599bd93SRobert Mustacchi const char *q;
88b599bd93SRobert Mustacchi char *p;
897c478bd9Sstevel@tonic-gate const char *catstr;
90f13ac639Smuffin uint32_t cblen, loclen, catlen, totallen;
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
93f13ac639Smuffin gprintf(0, "*************** mk_msgfile(0x%p)\n", (void *)mp);
94f13ac639Smuffin printmp(mp, 1);
957c478bd9Sstevel@tonic-gate #endif
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate p = mp->msgfile;
987c478bd9Sstevel@tonic-gate q = mp->binding;
99*00ae5933SToomas Soome while ((*p = *q++) != '\0')
1007c478bd9Sstevel@tonic-gate p++;
101f13ac639Smuffin cblen = (uint32_t)(p - mp->msgfile);
1027c478bd9Sstevel@tonic-gate if (*(p - 1) != '/') {
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate * if the last character of binding
1057c478bd9Sstevel@tonic-gate * isn't a '/', adding '/'.
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate if (cblen + 1 >= MAXPATHLEN) {
1087c478bd9Sstevel@tonic-gate /* MAXPATHLEN includes a null termination */
1097c478bd9Sstevel@tonic-gate return (NULL);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate *p++ = '/';
1127c478bd9Sstevel@tonic-gate cblen++;
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate
115f13ac639Smuffin loclen = strlen(mp->locale);
1167c478bd9Sstevel@tonic-gate catstr = category_name[mp->category];
117f13ac639Smuffin catlen = (uint32_t)category_name_len[mp->category];
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate * totallen is the length of the msgfile
1207c478bd9Sstevel@tonic-gate * pathname excluding a null termination.
1217c478bd9Sstevel@tonic-gate */
1227c478bd9Sstevel@tonic-gate
123f13ac639Smuffin totallen = cblen + loclen + 1 + catlen + 1 +
124f13ac639Smuffin mp->domain_len + MSGFILESUFFIXLEN;
1257c478bd9Sstevel@tonic-gate if (totallen >= MAXPATHLEN)
1267c478bd9Sstevel@tonic-gate return (NULL);
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate q = mp->locale;
129*00ae5933SToomas Soome while ((*p++ = *q++) != '\0')
1307c478bd9Sstevel@tonic-gate ;
1317c478bd9Sstevel@tonic-gate *(p - 1) = '/';
132*00ae5933SToomas Soome while ((*p++ = *catstr++) != '\0')
1337c478bd9Sstevel@tonic-gate ;
1347c478bd9Sstevel@tonic-gate *(p - 1) = '/';
1357c478bd9Sstevel@tonic-gate q = mp->domain;
136*00ae5933SToomas Soome while ((*p = *q++) != '\0')
137f13ac639Smuffin p++;
138f13ac639Smuffin q = MSGFILESUFFIX;
139*00ae5933SToomas Soome while ((*p++ = *q++) != '\0')
1407c478bd9Sstevel@tonic-gate ;
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
143f13ac639Smuffin gprintf(0, "*************** Exiting mk_msgfile\n");
144f13ac639Smuffin gprintf(0, "mp->msgfile: \"%s\"\n", mp->msgfile);
1457c478bd9Sstevel@tonic-gate #endif
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate return (mp->msgfile);
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate * check_cache
1527c478bd9Sstevel@tonic-gate *
1537c478bd9Sstevel@tonic-gate * INPUT
1547c478bd9Sstevel@tonic-gate * mp - may use the following members:
1557c478bd9Sstevel@tonic-gate * msgfile - pathname to the message catalog file
156f13ac639Smuffin * hash_domain - hash id of this domain
1577c478bd9Sstevel@tonic-gate *
1587c478bd9Sstevel@tonic-gate * RETURN
159f13ac639Smuffin * non-NULL
160f13ac639Smuffin * pointer to the Msg_node object of the current message catalog
161f13ac639Smuffin * found in the cache
162f13ac639Smuffin *
163f13ac639Smuffin * NULL
164f13ac639Smuffin * this message catalog does not exist in the cache
1657c478bd9Sstevel@tonic-gate */
166f13ac639Smuffin Msg_node *
check_cache(struct msg_pack * mp)167f13ac639Smuffin check_cache(struct msg_pack *mp)
1687c478bd9Sstevel@tonic-gate {
169f13ac639Smuffin Msg_node *cur_msg, *mnp;
1707c478bd9Sstevel@tonic-gate Gettext_t *gt = global_gt;
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
173f13ac639Smuffin gprintf(0, "*************** check_cache(0x%p)\n", mp);
174f13ac639Smuffin printmp(mp, 1);
1757c478bd9Sstevel@tonic-gate #endif
1767c478bd9Sstevel@tonic-gate
177f13ac639Smuffin cur_msg = gt->c_m_node; /* current Msg_node */
1787c478bd9Sstevel@tonic-gate if (cur_msg &&
179f13ac639Smuffin cur_msg->hashid == mp->hash_domain &&
180f13ac639Smuffin strcmp(cur_msg->path, mp->msgfile) == 0) {
1817c478bd9Sstevel@tonic-gate /*
1827c478bd9Sstevel@tonic-gate * msgfile is the same as the previous message file
1837c478bd9Sstevel@tonic-gate */
1847c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
185f13ac639Smuffin gprintf(0, "*** cache found\n");
186f13ac639Smuffin gprintf(0, "************* exiting check_cache\n");
187f13ac639Smuffin printmnp(cur_msg, 1);
1887c478bd9Sstevel@tonic-gate #endif
189f13ac639Smuffin return (cur_msg);
1907c478bd9Sstevel@tonic-gate }
191f13ac639Smuffin mnp = gt->m_node;
192f13ac639Smuffin while (mnp) {
1937c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
194f13ac639Smuffin gprintf(0, "========== descending the list\n");
195f13ac639Smuffin gprintf(0, " hashid: %d, hash_domain: %d\n",
196f13ac639Smuffin mnp->hashid, mp->hash_domain);
197f13ac639Smuffin printmnp(mnp, 1);
1987c478bd9Sstevel@tonic-gate #endif
199f13ac639Smuffin if (mnp->hashid == mp->hash_domain &&
200f13ac639Smuffin strcmp(mnp->path, mp->msgfile) == 0) {
2017c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
202f13ac639Smuffin gprintf(0, "*** cache found\n");
203f13ac639Smuffin gprintf(0, "******* exiting check_cache\n");
204f13ac639Smuffin printmnp(mnp, 1);
2057c478bd9Sstevel@tonic-gate #endif
206f13ac639Smuffin gt->c_m_node = mnp;
207f13ac639Smuffin return (mnp);
2087c478bd9Sstevel@tonic-gate }
209f13ac639Smuffin mnp = mnp->next;
2107c478bd9Sstevel@tonic-gate }
211f13ac639Smuffin
2127c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
213f13ac639Smuffin gprintf(0, "*** cache not found\n");
214f13ac639Smuffin gprintf(0, "******* exiting check_cache\n");
2157c478bd9Sstevel@tonic-gate #endif
216f13ac639Smuffin return (NULL);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate char *
get_codeset(const char * domain)2207c478bd9Sstevel@tonic-gate get_codeset(const char *domain)
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate char *codeset;
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
225f13ac639Smuffin gprintf(0, "*************** get_codeset(\"%s\")\n",
226f13ac639Smuffin domain ? domain : "(null)");
2277c478bd9Sstevel@tonic-gate #endif
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate codeset = _real_bindtextdomain_u(domain, NULL, TP_CODESET);
230f13ac639Smuffin if (codeset == NULL) {
2317c478bd9Sstevel@tonic-gate /* no codeset is bound to this domain */
2327c478bd9Sstevel@tonic-gate codeset = nl_langinfo(CODESET);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
235f13ac639Smuffin gprintf(0, "*************** existing get_codeset(\"%s\")\n",
236f13ac639Smuffin domain ? domain : "(null)");
237f13ac639Smuffin gprintf(0, " = \"%s\"\n", codeset);
2387c478bd9Sstevel@tonic-gate #endif
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate return (codeset);
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate /*
244f13ac639Smuffin * get_hashid (hashpjw)
2457c478bd9Sstevel@tonic-gate *
2467c478bd9Sstevel@tonic-gate * Calculates the hash value from the specified string.
2477c478bd9Sstevel@tonic-gate * Actual hashid will be mod(hash value, PRIME_NUMBER).
2487c478bd9Sstevel@tonic-gate *
2497c478bd9Sstevel@tonic-gate * Ref: Compilers - Principles, Techniques, and Tools
2507c478bd9Sstevel@tonic-gate * Aho, Sethi, and Ullman
2517c478bd9Sstevel@tonic-gate */
252f13ac639Smuffin uint32_t
get_hashid(const char * str,uint32_t * len)253f13ac639Smuffin get_hashid(const char *str, uint32_t *len)
2547c478bd9Sstevel@tonic-gate {
255f13ac639Smuffin const unsigned char *p = (unsigned char *)str;
256f13ac639Smuffin uint32_t h = 0;
257f13ac639Smuffin uint32_t g;
2587c478bd9Sstevel@tonic-gate
259f13ac639Smuffin for (; *p; p++) {
2607c478bd9Sstevel@tonic-gate h = (h << 4) + *p;
2617c478bd9Sstevel@tonic-gate g = h & 0xf0000000;
2627c478bd9Sstevel@tonic-gate if (g) {
2637c478bd9Sstevel@tonic-gate h = h ^ (g >> 24);
2647c478bd9Sstevel@tonic-gate h = h ^ g;
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate }
267f13ac639Smuffin
2687c478bd9Sstevel@tonic-gate if (len)
269f13ac639Smuffin *len = (uint32_t)(p - (unsigned char *)str);
2707c478bd9Sstevel@tonic-gate return (h);
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate
273f13ac639Smuffin uint32_t
doswap32(uint32_t n)274f13ac639Smuffin doswap32(uint32_t n)
2757c478bd9Sstevel@tonic-gate {
276f13ac639Smuffin uint32_t r;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate r = (n << 24) | ((n & 0xff00) << 8) |
279f13ac639Smuffin ((n >> 8) & 0xff00) | (n >> 24);
2807c478bd9Sstevel@tonic-gate return (r);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG
284f13ac639Smuffin static uint32_t
search_msg(Msg_g_node * p,const char * id,uint32_t hash_val,struct gnu_msg_ent * m)285f13ac639Smuffin search_msg(Msg_g_node *p, const char *id, uint32_t hash_val,
286f13ac639Smuffin struct gnu_msg_ent *m)
287f13ac639Smuffin {
288f13ac639Smuffin char *base = (char *)p->msg_file_info;
289f13ac639Smuffin uint32_t hash_size, num_of_str, i, idx, inc;
290f13ac639Smuffin char *ms;
291f13ac639Smuffin
292f13ac639Smuffin num_of_str = p->num_of_str;
293f13ac639Smuffin hash_size = p->hash_size;
294f13ac639Smuffin idx = hash_val % hash_size;
295f13ac639Smuffin inc = 1 + (hash_val % (hash_size - 2));
296f13ac639Smuffin
297f13ac639Smuffin while ((i = p->hash_table[idx]) != 0) {
298f13ac639Smuffin ms = (i <= num_of_str) ?
299f13ac639Smuffin base + SWAP(p, m[i-1].offset) :
300f13ac639Smuffin p->mchunk + p->d_msg[MSGID][i-num_of_str-1].offset;
301f13ac639Smuffin if (strcmp(id, ms) == 0) {
302f13ac639Smuffin /* found */
303f13ac639Smuffin return (i);
304f13ac639Smuffin }
305f13ac639Smuffin idx = (idx + inc) % hash_size;
306f13ac639Smuffin }
307f13ac639Smuffin /* not found */
308f13ac639Smuffin return (0);
309f13ac639Smuffin }
310f13ac639Smuffin
311f13ac639Smuffin void
print_rev1_info(Msg_g_node * p)312f13ac639Smuffin print_rev1_info(Msg_g_node *p)
313f13ac639Smuffin {
314f13ac639Smuffin char *base = (char *)p->msg_file_info;
315f13ac639Smuffin struct gnu_msg_info *header = p->msg_file_info;
316f13ac639Smuffin struct gnu_msg_ent *m;
317f13ac639Smuffin uint32_t hv, hidx;
318f13ac639Smuffin char *ms;
319f13ac639Smuffin enum gnu_msgidstr v;
320f13ac639Smuffin int x;
321f13ac639Smuffin
322f13ac639Smuffin #ifdef GETTEXT_DEBUG_DYMMSG
323f13ac639Smuffin gprintf(0, "******** dynamic msgid/msgstr\n");
324f13ac639Smuffin for (v = MSGID; v <= MSGSTR; v++) {
325f13ac639Smuffin for (x = 0; x < p->num_of_d_str; x++) {
326f13ac639Smuffin gprintf(0, "len: %u\n", p->d_msg[v][x].len);
327f13ac639Smuffin gprintf(0, "str: \"%s\"\n",
328f13ac639Smuffin p->mchunk + p->d_msg[v][x].offset);
329f13ac639Smuffin }
330f13ac639Smuffin }
331f13ac639Smuffin #endif
332f13ac639Smuffin #ifdef GETTEXT_DEBUG_HASHTBL
333f13ac639Smuffin gprintf(0, "******** dynamic hash table\n");
334f13ac639Smuffin for (x = 0; x < p->hash_size; x++) {
335f13ac639Smuffin gprintf(0, "%d: %u\n", x, p->hash_table[x]);
336f13ac639Smuffin }
337f13ac639Smuffin #endif
338f13ac639Smuffin #ifdef GETTEXT_DEBUG_CHECK_STMSGID
339f13ac639Smuffin gprintf(0, "******** sanity check of static msgid\n");
340f13ac639Smuffin m = (struct gnu_msg_ent *)(uintptr_t)
341f13ac639Smuffin (base + SWAP(p, header->off_msgid_tbl));
342f13ac639Smuffin for (x = 0; x < p->num_of_str; x++) {
343f13ac639Smuffin ms = base + SWAP(p, m[x].offset);
344f13ac639Smuffin gprintf(0, "\"%s\"\n", ms);
345f13ac639Smuffin hv = get_hashid(ms, NULL);
346f13ac639Smuffin hidx = search_msg(p, ms, hv, m);
347f13ac639Smuffin if (hidx == 0) {
348f13ac639Smuffin gprintf(0,
349f13ac639Smuffin "failed to find this msg in the hash table\n");
350f13ac639Smuffin } else {
351f13ac639Smuffin if (hidx != x + 1) {
352f13ac639Smuffin gprintf(0, "hash table mismatch\n");
353f13ac639Smuffin }
354f13ac639Smuffin }
355f13ac639Smuffin }
356f13ac639Smuffin #endif
357f13ac639Smuffin #ifdef GETTEXT_DEBUG_CHECK_DYMMSGID
358f13ac639Smuffin gprintf(0, "******* sanity check of dynamic msgid\n");
359f13ac639Smuffin m = (struct gnu_msg_ent *)(uintptr_t)
360f13ac639Smuffin (base + SWAP(p, header->off_msgid_tbl));
361f13ac639Smuffin for (x = 0; x < p->num_of_d_str; x++) {
362f13ac639Smuffin ms = p->mchunk + p->d_msg[MSGID][x].offset;
363f13ac639Smuffin gprintf(0, "\"%s\"\n", ms);
364f13ac639Smuffin hv = get_hashid(ms, NULL);
365f13ac639Smuffin hidx = search_msg(p, ms, hv, m);
366f13ac639Smuffin if (hidx == 0) {
367f13ac639Smuffin gprintf(0,
368f13ac639Smuffin "failed to find this msg in the hash table\n");
369f13ac639Smuffin } else {
370f13ac639Smuffin if (hidx != x + p->num_of_str + 1) {
371f13ac639Smuffin gprintf(0, "hash table mismatch\n");
372f13ac639Smuffin }
373f13ac639Smuffin }
374f13ac639Smuffin }
375f13ac639Smuffin #endif
376f13ac639Smuffin }
377f13ac639Smuffin
3787c478bd9Sstevel@tonic-gate void
gprintf(int level,const char * format,...)3797c478bd9Sstevel@tonic-gate gprintf(int level, const char *format, ...)
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate va_list ap;
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate va_start(ap, format);
3847c478bd9Sstevel@tonic-gate
385f13ac639Smuffin while (level-- > 0) {
3867c478bd9Sstevel@tonic-gate (void) fputs(" ", stdout);
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate (void) vprintf(format, ap);
3897c478bd9Sstevel@tonic-gate va_end(ap);
390f13ac639Smuffin
391f13ac639Smuffin (void) fflush(stdout);
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate void
printlist(void)3957c478bd9Sstevel@tonic-gate printlist(void)
3967c478bd9Sstevel@tonic-gate {
3977c478bd9Sstevel@tonic-gate struct domain_binding *ppp;
3987c478bd9Sstevel@tonic-gate Gettext_t *gt = global_gt;
3997c478bd9Sstevel@tonic-gate
400f13ac639Smuffin gprintf(0, "=== Printing default list and regural list\n");
401f13ac639Smuffin gprintf(0, " Default domain=<%s>, binding=<%s>\n",
4027c478bd9Sstevel@tonic-gate DEFAULT_DOMAIN, defaultbind);
4037c478bd9Sstevel@tonic-gate
4047c478bd9Sstevel@tonic-gate ppp = FIRSTBIND(gt);
4057c478bd9Sstevel@tonic-gate while (ppp) {
406f13ac639Smuffin gprintf(0, " domain=<%s>, binding=<%s>, codeset=<%s>\n",
4077c478bd9Sstevel@tonic-gate ppp->domain ? ppp->domain : "(null)",
408f13ac639Smuffin ppp->binding ? ppp->binding : "(null)",
409f13ac639Smuffin ppp->codeset ? ppp->codeset : "(null)");
4107c478bd9Sstevel@tonic-gate ppp = ppp->next;
4117c478bd9Sstevel@tonic-gate }
412f13ac639Smuffin (void) fflush(stdout);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate void
printmp(struct msg_pack * mp,int level)4167c478bd9Sstevel@tonic-gate printmp(struct msg_pack *mp, int level)
4177c478bd9Sstevel@tonic-gate {
4187c478bd9Sstevel@tonic-gate gprintf(level, "=== mp ===\n");
4197c478bd9Sstevel@tonic-gate gprintf(level, " msgid1: \"%s\"\n",
420f13ac639Smuffin mp->msgid1 ? mp->msgid1 : "(null)");
4217c478bd9Sstevel@tonic-gate gprintf(level, " msgid2: \"%s\"\n",
422f13ac639Smuffin mp->msgid2 ? mp->msgid2 : "(null)");
423f13ac639Smuffin gprintf(level, " msgfile: \"%s\"\n",
424f13ac639Smuffin mp->msgfile ? mp->msgfile : "(null)");
4257c478bd9Sstevel@tonic-gate gprintf(level, " domain: \"%s\"\n",
426f13ac639Smuffin mp->domain ? mp->domain : "(null)");
4277c478bd9Sstevel@tonic-gate gprintf(level, " binding: \"%s\"\n",
428f13ac639Smuffin mp->binding ? mp->binding : "(null)");
4297c478bd9Sstevel@tonic-gate gprintf(level, " locale: \"%s\"\n",
430f13ac639Smuffin mp->locale ? mp->locale : "(null)");
4317c478bd9Sstevel@tonic-gate gprintf(level, " language: \"%s\"\n",
432f13ac639Smuffin mp->language ? mp->language : "(null)");
4337c478bd9Sstevel@tonic-gate gprintf(level, " addr: 0x%p\n", mp->addr);
4347c478bd9Sstevel@tonic-gate gprintf(level, " fsz: %d\n", mp->fsz);
435f13ac639Smuffin gprintf(level, " hash_domain: %d\n", mp->hash_domain);
436f13ac639Smuffin gprintf(level, " domain_len: %d\n", mp->domain_len);
437f13ac639Smuffin gprintf(level, " n: %d\n", mp->n);
438f13ac639Smuffin gprintf(level, " category: \"%s\"\n",
439f13ac639Smuffin category_name[mp->category]);
440f13ac639Smuffin gprintf(level, " plural: %d\n", mp->plural);
441f13ac639Smuffin gprintf(level, " nlsp: %d\n", mp->nlsp);
4427c478bd9Sstevel@tonic-gate gprintf(level, " trusted: %d\n", mp->trusted);
443f13ac639Smuffin gprintf(level, " status: %d\n", mp->status);
4447c478bd9Sstevel@tonic-gate }
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate void
printsunmsg(Msg_s_node * smnp,int level)4477c478bd9Sstevel@tonic-gate printsunmsg(Msg_s_node *smnp, int level)
4487c478bd9Sstevel@tonic-gate {
4497c478bd9Sstevel@tonic-gate gprintf(level, "=== sunmsg ===\n");
4507c478bd9Sstevel@tonic-gate gprintf(level, " msg_file_info: 0x%p\n",
451f13ac639Smuffin (void *)smnp->msg_file_info);
4527c478bd9Sstevel@tonic-gate gprintf(level, " msg_mid: %d\n",
453f13ac639Smuffin smnp->msg_file_info->msg_mid);
4547c478bd9Sstevel@tonic-gate gprintf(level, " msg_count: %d\n",
455f13ac639Smuffin smnp->msg_file_info->msg_count);
4567c478bd9Sstevel@tonic-gate gprintf(level, " str_count_msgid: %d\n",
457f13ac639Smuffin smnp->msg_file_info->str_count_msgid);
4587c478bd9Sstevel@tonic-gate gprintf(level, " str_count_msgstr: %d\n",
459f13ac639Smuffin smnp->msg_file_info->str_count_msgstr);
4607c478bd9Sstevel@tonic-gate gprintf(level, " msg_struct_size: %d\n",
461f13ac639Smuffin smnp->msg_file_info->msg_struct_size);
4627c478bd9Sstevel@tonic-gate gprintf(level, " msg_list: 0x%p\n",
463f13ac639Smuffin (void *)smnp->msg_list);
4647c478bd9Sstevel@tonic-gate gprintf(level, " msg_ids: 0x%p\n",
465f13ac639Smuffin (void *)smnp->msg_ids);
4667c478bd9Sstevel@tonic-gate gprintf(level, " msg_strs: 0x%p\n",
467f13ac639Smuffin (void *)smnp->msg_strs);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate void
printgnumsg(Msg_g_node * gmnp,int level)4717c478bd9Sstevel@tonic-gate printgnumsg(Msg_g_node *gmnp, int level)
4727c478bd9Sstevel@tonic-gate {
4737c478bd9Sstevel@tonic-gate gprintf(level, "=== gnumsg ===\n");
474f13ac639Smuffin gprintf(level, " msg_file_info: 0x%p\n", gmnp->msg_file_info);
4757c478bd9Sstevel@tonic-gate gprintf(level, " magic: 0x%x\n",
476f13ac639Smuffin gmnp->msg_file_info->magic);
4777c478bd9Sstevel@tonic-gate gprintf(level, " revision: %d\n",
478f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->revision));
4797c478bd9Sstevel@tonic-gate gprintf(level, " num_of_str: %d\n",
480f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->num_of_str));
4817c478bd9Sstevel@tonic-gate gprintf(level, " off_msgid_tbl: %d\n",
482f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->off_msgid_tbl));
4837c478bd9Sstevel@tonic-gate gprintf(level, " off_msgstr_tbl: %d\n",
484f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->off_msgstr_tbl));
4857c478bd9Sstevel@tonic-gate gprintf(level, " sz_hashtbl: %d\n",
486f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->sz_hashtbl));
4877c478bd9Sstevel@tonic-gate gprintf(level, " off_hashtbl: %d\n",
488f13ac639Smuffin SWAP(gmnp, gmnp->msg_file_info->off_hashtbl));
489f13ac639Smuffin if (gmnp->flag & ST_REV1) {
490f13ac639Smuffin struct gnu_msg_rev1_info *a =
491f13ac639Smuffin (struct gnu_msg_rev1_info *)(uintptr_t)
492f13ac639Smuffin ((char *)gmnp->msg_file_info +
493f13ac639Smuffin sizeof (struct gnu_msg_info));
494f13ac639Smuffin gprintf(level, " num_of_dynamic_macro: %d\n",
495f13ac639Smuffin SWAP(gmnp, a->num_of_dynamic_macro));
496f13ac639Smuffin gprintf(level, " off_dynamic_macro: %d\n",
497f13ac639Smuffin SWAP(gmnp, a->off_dynamic_macro));
498f13ac639Smuffin gprintf(level, " num_of_dynamic_str: %d\n",
499f13ac639Smuffin SWAP(gmnp, a->num_of_dynamic_str));
500f13ac639Smuffin gprintf(level, " off_dynamic_msgid_tbl: %d\n",
501f13ac639Smuffin SWAP(gmnp, a->off_dynamic_msgid_tbl));
502f13ac639Smuffin gprintf(level, " off_dynamic_msgstr_tbl: %d\n",
503f13ac639Smuffin SWAP(gmnp, a->off_dynamic_msgstr_tbl));
504f13ac639Smuffin }
505f13ac639Smuffin gprintf(level, " fsize: %lu\n", gmnp->fsize);
506f13ac639Smuffin gprintf(level, " flag: %08x\n", gmnp->flag);
507f13ac639Smuffin gprintf(level, " num_of_str: %u\n", gmnp->num_of_str);
508f13ac639Smuffin gprintf(level, " num_of_d_str: %u\n", gmnp->num_of_d_str);
509f13ac639Smuffin gprintf(level, " hash_size: %u\n", gmnp->hash_size);
510f13ac639Smuffin gprintf(level, " hash_table: 0x%p\n", (void *)gmnp->hash_table);
511f13ac639Smuffin gprintf(level, " d_msgid: 0x%p\n", (void *)gmnp->d_msg[MSGID]);
512f13ac639Smuffin gprintf(level, " d_msgstr: 0x%p\n", (void *)gmnp->d_msg[MSGSTR]);
513f13ac639Smuffin gprintf(level, " mchunk: 0x%p\n", (void *)gmnp->mchunk);
514f13ac639Smuffin
5157c478bd9Sstevel@tonic-gate gprintf(level, " src_encoding: \"%s\"\n",
516f13ac639Smuffin gmnp->src_encoding ? gmnp->src_encoding : "(null)");
5177c478bd9Sstevel@tonic-gate gprintf(level, " dst_encoding: \"%s\"\n",
518f13ac639Smuffin gmnp->dst_encoding ? gmnp->dst_encoding : "(null)");
5197c478bd9Sstevel@tonic-gate gprintf(level, " nplurals: %d\n",
520f13ac639Smuffin gmnp->nplurals);
5217c478bd9Sstevel@tonic-gate gprintf(level, " plural: 0x%p\n",
522f13ac639Smuffin (void *)gmnp->plural);
5237c478bd9Sstevel@tonic-gate if (gmnp->plural)
5247c478bd9Sstevel@tonic-gate printexpr(gmnp->plural, level+1);
5257c478bd9Sstevel@tonic-gate gprintf(level, " fd: 0x%p\n", (void *)gmnp->fd);
5267c478bd9Sstevel@tonic-gate gprintf(level, " conv_msgstr: 0x%p\n",
527f13ac639Smuffin (void *)gmnp->conv_msgstr);
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate
5307c478bd9Sstevel@tonic-gate void
printexpr(struct expr * e,int level)5317c478bd9Sstevel@tonic-gate printexpr(struct expr *e, int level)
5327c478bd9Sstevel@tonic-gate {
5337c478bd9Sstevel@tonic-gate static const char *op_name[] = {
534f13ac639Smuffin "NULL", "INIT", "EXP",
535f13ac639Smuffin "NUM", "VAR", "?", ":", "||",
536f13ac639Smuffin "&&", "==", "!=", ">", "<",
537f13ac639Smuffin ">=", "<=", "+", "-", "*", "/",
538f13ac639Smuffin "%", "!", "(", ")", "ERR"
5397c478bd9Sstevel@tonic-gate };
5407c478bd9Sstevel@tonic-gate switch (GETOPNUM(e->op)) {
5417c478bd9Sstevel@tonic-gate case 0:
5427c478bd9Sstevel@tonic-gate switch (GETTYPE(e->op)) {
5437c478bd9Sstevel@tonic-gate case T_NUM:
5447c478bd9Sstevel@tonic-gate gprintf(level, "NUM(%d)\n", e->num);
5457c478bd9Sstevel@tonic-gate break;
5467c478bd9Sstevel@tonic-gate case T_VAR:
5477c478bd9Sstevel@tonic-gate gprintf(level, "VAR(n)\n");
5487c478bd9Sstevel@tonic-gate break;
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate break;
5517c478bd9Sstevel@tonic-gate case 1:
5527c478bd9Sstevel@tonic-gate gprintf(level, "OP: !\n");
5537c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5547c478bd9Sstevel@tonic-gate break;
5557c478bd9Sstevel@tonic-gate case 2:
5567c478bd9Sstevel@tonic-gate gprintf(level, "OP: %s\n", op_name[GETTYPE(e->op)]);
5577c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5587c478bd9Sstevel@tonic-gate printexpr(e->nodes[1], level+1);
5597c478bd9Sstevel@tonic-gate break;
5607c478bd9Sstevel@tonic-gate case 3:
5617c478bd9Sstevel@tonic-gate gprintf(level, "OP: ?\n");
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1);
5647c478bd9Sstevel@tonic-gate printexpr(e->nodes[1], level+1);
5657c478bd9Sstevel@tonic-gate printexpr(e->nodes[2], level+1);
5667c478bd9Sstevel@tonic-gate break;
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate void
printmnp(Msg_node * mnp,int level)5727c478bd9Sstevel@tonic-gate printmnp(Msg_node *mnp, int level)
5737c478bd9Sstevel@tonic-gate {
5747c478bd9Sstevel@tonic-gate gprintf(level, "=== mnp ===\n");
5757c478bd9Sstevel@tonic-gate
576f13ac639Smuffin gprintf(level, " hashid: %d\n", mnp->hashid);
5777c478bd9Sstevel@tonic-gate gprintf(level, " type: \"%s\"\n",
578f13ac639Smuffin mnp->type == T_ILL_MO ? "T_ILL_MO" :
579f13ac639Smuffin mnp->type == T_SUN_MO ? "T_SUN_MO" :
580f13ac639Smuffin mnp->type == T_GNU_MO ? "T_GNU_MO" :
581f13ac639Smuffin "UNKNOWN TYPE");
5827c478bd9Sstevel@tonic-gate gprintf(level, " path: \"%s\"\n",
583f13ac639Smuffin mnp->path ? mnp->path : "(null)");
5847c478bd9Sstevel@tonic-gate gprintf(level, " msg_file_trusted: %d\n",
585f13ac639Smuffin mnp->trusted);
5867c478bd9Sstevel@tonic-gate if (mnp->type == T_SUN_MO)
5877c478bd9Sstevel@tonic-gate printsunmsg(mnp->msg.sunmsg, level+1);
5887c478bd9Sstevel@tonic-gate else if (mnp->type == T_GNU_MO)
5897c478bd9Sstevel@tonic-gate printgnumsg(mnp->msg.gnumsg, level+1);
5907c478bd9Sstevel@tonic-gate gprintf(level, " next: 0x%p\n", (void *)mnp->next);
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate void
printnls(Nls_node * n,int level)594f13ac639Smuffin printnls(Nls_node *n, int level)
5957c478bd9Sstevel@tonic-gate {
596f13ac639Smuffin gprintf(level, "=== nls ===\n");
597f13ac639Smuffin gprintf(level, " domain: \"%s\"\n", n->domain ? n->domain : "NULL");
598f13ac639Smuffin gprintf(level, " locale: \"%s\"\n", n->locale ? n->locale : "NULL");
599f13ac639Smuffin gprintf(level, " nlspath: \"%s\"\n", n->nlspath ? n->nlspath :
600f13ac639Smuffin "NULL");
601f13ac639Smuffin gprintf(level, " next: 0x%p\n", n->next);
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate void
printdbind(Dbinding * d,int level)605f13ac639Smuffin printdbind(Dbinding *d, int level)
6067c478bd9Sstevel@tonic-gate {
607f13ac639Smuffin gprintf(level, "=== dbind ===\n");
608f13ac639Smuffin gprintf(level, " domain: \"%s\"\n", d->domain ? d->domain : "NULL");
609f13ac639Smuffin gprintf(level, " binding: \"%s\"\n", d->binding ? d->binding :
610f13ac639Smuffin "NULL");
611f13ac639Smuffin gprintf(level, " codeset: \"%s\"\n", d->codeset ? d->codeset :
612f13ac639Smuffin "NULL");
613f13ac639Smuffin gprintf(level, " next: 0x%p\n", d->next);
6147c478bd9Sstevel@tonic-gate }
615f13ac639Smuffin
616f13ac639Smuffin void
printgt(Gettext_t * gt,int level)617f13ac639Smuffin printgt(Gettext_t *gt, int level)
618f13ac639Smuffin {
619f13ac639Smuffin gprintf(level, "=== gt ===\n");
620f13ac639Smuffin gprintf(level, " cur_domain: \"%s\"\n", gt->cur_domain);
621f13ac639Smuffin if (gt->dbind) {
622f13ac639Smuffin printdbind(gt->dbind, level+1);
623f13ac639Smuffin } else {
624f13ac639Smuffin gprintf(level, " dbind: NULL\n");
625f13ac639Smuffin }
626f13ac639Smuffin if (gt->m_node) {
627f13ac639Smuffin printmnp(gt->m_node, level + 1);
628f13ac639Smuffin } else {
629f13ac639Smuffin gprintf(level, " m_node: NULL\n");
630f13ac639Smuffin }
631f13ac639Smuffin if (gt->n_node) {
632f13ac639Smuffin printnls(gt->n_node, level + 1);
633f13ac639Smuffin } else {
634f13ac639Smuffin gprintf(level, " n_node: NULL\n");
635f13ac639Smuffin }
636f13ac639Smuffin if (gt->c_m_node) {
637f13ac639Smuffin printmnp(gt->c_m_node, level + 1);
638f13ac639Smuffin } else {
639f13ac639Smuffin gprintf(level, " c_m_node: NULL\n");
640f13ac639Smuffin }
641f13ac639Smuffin if (gt->c_n_node) {
642f13ac639Smuffin printnls(gt->c_n_node, level + 1);
643f13ac639Smuffin } else {
644f13ac639Smuffin gprintf(level, " c_n_node: NULL\n");
645f13ac639Smuffin }
646f13ac639Smuffin }
647f13ac639Smuffin
6487c478bd9Sstevel@tonic-gate #endif
649