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