Skip to content

Commit 0536b42

Browse files
committed
Add custom printf version
- add `js_snprintf`, `js_printf`... to handle extra conversions: - support for wxx length modifier - support for `%b` and `%B` - `%oa` and `%#oa` to convert `JSAtom` values - `%ps` to convert `JSString` values - add `dbuf_vprintf_fun` replaceable `dbuf_printf` handler - change `JS_DumpString` to `JS_FormatString` to convert `JSSAtom` to quoted strings - change `JS_AtomGetStrRT` to `JS_FormatAtom` to convert `JSAtom` to strings - change `JS_AtomGetStr` to return direct string pointer for builtin atoms - remove `print_atom` - use custom conversions for trace messages and error messages - add support for `%b`, `%B` and `w` length modifier in `std.printf` - remove error handlers: `JS_ThrowTypeErrorAtom` and `JS_ThrowSyntaxErrorAtom` - add `is_lower_ascii()` and `to_lower_ascii()` - add floating point conversions and wide string conversions - unbreak compilation: prevent name collision on pow10 - minimize `vsnprintf` calls in `dbuf_vprintf_default`
1 parent 3eaea6c commit 0536b42

File tree

7 files changed

+1618
-482
lines changed

7 files changed

+1618
-482
lines changed

cutils.c

+102-68
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;
@@ -105,11 +103,6 @@ void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func)
105103
s->realloc_func = realloc_func;
106104
}
107105

108-
void dbuf_init(DynBuf *s)
109-
{
110-
dbuf_init2(s, NULL, NULL);
111-
}
112-
113106
/* return < 0 if error */
114107
int dbuf_realloc(DynBuf *s, size_t new_size)
115108
{
@@ -178,29 +171,59 @@ int dbuf_putstr(DynBuf *s, const char *str)
178171
return dbuf_put(s, (const uint8_t *)str, strlen(str));
179172
}
180173

181-
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
182-
const char *fmt, ...)
174+
static int dbuf_vprintf_default(DynBuf *s, const char *fmt, va_list ap)
183175
{
184-
va_list ap;
185176
char buf[128];
177+
va_list arg;
178+
size_t size, avail, ulen;
186179
int len;
180+
char *dest;
181+
182+
dest = buf;
183+
size = sizeof buf;
184+
avail = s->allocated_size - s->size;
185+
if (avail > size) {
186+
dest = (char *)(s->buf + s->size);
187+
size = avail;
188+
}
189+
va_copy(arg, ap);
190+
len = vsnprintf(dest, size, fmt, arg);
191+
va_end(arg);
187192

188-
va_start(ap, fmt);
189-
len = vsnprintf(buf, sizeof(buf), fmt, ap);
190-
va_end(ap);
191-
if (len < sizeof(buf)) {
192-
/* fast case */
193-
return dbuf_put(s, (uint8_t *)buf, len);
194-
} else {
195-
if (dbuf_realloc(s, s->size + len + 1))
193+
if (len < 0)
194+
return len;
195+
196+
ulen = (size_t)len;
197+
if (ulen >= avail) {
198+
if (dbuf_realloc(s, s->size + ulen + 1))
196199
return -1;
197-
va_start(ap, fmt);
198-
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
199-
fmt, ap);
200-
va_end(ap);
201-
s->size += len;
202200
}
203-
return 0;
201+
if (dest == buf && ulen < sizeof buf) {
202+
memcpy(s->buf + s->size, buf, ulen + 1);
203+
} else
204+
if (ulen >= avail) {
205+
avail = s->allocated_size - s->size;
206+
va_copy(arg, ap);
207+
vsnprintf((char *)(s->buf + s->size), avail, fmt, arg);
208+
va_end(arg);
209+
}
210+
s->size += ulen;
211+
return len;
212+
}
213+
214+
/* replaceable formatter */
215+
int (*dbuf_vprintf_fun)(DynBuf *s, const char *fmt, va_list ap) = dbuf_vprintf_default;
216+
217+
__attribute__((format(printf, 2, 3)))
218+
int dbuf_printf(DynBuf *s, const char *fmt, ...)
219+
{
220+
va_list ap;
221+
int len;
222+
223+
va_start(ap, fmt);
224+
len = (*dbuf_vprintf_fun)(s, fmt, ap);
225+
va_end(ap);
226+
return len;
204227
}
205228

