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 54 typedef 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 84 sfprintf(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 89 sfprintf(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 126 sfprintf(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 140 char* 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 166 int 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