diff options
author | Ori Bernstein <ori@eigenstate.org> | 2020-05-12 10:48:33 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2020-05-12 10:48:33 -0700 |
commit | 73f38fc5460cb68662dd237022bda636ad734045 (patch) | |
tree | c42700d0d7597ae6c1971643388df9d1a5f37300 /sys/src/ape/lib | |
parent | 27fc79b04bee837f513f8ac92c3e50ae76c27abe (diff) |
[ape] add missing conversion flags for scanf
We're missing type flags for:
hh: char
ll: vlong
z: size_t
t: ptrdiff_t
j: intmax_t
The lack of '%lld' was causing us to fail when parsing
timezone files. This brings us in line with the specifiers
in the C99 standard, section 7.19.6.2p11
Diffstat (limited to 'sys/src/ape/lib')
-rw-r--r-- | sys/src/ape/lib/ap/gen/strtoll.c | 7 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/stdio/vfscanf.c | 29 |
2 files changed, 31 insertions, 5 deletions
diff --git a/sys/src/ape/lib/ap/gen/strtoll.c b/sys/src/ape/lib/ap/gen/strtoll.c index e633d2d08..96e3cf7fc 100644 --- a/sys/src/ape/lib/ap/gen/strtoll.c +++ b/sys/src/ape/lib/ap/gen/strtoll.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <stdint.h> #include <limits.h> #include <errno.h> @@ -101,3 +102,9 @@ Return: return -n; return n; } + +intmax_t +strtoimax(char *nptr, char **endptr, int base) +{ + return strtoll(nptr, endptr, base); +} diff --git a/sys/src/ape/lib/ap/stdio/vfscanf.c b/sys/src/ape/lib/ap/stdio/vfscanf.c index 95c14b7b2..5cbc1fee5 100644 --- a/sys/src/ape/lib/ap/stdio/vfscanf.c +++ b/sys/src/ape/lib/ap/stdio/vfscanf.c @@ -96,7 +96,16 @@ int vfscanf(FILE *f, const char *s, va_list args) } else width=-1; - type=*fmtp=='h' || *fmtp=='l' || *fmtp=='L'?*fmtp++:'n'; + type = 'n'; + if(*fmtp=='h' || *fmtp=='l' || *fmtp=='L' || *fmtp=='j' || *fmtp=='z' || *fmtp=='t') + type = *fmtp++; + if(type == 'l' && *fmtp == 'l'){ + type = 'V'; + fmtp++; + }else if(type == 'h' && *fmtp == 'h'){ + type = 'H'; + fmtp++; + } if(!icvt[*fmtp]) goto NonSpecial; if(!(*icvt[*fmtp])(f, &args, store, width, type)) return ncvt?ncvt:EOF; @@ -137,7 +146,7 @@ icvt_n(FILE *, va_list *args, int store, int, int type) static int icvt_fixed(FILE *f, va_list *args, int store, int width, int type, int unsgned, int base){ - unsigned long int num=0; + unsigned long long num=0; int sign=1, ndig=0, dig; int c; do @@ -194,18 +203,28 @@ Done: switch(unsgned){ case SIGNED: switch(type){ - case 'h': *va_arg(*args, short *)=num*sign; break; - case 'n': *va_arg(*args, int *)=num*sign; break; + case 'H': *va_arg(*args, char *)=num*sign; break; + case 'h': *va_arg(*args, short *)=num*sign; break; + case 'n': *va_arg(*args, int *)=num*sign; break; case 'l': - case 'L': *va_arg(*args, long *)=num*sign; break; + case 'L': *va_arg(*args, long *)=num*sign; break; + case 'j': + case 'V': *va_arg(*args, long long*)=num*sign; break; + case 'z': *va_arg(*args, ssize_t*)=num*sign; break; + case 't': *va_arg(*args, ptrdiff_t*)=num*sign; break; } break; case UNSIGNED: switch(type){ + case 'H': *va_arg(*args, unsigned char *)=num*sign; break; case 'h': *va_arg(*args, unsigned short *)=num*sign; break; case 'n': *va_arg(*args, unsigned int *)=num*sign; break; case 'l': case 'L': *va_arg(*args, unsigned long *)=num*sign; break; + case 'j': + case 'V': *va_arg(*args, unsigned long long *)=num*sign; break; + case 'z': *va_arg(*args, size_t*)=num*sign; break; + case 't': *va_arg(*args, ptrdiff_t*)=num*sign; break; } break; case POINTER: |