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 5*f13ac639Smuffin * Common Development and Distribution License (the "License"). 6*f13ac639Smuffin * 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 */ 21*f13ac639Smuffin 227c478bd9Sstevel@tonic-gate /* 23*f13ac639Smuffin * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include "synonyms.h" 307c478bd9Sstevel@tonic-gate #include "mtlib.h" 317c478bd9Sstevel@tonic-gate #include <ctype.h> 327c478bd9Sstevel@tonic-gate #include <stdio.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <sys/types.h> 367c478bd9Sstevel@tonic-gate #include <unistd.h> 377c478bd9Sstevel@tonic-gate #include <sys/mman.h> 387c478bd9Sstevel@tonic-gate #include <langinfo.h> 397c478bd9Sstevel@tonic-gate #include "libc.h" 407c478bd9Sstevel@tonic-gate #include "_loc_path.h" 417c478bd9Sstevel@tonic-gate #include "msgfmt.h" 427c478bd9Sstevel@tonic-gate #include "gettext.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 457c478bd9Sstevel@tonic-gate #include "plural_parser.h" 467c478bd9Sstevel@tonic-gate #include <stdarg.h> 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate static const char *category_name[] = { 507c478bd9Sstevel@tonic-gate "LC_CTYPE", 517c478bd9Sstevel@tonic-gate "LC_NUMERIC", 527c478bd9Sstevel@tonic-gate "LC_TIME", 537c478bd9Sstevel@tonic-gate "LC_COLLATE", 547c478bd9Sstevel@tonic-gate "LC_MONETARY", 557c478bd9Sstevel@tonic-gate "LC_MESSAGES" 567c478bd9Sstevel@tonic-gate }; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate static const int category_name_len[] = { 597c478bd9Sstevel@tonic-gate 8, 607c478bd9Sstevel@tonic-gate 10, 617c478bd9Sstevel@tonic-gate 7, 627c478bd9Sstevel@tonic-gate 10, 637c478bd9Sstevel@tonic-gate 11, 647c478bd9Sstevel@tonic-gate 11 657c478bd9Sstevel@tonic-gate }; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* 687c478bd9Sstevel@tonic-gate * mk_msgfile 697c478bd9Sstevel@tonic-gate * 707c478bd9Sstevel@tonic-gate * INPUT 717c478bd9Sstevel@tonic-gate * mp - uses the following members: 727c478bd9Sstevel@tonic-gate * msgfile - buffer to store the pathname to the message file 737c478bd9Sstevel@tonic-gate * binding - directory pathname bound to specified domain 747c478bd9Sstevel@tonic-gate * cblen - length of binding 757c478bd9Sstevel@tonic-gate * locale - locale name 767c478bd9Sstevel@tonic-gate * domain - domain name 777c478bd9Sstevel@tonic-gate * category - category 787c478bd9Sstevel@tonic-gate * domain_len - length of domain name 797c478bd9Sstevel@tonic-gate * 807c478bd9Sstevel@tonic-gate * OUTPUT 817c478bd9Sstevel@tonic-gate * mp->msgfile - pathname to the message file is stored 827c478bd9Sstevel@tonic-gate * 837c478bd9Sstevel@tonic-gate * RETURN 847c478bd9Sstevel@tonic-gate * mp->msgfile is returned 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate char * 877c478bd9Sstevel@tonic-gate mk_msgfile(struct msg_pack *mp) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate char *p, *q; 907c478bd9Sstevel@tonic-gate const char *catstr; 91*f13ac639Smuffin uint32_t cblen, loclen, catlen, totallen; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 94*f13ac639Smuffin gprintf(0, "*************** mk_msgfile(0x%p)\n", (void *)mp); 95*f13ac639Smuffin printmp(mp, 1); 967c478bd9Sstevel@tonic-gate #endif 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate p = mp->msgfile; 997c478bd9Sstevel@tonic-gate q = mp->binding; 1007c478bd9Sstevel@tonic-gate while (*p = *q++) 1017c478bd9Sstevel@tonic-gate p++; 102*f13ac639Smuffin cblen = (uint32_t)(p - mp->msgfile); 1037c478bd9Sstevel@tonic-gate if (*(p - 1) != '/') { 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * if the last character of binding 1067c478bd9Sstevel@tonic-gate * isn't a '/', adding '/'. 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate if (cblen + 1 >= MAXPATHLEN) { 1097c478bd9Sstevel@tonic-gate /* MAXPATHLEN includes a null termination */ 1107c478bd9Sstevel@tonic-gate return (NULL); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate *p++ = '/'; 1137c478bd9Sstevel@tonic-gate cblen++; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 116*f13ac639Smuffin loclen = strlen(mp->locale); 1177c478bd9Sstevel@tonic-gate catstr = category_name[mp->category]; 118*f13ac639Smuffin catlen = (uint32_t)category_name_len[mp->category]; 1197c478bd9Sstevel@tonic-gate /* 1207c478bd9Sstevel@tonic-gate * totallen is the length of the msgfile 1217c478bd9Sstevel@tonic-gate * pathname excluding a null termination. 1227c478bd9Sstevel@tonic-gate */ 1237c478bd9Sstevel@tonic-gate 124*f13ac639Smuffin totallen = cblen + loclen + 1 + catlen + 1 + 1257c478bd9Sstevel@tonic-gate mp->domain_len + MSGFILESUFFIXLEN; 1267c478bd9Sstevel@tonic-gate if (totallen >= MAXPATHLEN) 1277c478bd9Sstevel@tonic-gate return (NULL); 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate q = mp->locale; 1307c478bd9Sstevel@tonic-gate while (*p++ = *q++) 1317c478bd9Sstevel@tonic-gate ; 1327c478bd9Sstevel@tonic-gate *(p - 1) = '/'; 1337c478bd9Sstevel@tonic-gate while (*p++ = *catstr++) 1347c478bd9Sstevel@tonic-gate ; 1357c478bd9Sstevel@tonic-gate *(p - 1) = '/'; 1367c478bd9Sstevel@tonic-gate q = mp->domain; 137*f13ac639Smuffin while (*p = *q++) 138*f13ac639Smuffin p++; 139*f13ac639Smuffin q = MSGFILESUFFIX; 1407c478bd9Sstevel@tonic-gate while (*p++ = *q++) 1417c478bd9Sstevel@tonic-gate ; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 144*f13ac639Smuffin gprintf(0, "*************** Exiting mk_msgfile\n"); 145*f13ac639Smuffin gprintf(0, "mp->msgfile: \"%s\"\n", mp->msgfile); 1467c478bd9Sstevel@tonic-gate #endif 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate return (mp->msgfile); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * check_cache 1537c478bd9Sstevel@tonic-gate * 1547c478bd9Sstevel@tonic-gate * INPUT 1557c478bd9Sstevel@tonic-gate * mp - may use the following members: 1567c478bd9Sstevel@tonic-gate * msgfile - pathname to the message catalog file 157*f13ac639Smuffin * hash_domain - hash id of this domain 1587c478bd9Sstevel@tonic-gate * 1597c478bd9Sstevel@tonic-gate * RETURN 160*f13ac639Smuffin * non-NULL 161*f13ac639Smuffin * pointer to the Msg_node object of the current message catalog 162*f13ac639Smuffin * found in the cache 163*f13ac639Smuffin * 164*f13ac639Smuffin * NULL 165*f13ac639Smuffin * this message catalog does not exist in the cache 1667c478bd9Sstevel@tonic-gate */ 167*f13ac639Smuffin Msg_node * 168*f13ac639Smuffin check_cache(struct msg_pack *mp) 1697c478bd9Sstevel@tonic-gate { 170*f13ac639Smuffin Msg_node *cur_msg, *mnp; 1717c478bd9Sstevel@tonic-gate Gettext_t *gt = global_gt; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 174*f13ac639Smuffin gprintf(0, "*************** check_cache(0x%p)\n", mp); 175*f13ac639Smuffin printmp(mp, 1); 1767c478bd9Sstevel@tonic-gate #endif 1777c478bd9Sstevel@tonic-gate 178*f13ac639Smuffin cur_msg = gt->c_m_node; /* current Msg_node */ 1797c478bd9Sstevel@tonic-gate if (cur_msg && 180*f13ac639Smuffin cur_msg->hashid == mp->hash_domain && 181*f13ac639Smuffin strcmp(cur_msg->path, mp->msgfile) == 0) { 1827c478bd9Sstevel@tonic-gate /* 1837c478bd9Sstevel@tonic-gate * msgfile is the same as the previous message file 1847c478bd9Sstevel@tonic-gate */ 1857c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 186*f13ac639Smuffin gprintf(0, "*** cache found\n"); 187*f13ac639Smuffin gprintf(0, "************* exiting check_cache\n"); 188*f13ac639Smuffin printmnp(cur_msg, 1); 1897c478bd9Sstevel@tonic-gate #endif 190*f13ac639Smuffin return (cur_msg); 1917c478bd9Sstevel@tonic-gate } 192*f13ac639Smuffin mnp = gt->m_node; 193*f13ac639Smuffin while (mnp) { 1947c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 195*f13ac639Smuffin gprintf(0, "========== descending the list\n"); 196*f13ac639Smuffin gprintf(0, " hashid: %d, hash_domain: %d\n", 197*f13ac639Smuffin mnp->hashid, mp->hash_domain); 198*f13ac639Smuffin printmnp(mnp, 1); 1997c478bd9Sstevel@tonic-gate #endif 200*f13ac639Smuffin if (mnp->hashid == mp->hash_domain && 201*f13ac639Smuffin strcmp(mnp->path, mp->msgfile) == 0) { 2027c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 203*f13ac639Smuffin gprintf(0, "*** cache found\n"); 204*f13ac639Smuffin gprintf(0, "******* exiting check_cache\n"); 205*f13ac639Smuffin printmnp(mnp, 1); 2067c478bd9Sstevel@tonic-gate #endif 207*f13ac639Smuffin gt->c_m_node = mnp; 208*f13ac639Smuffin return (mnp); 2097c478bd9Sstevel@tonic-gate } 210*f13ac639Smuffin mnp = mnp->next; 211*f13ac639Smuffin } 212*f13ac639Smuffin 2137c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 214*f13ac639Smuffin gprintf(0, "*** cache not found\n"); 215*f13ac639Smuffin gprintf(0, "******* exiting check_cache\n"); 2167c478bd9Sstevel@tonic-gate #endif 217*f13ac639Smuffin return (NULL); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate char * 2217c478bd9Sstevel@tonic-gate get_codeset(const char *domain) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate char *codeset; 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 226*f13ac639Smuffin gprintf(0, "*************** get_codeset(\"%s\")\n", 2277c478bd9Sstevel@tonic-gate domain ? domain : "(null)"); 2287c478bd9Sstevel@tonic-gate #endif 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate codeset = _real_bindtextdomain_u(domain, NULL, TP_CODESET); 231*f13ac639Smuffin if (codeset == NULL) { 2327c478bd9Sstevel@tonic-gate /* no codeset is bound to this domain */ 2337c478bd9Sstevel@tonic-gate codeset = nl_langinfo(CODESET); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 236*f13ac639Smuffin gprintf(0, "*************** existing get_codeset(\"%s\")\n", 2377c478bd9Sstevel@tonic-gate domain ? domain : "(null)"); 238*f13ac639Smuffin gprintf(0, " = \"%s\"\n", codeset); 2397c478bd9Sstevel@tonic-gate #endif 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate return (codeset); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 245*f13ac639Smuffin * get_hashid (hashpjw) 2467c478bd9Sstevel@tonic-gate * 2477c478bd9Sstevel@tonic-gate * Calculates the hash value from the specified string. 2487c478bd9Sstevel@tonic-gate * Actual hashid will be mod(hash value, PRIME_NUMBER). 2497c478bd9Sstevel@tonic-gate * 2507c478bd9Sstevel@tonic-gate * Ref: Compilers - Principles, Techniques, and Tools 2517c478bd9Sstevel@tonic-gate * Aho, Sethi, and Ullman 2527c478bd9Sstevel@tonic-gate */ 253*f13ac639Smuffin uint32_t 254*f13ac639Smuffin get_hashid(const char *str, uint32_t *len) 2557c478bd9Sstevel@tonic-gate { 256*f13ac639Smuffin const unsigned char *p = (unsigned char *)str; 257*f13ac639Smuffin uint32_t h = 0; 258*f13ac639Smuffin uint32_t g; 2597c478bd9Sstevel@tonic-gate 260*f13ac639Smuffin for (; *p; p++) { 2617c478bd9Sstevel@tonic-gate h = (h << 4) + *p; 2627c478bd9Sstevel@tonic-gate g = h & 0xf0000000; 2637c478bd9Sstevel@tonic-gate if (g) { 2647c478bd9Sstevel@tonic-gate h = h ^ (g >> 24); 2657c478bd9Sstevel@tonic-gate h = h ^ g; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate } 268*f13ac639Smuffin 2697c478bd9Sstevel@tonic-gate if (len) 270*f13ac639Smuffin *len = (uint32_t)(p - (unsigned char *)str); 2717c478bd9Sstevel@tonic-gate return (h); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 274*f13ac639Smuffin uint32_t 275*f13ac639Smuffin doswap32(uint32_t n) 2767c478bd9Sstevel@tonic-gate { 277*f13ac639Smuffin uint32_t r; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate r = (n << 24) | ((n & 0xff00) << 8) | 2807c478bd9Sstevel@tonic-gate ((n >> 8) & 0xff00) | (n >> 24); 2817c478bd9Sstevel@tonic-gate return (r); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate #ifdef GETTEXT_DEBUG 285*f13ac639Smuffin static uint32_t 286*f13ac639Smuffin search_msg(Msg_g_node *p, const char *id, uint32_t hash_val, 287*f13ac639Smuffin struct gnu_msg_ent *m) 288*f13ac639Smuffin { 289*f13ac639Smuffin char *base = (char *)p->msg_file_info; 290*f13ac639Smuffin uint32_t hash_size, num_of_str, i, idx, inc; 291*f13ac639Smuffin char *ms; 292*f13ac639Smuffin 293*f13ac639Smuffin num_of_str = p->num_of_str; 294*f13ac639Smuffin hash_size = p->hash_size; 295*f13ac639Smuffin idx = hash_val % hash_size; 296*f13ac639Smuffin inc = 1 + (hash_val % (hash_size - 2)); 297*f13ac639Smuffin 298*f13ac639Smuffin while ((i = p->hash_table[idx]) != 0) { 299*f13ac639Smuffin ms = (i <= num_of_str) ? 300*f13ac639Smuffin base + SWAP(p, m[i-1].offset) : 301*f13ac639Smuffin p->mchunk + p->d_msg[MSGID][i-num_of_str-1].offset; 302*f13ac639Smuffin if (strcmp(id, ms) == 0) { 303*f13ac639Smuffin /* found */ 304*f13ac639Smuffin return (i); 305*f13ac639Smuffin } 306*f13ac639Smuffin idx = (idx + inc) % hash_size; 307*f13ac639Smuffin } 308*f13ac639Smuffin /* not found */ 309*f13ac639Smuffin return (0); 310*f13ac639Smuffin } 311*f13ac639Smuffin 312*f13ac639Smuffin void 313*f13ac639Smuffin print_rev1_info(Msg_g_node *p) 314*f13ac639Smuffin { 315*f13ac639Smuffin char *base = (char *)p->msg_file_info; 316*f13ac639Smuffin struct gnu_msg_info *header = p->msg_file_info; 317*f13ac639Smuffin struct gnu_msg_ent *m; 318*f13ac639Smuffin uint32_t hv, hidx; 319*f13ac639Smuffin char *ms; 320*f13ac639Smuffin enum gnu_msgidstr v; 321*f13ac639Smuffin int x; 322*f13ac639Smuffin 323*f13ac639Smuffin #ifdef GETTEXT_DEBUG_DYMMSG 324*f13ac639Smuffin gprintf(0, "******** dynamic msgid/msgstr\n"); 325*f13ac639Smuffin for (v = MSGID; v <= MSGSTR; v++) { 326*f13ac639Smuffin for (x = 0; x < p->num_of_d_str; x++) { 327*f13ac639Smuffin gprintf(0, "len: %u\n", p->d_msg[v][x].len); 328*f13ac639Smuffin gprintf(0, "str: \"%s\"\n", 329*f13ac639Smuffin p->mchunk + p->d_msg[v][x].offset); 330*f13ac639Smuffin } 331*f13ac639Smuffin } 332*f13ac639Smuffin #endif 333*f13ac639Smuffin #ifdef GETTEXT_DEBUG_HASHTBL 334*f13ac639Smuffin gprintf(0, "******** dynamic hash table\n"); 335*f13ac639Smuffin for (x = 0; x < p->hash_size; x++) { 336*f13ac639Smuffin gprintf(0, "%d: %u\n", x, p->hash_table[x]); 337*f13ac639Smuffin } 338*f13ac639Smuffin #endif 339*f13ac639Smuffin #ifdef GETTEXT_DEBUG_CHECK_STMSGID 340*f13ac639Smuffin gprintf(0, "******** sanity check of static msgid\n"); 341*f13ac639Smuffin m = (struct gnu_msg_ent *)(uintptr_t) 342*f13ac639Smuffin (base + SWAP(p, header->off_msgid_tbl)); 343*f13ac639Smuffin for (x = 0; x < p->num_of_str; x++) { 344*f13ac639Smuffin ms = base + SWAP(p, m[x].offset); 345*f13ac639Smuffin gprintf(0, "\"%s\"\n", ms); 346*f13ac639Smuffin hv = get_hashid(ms, NULL); 347*f13ac639Smuffin hidx = search_msg(p, ms, hv, m); 348*f13ac639Smuffin if (hidx == 0) { 349*f13ac639Smuffin gprintf(0, 350*f13ac639Smuffin "failed to find this msg in the hash table\n"); 351*f13ac639Smuffin } else { 352*f13ac639Smuffin if (hidx != x + 1) { 353*f13ac639Smuffin gprintf(0, "hash table mismatch\n"); 354*f13ac639Smuffin } 355*f13ac639Smuffin } 356*f13ac639Smuffin } 357*f13ac639Smuffin #endif 358*f13ac639Smuffin #ifdef GETTEXT_DEBUG_CHECK_DYMMSGID 359*f13ac639Smuffin gprintf(0, "******* sanity check of dynamic msgid\n"); 360*f13ac639Smuffin m = (struct gnu_msg_ent *)(uintptr_t) 361*f13ac639Smuffin (base + SWAP(p, header->off_msgid_tbl)); 362*f13ac639Smuffin for (x = 0; x < p->num_of_d_str; x++) { 363*f13ac639Smuffin ms = p->mchunk + p->d_msg[MSGID][x].offset; 364*f13ac639Smuffin gprintf(0, "\"%s\"\n", ms); 365*f13ac639Smuffin hv = get_hashid(ms, NULL); 366*f13ac639Smuffin hidx = search_msg(p, ms, hv, m); 367*f13ac639Smuffin if (hidx == 0) { 368*f13ac639Smuffin gprintf(0, 369*f13ac639Smuffin "failed to find this msg in the hash table\n"); 370*f13ac639Smuffin } else { 371*f13ac639Smuffin if (hidx != x + p->num_of_str + 1) { 372*f13ac639Smuffin gprintf(0, "hash table mismatch\n"); 373*f13ac639Smuffin } 374*f13ac639Smuffin } 375*f13ac639Smuffin } 376*f13ac639Smuffin #endif 377*f13ac639Smuffin } 378*f13ac639Smuffin 3797c478bd9Sstevel@tonic-gate void 3807c478bd9Sstevel@tonic-gate gprintf(int level, const char *format, ...) 3817c478bd9Sstevel@tonic-gate { 3827c478bd9Sstevel@tonic-gate va_list ap; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate va_start(ap, format); 3857c478bd9Sstevel@tonic-gate 386*f13ac639Smuffin while (level-- > 0) { 3877c478bd9Sstevel@tonic-gate (void) fputs(" ", stdout); 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate (void) vprintf(format, ap); 3907c478bd9Sstevel@tonic-gate va_end(ap); 391*f13ac639Smuffin 392*f13ac639Smuffin (void) fflush(stdout); 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate void 3967c478bd9Sstevel@tonic-gate printlist(void) 3977c478bd9Sstevel@tonic-gate { 3987c478bd9Sstevel@tonic-gate struct domain_binding *ppp; 3997c478bd9Sstevel@tonic-gate Gettext_t *gt = global_gt; 4007c478bd9Sstevel@tonic-gate 401*f13ac639Smuffin gprintf(0, "=== Printing default list and regural list\n"); 402*f13ac639Smuffin gprintf(0, " Default domain=<%s>, binding=<%s>\n", 4037c478bd9Sstevel@tonic-gate DEFAULT_DOMAIN, defaultbind); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate ppp = FIRSTBIND(gt); 4067c478bd9Sstevel@tonic-gate while (ppp) { 407*f13ac639Smuffin gprintf(0, " domain=<%s>, binding=<%s>, codeset=<%s>\n", 4087c478bd9Sstevel@tonic-gate ppp->domain ? ppp->domain : "(null)", 4097c478bd9Sstevel@tonic-gate ppp->binding ? ppp->binding : "(null)", 4107c478bd9Sstevel@tonic-gate ppp->codeset ? ppp->codeset : "(null)"); 4117c478bd9Sstevel@tonic-gate ppp = ppp->next; 4127c478bd9Sstevel@tonic-gate } 413*f13ac639Smuffin (void) fflush(stdout); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate void 4177c478bd9Sstevel@tonic-gate printmp(struct msg_pack *mp, int level) 4187c478bd9Sstevel@tonic-gate { 4197c478bd9Sstevel@tonic-gate gprintf(level, "=== mp ===\n"); 4207c478bd9Sstevel@tonic-gate gprintf(level, " msgid1: \"%s\"\n", 4217c478bd9Sstevel@tonic-gate mp->msgid1 ? mp->msgid1 : "(null)"); 4227c478bd9Sstevel@tonic-gate gprintf(level, " msgid2: \"%s\"\n", 4237c478bd9Sstevel@tonic-gate mp->msgid2 ? mp->msgid2 : "(null)"); 424*f13ac639Smuffin gprintf(level, " msgfile: \"%s\"\n", 425*f13ac639Smuffin mp->msgfile ? mp->msgfile : "(null)"); 4267c478bd9Sstevel@tonic-gate gprintf(level, " domain: \"%s\"\n", 4277c478bd9Sstevel@tonic-gate mp->domain ? mp->domain : "(null)"); 4287c478bd9Sstevel@tonic-gate gprintf(level, " binding: \"%s\"\n", 4297c478bd9Sstevel@tonic-gate mp->binding ? mp->binding : "(null)"); 4307c478bd9Sstevel@tonic-gate gprintf(level, " locale: \"%s\"\n", 4317c478bd9Sstevel@tonic-gate mp->locale ? mp->locale : "(null)"); 4327c478bd9Sstevel@tonic-gate gprintf(level, " language: \"%s\"\n", 4337c478bd9Sstevel@tonic-gate mp->language ? mp->language : "(null)"); 4347c478bd9Sstevel@tonic-gate gprintf(level, " addr: 0x%p\n", mp->addr); 4357c478bd9Sstevel@tonic-gate gprintf(level, " fsz: %d\n", mp->fsz); 436*f13ac639Smuffin gprintf(level, " hash_domain: %d\n", mp->hash_domain); 437*f13ac639Smuffin gprintf(level, " domain_len: %d\n", mp->domain_len); 438*f13ac639Smuffin gprintf(level, " n: %d\n", mp->n); 439*f13ac639Smuffin gprintf(level, " category: \"%s\"\n", 440*f13ac639Smuffin category_name[mp->category]); 441*f13ac639Smuffin gprintf(level, " plural: %d\n", mp->plural); 442*f13ac639Smuffin gprintf(level, " nlsp: %d\n", mp->nlsp); 4437c478bd9Sstevel@tonic-gate gprintf(level, " trusted: %d\n", mp->trusted); 444*f13ac639Smuffin gprintf(level, " status: %d\n", mp->status); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate void 4487c478bd9Sstevel@tonic-gate printsunmsg(Msg_s_node *smnp, int level) 4497c478bd9Sstevel@tonic-gate { 4507c478bd9Sstevel@tonic-gate gprintf(level, "=== sunmsg ===\n"); 4517c478bd9Sstevel@tonic-gate gprintf(level, " msg_file_info: 0x%p\n", 4527c478bd9Sstevel@tonic-gate (void *)smnp->msg_file_info); 4537c478bd9Sstevel@tonic-gate gprintf(level, " msg_mid: %d\n", 4547c478bd9Sstevel@tonic-gate smnp->msg_file_info->msg_mid); 4557c478bd9Sstevel@tonic-gate gprintf(level, " msg_count: %d\n", 4567c478bd9Sstevel@tonic-gate smnp->msg_file_info->msg_count); 4577c478bd9Sstevel@tonic-gate gprintf(level, " str_count_msgid: %d\n", 4587c478bd9Sstevel@tonic-gate smnp->msg_file_info->str_count_msgid); 4597c478bd9Sstevel@tonic-gate gprintf(level, " str_count_msgstr: %d\n", 4607c478bd9Sstevel@tonic-gate smnp->msg_file_info->str_count_msgstr); 4617c478bd9Sstevel@tonic-gate gprintf(level, " msg_struct_size: %d\n", 4627c478bd9Sstevel@tonic-gate smnp->msg_file_info->msg_struct_size); 4637c478bd9Sstevel@tonic-gate gprintf(level, " msg_list: 0x%p\n", 4647c478bd9Sstevel@tonic-gate (void *)smnp->msg_list); 4657c478bd9Sstevel@tonic-gate gprintf(level, " msg_ids: 0x%p\n", 4667c478bd9Sstevel@tonic-gate (void *)smnp->msg_ids); 4677c478bd9Sstevel@tonic-gate gprintf(level, " msg_strs: 0x%p\n", 4687c478bd9Sstevel@tonic-gate (void *)smnp->msg_strs); 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate void 4727c478bd9Sstevel@tonic-gate printgnumsg(Msg_g_node *gmnp, int level) 4737c478bd9Sstevel@tonic-gate { 4747c478bd9Sstevel@tonic-gate gprintf(level, "=== gnumsg ===\n"); 475*f13ac639Smuffin gprintf(level, " msg_file_info: 0x%p\n", gmnp->msg_file_info); 4767c478bd9Sstevel@tonic-gate gprintf(level, " magic: 0x%x\n", 4777c478bd9Sstevel@tonic-gate gmnp->msg_file_info->magic); 4787c478bd9Sstevel@tonic-gate gprintf(level, " revision: %d\n", 4797c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->revision)); 4807c478bd9Sstevel@tonic-gate gprintf(level, " num_of_str: %d\n", 4817c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->num_of_str)); 4827c478bd9Sstevel@tonic-gate gprintf(level, " off_msgid_tbl: %d\n", 4837c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->off_msgid_tbl)); 4847c478bd9Sstevel@tonic-gate gprintf(level, " off_msgstr_tbl: %d\n", 4857c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->off_msgstr_tbl)); 4867c478bd9Sstevel@tonic-gate gprintf(level, " sz_hashtbl: %d\n", 4877c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->sz_hashtbl)); 4887c478bd9Sstevel@tonic-gate gprintf(level, " off_hashtbl: %d\n", 4897c478bd9Sstevel@tonic-gate SWAP(gmnp, gmnp->msg_file_info->off_hashtbl)); 490*f13ac639Smuffin if (gmnp->flag & ST_REV1) { 491*f13ac639Smuffin struct gnu_msg_rev1_info *a = 492*f13ac639Smuffin (struct gnu_msg_rev1_info *)(uintptr_t) 493*f13ac639Smuffin ((char *)gmnp->msg_file_info + 494*f13ac639Smuffin sizeof (struct gnu_msg_info)); 495*f13ac639Smuffin gprintf(level, " num_of_dynamic_macro: %d\n", 496*f13ac639Smuffin SWAP(gmnp, a->num_of_dynamic_macro)); 497*f13ac639Smuffin gprintf(level, " off_dynamic_macro: %d\n", 498*f13ac639Smuffin SWAP(gmnp, a->off_dynamic_macro)); 499*f13ac639Smuffin gprintf(level, " num_of_dynamic_str: %d\n", 500*f13ac639Smuffin SWAP(gmnp, a->num_of_dynamic_str)); 501*f13ac639Smuffin gprintf(level, " off_dynamic_msgid_tbl: %d\n", 502*f13ac639Smuffin SWAP(gmnp, a->off_dynamic_msgid_tbl)); 503*f13ac639Smuffin gprintf(level, " off_dynamic_msgstr_tbl: %d\n", 504*f13ac639Smuffin SWAP(gmnp, a->off_dynamic_msgstr_tbl)); 505*f13ac639Smuffin } 506*f13ac639Smuffin gprintf(level, " fsize: %lu\n", gmnp->fsize); 507*f13ac639Smuffin gprintf(level, " flag: %08x\n", gmnp->flag); 508*f13ac639Smuffin gprintf(level, " num_of_str: %u\n", gmnp->num_of_str); 509*f13ac639Smuffin gprintf(level, " num_of_d_str: %u\n", gmnp->num_of_d_str); 510*f13ac639Smuffin gprintf(level, " hash_size: %u\n", gmnp->hash_size); 511*f13ac639Smuffin gprintf(level, " hash_table: 0x%p\n", (void *)gmnp->hash_table); 512*f13ac639Smuffin gprintf(level, " d_msgid: 0x%p\n", (void *)gmnp->d_msg[MSGID]); 513*f13ac639Smuffin gprintf(level, " d_msgstr: 0x%p\n", (void *)gmnp->d_msg[MSGSTR]); 514*f13ac639Smuffin gprintf(level, " mchunk: 0x%p\n", (void *)gmnp->mchunk); 515*f13ac639Smuffin 5167c478bd9Sstevel@tonic-gate gprintf(level, " src_encoding: \"%s\"\n", 5177c478bd9Sstevel@tonic-gate gmnp->src_encoding ? gmnp->src_encoding : "(null)"); 5187c478bd9Sstevel@tonic-gate gprintf(level, " dst_encoding: \"%s\"\n", 5197c478bd9Sstevel@tonic-gate gmnp->dst_encoding ? gmnp->dst_encoding : "(null)"); 5207c478bd9Sstevel@tonic-gate gprintf(level, " nplurals: %d\n", 5217c478bd9Sstevel@tonic-gate gmnp->nplurals); 5227c478bd9Sstevel@tonic-gate gprintf(level, " plural: 0x%p\n", 5237c478bd9Sstevel@tonic-gate (void *)gmnp->plural); 5247c478bd9Sstevel@tonic-gate if (gmnp->plural) 5257c478bd9Sstevel@tonic-gate printexpr(gmnp->plural, level+1); 5267c478bd9Sstevel@tonic-gate gprintf(level, " fd: 0x%p\n", (void *)gmnp->fd); 5277c478bd9Sstevel@tonic-gate gprintf(level, " conv_msgstr: 0x%p\n", 5287c478bd9Sstevel@tonic-gate (void *)gmnp->conv_msgstr); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate void 5327c478bd9Sstevel@tonic-gate printexpr(struct expr *e, int level) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate static const char *op_name[] = { 5357c478bd9Sstevel@tonic-gate "NULL", "INIT", "EXP", 5367c478bd9Sstevel@tonic-gate "NUM", "VAR", "?", ":", "||", 5377c478bd9Sstevel@tonic-gate "&&", "==", "!=", ">", "<", 5387c478bd9Sstevel@tonic-gate ">=", "<=", "+", "-", "*", "/", 5397c478bd9Sstevel@tonic-gate "%", "!", "(", ")", "ERR" 5407c478bd9Sstevel@tonic-gate }; 5417c478bd9Sstevel@tonic-gate switch (GETOPNUM(e->op)) { 5427c478bd9Sstevel@tonic-gate case 0: 5437c478bd9Sstevel@tonic-gate switch (GETTYPE(e->op)) { 5447c478bd9Sstevel@tonic-gate case T_NUM: 5457c478bd9Sstevel@tonic-gate gprintf(level, "NUM(%d)\n", e->num); 5467c478bd9Sstevel@tonic-gate break; 5477c478bd9Sstevel@tonic-gate case T_VAR: 5487c478bd9Sstevel@tonic-gate gprintf(level, "VAR(n)\n"); 5497c478bd9Sstevel@tonic-gate break; 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate break; 5527c478bd9Sstevel@tonic-gate case 1: 5537c478bd9Sstevel@tonic-gate gprintf(level, "OP: !\n"); 5547c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1); 5557c478bd9Sstevel@tonic-gate break; 5567c478bd9Sstevel@tonic-gate case 2: 5577c478bd9Sstevel@tonic-gate gprintf(level, "OP: %s\n", op_name[GETTYPE(e->op)]); 5587c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1); 5597c478bd9Sstevel@tonic-gate printexpr(e->nodes[1], level+1); 5607c478bd9Sstevel@tonic-gate break; 5617c478bd9Sstevel@tonic-gate case 3: 5627c478bd9Sstevel@tonic-gate gprintf(level, "OP: ?\n"); 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate printexpr(e->nodes[0], level+1); 5657c478bd9Sstevel@tonic-gate printexpr(e->nodes[1], level+1); 5667c478bd9Sstevel@tonic-gate printexpr(e->nodes[2], level+1); 5677c478bd9Sstevel@tonic-gate break; 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate void 5737c478bd9Sstevel@tonic-gate printmnp(Msg_node *mnp, int level) 5747c478bd9Sstevel@tonic-gate { 5757c478bd9Sstevel@tonic-gate gprintf(level, "=== mnp ===\n"); 5767c478bd9Sstevel@tonic-gate 577*f13ac639Smuffin gprintf(level, " hashid: %d\n", mnp->hashid); 5787c478bd9Sstevel@tonic-gate gprintf(level, " type: \"%s\"\n", 5797c478bd9Sstevel@tonic-gate mnp->type == T_ILL_MO ? "T_ILL_MO" : 5807c478bd9Sstevel@tonic-gate mnp->type == T_SUN_MO ? "T_SUN_MO" : 5817c478bd9Sstevel@tonic-gate mnp->type == T_GNU_MO ? "T_GNU_MO" : 5827c478bd9Sstevel@tonic-gate "UNKNOWN TYPE"); 5837c478bd9Sstevel@tonic-gate gprintf(level, " path: \"%s\"\n", 5847c478bd9Sstevel@tonic-gate mnp->path ? mnp->path : "(null)"); 5857c478bd9Sstevel@tonic-gate gprintf(level, " msg_file_trusted: %d\n", 5867c478bd9Sstevel@tonic-gate mnp->trusted); 5877c478bd9Sstevel@tonic-gate if (mnp->type == T_SUN_MO) 5887c478bd9Sstevel@tonic-gate printsunmsg(mnp->msg.sunmsg, level+1); 5897c478bd9Sstevel@tonic-gate else if (mnp->type == T_GNU_MO) 5907c478bd9Sstevel@tonic-gate printgnumsg(mnp->msg.gnumsg, level+1); 5917c478bd9Sstevel@tonic-gate gprintf(level, " next: 0x%p\n", (void *)mnp->next); 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate void 595*f13ac639Smuffin printnls(Nls_node *n, int level) 5967c478bd9Sstevel@tonic-gate { 597*f13ac639Smuffin gprintf(level, "=== nls ===\n"); 598*f13ac639Smuffin gprintf(level, " domain: \"%s\"\n", n->domain ? n->domain : "NULL"); 599*f13ac639Smuffin gprintf(level, " locale: \"%s\"\n", n->locale ? n->locale : "NULL"); 600*f13ac639Smuffin gprintf(level, " nlspath: \"%s\"\n", n->nlspath ? n->nlspath : 601*f13ac639Smuffin "NULL"); 602*f13ac639Smuffin gprintf(level, " next: 0x%p\n", n->next); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate void 606*f13ac639Smuffin printdbind(Dbinding *d, int level) 6077c478bd9Sstevel@tonic-gate { 608*f13ac639Smuffin gprintf(level, "=== dbind ===\n"); 609*f13ac639Smuffin gprintf(level, " domain: \"%s\"\n", d->domain ? d->domain : "NULL"); 610*f13ac639Smuffin gprintf(level, " binding: \"%s\"\n", d->binding ? d->binding : 611*f13ac639Smuffin "NULL"); 612*f13ac639Smuffin gprintf(level, " codeset: \"%s\"\n", d->codeset ? d->codeset : 613*f13ac639Smuffin "NULL"); 614*f13ac639Smuffin gprintf(level, " next: 0x%p\n", d->next); 6157c478bd9Sstevel@tonic-gate } 616*f13ac639Smuffin 617*f13ac639Smuffin void 618*f13ac639Smuffin printgt(Gettext_t *gt, int level) 619*f13ac639Smuffin { 620*f13ac639Smuffin gprintf(level, "=== gt ===\n"); 621*f13ac639Smuffin gprintf(level, " cur_domain: \"%s\"\n", gt->cur_domain); 622*f13ac639Smuffin if (gt->dbind) { 623*f13ac639Smuffin printdbind(gt->dbind, level+1); 624*f13ac639Smuffin } else { 625*f13ac639Smuffin gprintf(level, " dbind: NULL\n"); 626*f13ac639Smuffin } 627*f13ac639Smuffin if (gt->m_node) { 628*f13ac639Smuffin printmnp(gt->m_node, level + 1); 629*f13ac639Smuffin } else { 630*f13ac639Smuffin gprintf(level, " m_node: NULL\n"); 631*f13ac639Smuffin } 632*f13ac639Smuffin if (gt->n_node) { 633*f13ac639Smuffin printnls(gt->n_node, level + 1); 634*f13ac639Smuffin } else { 635*f13ac639Smuffin gprintf(level, " n_node: NULL\n"); 636*f13ac639Smuffin } 637*f13ac639Smuffin if (gt->c_m_node) { 638*f13ac639Smuffin printmnp(gt->c_m_node, level + 1); 639*f13ac639Smuffin } else { 640*f13ac639Smuffin gprintf(level, " c_m_node: NULL\n"); 641*f13ac639Smuffin } 642*f13ac639Smuffin if (gt->c_n_node) { 643*f13ac639Smuffin printnls(gt->c_n_node, level + 1); 644*f13ac639Smuffin } else { 645*f13ac639Smuffin gprintf(level, " c_n_node: NULL\n"); 646*f13ac639Smuffin } 647*f13ac639Smuffin } 648*f13ac639Smuffin 6497c478bd9Sstevel@tonic-gate #endif 650