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