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