xref: /illumos-gate/usr/src/lib/libc/port/i18n/gettext.h (revision e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_LIBC_PORT_I18N_GETTEXT_H
28 #define	_LIBC_PORT_I18N_GETTEXT_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/param.h>
33 #include <iconv.h>
34 #include <synch.h>
35 
36 #ifdef	__cplusplus
37 extern "C" {
38 #endif
39 
40 /* Type of MO file */
41 #define	T_MO_MASK		0x07
42 #define	T_SUN_MO		0x01
43 #define	T_GNU_MO		0x02
44 #define	T_ILL_MO		0x04
45 
46 #define	T_GNU_MASK		0x300
47 #define	T_GNU_SWAPPED		0x100
48 #define	T_GNU_REV1		0x200
49 
50 #define	TP_BINDING	0
51 #define	TP_CODESET	1
52 
53 /* Msg_g_node->flag */
54 #define	ST_CHK	0x1			/* header has been checked? */
55 #define	ST_SWP	0x2			/* reversed endian? */
56 #define	ST_REV1	0x4			/* Revision 1 */
57 
58 /*
59  * msg_pack->status:
60  * interaction between handle_lang() and handle_mo()
61  */
62 #define	ST_GNU_MSG_FOUND	0x1	/* valid msg found in GNU MO */
63 #define	ST_GNU_MO_FOUND		0x2	/* GNU MO found */
64 #define	ST_SUN_MO_FOUND		0x4	/* Sun MO found */
65 
66 typedef struct domain_binding {
67 	char	*domain;	/* domain name */
68 	char	*binding;	/* binding directory */
69 	char	*codeset;	/* codeset */
70 	struct domain_binding	*next;
71 } Dbinding;
72 
73 /*
74  * this structure is used for preserving nlspath templates before
75  * passing them to bindtextdomain():
76  */
77 typedef struct nlstmp {
78 	char	pathname[MAXPATHLEN];	/* the full pathname to file */
79 	size_t	len;			/* length of pathname */
80 	struct nlstmp	*next;		/* link to the next entry */
81 } Nlstmp;
82 
83 typedef struct {
84 	struct msg_info	*msg_file_info;	/* information of msg file */
85 	struct msg_struct	*msg_list;	/* message list */
86 	char	*msg_ids;		/* actual message ids */
87 	char	*msg_strs;		/* actual message strs */
88 } Msg_s_node;
89 
90 typedef struct expr	*plural_expr_t;
91 
92 typedef struct {
93 	unsigned int	len;	/* length of the expanded str of macro */
94 	const char	*ptr;	/* pointer to the expanded str of macro */
95 } gnu_d_macro_t;
96 
97 typedef struct {
98 	struct gnu_msg_info	*msg_file_info;
99 	struct gnu_msg_rev1_info	*rev1_header;
100 	size_t	fsize;			/* size of the GNU mo file */
101 	uint32_t	flag;		/* status */
102 	uint32_t	num_of_str;	/* number of static msgs */
103 	uint32_t	num_of_d_str;	/* number of dynamic msgs */
104 	uint32_t	hash_size;	/* hash table size  */
105 	uint32_t	*hash_table;	/* hash table */
106 	struct gnu_msg_ent	*msg_tbl[2]; 	/* msgid/str entries */
107 	struct gnu_msg_ent	*d_msg[2];	/* dynamic msgid/str entries */
108 	char	*mchunk;	/* pointer to memory chunk of dynamic strs */
109 	char	*src_encoding;	/* src encoding */
110 	char	*dst_encoding;	/* dst encoding */
111 	unsigned int	nplurals;	/* number of plural forms */
112 	plural_expr_t	plural;		/* plural expression */
113 	iconv_t	fd;			/* iconv descriptor */
114 	uint32_t	**conv_msgstr;	/* code-converted msgstr */
115 } Msg_g_node;
116 
117 typedef struct msg_node {
118 	uint32_t	hashid;	/* hashed value of the domain name */
119 	uint16_t	type;	/* T_SUN_MO, T_GNU_MO, or T_ILL_MO */
120 	uint16_t	trusted;	/* is this a trusted source? */
121 	char	*path;		/* name of message catalog */
122 	union {
123 		Msg_s_node	*sunmsg;
124 		Msg_g_node	*gnumsg;
125 	} msg;
126 	struct msg_node	*next;	/* link to the next */
127 } Msg_node;
128 
129 typedef struct nls_node {
130 	char	*domain;		/* key: domain name */
131 	char	*locale;		/* key: locale name */
132 	char	*nlspath;		/* key: NLSPATH */
133 	char	*ppaths;		/* value: expanded path */
134 	struct nls_node	*next;	/* link to the next */
135 } Nls_node;
136 
137 typedef struct {
138 	char	*cur_domain;	/* current domain */
139 	Dbinding	*dbind;		/* domain binding */
140 	Msg_node	*m_node; 	/* link to the Msg_node cache */
141 	Nls_node	*n_node; 	/* link to the Nls_node cache */
142 	Msg_node	*c_m_node;	/* link to the current Msg_node */
143 	Nls_node	*c_n_node;	/* link to the current Nls_node */
144 } Gettext_t;
145 
146 struct msg_pack {
147 	const char	*msgid1;	/* msgid1 argument */
148 	const char	*msgid2;	/* msgid2 argument */
149 	char	*msgfile;		/* msg catalog file to open */
150 	char	*domain;		/* textdomain name */
151 	char	*binding;		/* binding */
152 	char	*locale;		/* locale */
153 	char	*language;		/* LANGUAGE env */
154 	caddr_t	addr;			/* mmap'ed address */
155 	size_t	fsz;			/* file size */
156 	uint32_t	hash_domain;	/* hash ID of domain */
157 	uint32_t	domain_len;	/* length of domain */
158 	unsigned int	n;		/* n argument */
159 	int	category;		/* category argument */
160 	int	plural;			/* plural or not */
161 	int	nlsp;			/* nlsp */
162 	int	trusted;		/* trusted msg catalog or not */
163 	int	status;			/* status */
164 };
165 
166 #define	DEFAULT_DOMAIN		"messages"
167 #define	DEFAULT_BINDING		_DFLT_LOC_PATH
168 #define	MSGFILESUFFIX		".mo"
169 #define	MSGFILESUFFIXLEN	(sizeof (MSGFILESUFFIX) - 1)
170 
171 #define	CURRENT_DOMAIN(gt)	(gt)->cur_domain
172 #define	FIRSTBIND(gt)	(gt)->dbind
173 
174 #define	DFLTMSG(result, msgid1, msgid2, n, plural) \
175 	result = (plural ? \
176 		((n == 1) ? (char *)msgid1 : (char *)msgid2) : \
177 		(char *)msgid1)
178 
179 #define	ROUND(m, s)	if ((m) % (s)) (m) += ((s) - ((m) % (s)))
180 
181 #define	SWAP(p, ui32) \
182 	(((p)->flag & ST_SWP) ? doswap32(ui32) : (ui32))
183 
184 #define	HASH_TBL(p, ui32)	\
185 	((((p)->flag & (ST_REV1|ST_SWP)) == ST_SWP) ? \
186 	    doswap32(ui32) : (ui32))
187 
188 extern const char	*defaultbind;
189 extern const char	default_domain[];
190 extern Gettext_t	*global_gt;
191 
192 extern char	*_textdomain_u(const char *, char *);
193 extern char	*_real_bindtextdomain_u(const char *, const char *, int);
194 extern char	*_real_gettext_u(const char *, const char *,
195     const char *, unsigned long int, int, int);
196 extern char	*handle_mo(struct msg_pack *);
197 
198 extern int	gnu_setmsg(Msg_node *, char *, size_t);
199 extern char	*handle_lang(struct msg_pack *);
200 extern char	*mk_msgfile(struct msg_pack *);
201 extern Msg_node	*check_cache(struct msg_pack *);
202 extern uint32_t	get_hashid(const char *, uint32_t *);
203 extern uint32_t	doswap32(uint32_t);
204 
205 extern int	plural_expr(plural_expr_t *, const char *);
206 extern unsigned int	plural_eval(plural_expr_t, unsigned int);
207 
208 extern char	*gnu_key_2_text(Msg_g_node *, const char *, struct msg_pack *);
209 
210 extern char	*get_codeset(const char *);
211 
212 #ifdef GETTEXT_DEBUG
213 extern void	gprintf(int, const char *, ...);
214 extern void	printgt(Gettext_t *, int);
215 extern void	printmp(struct msg_pack *, int);
216 extern void	printsunmsg(Msg_s_node *, int);
217 extern void	printgnumsg(Msg_g_node *, int);
218 extern void	printexpr(plural_expr_t, int);
219 extern void	printmnp(Msg_node *, int);
220 extern void	printlist(void);
221 extern void	print_rev1_info(Msg_g_node *);
222 #endif
223 
224 #ifdef	__cplusplus
225 }
226 #endif
227 
228 #endif	/* !_LIBC_PORT_I18N_GETTEXT_H */
229