]> git.saurik.com Git - apple/icu.git/blob - icuSources/extra/uconv/uwmsg.c
ICU-511.27.tar.gz
[apple/icu.git] / icuSources / extra / uconv / uwmsg.c
1 /*
2 **********************************************************************
3 * Copyright (C) 1998-2012, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 **********************************************************************
6 *
7 * File uwmsg.c
8 *
9 * Modification History:
10 *
11 * Date Name Description
12 * 06/14/99 stephen Creation.
13 *******************************************************************************
14 */
15
16 #include "unicode/ucnv.h"
17 #include "unicode/ustring.h"
18 #include "unicode/umsg.h"
19 #include "unicode/uwmsg.h"
20 #include "unicode/ures.h"
21 #include "unicode/putil.h"
22 #include "cstring.h"
23
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
30
31 #define BUF_SIZE 128
32
33 /* Print a ustring to the specified FILE* in the default codepage */
34 static void
35 uprint(const UChar *s,
36 int32_t sourceLen,
37 FILE *f,
38 UErrorCode *status)
39 {
40 /* converter */
41 UConverter *converter;
42 char buf [BUF_SIZE];
43 const UChar *mySource;
44 const UChar *mySourceEnd;
45 char *myTarget;
46 int32_t arraySize;
47
48 if(s == 0) return;
49
50 /* set up the conversion parameters */
51 mySource = s;
52 mySourceEnd = mySource + sourceLen;
53 myTarget = buf;
54 arraySize = BUF_SIZE;
55
56 /* open a default converter */
57 converter = ucnv_open(0, status);
58
59 /* if we failed, clean up and exit */
60 if(U_FAILURE(*status)) goto finish;
61
62 /* perform the conversion */
63 do {
64 /* reset the error code */
65 *status = U_ZERO_ERROR;
66
67 /* perform the conversion */
68 ucnv_fromUnicode(converter, &myTarget, myTarget + arraySize,
69 &mySource, mySourceEnd, NULL,
70 TRUE, status);
71
72 /* Write the converted data to the FILE* */
73 fwrite(buf, sizeof(char), myTarget - buf, f);
74
75 /* update the conversion parameters*/
76 myTarget = buf;
77 arraySize = BUF_SIZE;
78 }
79 while(*status == U_BUFFER_OVERFLOW_ERROR);
80
81 finish:
82
83 /* close the converter */
84 ucnv_close(converter);
85 }
86
87 static UResourceBundle *gBundle = NULL;
88
89 U_STRING_DECL(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
90
91 U_CFUNC UResourceBundle *u_wmsg_setPath(const char *path, UErrorCode *err)
92 {
93 if(U_FAILURE(*err))
94 {
95 return 0;
96 }
97
98 if(gBundle != NULL)
99 {
100 *err = U_ILLEGAL_ARGUMENT_ERROR;
101 return 0;
102 }
103 else
104 {
105 UResourceBundle *b = NULL;
106 b = ures_open(path, NULL, err);
107 if(U_FAILURE(*err))
108 {
109 return 0;
110 }
111
112 gBundle = b;
113
114 U_STRING_INIT(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
115 }
116
117 return gBundle;
118 }
119
120 /* Format a message and print it's output to fp */
121 U_CFUNC int u_wmsg(FILE *fp, const char *tag, ... )
122 {
123 const UChar *msg;
124 int32_t msgLen;
125 UErrorCode err = U_ZERO_ERROR;
126 #if !UCONFIG_NO_FORMATTING
127 va_list ap;
128 #endif
129 UChar result[4096];
130 int32_t resultLength = LENGTHOF(result);
131
132 if(gBundle == NULL)
133 {
134 #if 0
135 fprintf(stderr, "u_wmsg: No path set!!\n"); /* FIXME: codepage?? */
136 #endif
137 return -1;
138 }
139
140 msg = ures_getStringByKey(gBundle, tag, &msgLen, &err);
141
142 if(U_FAILURE(err))
143 {
144 return -1;
145 }
146
147 #if UCONFIG_NO_FORMATTING
148 resultLength = sizeof(gNoFormatting) / U_SIZEOF_UCHAR;
149 if((msgLen + resultLength) <= LENGTHOF(result)) {
150 memcpy(result, msg, msgLen * U_SIZEOF_UCHAR);
151 memcpy(result + msgLen, gNoFormatting, resultLength);
152 resultLength += msgLen;
153 uprint(result, resultLength, fp, &err);
154 } else {
155 uprint(msg,msgLen, fp, &err);
156 }
157 #else
158 va_start(ap, tag);
159
160 resultLength = u_vformatMessage(uloc_getDefault(), msg, msgLen, result, resultLength, ap, &err);
161
162 va_end(ap);
163
164 if(U_FAILURE(err))
165 {
166 #if 0
167 fprintf(stderr, "u_wmsg: failed to format %s:%s, err %s\n",
168 uloc_getDefault(),
169 tag,
170 u_errorName(err));
171 #endif
172 err = U_ZERO_ERROR;
173 uprint(msg,msgLen, fp, &err);
174 return -1;
175 }
176
177 uprint(result, resultLength, fp, &err);
178 #endif
179
180 if(U_FAILURE(err))
181 {
182 #if 0
183 fprintf(stderr, "u_wmsg: failed to print %s: %s, err %s\n",
184 uloc_getDefault(),
185 tag,
186 u_errorName(err));
187 #endif
188 return -1;
189 }
190
191 return 0;
192 }
193
194 /* these will break if the # of messages change. simply add or remove 0's .. */
195 UChar **gInfoMessages = NULL;
196
197 UChar **gErrMessages = NULL;
198
199 static const UChar *fetchErrorName(UErrorCode err)
200 {
201 if (!gInfoMessages) {
202 gInfoMessages = (UChar **)malloc((U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
203 memset(gInfoMessages, 0, (U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
204 }
205 if (!gErrMessages) {
206 gErrMessages = (UChar **)malloc(U_ERROR_LIMIT*sizeof(UChar*));
207 memset(gErrMessages, 0, U_ERROR_LIMIT*sizeof(UChar*));
208 }
209 if(err>=0)
210 return gErrMessages[err];
211 else
212 return gInfoMessages[err-U_ERROR_WARNING_START];
213 }
214
215 U_CFUNC const UChar *u_wmsg_errorName(UErrorCode err)
216 {
217 UChar *msg;
218 int32_t msgLen;
219 UErrorCode subErr = U_ZERO_ERROR;
220 const char *textMsg = NULL;
221
222 /* try the cache */
223 msg = (UChar*)fetchErrorName(err);
224
225 if(msg)
226 {
227 return msg;
228 }
229
230 if(gBundle == NULL)
231 {
232 msg = NULL;
233 }
234 else
235 {
236 const char *errname = u_errorName(err);
237 if (errname) {
238 msg = (UChar*)ures_getStringByKey(gBundle, errname, &msgLen, &subErr);
239 if(U_FAILURE(subErr))
240 {
241 msg = NULL;
242 }
243 }
244 }
245
246 if(msg == NULL) /* Couldn't find it anywhere.. */
247 {
248 char error[128];
249 textMsg = u_errorName(err);
250 if (!textMsg) {
251 sprintf(error, "UNDOCUMENTED ICU ERROR %d", err);
252 textMsg = error;
253 }
254 msg = (UChar*)malloc((strlen(textMsg)+1)*sizeof(msg[0]));
255 u_charsToUChars(textMsg, msg, (int32_t)(strlen(textMsg)+1));
256 }
257
258 if(err>=0)
259 gErrMessages[err] = msg;
260 else
261 gInfoMessages[err-U_ERROR_WARNING_START] = msg;
262
263 return msg;
264 }