206229
void dbuf_free(DynBuf *s)
@@ -589,6 +612,7 @@ size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_
589612

590613
/* 2 <= base <= 36 */
591614
char const digits36[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
615+
char const digits36_upper[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
592616

593617
#define USE_SPECIAL_RADIX_10 1 // special case base 10 radix conversions
594618
#define USE_SINGLE_CASE_FAST 1 // special case single digit numbers
@@ -600,7 +624,7 @@ char const digits36[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
600624
else \
601625
buf = (buf << 8) | (c)
602626

603-
size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
627+
static size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
604628
{
605629
size_t len = 1;
606630
uint64_t buf = 0;
@@ -615,7 +639,7 @@ size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
615639
return len;
616640
}
617641

618-
size_t u07toa_shift(char dest[minimum_length(8)], uint32_t n, size_t len)
642+
static size_t u07toa_shift(char dest[minimum_length(8)], uint32_t n, size_t len)
619643
{
620644
size_t i;
621645
dest += len;
@@ -641,39 +665,41 @@ size_t u32toa(char buf[minimum_length(11)], uint32_t n)
641665
#define TEN_POW_7 10000000
642666
if (n >= TEN_POW_7) {
643667
uint32_t quo = n / TEN_POW_7;
668+
size_t len;
644669
n %= TEN_POW_7;
645-
size_t len = u7toa_shift(buf, quo);
670+
len = u7toa_shift(buf, quo);
646671
return u07toa_shift(buf, n, len);
647672
}
648673
return u7toa_shift(buf, n);
649674
}
650675

651676
size_t u64toa(char buf[minimum_length(21)], uint64_t n)
652677
{
678+
size_t len;
679+
653680
if (likely(n < 0x100000000))
654-
return u32toa(buf, n);
681+
return u32toa(buf, (uint32_t)n);
655682

656-
size_t len;
657683
if (n >= TEN_POW_7) {
658684
uint64_t n1 = n / TEN_POW_7;
659685
n %= TEN_POW_7;
660686
if (n1 >= TEN_POW_7) {
661-
uint32_t quo = n1 / TEN_POW_7;
687+
uint32_t quo = (uint32_t)(n1 / TEN_POW_7);
662688
n1 %= TEN_POW_7;
663689
len = u7toa_shift(buf, quo);
664-
len = u07toa_shift(buf, n1, len);
690+
len = u07toa_shift(buf, (uint32_t)n1, len);
665691
} else {
666-
len = u7toa_shift(buf, n1);
692+
len = u7toa_shift(buf, (uint32_t)n1);
667693
}
668-
return u07toa_shift(buf, n, len);
694+
return u07toa_shift(buf, (uint32_t)n, len);
669695
}
670-
return u7toa_shift(buf, n);
696+
return u7toa_shift(buf, (uint32_t)n);
671697
}
672698

673699
size_t i32toa(char buf[minimum_length(12)], int32_t n)
674700
{
675701
if (likely(n >= 0))
676-
return u32toa(buf, n);
702+
return u32toa(buf, (uint32_t)n);
677703

678704
buf[0] = '-';
679705
return 1 + u32toa(buf + 1, -(uint32_t)n);
@@ -682,7 +708,7 @@ size_t i32toa(char buf[minimum_length(12)], int32_t n)
682708
size_t i64toa(char buf[minimum_length(22)], int64_t n)
683709
{
684710
if (likely(n >= 0))
685-
return u64toa(buf, n);
711+
return u64toa(buf, (uint64_t)n);
686712

687713
buf[0] = '-';
688714
return 1 + u64toa(buf + 1, -(uint64_t)n);
@@ -713,7 +739,7 @@ size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
713739
shift = radix_shift[base & 63];
714740
if (shift) {
715741
uint32_t mask = (1 << shift) - 1;
716-
size_t len = (32 - clz32(n) + shift - 1) / shift;
742+
size_t len = (size_t)((32 - clz32(n) + shift - 1) / shift);
717743
size_t last = n & mask;
718744
char *end = buf + len;
719745
n >>= shift;
@@ -729,13 +755,14 @@ size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
729755
} else {
730756
size_t len = 2;
731757
size_t last = n % base;
732-
n /= base;
733758
uint32_t nbase = base;
759+
char *end;
760+
n /= base;
734761
while (n >= nbase) {
735762
nbase *= base;
736763
len++;
737764
}
738-
char *end = buf + len;
765+
end = buf + len;
739766
*end-- = '\0';
740767
*end-- = digits36[last];
741768
while (n >= base) {
@@ -762,33 +789,36 @@ size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned base)
762789
buf[0] = digits36[n];
763790
buf[1] = '\0';
764791
return 1;
765-
}
766-
uint64_t mask = (1 << shift) - 1;
767-
size_t len = (64 - clz64(n) + shift - 1) / shift;
768-
size_t last = n & mask;
769-
char *end = buf + len;
770-
n >>= shift;
771-
*end-- = '\0';
772-
*end-- = digits36[last];
773-
while (n >= base) {
774-
size_t quo = n & mask;
792+
} else {
793+
uint64_t mask = (1 << shift) - 1;
794+
size_t len = (size_t)((64 - clz64(n) + shift - 1) / shift);
795+
size_t last = n & mask;
796+
char *end = buf + len;
775797
n >>= shift;
776-
*end-- = digits36[quo];
798+
*end-- = '\0';
799+
*end-- = digits36[last];
800+
while (n >= base) {
801+
size_t quo = n & mask;
802+
n >>= shift;
803+
*end-- = digits36[quo];
804+
}
805+
*end = digits36[n];
806+
return len;
777807
}
778-
*end = digits36[n];
779-
return len;
808+
} else
809+
if (likely(n < 0x100000000)) {
810+
return u32toa_radix(buf, (uint32_t)n, base);
780811
} else {
781-
if (likely(n < 0x100000000))
782-
return u32toa_radix(buf, n, base);
783812
size_t last = n % base;
784-
n /= base;
785813
uint64_t nbase = base;
786814
size_t len = 2;
815+
char *end;
816+
n /= base;
787817
while (n >= nbase) {
788818
nbase *= base;
789819
len++;
790820
}
791-
char *end = buf + len;
821+
end = buf + len;
792822
*end-- = '\0';
793823
*end-- = digits36[last];
794824
while (n >= base) {
@@ -813,7 +843,7 @@ size_t i32toa_radix(char buf[minimum_length(34)], int32_t n, unsigned int base)
813843
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base)
814844
{
815845
if (likely(n >= 0))
816-
return u64toa_radix(buf, n, base);
846+
return u64toa_radix(buf, (uint64_t)n, base);
817847

818848
buf[0] = '-';
819849
return 1 + u64toa_radix(buf + 1, -(uint64_t)n, base);
@@ -1008,7 +1038,14 @@ static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
10081038
/* pointer based version with local stack and insertion sort threshhold */
10091039
void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
10101040
{
1011-
struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
1041+
struct {
1042+
uint8_t *base;
1043+
size_t count;
1044+
int depth;
1045+
#if SIZE_MAX > UINT_MAX
1046+
int pad;
1047+
#endif
1048+
} stack[50], *sp = stack;
10121049
uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
10131050
size_t m4, i, lt, gt, span, span2;
10141051
int c, depth;
@@ -1391,12 +1428,9 @@ int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
13911428
if (r == 0)
13921429
return 0;
13931430

1394-
if (r == ETIMEDOUT)
1395-
return -1;
1396-
1397-
abort();
1431+
if (r != ETIMEDOUT)
1432+
abort();
13981433

1399-
/* Pacify some compilers. */
14001434
return -1;
14011435
}
14021436

0 commit comments

Comments
 (0)