]> git.saurik.com Git - apple/icu.git/blame - icuSources/extra/uconv/uwmsg.c
ICU-531.30.tar.gz
[apple/icu.git] / icuSources / extra / uconv / uwmsg.c
CommitLineData
b75a7d8f
A
1/*
2**********************************************************************
51004dcb 3* Copyright (C) 1998-2012, 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
b75a7d8f
A
87static UResourceBundle *gBundle = NULL;
88
89U_STRING_DECL(gNoFormatting, " (UCONFIG_NO_FORMATTING see uconfig.h)", 38);
90
374ca955 91U_CFUNC UResourceBundle *u_wmsg_setPath(const char *path, UErrorCode *err)
b75a7d8f
A
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
b75a7d8f
A
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 */
374ca955 121U_CFUNC int u_wmsg(FILE *fp, const char *tag, ... )
b75a7d8f
A
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 {
b75a7d8f
A
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 .. */
374ca955 195UChar **gInfoMessages = NULL;
b75a7d8f 196
374ca955 197UChar **gErrMessages = NULL;
b75a7d8f
A
198
199static const UChar *fetchErrorName(UErrorCode err)
200{
374ca955
A
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 }
b75a7d8f
A
209 if(err>=0)
210 return gErrMessages[err];
211 else
212 return gInfoMessages[err-U_ERROR_WARNING_START];
213}
214
374ca955 215U_CFUNC const UChar *u_wmsg_errorName(UErrorCode err)
b75a7d8f
A
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}