From 0c64a71bcdcff8ac3eab55292f245a72703bb90b Mon Sep 17 00:00:00 2001 From: weicheng Date: Thu, 17 Mar 2022 14:41:55 +0800 Subject: [PATCH] update liteos_m porting Signed-off-by: weicheng --- porting/liteos_m/kernel/musl.gni | 7 + .../liteos_m/kernel/src/multibyte/mbrtowc.c | 51 +++ .../liteos_m/kernel/src/multibyte/mbsinit.c | 6 + .../liteos_m/kernel/src/stdio/__string_read.c | 16 + porting/liteos_m/kernel/src/stdio/sscanf.c | 14 + porting/liteos_m/kernel/src/stdio/vfscanf.c | 336 ++++++++++++++++++ porting/liteos_m/kernel/src/stdio/vscanf.c | 9 + porting/liteos_m/kernel/src/stdio/vsscanf.c | 17 + porting/liteos_m/kernel/src/stdlib/strtol.c | 6 + porting/liteos_m/kernel/src/string/strtok_r.c | 12 + 10 files changed, 474 insertions(+) create mode 100644 porting/liteos_m/kernel/src/multibyte/mbrtowc.c create mode 100644 porting/liteos_m/kernel/src/multibyte/mbsinit.c create mode 100644 porting/liteos_m/kernel/src/stdio/__string_read.c create mode 100644 porting/liteos_m/kernel/src/stdio/sscanf.c create mode 100644 porting/liteos_m/kernel/src/stdio/vfscanf.c create mode 100644 porting/liteos_m/kernel/src/stdio/vscanf.c create mode 100644 porting/liteos_m/kernel/src/stdio/vsscanf.c create mode 100644 porting/liteos_m/kernel/src/string/strtok_r.c diff --git a/porting/liteos_m/kernel/musl.gni b/porting/liteos_m/kernel/musl.gni index 0487ba5d..fdd5c9e3 100644 --- a/porting/liteos_m/kernel/musl.gni +++ b/porting/liteos_m/kernel/musl.gni @@ -57,6 +57,8 @@ MUSL_LIBC_SRC = [ "$MUSLPORTINGDIR/src/misc/dirname.c", "$MUSLPORTINGDIR/src/misc/realpath.c", "$MUSLPORTINGDIR/src/multibyte/internal.c", + "$MUSLPORTINGDIR/src/multibyte/mbrtowc.c", + "$MUSLPORTINGDIR/src/multibyte/mbsinit.c", "$MUSLPORTINGDIR/src/multibyte/mbtowc.c", "$MUSLPORTINGDIR/src/multibyte/wcrtomb.c", "$MUSLPORTINGDIR/src/multibyte/wctomb.c", @@ -79,6 +81,7 @@ MUSL_LIBC_SRC = [ "$MUSLPORTINGDIR/src/stdio/__stdio_seek.c", "$MUSLPORTINGDIR/src/stdio/__stdio_write.c", "$MUSLPORTINGDIR/src/stdio/__stdout_write.c", + "$MUSLPORTINGDIR/src/stdio/__string_read.c", "$MUSLPORTINGDIR/src/stdio/__toread.c", "$MUSLPORTINGDIR/src/stdio/__towrite.c", "$MUSLPORTINGDIR/src/stdio/__uflow.c", @@ -102,13 +105,16 @@ MUSL_LIBC_SRC = [ "$MUSLPORTINGDIR/src/stdio/remove.c", "$MUSLPORTINGDIR/src/stdio/rewind.c", "$MUSLPORTINGDIR/src/stdio/snprintf.c", + "$MUSLPORTINGDIR/src/stdio/sscanf.c", "$MUSLPORTINGDIR/src/stdio/stderr.c", "$MUSLPORTINGDIR/src/stdio/stdin.c", "$MUSLPORTINGDIR/src/stdio/stdout.c", "$MUSLPORTINGDIR/src/stdio/ungetc.c", "$MUSLPORTINGDIR/src/stdio/vfprintf.c", + "$MUSLPORTINGDIR/src/stdio/vfscanf.c", "$MUSLPORTINGDIR/src/stdio/vsnprintf.c", "$MUSLPORTINGDIR/src/stdio/vsprintf.c", + "$MUSLPORTINGDIR/src/stdio/vsscanf.c", "$MUSLPORTINGDIR/src/stdlib/abs.c", "$MUSLPORTINGDIR/src/stdlib/atof.c", "$MUSLPORTINGDIR/src/stdlib/atoi.c", @@ -144,6 +150,7 @@ MUSL_LIBC_SRC = [ "$MUSLPORTINGDIR/src/string/strspn.c", "$MUSLPORTINGDIR/src/string/strstr.c", "$MUSLPORTINGDIR/src/string/strtok.c", + "$MUSLPORTINGDIR/src/string/strtok_r.c", "$MUSLPORTINGDIR/src/string/wcschr.c", "$MUSLPORTINGDIR/src/string/wcslen.c", "$MUSLPORTINGDIR/src/time/__month_to_secs.c", diff --git a/porting/liteos_m/kernel/src/multibyte/mbrtowc.c b/porting/liteos_m/kernel/src/multibyte/mbrtowc.c new file mode 100644 index 00000000..c94819e7 --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/mbrtowc.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include "internal.h" + +size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st) +{ + static unsigned internal_state; + unsigned c; + const unsigned char *s = (const void *)src; + const unsigned N = n; + wchar_t dummy; + + if (!st) st = (void *)&internal_state; + c = *(unsigned *)st; + + if (!s) { + if (c) goto ilseq; + return 0; + } else if (!wc) wc = &dummy; + + if (!n) return -2; + if (!c) { + if (*s < 0x80) return !!(*wc = *s); + if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1; + if (*s-SA > SB-SA) goto ilseq; + c = bittab[*s++-SA]; n--; + } + + if (n) { + if (OOB(c,*s)) goto ilseq; +loop: + c = c<<6 | *s++-0x80; n--; + if (!(c&(1U<<31))) { + *(unsigned *)st = 0; + *wc = c; + return N-n; + } + if (n) { + if (*s-0x80u >= 0x40) goto ilseq; + goto loop; + } + } + + *(unsigned *)st = c; + return -2; +ilseq: + *(unsigned *)st = 0; + errno = EILSEQ; + return -1; +} diff --git a/porting/liteos_m/kernel/src/multibyte/mbsinit.c b/porting/liteos_m/kernel/src/multibyte/mbsinit.c new file mode 100644 index 00000000..c608194a --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/mbsinit.c @@ -0,0 +1,6 @@ +#include + +int mbsinit(const mbstate_t *st) +{ + return !st || !*(unsigned *)st; +} diff --git a/porting/liteos_m/kernel/src/stdio/__string_read.c b/porting/liteos_m/kernel/src/stdio/__string_read.c new file mode 100644 index 00000000..7b50a7e1 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/__string_read.c @@ -0,0 +1,16 @@ +#include "stdio_impl.h" +#include + +size_t __string_read(FILE *f, unsigned char *buf, size_t len) +{ + char *src = f->cookie; + size_t k = len+256; + char *end = memchr(src, 0, k); + if (end) k = end-src; + if (k < len) len = k; + memcpy(buf, src, len); + f->rpos = (void *)(src+len); + f->rend = (void *)(src+k); + f->cookie = src+k; + return len; +} diff --git a/porting/liteos_m/kernel/src/stdio/sscanf.c b/porting/liteos_m/kernel/src/stdio/sscanf.c new file mode 100644 index 00000000..f2ac2f5d --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/sscanf.c @@ -0,0 +1,14 @@ +#include +#include + +int sscanf(const char *restrict s, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsscanf(s, fmt, ap); + va_end(ap); + return ret; +} + +weak_alias(sscanf,__isoc99_sscanf); diff --git a/porting/liteos_m/kernel/src/stdio/vfscanf.c b/porting/liteos_m/kernel/src/stdio/vfscanf.c new file mode 100644 index 00000000..9e030fc4 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vfscanf.c @@ -0,0 +1,336 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stdio_impl.h" +#include "shgetc.h" +#include "intscan.h" +#include "floatscan.h" + +#define SIZE_hh -2 +#define SIZE_h -1 +#define SIZE_def 0 +#define SIZE_l 1 +#define SIZE_L 2 +#define SIZE_ll 3 + +static void store_int(void *dest, int size, unsigned long long i) +{ + if (!dest) return; + switch (size) { + case SIZE_hh: + *(char *)dest = i; + break; + case SIZE_h: + *(short *)dest = i; + break; + case SIZE_def: + *(int *)dest = i; + break; + case SIZE_l: + *(long *)dest = i; + break; + case SIZE_ll: + *(long long *)dest = i; + break; + } +} + +static void *arg_n(va_list ap, unsigned int n) +{ + void *p; + unsigned int i; + va_list ap2; + va_copy(ap2, ap); + for (i=n; i>1; i--) va_arg(ap2, void *); + p = va_arg(ap2, void *); + va_end(ap2); + return p; +} + +int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap) +{ + int width; + int size; + int alloc; + int base; + const unsigned char *p; + int c, t; + char *s; + wchar_t *wcs; + mbstate_t st; + void *dest=NULL; + int invert; + int matches=0; + unsigned long long x; + long double y; + off_t pos = 0; + unsigned char scanset[257]; + size_t i, k; + wchar_t wc; + + FLOCK(f); + + for (p=(const unsigned char *)fmt; *p; p++) { + + alloc = 0; + + if (isspace(*p)) { + while (isspace(p[1])) p++; + shlim(f, 0); + while (isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + continue; + } + if (*p != '%' || p[1] == '%') { + shlim(f, 0); + if (*p == '%') { + p++; + while (isspace((c=shgetc(f)))); + } else { + c = shgetc(f); + } + if (c!=*p) { + shunget(f); + if (c<0) goto input_fail; + goto match_fail; + } + pos += shcnt(f); + continue; + } + + p++; + if (*p=='*') { + dest = 0; p++; + } else if (isdigit(*p) && p[1]=='$') { + dest = arg_n(ap, *p-'0'); p+=2; + } else { + dest = va_arg(ap, void *); + } + + for (width=0; isdigit(*p); p++) { + width = 10*width + *p - '0'; + } + + if (*p=='m') { + wcs = 0; + s = 0; + alloc = !!dest; + p++; + } else { + alloc = 0; + } + + size = SIZE_def; + switch (*p++) { + case 'h': + if (*p == 'h') p++, size = SIZE_hh; + else size = SIZE_h; + break; + case 'l': + if (*p == 'l') p++, size = SIZE_ll; + else size = SIZE_l; + break; + case 'j': + size = SIZE_ll; + break; + case 'z': + case 't': + size = SIZE_l; + break; + case 'L': + size = SIZE_L; + break; + case 'd': case 'i': case 'o': case 'u': case 'x': + case 'a': case 'e': case 'f': case 'g': + case 'A': case 'E': case 'F': case 'G': case 'X': + case 's': case 'c': case '[': + case 'S': case 'C': + case 'p': case 'n': + p--; + break; + default: + goto fmt_fail; + } + + t = *p; + + /* C or S */ + if ((t&0x2f) == 3) { + t |= 32; + size = SIZE_l; + } + + switch (t) { + case 'c': + if (width < 1) width = 1; + case '[': + break; + case 'n': + store_int(dest, size, pos); + /* do not increment match count, etc! */ + continue; + default: + shlim(f, 0); + while (isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + } + + shlim(f, width); + if (shgetc(f) < 0) goto input_fail; + shunget(f); + + switch (t) { + case 's': + case 'c': + case '[': + if (t == 'c' || t == 's') { + memset(scanset, -1, sizeof scanset); + scanset[0] = 0; + if (t == 's') { + scanset[1+'\t'] = 0; + scanset[1+'\n'] = 0; + scanset[1+'\v'] = 0; + scanset[1+'\f'] = 0; + scanset[1+'\r'] = 0; + scanset[1+' '] = 0; + } + } else { + if (*++p == '^') p++, invert = 1; + else invert = 0; + memset(scanset, invert, sizeof scanset); + scanset[0] = 0; + if (*p == '-') p++, scanset[1+'-'] = 1-invert; + else if (*p == ']') p++, scanset[1+']'] = 1-invert; + for (; *p != ']'; p++) { + if (!*p) goto fmt_fail; + if (*p=='-' && p[1] && p[1] != ']') + for (c=p++[-1]; c<*p; c++) + scanset[1+c] = 1-invert; + scanset[1+*p] = 1-invert; + } + } + wcs = 0; + s = 0; + i = 0; + k = t=='c' ? width+1U : 31; + if (size == SIZE_l) { + if (alloc) { + wcs = malloc(k*sizeof(wchar_t)); + if (!wcs) goto alloc_fail; + } else { + wcs = dest; + } + st = (mbstate_t){0}; + while (scanset[(c=shgetc(f))+1]) { + switch (mbrtowc(&wc, &(char){c}, 1, &st)) { + case -1: + goto input_fail; + case -2: + continue; + } + if (wcs) wcs[i++] = wc; + if (alloc && i==k) { + k+=k+1; + wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t)); + if (!tmp) goto alloc_fail; + wcs = tmp; + } + } + if (!mbsinit(&st)) goto input_fail; + } else if (alloc) { + s = malloc(k); + if (!s) goto alloc_fail; + while (scanset[(c=shgetc(f))+1]) { + s[i++] = c; + if (i==k) { + k+=k+1; + char *tmp = realloc(s, k); + if (!tmp) goto alloc_fail; + s = tmp; + } + } + } else if ((s = dest)) { + while (scanset[(c=shgetc(f))+1]) + s[i++] = c; + } else { + while (scanset[(c=shgetc(f))+1]); + } + shunget(f); + if (!shcnt(f)) goto match_fail; + if (t == 'c' && shcnt(f) != width) goto match_fail; + if (alloc) { + if (size == SIZE_l) *(wchar_t **)dest = wcs; + else *(char **)dest = s; + } + if (t != 'c') { + if (wcs) wcs[i] = 0; + if (s) s[i] = 0; + } + break; + case 'p': + case 'X': + case 'x': + base = 16; + goto int_common; + case 'o': + base = 8; + goto int_common; + case 'd': + case 'u': + base = 10; + goto int_common; + case 'i': + base = 0; + int_common: + x = __intscan(f, base, 0, ULLONG_MAX); + if (!shcnt(f)) goto match_fail; + if (t=='p' && dest) *(void **)dest = (void *)(uintptr_t)x; + else store_int(dest, size, x); + break; + case 'a': case 'A': + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': + y = __floatscan(f, size, 0); + if (!shcnt(f)) goto match_fail; + if (dest) switch (size) { + case SIZE_def: + *(float *)dest = y; + break; + case SIZE_l: + *(double *)dest = y; + break; + case SIZE_L: + *(long double *)dest = y; + break; + } + break; + } + + pos += shcnt(f); + if (dest) matches++; + } + if (0) { +fmt_fail: +alloc_fail: +input_fail: + if (!matches) matches--; +match_fail: + if (alloc) { + free(s); + free(wcs); + } + } + FUNLOCK(f); + return matches; +} + +weak_alias(vfscanf,__isoc99_vfscanf); diff --git a/porting/liteos_m/kernel/src/stdio/vscanf.c b/porting/liteos_m/kernel/src/stdio/vscanf.c new file mode 100644 index 00000000..9d46ab09 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vscanf.c @@ -0,0 +1,9 @@ +#include +#include + +int vscanf(const char *restrict fmt, va_list ap) +{ + return vfscanf(stdin, fmt, ap); +} + +weak_alias(vscanf,__isoc99_vscanf); diff --git a/porting/liteos_m/kernel/src/stdio/vsscanf.c b/porting/liteos_m/kernel/src/stdio/vsscanf.c new file mode 100644 index 00000000..98500225 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vsscanf.c @@ -0,0 +1,17 @@ +#include "stdio_impl.h" + +static size_t do_read(FILE *f, unsigned char *buf, size_t len) +{ + return __string_read(f, buf, len); +} + +int vsscanf(const char *restrict s, const char *restrict fmt, va_list ap) +{ + FILE f = { + .buf = (void *)s, .cookie = (void *)s, + .read = do_read, .lock = -1 + }; + return vfscanf(&f, fmt, ap); +} + +weak_alias(vsscanf,__isoc99_vsscanf); diff --git a/porting/liteos_m/kernel/src/stdlib/strtol.c b/porting/liteos_m/kernel/src/stdlib/strtol.c index 4a3f7942..ceccfbf0 100644 --- a/porting/liteos_m/kernel/src/stdlib/strtol.c +++ b/porting/liteos_m/kernel/src/stdlib/strtol.c @@ -23,6 +23,11 @@ unsigned long long strtoull(const char *restrict s, char **restrict p, int base) return strtox(s, p, base, ULLONG_MAX); } +long long strtoll(const char *restrict s, char **restrict p, int base) +{ + return strtox(s, p, base, LLONG_MIN); +} + unsigned long strtoul(const char *restrict s, char **restrict p, int base) { return strtox(s, p, base, ULONG_MAX); @@ -34,5 +39,6 @@ long strtol(const char *restrict s, char **restrict p, int base) } weak_alias(strtol, __strtol_internal); +weak_alias(strtoll, __strtoll_internal); weak_alias(strtoul, __strtoul_internal); weak_alias(strtoull, __strtoull_internal); diff --git a/porting/liteos_m/kernel/src/string/strtok_r.c b/porting/liteos_m/kernel/src/string/strtok_r.c new file mode 100644 index 00000000..862d4fe4 --- /dev/null +++ b/porting/liteos_m/kernel/src/string/strtok_r.c @@ -0,0 +1,12 @@ +#include + +char *strtok_r(char *restrict s, const char *restrict sep, char **restrict p) +{ + if (!s && !(s = *p)) return NULL; + s += strspn(s, sep); + if (!*s) return *p = 0; + *p = s + strcspn(s, sep); + if (**p) *(*p)++ = 0; + else *p = 0; + return s; +} -- GitLab