1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 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 44 #if _lib_catopen 45 46 #undef nl_catd 47 #undef catopen 48 #undef catgets 49 #undef catclose 50 51 typedef struct 52 { 53 Mcset_t* set; 54 nl_catd cat; 55 iconv_t cvt; 56 Sfio_t* tmp; 57 } Cc_t; 58 59 #else 60 61 #define _ast_nl_catd nl_catd 62 #define _ast_catopen catopen 63 #define _ast_catgets catgets 64 #define _ast_catclose catclose 65 66 #endif 67 68 _ast_nl_catd 69 _ast_catopen(const char* name, int flag) 70 { 71 Mc_t* mc; 72 char* s; 73 Sfio_t* ip; 74 char path[PATH_MAX]; 75 76 /* 77 * first try the ast catalogs 78 */ 79 80 #if DEBUG_trace 81 sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, name); 82 #endif 83 if ((s = mcfind(path, NiL, name, LC_MESSAGES, flag)) && (ip = sfopen(NiL, s, "r"))) 84 { 85 #if DEBUG_trace 86 sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s); 87 #endif 88 mc = mcopen(ip); 89 sfclose(ip); 90 if (mc) 91 return (_ast_nl_catd)mc; 92 } 93 #if _lib_catopen 94 if (strcmp(setlocale(LC_MESSAGES, NiL), "debug")) 95 { 96 Cc_t* cc; 97 nl_catd d; 98 99 /* 100 * now the native catalogs 101 */ 102 103 if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1)) 104 { 105 if (!(cc = newof(0, Cc_t, 1, 0))) 106 { 107 catclose(d); 108 return (_ast_nl_catd)(-1); 109 } 110 cc->cat = d; 111 if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES))) 112 { 113 if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen())) 114 { 115 catclose(d); 116 return (_ast_nl_catd)(-1); 117 } 118 } 119 else 120 cc->cvt = (iconv_t)(-1); 121 #if DEBUG_trace 122 sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat); 123 #endif 124 return (_ast_nl_catd)cc; 125 } 126 } 127 #endif 128 129 /* 130 * loser 131 */ 132 133 return (_ast_nl_catd)(-1); 134 } 135 136 char* 137 _ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg) 138 { 139 if (cat == (_ast_nl_catd)(-1)) 140 return (char*)msg; 141 #if _lib_catopen 142 if (!((Cc_t*)cat)->set) 143 { 144 char* s; 145 size_t n; 146 147 msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg); 148 if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) 149 { 150 s = (char*)msg; 151 n = strlen(s); 152 iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL); 153 if (s = sfstruse(((Cc_t*)cat)->tmp)) 154 return s; 155 } 156 return (char*)msg; 157 } 158 #endif 159 return mcget((Mc_t*)cat, set, num, msg); 160 } 161 162 int 163 _ast_catclose(_ast_nl_catd cat) 164 { 165 if (cat == (_ast_nl_catd)(-1)) 166 return -1; 167 #if _lib_catopen 168 if (!((Cc_t*)cat)->set) 169 { 170 if (((Cc_t*)cat)->cvt != (iconv_t)(-1)) 171 iconv_close(((Cc_t*)cat)->cvt); 172 if (((Cc_t*)cat)->tmp) 173 sfclose(((Cc_t*)cat)->tmp); 174 return catclose(((Cc_t*)cat)->cat); 175 } 176 #endif 177 return mcclose((Mc_t*)cat); 178 } 179