]> git.saurik.com Git - apple/icu.git/blame - icuSources/extra/uconv/uwmsg.c
ICU-400.37.tar.gz
[apple/icu.git] / icuSources / extra / uconv / uwmsg.c
CommitLineData
b75a7d8f
A
1/*
2**********************************************************************
374ca955 3* Copyright (C) 1998-2004, International Business Machines Corporation
b75a7d8f
A
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"
374ca955 21#include "unicode/putil.h"
b75a7d8f
A
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 */
34static void
35uprint(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
81finish:
82
83 /* close the converter */
84 ucnv_close(converter);
85}
86
87static const char *gPath = 0;
88static UResourceBundle *gBundle = NULL;
89
90U_STRING_DECL(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
91
374ca955 92U_CFUNC UResourceBundle *u_wmsg_setPath(const char *path, UErrorCode *err)
b75a7d8f
A
93{
94 if(U_FAILURE(*err))
95 {
96 return 0;
97 }
98
99 if(gBundle != NULL)
100 {
101 *err = U_ILLEGAL_ARGUMENT_ERROR;
102 return 0;
103 }
104 else
105 {
106 UResourceBundle *b = NULL;
107 b = ures_open(path, NULL, err);
108 if(U_FAILURE(*err))
109 {
110 return 0;
111 }
112
113 gPath = uprv_strdup(path);
114 gBundle = b;
115
116 U_STRING_INIT(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
117 }
118
119 return gBundle;
120}
121
122/* Format a message and print it's output to fp */
374ca955 123U_CFUNC int u_wmsg(FILE *fp, const char *tag, ... )
b75a7d8f
A
124{
125 const UChar *msg;
126 int32_t msgLen;
127 UErrorCode err = U_ZERO_ERROR;
128#if !UCONFIG_NO_FORMATTING
129 va_list ap;
130#endif
131 UChar result[4096];
132 int32_t resultLength = LENGTHOF(result);
133
134 if(gBundle == NULL)
135 {
136#if 0
137 fprintf(stderr, "u_wmsg: No path set!!\n"); /* FIXME: codepage?? */
138#endif
139 return -1;
140 }
141
142 msg = ures_getStringByKey(gBundle, tag, &msgLen, &err);
143
144 if(U_FAILURE(err))
145 {
146#if 0
147 fprintf(stderr, "u_wmsg: failed to load tag [%s] [%s] [%s]!!\n", tag, u_errorName(err), gPath);
148#endif
149 return -1;
150 }
151
152#if UCONFIG_NO_FORMATTING
153 resultLength = sizeof(gNoFormatting) / U_SIZEOF_UCHAR;
154 if((msgLen + resultLength) <= LENGTHOF(result)) {
155 memcpy(result, msg, msgLen * U_SIZEOF_UCHAR);
156 memcpy(result + msgLen, gNoFormatting, resultLength);
157 resultLength += msgLen;
158 uprint(result, resultLength, fp, &err);
159 } else {
160 uprint(msg,msgLen, fp, &err);
161 }
162#else
163 va_start(ap, tag);
164
165 resultLength = u_vformatMessage(uloc_getDefault(), msg, msgLen, result, resultLength, ap, &err);
166
167 va_end(ap);
168
169 if(U_FAILURE(err))
170 {
171#if 0
172 fprintf(stderr, "u_wmsg: failed to format %s:%s, err %s\n",
173 uloc_getDefault(),
174 tag,
175 u_errorName(err));
176#endif
177 err = U_ZERO_ERROR;
178 uprint(msg,msgLen, fp, &err);
179 return -1;
180 }
181
182 uprint(result, resultLength, fp, &err);
183#endif
184
185 if(U_FAILURE(err))
186 {
187#if 0
188 fprintf(stderr, "u_wmsg: failed to print %s: %s, err %s\n",
189 uloc_getDefault(),
190 tag,
191 u_errorName(err));
192#endif
193 return -1;
194 }
195
196 return 0;
197}
198
199/* these will break if the # of messages change. simply add or remove 0's .. */
374ca955 200UChar **gInfoMessages = NULL;
b75a7d8f 201
374ca955 202UChar **gErrMessages = NULL;
b75a7d8f
A
203
204static const UChar *fetchErrorName(UErrorCode err)
205{
374ca955
A
206 if (!gInfoMessages) {
207 gInfoMessages = (UChar **)malloc((U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
208 memset(gInfoMessages, 0, (U_ERROR_WARNING_LIMIT-U_ERROR_WARNING_START)*sizeof(UChar*));
209 }
210 if (!gErrMessages) {
211 gErrMessages = (UChar **)malloc(U_ERROR_LIMIT*sizeof(UChar*));
212 memset(gErrMessages, 0, U_ERROR_LIMIT*sizeof(UChar*));
213 }
b75a7d8f
A
214 if(err>=0)
215 return gErrMessages[err];
216 else
217 return gInfoMessages[err-U_ERROR_WARNING_START];
218}
219
374ca955 220U_CFUNC const UChar *u_wmsg_errorName(UErrorCode err)
b75a7d8f
A
221{
222 UChar *msg;
223 int32_t msgLen;
224 UErrorCode subErr = U_ZERO_ERROR;
225 const char *textMsg = NULL;
226
227 /* try the cache */
228 msg = (UChar*)fetchErrorName(err);
229
230 if(msg)
231 {
232 return msg;
233 }
234
235 if(gBundle == NULL)
236 {
237 msg = NULL;
238 }
239 else
240 {
241 const char *errname = u_errorName(err);
242 if (errname) {
243 msg = (UChar*)ures_getStringByKey(gBundle, errname, &msgLen, &subErr);
244 if(U_FAILURE(subErr))
245 {
246 msg = NULL;
247 }
248 }
249 }
250
251 if(msg == NULL) /* Couldn't find it anywhere.. */
252 {
253 char error[128];
254 textMsg = u_errorName(err);
255 if (!textMsg) {
256 sprintf(error, "UNDOCUMENTED ICU ERROR %d", err);
257 textMsg = error;
258 }
259 msg = (UChar*)malloc((strlen(textMsg)+1)*sizeof(msg[0]));
260 u_charsToUChars(textMsg, msg, (int32_t)(strlen(textMsg)+1));
261 }
262
263 if(err>=0)
264 gErrMessages[err] = msg;
265 else
266 gInfoMessages[err-U_ERROR_WARNING_START] = msg;
267
268 return msg;
269}