14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin
244887Schin /*
254887Schin * catopen intercept
264887Schin * the ast catalogs are checked first
274887Schin * the ast mc* and native cat* routines do all the work
284887Schin * catalogs found by mcfind() are converted from utf to ucs
294887Schin *
304887Schin * nl_catd is cast to void*
314887Schin * this is either an Mc_t* (Mc_t.set != 0)
324887Schin * or a Cc_t* where Cc_t.cat is the native nl_catd
334887Schin */
344887Schin
354887Schin #include <ast.h>
364887Schin #include <mc.h>
374887Schin #include <nl_types.h>
384887Schin #include <iconv.h>
394887Schin
404887Schin #ifndef DEBUG_trace
414887Schin #define DEBUG_trace 0
424887Schin #endif
434887Schin
444887Schin #if _lib_catopen
454887Schin
464887Schin #undef nl_catd
474887Schin #undef catopen
484887Schin #undef catgets
494887Schin #undef catclose
504887Schin
514887Schin typedef struct
524887Schin {
534887Schin Mcset_t* set;
544887Schin nl_catd cat;
554887Schin iconv_t cvt;
564887Schin Sfio_t* tmp;
574887Schin } Cc_t;
584887Schin
594887Schin #else
604887Schin
614887Schin #define _ast_nl_catd nl_catd
624887Schin #define _ast_catopen catopen
634887Schin #define _ast_catgets catgets
644887Schin #define _ast_catclose catclose
654887Schin
664887Schin #endif
674887Schin
684887Schin _ast_nl_catd
_ast_catopen(const char * name,int flag)694887Schin _ast_catopen(const char* name, int flag)
704887Schin {
714887Schin Mc_t* mc;
724887Schin char* s;
734887Schin Sfio_t* ip;
744887Schin char path[PATH_MAX];
754887Schin
764887Schin /*
774887Schin * first try the ast catalogs
784887Schin */
794887Schin
804887Schin #if DEBUG_trace
814887Schin sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, name);
824887Schin #endif
834887Schin if ((s = mcfind(path, NiL, name, LC_MESSAGES, flag)) && (ip = sfopen(NiL, s, "r")))
844887Schin {
854887Schin #if DEBUG_trace
864887Schin sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
874887Schin #endif
884887Schin mc = mcopen(ip);
894887Schin sfclose(ip);
904887Schin if (mc)
914887Schin return (_ast_nl_catd)mc;
924887Schin }
934887Schin #if _lib_catopen
944887Schin if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
954887Schin {
964887Schin Cc_t* cc;
974887Schin nl_catd d;
984887Schin
994887Schin /*
1004887Schin * now the native catalogs
1014887Schin */
1024887Schin
1034887Schin if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
1044887Schin {
1054887Schin if (!(cc = newof(0, Cc_t, 1, 0)))
1064887Schin {
1074887Schin catclose(d);
1084887Schin return (_ast_nl_catd)(-1);
1094887Schin }
1104887Schin cc->cat = d;
1114887Schin if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
1124887Schin {
1134887Schin if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
1144887Schin {
1154887Schin catclose(d);
1164887Schin return (_ast_nl_catd)(-1);
1174887Schin }
1184887Schin }
1194887Schin else
1204887Schin cc->cvt = (iconv_t)(-1);
1214887Schin #if DEBUG_trace
1224887Schin sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
1234887Schin #endif
1244887Schin return (_ast_nl_catd)cc;
1254887Schin }
1264887Schin }
1274887Schin #endif
1284887Schin
1294887Schin /*
1304887Schin * loser
1314887Schin */
1324887Schin
1334887Schin return (_ast_nl_catd)(-1);
1344887Schin }
1354887Schin
1364887Schin char*
_ast_catgets(_ast_nl_catd cat,int set,int num,const char * msg)1374887Schin _ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
1384887Schin {
1394887Schin if (cat == (_ast_nl_catd)(-1))
1404887Schin return (char*)msg;
1414887Schin #if _lib_catopen
1424887Schin if (!((Cc_t*)cat)->set)
1434887Schin {
1444887Schin char* s;
1454887Schin size_t n;
1464887Schin
1474887Schin msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
1484887Schin if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
1494887Schin {
1504887Schin s = (char*)msg;
1514887Schin n = strlen(s);
1524887Schin iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
1534887Schin if (s = sfstruse(((Cc_t*)cat)->tmp))
1544887Schin return s;
1554887Schin }
1564887Schin return (char*)msg;
1574887Schin }
1584887Schin #endif
1594887Schin return mcget((Mc_t*)cat, set, num, msg);
1604887Schin }
1614887Schin
1624887Schin int
_ast_catclose(_ast_nl_catd cat)1634887Schin _ast_catclose(_ast_nl_catd cat)
1644887Schin {
1654887Schin if (cat == (_ast_nl_catd)(-1))
1664887Schin return -1;
1674887Schin #if _lib_catopen
1684887Schin if (!((Cc_t*)cat)->set)
1694887Schin {
1704887Schin if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
1714887Schin iconv_close(((Cc_t*)cat)->cvt);
1724887Schin if (((Cc_t*)cat)->tmp)
1734887Schin sfclose(((Cc_t*)cat)->tmp);
1744887Schin return catclose(((Cc_t*)cat)->cat);
1754887Schin }
1764887Schin #endif
1774887Schin return mcclose((Mc_t*)cat);
1784887Schin }
179