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