1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/extra/uconv/uwmsg.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,264 @@ 1.4 +/* 1.5 +********************************************************************** 1.6 +* Copyright (C) 1998-2012, International Business Machines Corporation 1.7 +* and others. All Rights Reserved. 1.8 +********************************************************************** 1.9 +* 1.10 +* File uwmsg.c 1.11 +* 1.12 +* Modification History: 1.13 +* 1.14 +* Date Name Description 1.15 +* 06/14/99 stephen Creation. 1.16 +******************************************************************************* 1.17 +*/ 1.18 + 1.19 +#include "unicode/ucnv.h" 1.20 +#include "unicode/ustring.h" 1.21 +#include "unicode/umsg.h" 1.22 +#include "unicode/uwmsg.h" 1.23 +#include "unicode/ures.h" 1.24 +#include "unicode/putil.h" 1.25 +#include "cstring.h" 1.26 + 1.27 +#include <stdlib.h> 1.28 +#include <stdarg.h> 1.29 +#include <stdio.h> 1.30 +#include <string.h> 1.31 + 1.32 +#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0])) 1.33 + 1.34 +#define BUF_SIZE 128 1.35 + 1.36 +/* Print a ustring to the specified FILE* in the default codepage */ 1.37 +static void 1.38 +uprint(const UChar *s, 1.39 + int32_t sourceLen, 1.40 + FILE *f, 1.41 + UErrorCode *status) 1.42 +{ 1.43 + /* converter */ 1.44 + UConverter *converter; 1.45 + char buf [BUF_SIZE]; 1.46 + const UChar *mySource; 1.47 + const UChar *mySourceEnd; 1.48 + char *myTarget; 1.49 + int32_t arraySize; 1.50 + 1.51 + if(s == 0) return; 1.52 + 1.53 + /* set up the conversion parameters */ 1.54 + mySource = s; 1.55 + mySourceEnd = mySource + sourceLen; 1.56 + myTarget = buf; 1.57 + arraySize = BUF_SIZE; 1.58 + 1.59 + /* open a default converter */ 1.60 + converter = ucnv_open(0, status); 1.61 + 1.62 + /* if we failed, clean up and exit */ 1.63 + if(U_FAILURE(*status)) goto finish; 1.64 + 1.65 + /* perform the conversion */ 1.66 + do { 1.67 + /* reset the error code */ 1.68 + *status = U_ZERO_ERROR; 1.69 + 1.70 + /* perform the conversion */ 1.71 + ucnv_fromUnicode(converter, &myTarget, myTarget + arraySize, 1.72 + &mySource, mySourceEnd, NULL, 1.73 + TRUE, status); 1.74 + 1.75 + /* Write the converted data to the FILE* */ 1.76 + fwrite(buf, sizeof(char), myTarget - buf, f); 1.77 + 1.78 + /* update the conversion parameters*/ 1.79 + myTarget = buf; 1.80 + arraySize = BUF_SIZE; 1.81 + } 1.82 + while(*status == U_BUFFER_OVERFLOW_ERROR); 1.83 + 1.84 +finish: 1.85 + 1.86 + /* close the converter */ 1.87 + ucnv_close(converter); 1.88 +} 1.89 + 1.90 +static UResourceBundle *gBundle = NULL; 1.91 + 1.92 +U_STRING_DECL(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38); 1.93 + 1.94 +U_CFUNC UResourceBundle *u_wmsg_setPath(const char *path, UErrorCode *err) 1.95 +{ 1.96 + if(U_FAILURE(*err)) 1.97 + { 1.98 + return 0; 1.99 + } 1.100 + 1.101 + if(gBundle != NULL) 1.102 + { 1.103 + *err = U_ILLEGAL_ARGUMENT_ERROR; 1.104 + return 0; 1.105 + } 1.106 + else 1.107 + { 1.108 + UResourceBundle *b = NULL; 1.109 + b = ures_open(path, NULL, err); 1.110 + if(U_FAILURE(*err)) 1.111 + { 1.112 + return 0; 1.113 + } 1.114 + 1.115 + gBundle = b; 1.116 + 1.117 + U_STRING_INIT(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38); 1.118 + } 1.119 + 1.120 + return gBundle; 1.121 +} 1.122 + 1.123 +/* Format a message and print it's output to fp */ 1.124 +U_CFUNC int u_wmsg(FILE *fp, const char *tag, ... ) 1.125 +{ 1.126 + const UChar *msg; 1.127 + int32_t msgLen; 1.128 + UErrorCode err = U_ZERO_ERROR; 1.129 +#if !UCONFIG_NO_FORMATTING 1.130 + va_list ap; 1.131 +#endif 1.132 + UChar result[4096]; 1.133 + int32_t resultLength = LENGTHOF(result); 1.134 + 1.135 + if(gBundle == NULL) 1.136 + { 1.137 +#if 0 1.138 + fprintf(stderr, "u_wmsg: No path set!!\n"); /* FIXME: codepage?? */ 1.139 +#endif 1.140 + return -1; 1.141 + } 1.142 + 1.143 + msg = ures_getStringByKey(gBundle, tag, &msgLen, &err); 1.144 + 1.145 + if(U_FAILURE(err)) 1.146 + { 1.147 + return -1; 1.148 + } 1.149 + 1.150 +#if UCONFIG_NO_FORMATTING 1.151 + resultLength = sizeof(gNoFormatting) / U_SIZEOF_UCHAR; 1.152 + if((msgLen + resultLength) <= LENGTHOF(result)) { 1.153 + memcpy(result, msg, msgLen * U_SIZEOF_UCHAR); 1.154 + memcpy(result + msgLen, gNoFormatting, resultLength); 1.155 + resultLength += msgLen; 1.156 + uprint(result, resultLength, fp, &err); 1.157 + } else { 1.158 + uprint(msg,msgLen, fp, &err); 1.159 + } 1.160 +#else 1.161 + va_start(ap, tag); 1.162 + 1.163 + resultLength = u_vformatMessage(uloc_getDefault(), msg, msgLen, result, resultLength, ap, &err); 1.164 + 1.165 + va_end(ap); 1.166 + 1.167 + if(U_FAILURE(err)) 1.168 + { 1.169 +#if 0 1.170 + fprintf(stderr, "u_wmsg: failed to format %s:%s, err %s\n", 1.171 + uloc_getDefault(), 1.172 + tag, 1.173 + u_errorName(err)); 1.174 +#endif 1.175 + err = U_ZERO_ERROR; 1.176 + uprint(msg,msgLen, fp, &err); 1.177 + return -1; 1.178 + } 1.179 + 1.180 + uprint(result, resultLength, fp, &err); 1.181 +#endif 1.182 + 1.183 + if(U_FAILURE(err)) 1.184 + { 1.185 +#if 0 1.186 + fprintf(stderr, "u_wmsg: failed to print %s: %s, err %s\n", 1.187 + uloc_getDefault(), 1.188 + tag, 1.189 + u_errorName(err)); 1.190 +#endif 1.191 + return -1; 1.192 + } 1.193 + 1.194 + return 0; 1.195 +} 1.196 + 1.197 +/* these will break if the # of messages change. simply add or remove 0's .. */ 1.198 +UChar **gInfoMessages = NULL; 1.199 + 1.200 +UChar **gErrMessages = NULL; 1.201 + 1.202 +static const UChar *fetchErrorName(UErrorCode err) 1.203 +{ 1.204 + if (!gInfoMessages) { 1.205 + gInfoMessages = (UChar **)malloc((U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*)); 1.206 + memset(gInfoMessages, 0, (U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*)); 1.207 + } 1.208 + if (!gErrMessages) { 1.209 + gErrMessages = (UChar **)malloc(U_ERROR_LIMIT*sizeof(UChar*)); 1.210 + memset(gErrMessages, 0, U_ERROR_LIMIT*sizeof(UChar*)); 1.211 + } 1.212 + if(err>=0) 1.213 + return gErrMessages[err]; 1.214 + else 1.215 + return gInfoMessages[err-U_ERROR_WARNING_START]; 1.216 +} 1.217 + 1.218 +U_CFUNC const UChar *u_wmsg_errorName(UErrorCode err) 1.219 +{ 1.220 + UChar *msg; 1.221 + int32_t msgLen; 1.222 + UErrorCode subErr = U_ZERO_ERROR; 1.223 + const char *textMsg = NULL; 1.224 + 1.225 + /* try the cache */ 1.226 + msg = (UChar*)fetchErrorName(err); 1.227 + 1.228 + if(msg) 1.229 + { 1.230 + return msg; 1.231 + } 1.232 + 1.233 + if(gBundle == NULL) 1.234 + { 1.235 + msg = NULL; 1.236 + } 1.237 + else 1.238 + { 1.239 + const char *errname = u_errorName(err); 1.240 + if (errname) { 1.241 + msg = (UChar*)ures_getStringByKey(gBundle, errname, &msgLen, &subErr); 1.242 + if(U_FAILURE(subErr)) 1.243 + { 1.244 + msg = NULL; 1.245 + } 1.246 + } 1.247 + } 1.248 + 1.249 + if(msg == NULL) /* Couldn't find it anywhere.. */ 1.250 + { 1.251 + char error[128]; 1.252 + textMsg = u_errorName(err); 1.253 + if (!textMsg) { 1.254 + sprintf(error, "UNDOCUMENTED ICU ERROR %d", err); 1.255 + textMsg = error; 1.256 + } 1.257 + msg = (UChar*)malloc((strlen(textMsg)+1)*sizeof(msg[0])); 1.258 + u_charsToUChars(textMsg, msg, (int32_t)(strlen(textMsg)+1)); 1.259 + } 1.260 + 1.261 + if(err>=0) 1.262 + gErrMessages[err] = msg; 1.263 + else 1.264 + gInfoMessages[err-U_ERROR_WARNING_START] = msg; 1.265 + 1.266 + return msg; 1.267 +}