Skip to content

Commit c31580b

Browse files
committed
Improve custom printf
- add `is_lower_ascii()` and `to_lower_ascii()` - fix compilation warnings - simplify `unicode_to_utf8()` - add `digits36_upper` - add floating point conversions - add wide string conversions - improve string conversions
1 parent 075f4bc commit c31580b

File tree

5 files changed

+931
-307
lines changed

5 files changed

+931
-307
lines changed

cutils.c

+107-82
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,19 @@
3535
#include "cutils.h"
3636

3737
#undef NANOSEC
38-
#define NANOSEC ((uint64_t) 1e9)
38+
#define NANOSEC 1000000000
3939

4040
#pragma GCC visibility push(default)
4141

42-
void pstrcpy(char *buf, int buf_size, const char *str)
42+
void pstrcpy(char *buf, size_t buf_size, const char *str)
4343
{
44-
int c;
4544
char *q = buf;
4645

4746
if (buf_size <= 0)
4847
return;
4948

5049
for(;;) {
51-
c = *str++;
50+
char c = *str++;
5251
if (c == 0 || q >= buf + buf_size - 1)
5352
break;
5453
*q++ = c;
@@ -57,10 +56,9 @@ void pstrcpy(char *buf, int buf_size, const char *str)
5756
}
5857

5958
/* strcat and truncate. */
60-
char *pstrcat(char *buf, int buf_size, const char *s)
59+
char *pstrcat(char *buf, size_t buf_size, const char *s)
6160
{
62-
int len;
63-
len = strlen(buf);
61+
size_t len = strlen(buf);
6462
if (len < buf_size)
6563
pstrcpy(buf + len, buf_size - len, s);
6664
return buf;
@@ -189,15 +187,16 @@ static int dbuf_vprintf_default(DynBuf *s, const char *fmt, va_list ap)
189187
va_end(arg);
190188

191189
if (len >= 0) {
192-
if ((size_t)len >= avail) {
193-
if (dbuf_realloc(s, s->size + len + 1))
190+
size_t ulen = (size_t)len;
191+
if (ulen >= avail) {
192+
if (dbuf_realloc(s, s->size + ulen + 1))
194193
return -1;
195194
avail = s->allocated_size - s->size;
196195
va_copy(arg, ap);
197196
vsnprintf((char *)(s->buf + s->size), avail, fmt, arg);
198197
va_end(arg);
199198
}
200-
s->size += len;
199+
s->size += ulen;
201200
}
202201
return len;
203202
}
@@ -231,42 +230,55 @@ void dbuf_free(DynBuf *s)
231230

232231
/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
233232
are output. */
234-
int unicode_to_utf8(uint8_t *buf, unsigned int c)
233+
size_t unicode_to_utf8(uint8_t *buf, unsigned int c)
235234
{
236-
uint8_t *q = buf;
237-
238235
if (c < 0x80) {
239-
*q++ = c;
240-
} else {
241-
if (c < 0x800) {
242-
*q++ = (c >> 6) | 0xc0;
243-
} else {
244-
if (c < 0x10000) {
245-
*q++ = (c >> 12) | 0xe0;
246-
} else {
247-
if (c < 0x00200000) {
248-
*q++ = (c >> 18) | 0xf0;
249-
} else {
250-
if (c < 0x04000000) {
251-
*q++ = (c >> 24) | 0xf8;
252-
} else if (c < 0x80000000) {
253-
*q++ = (c >> 30) | 0xfc;
254-
*q++ = ((c >> 24) & 0x3f) | 0x80;
255-
} else {
256-
return 0;
257-
}
258-
*q++ = ((c >> 18) & 0x3f) | 0x80;
259-
}
260-
*q++ = ((c >> 12) & 0x3f) | 0x80;
261-
}
262-
*q++ = ((c >> 6) & 0x3f) | 0x80;
263-
}
264-
*q++ = (c & 0x3f) | 0x80;
236+
buf[0] = (uint8_t)c;
237+
return 1;
238+
}
239+
if (c < 0x800) {
240+
buf[0] = (uint8_t)((c >> 6) | 0xc0);
241+
buf[1] = (uint8_t)((c & 0x3f) | 0x80);
242+
return 2;
265243
}
266-
return q - buf;
244+
if (c < 0x10000) {
245+
buf[0] = (uint8_t)((c >> 12) | 0xe0);
246+
buf[1] = (uint8_t)(((c >> 6) & 0x3f) | 0x80);
247+
buf[2] = (uint8_t)((c & 0x3f) | 0x80);
248+
return 3;
249+
}
250+
if (c < 0x00200000) {
251+
buf[0] = (uint8_t)((c >> 18) | 0xf0);
252+
buf[1] = (uint8_t)(((c >> 12) & 0x3f) | 0x80);
253+
buf[2] = (uint8_t)(((c >> 6) & 0x3f) | 0x80);
254+
buf[3] = (uint8_t)((c & 0x3f) | 0x80);
255+
return 4;
256+
}
257+
#if 0
258+
if (c < 0x04000000) {
259+
buf[0] = (uint8_t)((c >> 24) | 0xf8);
260+
buf[1] = (uint8_t)(((c >> 18) & 0x3f) | 0x80);
261+
buf[2] = (uint8_t)(((c >> 12) & 0x3f) | 0x80);
262+
buf[3] = (uint8_t)(((c >> 6) & 0x3f) | 0x80);
263+
buf[4] = (uint8_t)((c & 0x3f) | 0x80);
264+
return 5;
265+
}
266+
buf[0] = (uint8_t)((c >> 30) | 0xfc);
267+
buf[1] = (uint8_t)(((c >> 24) & 0x3f) | 0x80);
268+
buf[2] = (uint8_t)(((c >> 18) & 0x3f) | 0x80);
269+
buf[3] = (uint8_t)(((c >> 12) & 0x3f) | 0x80);
270+
buf[4] = (uint8_t)(((c >> 6) & 0x3f) | 0x80);
271+
buf[5] = (uint8_t)((c & 0x3f) | 0x80);
272+
return 6;
273+
#else
274+
buf[0] = (uint8_t)((0xFFFD >> 12) | 0xe0);
275+
buf[1] = (uint8_t)(((0xFFFD >> 6) & 0x3f) | 0x80);
276+
buf[2] = (uint8_t)((0xFFFD & 0x3f) | 0x80);
277+
return 3;
278+
#endif
267279
}
268280

269-
static const unsigned int utf8_min_code[5] = {
281+
static const int utf8_min_code[5] = {
270282
0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
271283
};
272284

@@ -342,6 +354,7 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
342354

343355
/* 2 <= base <= 36 */
344356
char const digits36[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
357+
char const digits36_upper[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
345358

346359
/* using u32toa_shift variant */
347360

@@ -350,7 +363,7 @@ char const digits36[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
350363
else \
351364
buf = (buf << 8) | (c)
352365

353-
size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
366+
static size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
354367
{
355368
size_t len = 1;
356369
uint64_t buf = 0;
@@ -365,7 +378,7 @@ size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
365378
return len;
366379
}
367380

368-
size_t u07toa_shift(char dest[minimum_length(8)], uint32_t n, size_t len)
381+
static size_t u07toa_shift(char dest[minimum_length(8)], uint32_t n, size_t len)
369382
{
370383
size_t i;
371384
dest += len;
@@ -389,39 +402,41 @@ size_t u32toa(char buf[minimum_length(11)], uint32_t n)
389402
#define TEN_POW_7 10000000
390403
if (n >= TEN_POW_7) {
391404
uint32_t quo = n / TEN_POW_7;
405+
size_t len;
392406
n %= TEN_POW_7;
393-
size_t len = u7toa_shift(buf, quo);
407+
len = u7toa_shift(buf, quo);
394408
return u07toa_shift(buf, n, len);
395409
}
396410
return u7toa_shift(buf, n);
397411
}
398412

399413
size_t u64toa(char buf[minimum_length(21)], uint64_t n)
400414
{
415+
size_t len;
416+
401417
if (likely(n < 0x100000000))
402-
return u32toa(buf, n);
418+
return u32toa(buf, (uint32_t)n);
403419

404-
size_t len;
405420
if (n >= TEN_POW_7) {
406421
uint64_t n1 = n / TEN_POW_7;
407422
n %= TEN_POW_7;
408423
if (n1 >= TEN_POW_7) {
409-
uint32_t quo = n1 / TEN_POW_7;
424+
uint32_t quo = (uint32_t)(n1 / TEN_POW_7);
410425
n1 %= TEN_POW_7;
411426
len = u7toa_shift(buf, quo);
412-
len = u07toa_shift(buf, n1, len);
427+
len = u07toa_shift(buf, (uint32_t)n1, len);
413428
} else {
414-
len = u7toa_shift(buf, n1);
429+
len = u7toa_shift(buf, (uint32_t)n1);
415430
}
416-
return u07toa_shift(buf, n, len);
431+
return u07toa_shift(buf, (uint32_t)n, len);
417432
}
418-
return u7toa_shift(buf, n);
433+
return u7toa_shift(buf, (uint32_t)n);
419434
}
420435

421436
size_t i32toa(char buf[minimum_length(12)], int32_t n)
422437
{
423438
if (likely(n >= 0))
424-
return u32toa(buf, n);
439+
return u32toa(buf, (uint32_t)n);
425440

426441
buf[0] = '-';
427442
return 1 + u32toa(buf + 1, -(uint32_t)n);
@@ -430,7 +445,7 @@ size_t i32toa(char buf[minimum_length(12)], int32_t n)
430445
size_t i64toa(char buf[minimum_length(22)], int64_t n)
431446
{
432447
if (likely(n >= 0))
433-
return u64toa(buf, n);
448+
return u64toa(buf, (uint64_t)n);
434449

435450
buf[0] = '-';
436451
return 1 + u64toa(buf + 1, -(uint64_t)n);
@@ -447,6 +462,9 @@ static uint8_t const radix_shift[64] = {
447462

448463
size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
449464
{
465+
int shift;
466+
char *end;
467+
450468
#ifdef USE_SPECIAL_RADIX_10
451469
if (likely(base == 10))
452470
return u32toa(buf, n);
@@ -456,13 +474,13 @@ size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
456474
buf[1] = '\0';
457475
return 1;
458476
}
459-
int shift = radix_shift[base & 63];
477+
shift = radix_shift[base & 63];
460478
if (shift) {
461479
uint32_t mask = (1 << shift) - 1;
462-
size_t len = (32 - clz32(n) + shift - 1) / shift;
480+
size_t len = (size_t)((32 - clz32(n) + shift - 1) / shift);
463481
size_t last = n & mask;
464-
n /= base;
465-
char *end = buf + len;
482+
end = buf + len;
483+
n >>= shift;
466484
*end-- = '\0';
467485
*end-- = digits36[last];
468486
while (n >= base) {
@@ -474,14 +492,14 @@ size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
474492
return len;
475493
} else {
476494
size_t len = 2;
495+
uint32_t nbase = base;
477496
size_t last = n % base;
478497
n /= base;
479-
uint32_t nbase = base;
480498
while (n >= nbase) {
481499
nbase *= base;
482500
len++;
483501
}
484-
char *end = buf + len;
502+
end = buf + len;
485503
*end-- = '\0';
486504
*end-- = digits36[last];
487505
while (n >= base) {
@@ -496,22 +514,24 @@ size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
496514

497515
size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned base)
498516
{
499-
#ifdef USE_SPECIAL_RADIX_10
500-
if (likely(base == 10))
517+
int shift;
518+
char *end;
519+
520+
if (n < base) {
521+
buf[0] = digits36[n];
522+
buf[1] = '\0';
523+
return 1;
524+
}
525+
if (likely(base == 10)) {
501526
return u64toa(buf, n);
502-
#endif
503-
int shift = radix_shift[base & 63];
527+
}
528+
shift = radix_shift[base & 63];
504529
if (shift) {
505-
if (n < base) {
506-
buf[0] = digits36[n];
507-
buf[1] = '\0';
508-
return 1;
509-
}
510530
uint64_t mask = (1 << shift) - 1;
511-
size_t len = (64 - clz64(n) + shift - 1) / shift;
531+
size_t len = (size_t)((64 - clz64(n) + shift - 1) / shift);
512532
size_t last = n & mask;
513-
n /= base;
514-
char *end = buf + len;
533+
end = buf + len;
534+
n >>= shift;
515535
*end-- = '\0';
516536
*end-- = digits36[last];
517537
while (n >= base) {
@@ -521,18 +541,19 @@ size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned base)
521541
}
522542
*end = digits36[n];
523543
return len;
544+
} else
545+
if (likely(n < 0x100000000)) {
546+
return u32toa_radix(buf, (uint32_t)n, base);
524547
} else {
525-
if (likely(n < 0x100000000))
526-
return u32toa_radix(buf, n, base);
527548
size_t last = n % base;
528-
n /= base;
529549
uint64_t nbase = base;
530550
size_t len = 2;
551+
n /= base;
531552
while (n >= nbase) {
532553
nbase *= base;
533554
len++;
534555
}
535-
char *end = buf + len;
556+
end = buf + len;
536557
*end-- = '\0';
537558
*end-- = digits36[last];
538559
while (n >= base) {
@@ -548,7 +569,7 @@ size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned base)
548569
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base)
549570
{
550571
if (likely(n >= 0))
551-
return u64toa_radix(buf, n, base);
572+
return u64toa_radix(buf, (uint64_t)n, base);
552573

553574
buf[0] = '-';
554575
return 1 + u64toa_radix(buf + 1, -(uint64_t)n, base);
@@ -738,7 +759,14 @@ static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
738759
/* pointer based version with local stack and insertion sort threshhold */
739760
void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
740761
{
741-
struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
762+
struct {
763+
uint8_t *base;
764+
size_t count;
765+
int depth;
766+
#if SIZE_MAX > UINT_MAX
767+
int pad;
768+
#endif
769+
} stack[50], *sp = stack;
742770
uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
743771
size_t m4, i, lt, gt, span, span2;
744772
int c, depth;
@@ -1121,12 +1149,9 @@ int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
11211149
if (r == 0)
11221150
return 0;
11231151

1124-
if (r == ETIMEDOUT)
1125-
return -1;
1126-
1127-
abort();
1152+
if (r != ETIMEDOUT)
1153+
abort();
11281154

1129-
/* Pacify some compilers. */
11301155
return -1;
11311156
}
11321157

0 commit comments

Comments
 (0)