1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                 Eclipse Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*          http://www.eclipse.org/org/documents/epl-v10.html           *
11*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23
24/*
25 * catopen intercept
26 * the ast catalogs are checked first
27 * the ast mc* and native cat* routines do all the work
28 * catalogs found by mcfind() are converted from utf to ucs
29 *
30 * nl_catd is cast to void*
31 * this is either an Mc_t* (Mc_t.set != 0)
32 * or a Cc_t* where Cc_t.cat is the native nl_catd
33 */
34
35#include <ast.h>
36#include <mc.h>
37#include <nl_types.h>
38#include <iconv.h>
39
40#ifndef DEBUG_trace
41#define DEBUG_trace		0
42#endif
43#if DEBUG_trace
44#undef setlocale
45#endif
46
47#if _lib_catopen
48
49#undef	nl_catd
50#undef	catopen
51#undef	catgets
52#undef	catclose
53
54typedef struct
55{
56	Mcset_t*	set;
57	nl_catd		cat;
58	iconv_t		cvt;
59	Sfio_t*		tmp;
60} Cc_t;
61
62#else
63
64#define _ast_nl_catd	nl_catd
65#define _ast_catopen	catopen
66#define _ast_catgets	catgets
67#define _ast_catclose	catclose
68
69#endif
70
71_ast_nl_catd
72_ast_catopen(const char* name, int flag)
73{
74	Mc_t*		mc;
75	char*		s;
76	Sfio_t*		ip;
77	char		path[PATH_MAX];
78
79	/*
80	 * first try the ast catalogs
81	 */
82
83#if DEBUG_trace
84sfprintf(sfstderr, "AHA#%d:%s %s LC_MESSAGES=%s:%s\n", __LINE__, __FILE__, name, _ast_setlocale(LC_MESSAGES, 0), setlocale(LC_MESSAGES, 0));
85#endif
86	if ((s = mcfind(NiL, name, LC_MESSAGES, flag, path, sizeof(path))) && (ip = sfopen(NiL, s, "r")))
87	{
88#if DEBUG_trace
89sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
90#endif
91		mc = mcopen(ip);
92		sfclose(ip);
93		if (mc)
94			return (_ast_nl_catd)mc;
95	}
96#if _lib_catopen
97	if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
98	{
99		Cc_t*		cc;
100		nl_catd		d;
101
102		/*
103		 * now the native catalogs
104		 */
105
106		if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
107		{
108			if (!(cc = newof(0, Cc_t, 1, 0)))
109			{
110				catclose(d);
111				return (_ast_nl_catd)(-1);
112			}
113			cc->cat = d;
114			if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
115			{
116				if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
117				{
118					catclose(d);
119					free(cc);
120					return (_ast_nl_catd)(-1);
121				}
122			}
123			else
124				cc->cvt = (iconv_t)(-1);
125#if DEBUG_trace
126sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
127#endif
128			return (_ast_nl_catd)cc;
129		}
130	}
131#endif
132
133	/*
134	 * loser
135	 */
136
137	return (_ast_nl_catd)(-1);
138}
139
140char*
141_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
142{
143	if (cat == (_ast_nl_catd)(-1))
144		return (char*)msg;
145#if _lib_catopen
146	if (!((Cc_t*)cat)->set)
147	{
148		char*	s;
149		size_t	n;
150
151		msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
152		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
153		{
154			s = (char*)msg;
155			n = strlen(s);
156			iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
157			if (s = sfstruse(((Cc_t*)cat)->tmp))
158				return s;
159		}
160		return (char*)msg;
161	}
162#endif
163	return mcget((Mc_t*)cat, set, num, msg);
164}
165
166int
167_ast_catclose(_ast_nl_catd cat)
168{
169	if (cat == (_ast_nl_catd)(-1))
170		return -1;
171#if _lib_catopen
172	if (!((Cc_t*)cat)->set)
173	{
174		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
175			iconv_close(((Cc_t*)cat)->cvt);
176		if (((Cc_t*)cat)->tmp)
177			sfclose(((Cc_t*)cat)->tmp);
178		return catclose(((Cc_t*)cat)->cat);
179	}
180#endif
181	return mcclose((Mc_t*)cat);
182}
183