1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A
1N/A/*
1N/A * catopen intercept
1N/A * the ast catalogs are checked first
1N/A * the ast mc* and native cat* routines do all the work
1N/A * catalogs found by mcfind() are converted from utf to ucs
1N/A *
1N/A * nl_catd is cast to void*
1N/A * this is either an Mc_t* (Mc_t.set != 0)
1N/A * or a Cc_t* where Cc_t.cat is the native nl_catd
1N/A */
1N/A
1N/A#include <ast.h>
1N/A#include <mc.h>
1N/A#include <nl_types.h>
1N/A#include <iconv.h>
1N/A
1N/A#ifndef DEBUG_trace
1N/A#define DEBUG_trace 0
1N/A#endif
1N/A#if DEBUG_trace
1N/A#undef setlocale
1N/A#endif
1N/A
1N/A#if _lib_catopen
1N/A
1N/A#undef nl_catd
1N/A#undef catopen
1N/A#undef catgets
1N/A#undef catclose
1N/A
1N/Atypedef struct
1N/A{
1N/A Mcset_t* set;
1N/A nl_catd cat;
1N/A iconv_t cvt;
1N/A Sfio_t* tmp;
1N/A} Cc_t;
1N/A
1N/A#else
1N/A
1N/A#define _ast_nl_catd nl_catd
1N/A#define _ast_catopen catopen
1N/A#define _ast_catgets catgets
1N/A#define _ast_catclose catclose
1N/A
1N/A#endif
1N/A
1N/A_ast_nl_catd
1N/A_ast_catopen(const char* name, int flag)
1N/A{
1N/A Mc_t* mc;
1N/A char* s;
1N/A Sfio_t* ip;
1N/A char path[PATH_MAX];
1N/A
1N/A /*
1N/A * first try the ast catalogs
1N/A */
1N/A
1N/A#if DEBUG_trace
1N/Asfprintf(sfstderr, "AHA#%d:%s %s LC_MESSAGES=%s:%s\n", __LINE__, __FILE__, name, _ast_setlocale(LC_MESSAGES, 0), setlocale(LC_MESSAGES, 0));
1N/A#endif
1N/A if ((s = mcfind(NiL, name, LC_MESSAGES, flag, path, sizeof(path))) && (ip = sfopen(NiL, s, "r")))
1N/A {
1N/A#if DEBUG_trace
1N/Asfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
1N/A#endif
1N/A mc = mcopen(ip);
1N/A sfclose(ip);
1N/A if (mc)
1N/A return (_ast_nl_catd)mc;
1N/A }
1N/A#if _lib_catopen
1N/A if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
1N/A {
1N/A Cc_t* cc;
1N/A nl_catd d;
1N/A
1N/A /*
1N/A * now the native catalogs
1N/A */
1N/A
1N/A if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
1N/A {
1N/A if (!(cc = newof(0, Cc_t, 1, 0)))
1N/A {
1N/A catclose(d);
1N/A return (_ast_nl_catd)(-1);
1N/A }
1N/A cc->cat = d;
1N/A if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
1N/A {
1N/A if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
1N/A {
1N/A catclose(d);
1N/A return (_ast_nl_catd)(-1);
1N/A }
1N/A }
1N/A else
1N/A cc->cvt = (iconv_t)(-1);
1N/A#if DEBUG_trace
1N/Asfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
1N/A#endif
1N/A return (_ast_nl_catd)cc;
1N/A }
1N/A }
1N/A#endif
1N/A
1N/A /*
1N/A * loser
1N/A */
1N/A
1N/A return (_ast_nl_catd)(-1);
1N/A}
1N/A
1N/Achar*
1N/A_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
1N/A{
1N/A if (cat == (_ast_nl_catd)(-1))
1N/A return (char*)msg;
1N/A#if _lib_catopen
1N/A if (!((Cc_t*)cat)->set)
1N/A {
1N/A char* s;
1N/A size_t n;
1N/A
1N/A msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
1N/A if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
1N/A {
1N/A s = (char*)msg;
1N/A n = strlen(s);
1N/A iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
1N/A if (s = sfstruse(((Cc_t*)cat)->tmp))
1N/A return s;
1N/A }
1N/A return (char*)msg;
1N/A }
1N/A#endif
1N/A return mcget((Mc_t*)cat, set, num, msg);
1N/A}
1N/A
1N/Aint
1N/A_ast_catclose(_ast_nl_catd cat)
1N/A{
1N/A if (cat == (_ast_nl_catd)(-1))
1N/A return -1;
1N/A#if _lib_catopen
1N/A if (!((Cc_t*)cat)->set)
1N/A {
1N/A if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
1N/A iconv_close(((Cc_t*)cat)->cvt);
1N/A if (((Cc_t*)cat)->tmp)
1N/A sfclose(((Cc_t*)cat)->tmp);
1N/A return catclose(((Cc_t*)cat)->cat);
1N/A }
1N/A#endif
1N/A return mcclose((Mc_t*)cat);
1N/A}