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
54 typedef 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
_ast_catopen(const char * name,int flag)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
84 sfprintf(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
89 sfprintf(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
126 sfprintf(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
140 char*
_ast_catgets(_ast_nl_catd cat,int set,int num,const char * msg)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
166 int
_ast_catclose(_ast_nl_catd cat)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