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* Common Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.opensource.org/licenses/cpl1.0.txt * 11* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 return (_ast_nl_catd)(-1); 120 } 121 } 122 else 123 cc->cvt = (iconv_t)(-1); 124#if DEBUG_trace 125sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat); 126#endif 127 return (_ast_nl_catd)cc; 128 } 129 } 130#endif 131 132 /* 133 * loser 134 */ 135 136 return (_ast_nl_catd)(-1); 137} 138 139char* 140_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg) 141{ 142 if (cat == (_ast_nl_catd)(-1)) 143 return (char*)msg; 144#if _lib_catopen 145 if (!((Cc_t*)cat)->set) 146 { 147 char* s; 148 size_t n; 149 150 msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg); 151 if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) 152 { 153 s = (char*)msg; 154 n = strlen(s); 155 iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL); 156 if (s = sfstruse(((Cc_t*)cat)->tmp)) 157 return s; 158 } 159 return (char*)msg; 160 } 161#endif 162 return mcget((Mc_t*)cat, set, num, msg); 163} 164 165int 166_ast_catclose(_ast_nl_catd cat) 167{ 168 if (cat == (_ast_nl_catd)(-1)) 169 return -1; 170#if _lib_catopen 171 if (!((Cc_t*)cat)->set) 172 { 173 if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) 174 iconv_close(((Cc_t*)cat)->cvt); 175 if (((Cc_t*)cat)->tmp) 176 sfclose(((Cc_t*)cat)->tmp); 177 return catclose(((Cc_t*)cat)->cat); 178 } 179#endif 180 return mcclose((Mc_t*)cat); 181} 182