diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/comp/catopen.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/comp/catopen.c')
-rw-r--r-- | src/lib/libast/comp/catopen.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/lib/libast/comp/catopen.c b/src/lib/libast/comp/catopen.c new file mode 100644 index 0000000..7bace39 --- /dev/null +++ b/src/lib/libast/comp/catopen.c @@ -0,0 +1,182 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped + +/* + * catopen intercept + * the ast catalogs are checked first + * the ast mc* and native cat* routines do all the work + * catalogs found by mcfind() are converted from utf to ucs + * + * nl_catd is cast to void* + * this is either an Mc_t* (Mc_t.set != 0) + * or a Cc_t* where Cc_t.cat is the native nl_catd + */ + +#include <ast.h> +#include <mc.h> +#include <nl_types.h> +#include <iconv.h> + +#ifndef DEBUG_trace +#define DEBUG_trace 0 +#endif +#if DEBUG_trace +#undef setlocale +#endif + +#if _lib_catopen + +#undef nl_catd +#undef catopen +#undef catgets +#undef catclose + +typedef struct +{ + Mcset_t* set; + nl_catd cat; + iconv_t cvt; + Sfio_t* tmp; +} Cc_t; + +#else + +#define _ast_nl_catd nl_catd +#define _ast_catopen catopen +#define _ast_catgets catgets +#define _ast_catclose catclose + +#endif + +_ast_nl_catd +_ast_catopen(const char* name, int flag) +{ + Mc_t* mc; + char* s; + Sfio_t* ip; + char path[PATH_MAX]; + + /* + * first try the ast catalogs + */ + +#if DEBUG_trace +sfprintf(sfstderr, "AHA#%d:%s %s LC_MESSAGES=%s:%s\n", __LINE__, __FILE__, name, _ast_setlocale(LC_MESSAGES, 0), setlocale(LC_MESSAGES, 0)); +#endif + if ((s = mcfind(NiL, name, LC_MESSAGES, flag, path, sizeof(path))) && (ip = sfopen(NiL, s, "r"))) + { +#if DEBUG_trace +sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s); +#endif + mc = mcopen(ip); + sfclose(ip); + if (mc) + return (_ast_nl_catd)mc; + } +#if _lib_catopen + if (strcmp(setlocale(LC_MESSAGES, NiL), "debug")) + { + Cc_t* cc; + nl_catd d; + + /* + * now the native catalogs + */ + + if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1)) + { + if (!(cc = newof(0, Cc_t, 1, 0))) + { + catclose(d); + return (_ast_nl_catd)(-1); + } + cc->cat = d; + if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES))) + { + if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen())) + { + catclose(d); + free(cc); + return (_ast_nl_catd)(-1); + } + } + else + cc->cvt = (iconv_t)(-1); +#if DEBUG_trace +sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat); +#endif + return (_ast_nl_catd)cc; + } + } +#endif + + /* + * loser + */ + + return (_ast_nl_catd)(-1); +} + +char* +_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg) +{ + if (cat == (_ast_nl_catd)(-1)) + return (char*)msg; +#if _lib_catopen + if (!((Cc_t*)cat)->set) + { + char* s; + size_t n; + + msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg); + if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) + { + s = (char*)msg; + n = strlen(s); + iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL); + if (s = sfstruse(((Cc_t*)cat)->tmp)) + return s; + } + return (char*)msg; + } +#endif + return mcget((Mc_t*)cat, set, num, msg); +} + +int +_ast_catclose(_ast_nl_catd cat) +{ + if (cat == (_ast_nl_catd)(-1)) + return -1; +#if _lib_catopen + if (!((Cc_t*)cat)->set) + { + if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) + iconv_close(((Cc_t*)cat)->cvt); + if (((Cc_t*)cat)->tmp) + sfclose(((Cc_t*)cat)->tmp); + return catclose(((Cc_t*)cat)->cat); + } +#endif + return mcclose((Mc_t*)cat); +} |