blob: 9e03368cfb26098746f3d00ed76f189ffcb28130 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#ifdef UEMF
2 #include "uemf.h"
3#else
4 #include "basic/basicInternal.h"
5#endif
6
7#define kUseMemcopy
8
9#define STR_REALLOC 0x1
10#define STR_INC 64
11
12typedef struct {
13 char_t *s;
14 int size;
15 int max;
16 int count;
17 int flags;
18} strbuf_t;
19
20enum flag {
21 flag_none = 0,
22 flag_minus = 1,
23 flag_plus = 2,
24 flag_space = 4,
25 flag_hash = 8,
26 flag_zero = 16,
27 flag_short = 32,
28 flag_long = 64
29};
30
31static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize);
32static int strnlen(char_t *s, unsigned int n);
33
34static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
35 int upper, char_t *prefix, int width, int prec, enum flag f);
36
37static void put_char(strbuf_t *buf, char_t c);
38static void put_string(strbuf_t *buf, char_t *s, int len,
39 int width, int prec, enum flag f);
40
41static void put_char(strbuf_t *buf, char_t c)
42{
43 if (buf->count >= (buf->size - 1)) {
44 if (! (buf->flags & STR_REALLOC)) {
45 return;
46 }
47 buf->size += STR_INC;
48 if (buf->size > buf->max && buf->size > STR_INC) {
49
50 buf->size -= STR_INC;
51 return;
52 }
53 if (buf->s == NULL) {
54 buf->s = balloc(B_L, buf->size * sizeof(char_t));
55 } else {
56 buf->s = brealloc(B_L, buf->s, buf->size * sizeof(char_t));
57 }
58 }
59 if(buf->s){
60 buf->s[buf->count] = c;
61 if (c != '\0') {
62 ++buf->count;
63 }
64 }
65}
66
67static void put_string(strbuf_t *buf, char_t *s, int len, int width,
68 int prec, enum flag f)
69{
70 int index;
71
72 if (len < 0) {
73 len = strnlen(s, prec >= 0 ? prec : ULONG_MAX);
74 } else if (prec >= 0 && prec < len) {
75 len = prec;
76 }
77 if (width > len && !(f & flag_minus)) {
78 for (index = len; index < width; ++index) {
79 put_char(buf, ' ');
80 }
81 }
82 for (index = 0; index < len; ++index) {
83 put_char(buf, s[index]);
84 }
85 if (width > len && f & flag_minus) {
86 for (index = len; index < width; ++index) {
87 put_char(buf, ' ');
88 }
89 }
90}
91
92int fmtAlloc(char_t **s, int n, char_t *fmt, ...)
93{
94 va_list ap = {0};
95 int result;
96
97 a_assert(s);
98 a_assert(fmt);
99
100 *s = NULL;
101 va_start(ap, fmt);
102 result = dsnprintf(s, n, fmt, ap, 0);
103 va_end(ap);
104 return result;
105}
106
107int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg)
108{
109 a_assert(s);
110 a_assert(fmt);
111
112 *s = NULL;
113 return dsnprintf(s, n, fmt, arg, 0);
114}
115
116int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...)
117{
118 va_list ap = {0};
119 int result;
120
121 a_assert(s);
122 a_assert(fmt);
123
124 if (msize == -1) {
125 *s = NULL;
126 }
127 va_start(ap, fmt);
128 result = dsnprintf(s, n, fmt, ap, msize);
129 va_end(ap);
130 return result;
131}
132
133static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize)
134{
135 char_t tmp_c;
136 strbuf_t tmp_buf;
137
138 a_assert(s);
139 a_assert(fmt);
140
141 memset(&tmp_buf, 0, sizeof(tmp_buf));
142 tmp_buf.s = *s;
143
144 if (*s == NULL || msize != 0) {
145 tmp_buf.max = size;
146 tmp_buf.flags |= STR_REALLOC;
147 if (msize != 0) {
148 tmp_buf.size = max(msize, 0);
149 }
150 if (*s != NULL && msize != 0) {
151 tmp_buf.count = gstrlen(*s);
152 }
153 } else {
154 tmp_buf.size = size;
155 }
156
157 while ((tmp_c = *fmt++) != '\0') {
158 if (tmp_c != '%' || (tmp_c = *fmt++) == '%') {
159 put_char(&tmp_buf, tmp_c);
160 } else {
161 enum flag f = flag_none;
162 int width = 0;
163 int prec = -1;
164 for ( ; tmp_c != '\0'; tmp_c = *fmt++) {
165 if (tmp_c == '-') {
166 f |= flag_minus;
167 } else if (tmp_c == '+') {
168 f |= flag_plus;
169 } else if (tmp_c == ' ') {
170 f |= flag_space;
171 } else if (tmp_c == '#') {
172 f |= flag_hash;
173 } else if (tmp_c == '0') {
174 f |= flag_zero;
175 } else {
176 break;
177 }
178 }
179 if (tmp_c == '*') {
180 width = va_arg(arg, int);
181 if (width < 0) {
182 f |= flag_minus;
183 width = -width;
184 }
185 tmp_c = *fmt++;
186 } else {
187 for ( ; gisdigit((int)tmp_c); tmp_c = *fmt++) {
188 width = width * 10 + (tmp_c - '0');
189 }
190 }
191 if (tmp_c == '.') {
192 f &= ~flag_zero;
193 tmp_c = *fmt++;
194 if (tmp_c == '*') {
195 prec = va_arg(arg, int);
196 tmp_c = *fmt++;
197 } else {
198 for (prec = 0; gisdigit((int)tmp_c); tmp_c = *fmt++) {
199 prec = prec * 10 + (tmp_c - '0');
200 }
201 }
202 }
203 if (tmp_c == 'h' || tmp_c == 'l') {
204 f |= (tmp_c == 'h' ? flag_short : flag_long);
205 tmp_c = *fmt++;
206 }
207 if (tmp_c == 'd' || tmp_c == 'i') {
208 long int value;
209 if (f & flag_short) {
210 value = (short int) va_arg(arg, int);
211 } else if (f & flag_long) {
212 value = va_arg(arg, long int);
213 } else {
214 value = va_arg(arg, int);
215 }
216 if (value >= 0) {
217 if (f & flag_plus) {
218 put_ulong(&tmp_buf, value, 10, 0, T("+"), width, prec, f);
219 } else if (f & flag_space) {
220 put_ulong(&tmp_buf, value, 10, 0, T(" "), width, prec, f);
221 } else {
222 put_ulong(&tmp_buf, value, 10, 0, NULL, width, prec, f);
223 }
224 } else {
225 put_ulong(&tmp_buf, -value, 10, 0, T("-"), width, prec, f);
226 }
227 } else if (tmp_c == 'o' || tmp_c == 'u' || tmp_c == 'x' || tmp_c == 'X') {
228 unsigned long int value;
229 if (f & flag_short) {
230 value = (unsigned short int) va_arg(arg, unsigned int);
231 } else if (f & flag_long) {
232 value = va_arg(arg, unsigned long int);
233 } else {
234 value = va_arg(arg, unsigned int);
235 }
236 if (tmp_c == 'o') {
237 if (f & flag_hash && value != 0) {
238 put_ulong(&tmp_buf, value, 8, 0, T("0"), width, prec, f);
239 } else {
240 put_ulong(&tmp_buf, value, 8, 0, NULL, width, prec, f);
241 }
242 } else if (tmp_c == 'u') {
243 put_ulong(&tmp_buf, value, 10, 0, NULL, width, prec, f);
244 } else {
245 if (f & flag_hash && value != 0) {
246 if (tmp_c == 'x') {
247 put_ulong(&tmp_buf, value, 16, 0, T("0x"), width, prec, f);
248 } else {
249 put_ulong(&tmp_buf, value, 16, 1, T("0X"), width, prec, f);
250 }
251 } else {
252 put_ulong(&tmp_buf, value, 16, ('X' == tmp_c) , NULL, width, prec, f);
253 }
254 }
255
256 } else if (tmp_c == 'c') {
257 char_t value = va_arg(arg, int);
258 put_char(&tmp_buf, value);
259
260 } else if (tmp_c == 's' || tmp_c == 'S') {
261 char_t *value = va_arg(arg, char_t *);
262 if (value == NULL) {
263 put_string(&tmp_buf, T("(null)"), -1, width, prec, f);
264 } else if (f & flag_hash) {
265 put_string(&tmp_buf,
266 value + 1, (char_t) *value, width, prec, f);
267 } else {
268 put_string(&tmp_buf, value, -1, width, prec, f);
269 }
270 } else if (tmp_c == 'p') {
271 void *value = va_arg(arg, void *);
272 put_ulong(&tmp_buf,
273 (unsigned long int) value, 16, 0, T("0x"), width, prec, f);
274 } else if (tmp_c == 'n') {
275 if (f & flag_short) {
276 short int *value = va_arg(arg, short int *);
277 *value = tmp_buf.count;
278 } else if (f & flag_long) {
279 long int *value = va_arg(arg, long int *);
280 *value = tmp_buf.count;
281 } else {
282 int *value = va_arg(arg, int *);
283 *value = tmp_buf.count;
284 }
285 } else {
286 put_char(&tmp_buf, tmp_c);
287 }
288 }
289 }
290 if (tmp_buf.s == NULL) {
291 put_char(&tmp_buf, '\0');
292 }
293
294 if (*s == NULL || msize != 0) {
295 *s = tmp_buf.s;
296 }
297
298 if (*s != NULL && size > 0) {
299 if (tmp_buf.count < size) {
300 (*s)[tmp_buf.count] = '\0';
301 } else {
302 (*s)[tmp_buf.size - 1] = '\0';
303 }
304 }
305
306 if (msize != 0) {
307 return tmp_buf.size;
308 }
309 return tmp_buf.count;
310}
311
312static int strnlen(char_t *s, unsigned int n)
313{
314 unsigned int len;
315
316 len = gstrlen(s);
317 return min(len, n);
318}
319
320
321static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
322 int upper, char_t *prefix, int width, int prec, enum flag f)
323{
324 unsigned long x, x2;
325 int len, zeros, index;
326
327 for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) {
328 x2 = x * base;
329 if (x2 > value) {
330 break;
331 }
332 }
333 zeros = (prec > len) ? prec - len : 0;
334 width -= zeros + len;
335 if (prefix != NULL) {
336 width -= strnlen(prefix, ULONG_MAX);
337 }
338 if (!(f & flag_minus)) {
339 if (f & flag_zero) {
340 for (index = 0; index < width; ++index) {
341 put_char(buf, '0');
342 }
343 } else {
344 for (index = 0; index < width; ++index) {
345 put_char(buf, ' ');
346 }
347 }
348 }
349 if (prefix != NULL) {
350 put_string(buf, prefix, -1, 0, -1, flag_none);
351 }
352 for (index = 0; index < zeros; ++index) {
353 put_char(buf, '0');
354 }
355 for ( ; x > 0; x /= base) {
356 int digit = (value / x) % base;
357 put_char(buf, (char)((digit < 10 ? '0' : (upper ? 'A' : 'a') - 10) + digit));
358 }
359 if (f & flag_minus) {
360 for (index = 0; index < width; ++index) {
361 put_char(buf, ' ');
362 }
363 }
364}
365
366char_t *ascToUni(char_t *ubuf, char *str, int nBytes)
367{
368 memcpy(ubuf, str, nBytes);
369 return ubuf;
370}
371
372
373char_t *ballocAscToUni(char *cp, int alen)
374{
375 char_t *unip;
376 int ulen;
377
378 ulen = (alen + 1) * sizeof(char_t);
379 if ((unip = balloc(B_L, ulen)) == NULL) {
380 return NULL;
381 }
382 ascToUni(unip, cp, ulen);
383 unip[alen] = 0;
384 return unip;
385}
386
387unsigned int hextoi(char_t *hexstring)
388{
389 register char_t *h;
390 register unsigned int c, v;
391
392 v = 0;
393 h = hexstring;
394 if (*h == '0' && (*(h+1) == 'x' || *(h+1) == 'X')) {
395 h += 2;
396 }
397 while ((c = (unsigned int)*h++) != 0) {
398 if (c >= '0' && c <= '9') {
399 c -= '0';
400 } else if (c >= 'a' && c <= 'f') {
401 c = (c - 'a') + 10;
402 } else if (c >= 'A' && c <= 'F') {
403 c = (c - 'A') + 10;
404 } else {
405 break;
406 }
407 v = (v * 0x10) + c;
408 }
409 return v;
410}
411
412char *uniToAsc(char *buf, char_t *ustr, int nBytes)
413{
414#ifdef UNICODE
415 if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes,
416 NULL, NULL) < 0)
417 {
418 return (char*) ustr;
419 }
420#else
421#ifdef kUseMemcopy
422 memcpy(buf, ustr, nBytes);
423#else
424 strncpy(buf, ustr, nBytes);
425#endif /* kUseMemcopy */
426#endif
427 return (char*) buf;
428}
429
430char *ballocUniToAsc(char_t *unip, int ulen)
431{
432 char * cp;
433
434 if ((cp = balloc(B_L, ulen+1)) == NULL) {
435 return NULL;
436 }
437 uniToAsc(cp, unip, ulen);
438 cp[ulen] = '\0';
439 return cp;
440}
441
442unsigned int gstrtoi(char_t *s)
443{
444 if (*s == '0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
445 s += 2;
446 return hextoi(s);
447 }
448 return gatoi(s);
449}
450