From d4ad1a7a9dd6f2ee1cc8586f81ac22e261141c88 Mon Sep 17 00:00:00 2001 From: silen Date: Thu, 12 Aug 2021 12:47:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20L0=20arm-qemu=E5=89=A5=E7=A6=BB?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E9=93=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ieb45066f200d0da1d28367ec4fac2e9c33378dc5 Signed-off-by: silen --- porting/liteos_m/kernel/BUILD.gn | 160 ++-- porting/liteos_m/kernel/src/math/frexp.c | 23 + porting/liteos_m/kernel/src/math/frexpl.c | 29 + .../liteos_m/kernel/src/multibyte/internal.c | 26 + .../liteos_m/kernel/src/multibyte/internal.h | 24 + .../liteos_m/kernel/src/multibyte/mbtowc.c | 47 ++ .../liteos_m/kernel/src/multibyte/wcrtomb.c | 37 + .../liteos_m/kernel/src/multibyte/wctomb.c | 8 + .../liteos_m/kernel/src/stdio/__overflow.c | 10 + porting/liteos_m/kernel/src/stdio/fgetc.c | 7 + porting/liteos_m/kernel/src/stdio/fputc.c | 7 + porting/liteos_m/kernel/src/stdio/putc.h | 18 + porting/liteos_m/kernel/src/stdio/remove.c | 11 + porting/liteos_m/kernel/src/stdio/snprintf.c | 8 + porting/liteos_m/kernel/src/stdio/vfprintf.c | 711 ++++++++++++++++++ porting/liteos_m/kernel/src/stdio/vprintf.c | 6 + porting/liteos_m/kernel/src/stdio/vsnprintf.c | 57 ++ porting/liteos_m/kernel/src/stdio/vsprintf.c | 7 + porting/liteos_m/kernel/src/string/strnlen.c | 7 + porting/liteos_m/kernel/src/time/asctime.c | 7 + porting/liteos_m/kernel/src/time/asctime_r.c | 28 + porting/liteos_m/kernel/src/time/ctime.c | 8 + 22 files changed, 1173 insertions(+), 73 deletions(-) create mode 100755 porting/liteos_m/kernel/src/math/frexp.c create mode 100755 porting/liteos_m/kernel/src/math/frexpl.c create mode 100755 porting/liteos_m/kernel/src/multibyte/internal.c create mode 100755 porting/liteos_m/kernel/src/multibyte/internal.h create mode 100755 porting/liteos_m/kernel/src/multibyte/mbtowc.c create mode 100755 porting/liteos_m/kernel/src/multibyte/wcrtomb.c create mode 100755 porting/liteos_m/kernel/src/multibyte/wctomb.c create mode 100755 porting/liteos_m/kernel/src/stdio/__overflow.c create mode 100755 porting/liteos_m/kernel/src/stdio/fgetc.c create mode 100755 porting/liteos_m/kernel/src/stdio/fputc.c create mode 100755 porting/liteos_m/kernel/src/stdio/putc.h create mode 100755 porting/liteos_m/kernel/src/stdio/remove.c create mode 100755 porting/liteos_m/kernel/src/stdio/snprintf.c create mode 100755 porting/liteos_m/kernel/src/stdio/vfprintf.c create mode 100755 porting/liteos_m/kernel/src/stdio/vprintf.c create mode 100755 porting/liteos_m/kernel/src/stdio/vsnprintf.c create mode 100755 porting/liteos_m/kernel/src/stdio/vsprintf.c create mode 100755 porting/liteos_m/kernel/src/string/strnlen.c create mode 100755 porting/liteos_m/kernel/src/time/asctime.c create mode 100755 porting/liteos_m/kernel/src/time/asctime_r.c create mode 100755 porting/liteos_m/kernel/src/time/ctime.c diff --git a/porting/liteos_m/kernel/BUILD.gn b/porting/liteos_m/kernel/BUILD.gn index 35e47c56..37b172e1 100644 --- a/porting/liteos_m/kernel/BUILD.gn +++ b/porting/liteos_m/kernel/BUILD.gn @@ -31,101 +31,113 @@ libc = "musl-c" libm = "musl-m" config("include") { - include_dirs = [ - "include", - ] + include_dirs = [ "include" ] } static_library(libc) { sources = [ - #"src/errno/strerror.c", - "src/internal/shgetc.c", - "src/internal/intscan.c", - "src/stdlib/atoi.c", - #"src/stdlib/strtol.c", - "src/stdlib/atol.c", - "src/stdlib/atoll.c", - "src/stdlib/abs.c", - "src/network/h_errno.c", - "src/network/htonl.c", - "src/network/htons.c", - "src/network/ntohl.c", - "src/network/ntohs.c", - "src/exit/abort.c", - "src/exit/assert.c", + "src/ctype/__ctype_get_mb_cur_max.c", + "src/ctype/isalnum.c", "src/ctype/isascii.c", - "src/ctype/isxdigit.c", "src/ctype/isdigit.c", - "src/ctype/isupper.c", - "src/ctype/isspace.c", - "src/ctype/isalnum.c", "src/ctype/islower.c", + "src/ctype/isprint.c", + "src/ctype/isspace.c", + "src/ctype/isupper.c", + "src/ctype/isxdigit.c", "src/ctype/tolower.c", "src/ctype/toupper.c", - "src/ctype/isprint.c", - "src/ctype/__ctype_get_mb_cur_max.c", - "src/misc/dirname.c", + "src/errno/strerror.c", + "src/exit/abort.c", + "src/exit/assert.c", + "src/internal/intscan.c", + "src/internal/shgetc.c", "src/locale/__lctrans.c", - "src/locale/langinfo.c", "src/locale/c_locale.c", - "src/stdio/fputs.c", + "src/locale/langinfo.c", + "src/misc/dirname.c", + "src/multibyte/wcrtomb.c", + "src/multibyte/wctomb.c", + "src/network/h_errno.c", + "src/network/htonl.c", + "src/network/htons.c", + "src/network/ntohl.c", + "src/network/ntohs.c", + "src/prng/random.c", + "src/regex/regcomp.c", + "src/regex/regexec.c", + "src/regex/tre-mem.c", + "src/stdio/__fdopen.c", + "src/stdio/__fmodeflags.c", + "src/stdio/__lockfile.c", + "src/stdio/__overflow.c", "src/stdio/__stdio_close.c", - "src/stdio/fflush.c", - "src/stdio/__toread.c", - "src/stdio/ofl_add.c", - "src/stdio/__stdio_seek.c", - "src/stdio/__uflow.c", - "src/stdio/ftell.c", "src/stdio/__stdio_read.c", - "src/stdio/fwrite.c", - "src/stdio/fread.c", - "src/stdio/fclose.c", - "src/stdio/stderr.c", - "src/stdio/fileno.c", - "src/stdio/perror.c", - "src/stdio/__lockfile.c", - "src/stdio/fgets.c", - "src/stdio/clearerr.c", + "src/stdio/__stdio_seek.c", "src/stdio/__stdio_write.c", - "src/stdio/__fmodeflags.c", - "src/stdio/__fdopen.c", - "src/stdio/ofl.c", - "src/stdio/fseek.c", "src/stdio/__stdout_write.c", - "src/stdio/rewind.c", + "src/stdio/__toread.c", "src/stdio/__towrite.c", + "src/stdio/__uflow.c", + "src/stdio/clearerr.c", + "src/stdio/fclose.c", "src/stdio/feof.c", + "src/stdio/fflush.c", + "src/stdio/fgets.c", + "src/stdio/fileno.c", "src/stdio/fopen.c", - "src/stdio/stdout.c", + "src/stdio/fputc.c", + "src/stdio/fputs.c", + "src/stdio/fread.c", + "src/stdio/fseek.c", + "src/stdio/ftell.c", + "src/stdio/fwrite.c", + "src/stdio/ofl.c", + "src/stdio/ofl_add.c", + "src/stdio/perror.c", + "src/stdio/remove.c", + "src/stdio/rewind.c", + "src/stdio/snprintf.c", + "src/stdio/stderr.c", "src/stdio/stdin.c", - "src/time/strptime.c", - "src/time/strftime.c", - "src/time/__year_to_secs.c", - "src/time/__month_to_secs.c", - "src/time/__tz.c", - "src/time/__tm_to_secs.c", - "src/prng/random.c", - "src/regex/regexec.c", - "src/regex/regcomp.c", - "src/regex/tre-mem.c", - "src/string/strrchr.c", + "src/stdio/stdout.c", + "src/stdio/vfprintf.c", + "src/stdio/vsnprintf.c", + "src/stdio/vsprintf.c", + "src/stdlib/abs.c", + "src/stdlib/atoi.c", + + #"src/stdlib/strtol.c", + "src/stdlib/atol.c", + "src/stdlib/atoll.c", + "src/string/memchr.c", "src/string/memcmp.c", - "src/string/strcspn.c", - "src/string/strstr.c", - "src/string/strchrnul.c", - "src/string/strchr.c", "src/string/memcpy.c", - "src/string/strncmp.c", + "src/string/memrchr.c", + "src/string/memset.c", "src/string/strcasecmp.c", + "src/string/strchr.c", + "src/string/strchrnul.c", "src/string/strcmp.c", - "src/string/strncasecmp.c", - "src/string/memchr.c", - "src/string/memrchr.c", + "src/string/strcspn.c", "src/string/strdup.c", - "src/string/wcslen.c", - "src/string/memset.c", "src/string/strlen.c", + "src/string/strncasecmp.c", + "src/string/strncmp.c", + "src/string/strnlen.c", + "src/string/strrchr.c", + "src/string/strstr.c", "src/string/wcschr.c", + "src/string/wcslen.c", + "src/time/__month_to_secs.c", + "src/time/__tm_to_secs.c", + "src/time/__tz.c", + "src/time/__year_to_secs.c", + "src/time/asctime.c", + "src/time/asctime_r.c", + "src/time/ctime.c", + "src/time/strftime.c", + "src/time/strptime.c", ] include_dirs = [ @@ -144,13 +156,15 @@ static_library(libc) { static_library(libm) { sources = [ - "src/math/pow.c", + "src/math/exp_data.c", + "src/math/frexp.c", + "src/math/frexpl.c", "src/math/log.c", - "src/math/sqrt.c", - "src/math/pow_data.c", "src/math/log_data.c", - "src/math/exp_data.c", + "src/math/pow.c", + "src/math/pow_data.c", "src/math/round.c", + "src/math/sqrt.c", ] include_dirs = [ diff --git a/porting/liteos_m/kernel/src/math/frexp.c b/porting/liteos_m/kernel/src/math/frexp.c new file mode 100755 index 00000000..27b6266e --- /dev/null +++ b/porting/liteos_m/kernel/src/math/frexp.c @@ -0,0 +1,23 @@ +#include +#include + +double frexp(double x, int *e) +{ + union { double d; uint64_t i; } y = { x }; + int ee = y.i>>52 & 0x7ff; + + if (!ee) { + if (x) { + x = frexp(x*0x1p64, e); + *e -= 64; + } else *e = 0; + return x; + } else if (ee == 0x7ff) { + return x; + } + + *e = ee - 0x3fe; + y.i &= 0x800fffffffffffffull; + y.i |= 0x3fe0000000000000ull; + return y.d; +} diff --git a/porting/liteos_m/kernel/src/math/frexpl.c b/porting/liteos_m/kernel/src/math/frexpl.c new file mode 100755 index 00000000..3c1b5537 --- /dev/null +++ b/porting/liteos_m/kernel/src/math/frexpl.c @@ -0,0 +1,29 @@ +#include "libm.h" + +#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 +long double frexpl(long double x, int *e) +{ + return frexp(x, e); +} +#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 +long double frexpl(long double x, int *e) +{ + union ldshape u = {x}; + int ee = u.i.se & 0x7fff; + + if (!ee) { + if (x) { + x = frexpl(x*0x1p120, e); + *e -= 120; + } else *e = 0; + return x; + } else if (ee == 0x7fff) { + return x; + } + + *e = ee - 0x3ffe; + u.i.se &= 0x8000; + u.i.se |= 0x3ffe; + return u.f; +} +#endif diff --git a/porting/liteos_m/kernel/src/multibyte/internal.c b/porting/liteos_m/kernel/src/multibyte/internal.c new file mode 100755 index 00000000..2f5aaa91 --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/internal.c @@ -0,0 +1,26 @@ +#include "internal.h" + +#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) ) +#define D(x) C((x+16)) +#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \ + x==0xd ? R(0x80,0xa0) : \ + R(0x80,0xc0) ) \ + | ( R(0x80,0xc0) >> 6 ) \ + | x ) +#define F(x) ( ( x>=5 ? 0 : \ + x==0 ? R(0x90,0xc0) : \ + x==4 ? R(0x80,0x90) : \ + R(0x80,0xc0) ) \ + | ( R(0x80,0xc0) >> 6 ) \ + | ( R(0x80,0xc0) >> 12 ) \ + | x ) + +const uint32_t bittab[] = { + C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7), + C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf), + D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7), + D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf), + E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7), + E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf), + F(0x0),F(0x1),F(0x2),F(0x3),F(0x4) +}; diff --git a/porting/liteos_m/kernel/src/multibyte/internal.h b/porting/liteos_m/kernel/src/multibyte/internal.h new file mode 100755 index 00000000..45bbc6d0 --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/internal.h @@ -0,0 +1,24 @@ +#define bittab __fsmu8 + +#include +#include + +extern hidden const uint32_t bittab[]; + +/* Upper 6 state bits are a negative integer offset to bound-check next byte */ +/* equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f */ +#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7) + +/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */ +#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23)) +#define FAILSTATE R(0x80,0x80) + +#define SA 0xc2u +#define SB 0xf4u + +/* Arbitrary encoding for representing code units instead of characters. */ +#define CODEUNIT(c) (0xdfff & (signed char)(c)) +#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80) + +/* Get inline definition of MB_CUR_MAX. */ +#include "locale_impl.h" diff --git a/porting/liteos_m/kernel/src/multibyte/mbtowc.c b/porting/liteos_m/kernel/src/multibyte/mbtowc.c new file mode 100755 index 00000000..87fb5ba3 --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/mbtowc.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "internal.h" + +int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n) +{ + unsigned c; + const unsigned char *s = (const void *)src; + wchar_t dummy; + + if (!s) return 0; + if (!n) goto ilseq; + if (!wc) wc = &dummy; + + 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]; + + /* Avoid excessive checks against n: If shifting the state n-1 + * times does not clear the high bit, then the value of n is + * insufficient to read a character */ + if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq; + + if (OOB(c,*s)) goto ilseq; + c = (c<<6) | (*s++-0x80); + if (!(c&(1U<<31))) { + *wc = c; + return 2; + } + + if (*s-0x80u >= 0x40) goto ilseq; + c = (c<<6) | (*s++-0x80); + if (!(c&(1U<<31))) { + *wc = c; + return 3; + } + + if (*s-0x80u >= 0x40) goto ilseq; + *wc = (c<<6) | (*s++-0x80); + return 4; + +ilseq: + errno = EILSEQ; + return -1; +} diff --git a/porting/liteos_m/kernel/src/multibyte/wcrtomb.c b/porting/liteos_m/kernel/src/multibyte/wcrtomb.c new file mode 100755 index 00000000..8e34926e --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/wcrtomb.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include "internal.h" + +size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st) +{ + if (!s) return 1; + if ((unsigned)wc < 0x80) { + *s = wc; + return 1; + } else if (MB_CUR_MAX == 1) { + if (!IS_CODEUNIT(wc)) { + errno = EILSEQ; + return -1; + } + *s = wc; + return 1; + } else if ((unsigned)wc < 0x800) { + *s++ = 0xc0 | (wc>>6); + *s = 0x80 | (wc&0x3f); + return 2; + } else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) { + *s++ = 0xe0 | (wc>>12); + *s++ = 0x80 | ((wc>>6)&0x3f); + *s = 0x80 | (wc&0x3f); + return 3; + } else if ((unsigned)wc-0x10000 < 0x100000) { + *s++ = 0xf0 | (wc>>18); + *s++ = 0x80 | ((wc>>12)&0x3f); + *s++ = 0x80 | ((wc>>6)&0x3f); + *s = 0x80 | (wc&0x3f); + return 4; + } + errno = EILSEQ; + return -1; +} diff --git a/porting/liteos_m/kernel/src/multibyte/wctomb.c b/porting/liteos_m/kernel/src/multibyte/wctomb.c new file mode 100755 index 00000000..bad41c5e --- /dev/null +++ b/porting/liteos_m/kernel/src/multibyte/wctomb.c @@ -0,0 +1,8 @@ +#include +#include + +int wctomb(char *s, wchar_t wc) +{ + if (!s) return 0; + return wcrtomb(s, wc, 0); +} diff --git a/porting/liteos_m/kernel/src/stdio/__overflow.c b/porting/liteos_m/kernel/src/stdio/__overflow.c new file mode 100755 index 00000000..e65a594d --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/__overflow.c @@ -0,0 +1,10 @@ +#include "stdio_impl.h" + +int __overflow(FILE *f, int _c) +{ + unsigned char c = _c; + if (!f->wend && __towrite(f)) return EOF; + if (f->wpos != f->wend && c != f->lbf) return *f->wpos++ = c; + if (f->write(f, &c, 1)!=1) return EOF; + return c; +} diff --git a/porting/liteos_m/kernel/src/stdio/fgetc.c b/porting/liteos_m/kernel/src/stdio/fgetc.c new file mode 100755 index 00000000..2578afcc --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/fgetc.c @@ -0,0 +1,7 @@ +#include +#include "getc.h" + +int fgetc(FILE *f) +{ + return do_getc(f); +} diff --git a/porting/liteos_m/kernel/src/stdio/fputc.c b/porting/liteos_m/kernel/src/stdio/fputc.c new file mode 100755 index 00000000..f364ed38 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/fputc.c @@ -0,0 +1,7 @@ +#include +#include "putc.h" + +int fputc(int c, FILE *f) +{ + return do_putc(c, f); +} diff --git a/porting/liteos_m/kernel/src/stdio/putc.h b/porting/liteos_m/kernel/src/stdio/putc.h new file mode 100755 index 00000000..332495a1 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/putc.h @@ -0,0 +1,18 @@ +#include "stdio_impl.h" +#include "pthread_impl.h" + +#ifdef __GNUC__ +__attribute__((__noinline__)) +#endif +static int locking_putc(int c, FILE *f) +{ + FLOCK(f); + c = putc_unlocked(c, f); + FUNLOCK(f); + return c; +} + +static inline int do_putc(int c, FILE *f) +{ + return locking_putc(c, f); +} diff --git a/porting/liteos_m/kernel/src/stdio/remove.c b/porting/liteos_m/kernel/src/stdio/remove.c new file mode 100755 index 00000000..84549a56 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/remove.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +int remove(const char *path) +{ + int r = unlink(path); + if (r==-EISDIR) r = rmdir(path); + return r; +} diff --git a/porting/liteos_m/kernel/src/stdio/snprintf.c b/porting/liteos_m/kernel/src/stdio/snprintf.c new file mode 100755 index 00000000..127c9557 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/snprintf.c @@ -0,0 +1,8 @@ +#include +#include + +int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) +{ + return 0; +} + diff --git a/porting/liteos_m/kernel/src/stdio/vfprintf.c b/porting/liteos_m/kernel/src/stdio/vfprintf.c new file mode 100755 index 00000000..f4371ae5 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vfprintf.c @@ -0,0 +1,711 @@ +#include "stdio_impl.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Some useful macros */ + +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +/* Convenient bit representation for modifier flags, which all fall + * within 31 codepoints of the space character. */ + +#define ALT_FORM (1U<<('#'-' ')) +#define ZERO_PAD (1U<<('0'-' ')) +#define LEFT_ADJ (1U<<('-'-' ')) +#define PAD_POS (1U<<(' '-' ')) +#define MARK_POS (1U<<('+'-' ')) +#define GROUPED (1U<<('\''-' ')) + +#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED) + +/* Redefine the CHAR type that defined in los_typedef.h and introduced + * in by limit.h to avoid conflicts with the following enum definition. */ +#define CHAR _CHAR + +/* State machine to accept length modifiers + conversion specifiers. + * Result is 0 on failure, or an argument type to pop on success. */ + +enum { + BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE, + ZTPRE, JPRE, + STOP, + PTR, INT, UINT, ULLONG, + LONG, ULONG, + SHORT, USHORT, CHAR, UCHAR, + LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR, + DBL, LDBL, + NOARG, + MAXSTATE +}; + +#define S(x) [(x)-'A'] + +static const unsigned char states[]['z'-'A'+1] = { + { /* 0: bare types */ + S('d') = INT, S('i') = INT, + S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT, + S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, + S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, + S('c') = CHAR, S('C') = INT, + S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, + S('m') = NOARG, + S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, + S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, + }, { /* 1: l-prefixed */ + S('d') = LONG, S('i') = LONG, + S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG, + S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, + S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, + S('c') = INT, S('s') = PTR, S('n') = PTR, + S('l') = LLPRE, + }, { /* 2: ll-prefixed */ + S('d') = LLONG, S('i') = LLONG, + S('o') = ULLONG, S('u') = ULLONG, + S('x') = ULLONG, S('X') = ULLONG, + S('n') = PTR, + }, { /* 3: h-prefixed */ + S('d') = SHORT, S('i') = SHORT, + S('o') = USHORT, S('u') = USHORT, + S('x') = USHORT, S('X') = USHORT, + S('n') = PTR, + S('h') = HHPRE, + }, { /* 4: hh-prefixed */ + S('d') = CHAR, S('i') = CHAR, + S('o') = UCHAR, S('u') = UCHAR, + S('x') = UCHAR, S('X') = UCHAR, + S('n') = PTR, + }, { /* 5: L-prefixed */ + S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL, + S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL, + S('n') = PTR, + }, { /* 6: z- or t-prefixed (assumed to be same size) */ + S('d') = PDIFF, S('i') = PDIFF, + S('o') = SIZET, S('u') = SIZET, + S('x') = SIZET, S('X') = SIZET, + S('n') = PTR, + }, { /* 7: j-prefixed */ + S('d') = IMAX, S('i') = IMAX, + S('o') = UMAX, S('u') = UMAX, + S('x') = UMAX, S('X') = UMAX, + S('n') = PTR, + } +}; + +#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A') + +union arg +{ + uintmax_t i; + long double f; + void *p; +}; + +static void pop_arg(union arg *arg, int type, va_list *ap) +{ + switch (type) { + case PTR: arg->p = va_arg(*ap, void *); + break; case INT: arg->i = va_arg(*ap, int); + break; case UINT: arg->i = va_arg(*ap, unsigned int); + break; case LONG: arg->i = va_arg(*ap, long); + break; case ULONG: arg->i = va_arg(*ap, unsigned long); + break; case ULLONG: arg->i = va_arg(*ap, unsigned long long); + break; case SHORT: arg->i = (short)va_arg(*ap, int); + break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int); + break; case CHAR: arg->i = (signed char)va_arg(*ap, int); + break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int); + break; case LLONG: arg->i = va_arg(*ap, long long); + break; case SIZET: arg->i = va_arg(*ap, size_t); + break; case IMAX: arg->i = va_arg(*ap, intmax_t); + break; case UMAX: arg->i = va_arg(*ap, uintmax_t); + break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); + break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); + break; case DBL: arg->f = va_arg(*ap, double); + break; case LDBL: arg->f = va_arg(*ap, long double); + } +} + +static void out(FILE *f, const char *s, size_t l) +{ + if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f); +} + +static void pad(FILE *f, char c, int w, int l, int fl) +{ + char pad[256]; + if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; + l = w - l; + memset(pad, c, l>sizeof pad ? sizeof pad : l); + for (; l >= sizeof pad; l -= sizeof pad) + out(f, pad, sizeof pad); + out(f, pad, l); +} + +static const char xdigits[16] = { + "0123456789ABCDEF" +}; + +static char *fmt_x(uintmax_t x, char *s, int lower) +{ + for (; x; x>>=4) *--s = xdigits[(x&15)]|lower; + return s; +} + +static char *fmt_o(uintmax_t x, char *s) +{ + for (; x; x>>=3) *--s = '0' + (x&7); + return s; +} + +static char *fmt_u(uintmax_t x, char *s) +{ + unsigned long y; + for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10; + for (y=x; y; y/=10) *--s = '0' + y%10; + return s; +} + +/* Do not override this check. The floating point printing code below + * depends on the float.h constants being right. If they are wrong, it + * may overflow the stack. */ +#if LDBL_MANT_DIG == 53 +// typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; +#endif + +static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) +{ + uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion + + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion + uint32_t *a, *d, *r, *z; + int e2=0, e, i, j, l; + char buf[9+LDBL_MANT_DIG/4], *s; + const char *prefix="-0X+0X 0X-0x+0x 0x"; + int pl; + char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)]; + char *estr = NULL; + + pl=1; + if (signbit(y)) { + y=-y; + } else if (fl & MARK_POS) { + prefix+=3; + } else if (fl & PAD_POS) { + prefix+=6; + } else prefix++, pl=0; + + if (!isfinite(y)) { + char *s = (t&32)?"inf":"INF"; + if (y!=y) s=(t&32)?"nan":"NAN"; + pad(f, ' ', w, 3+pl, fl&~ZERO_PAD); + out(f, prefix, pl); + out(f, s, 3); + pad(f, ' ', w, 3+pl, fl^LEFT_ADJ); + return MAX(w, 3+pl); + } + + y = frexpl(y, &e2) * 2; + if (y) e2--; + + if ((t|32)=='a') { + long double round = 8.0; + int re; + + if (t&32) prefix += 9; + pl += 2; + + if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; + else re=LDBL_MANT_DIG/4-1-p; + + if (re) { + round *= 1<<(LDBL_MANT_DIG%4); + while (re--) round*=16; + if (*prefix=='-') { + y=-y; + y-=round; + y+=round; + y=-y; + } else { + y+=round; + y-=round; + } + } + + estr=fmt_u(e2<0 ? -e2 : e2, ebuf); + if (estr==ebuf) *--estr='0'; + *--estr = (e2<0 ? '-' : '+'); + *--estr = t+('p'-'a'); + + s=buf; + do { + int x=y; + *s++=xdigits[x]|(t&32); + y=16*(y-x); + if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; + } while (y); + + if (p > INT_MAX-2-(ebuf-estr)-pl) + return -1; + if (p && s-buf-2 < p) + l = (p+2) + (ebuf-estr); + else + l = (s-buf) + (ebuf-estr); + + pad(f, ' ', w, pl+l, fl); + out(f, prefix, pl); + pad(f, '0', w, pl+l, fl^ZERO_PAD); + out(f, buf, s-buf); + pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); + out(f, estr, ebuf-estr); + pad(f, ' ', w, pl+l, fl^LEFT_ADJ); + return MAX(w, pl+l); + } + if (p<0) p=6; + + if (y) y *= 0x1p28, e2-=28; + + if (e2<0) a=r=z=big; + else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; + + do { + *z = y; + y = 1000000000*(y-*z++); + } while (y); + + while (e2>0) { + uint32_t carry=0; + int sh=MIN(29,e2); + for (d=z-1; d>=a; d--) { + uint64_t x = ((uint64_t)*d<a && !z[-1]) z--; + e2-=sh; + } + while (e2<0) { + uint32_t carry=0, *b; + int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3U+8)/9; + for (d=a; d>sh) + carry; + carry = (1000000000>>sh) * rm; + } + if (!*a) a++; + if (carry) *z++ = carry; + /* Avoid (slow!) computation past requested precision */ + b = (t|32)=='f' ? r : a; + if (z-b > need) z = b+need; + e2+=sh; + } + + if (a=i; i*=10, e++); + else e=0; + + /* Perform rounding: j is precision after the radix (possibly neg) */ + j = p - ((t|32)!='f')*e - ((t|32)=='g' && p); + if (j < 9*(z-r-1)) { + uint32_t x; + /* We avoid C's broken division of negative numbers */ + d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); + j += 9*LDBL_MAX_EXP; + j %= 9; + for (i=10, j++; j<9; i*=10, j++); + x = *d % i; + /* Are there any significant digits past j? */ + if (x || d+1!=z) { + long double round = 2/LDBL_EPSILON; + long double small; + if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1))) + round += 2; + if (x 999999999) { + *d--=0; + if (d=i; i*=10, e++); + } + } + if (z>d+1) z=d+1; + } + for (; z>a && !z[-1]; z--); + + if ((t|32)=='g') { + if (!p) p++; + if (p>e && e>=-4) { + t--; + p-=e+1; + } else { + t-=2; + p--; + } + if (!(fl&ALT_FORM)) { + /* Count trailing zeros in last place */ + if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); + else j=9; + if ((t|32)=='f') + p = MIN(p,MAX(0,9*(z-r-1)-j)); + else + p = MIN(p,MAX(0,9*(z-r-1)+e-j)); + } + } + if (p > INT_MAX-1-(p || (fl&ALT_FORM))) + return -1; + l = 1 + p + (p || (fl&ALT_FORM)); + if ((t|32)=='f') { + if (e > INT_MAX-l) return -1; + if (e>0) l+=e; + } else { + estr=fmt_u(e<0 ? -e : e, ebuf); + while(ebuf-estr<2) *--estr='0'; + *--estr = (e<0 ? '-' : '+'); + *--estr = t; + if (ebuf-estr > INT_MAX-l) return -1; + l += ebuf-estr; + } + + if (l > INT_MAX-pl) return -1; + pad(f, ' ', w, pl+l, fl); + out(f, prefix, pl); + pad(f, '0', w, pl+l, fl^ZERO_PAD); + + if ((t|32)=='f') { + if (a>r) a=r; + for (d=a; d<=r; d++) { + char *s = fmt_u(*d, buf+9); + if (d!=a) while (s>buf) *--s='0'; + else if (s==buf+9) *--s='0'; + out(f, s, buf+9-s); + } + if (p || (fl&ALT_FORM)) out(f, ".", 1); + for (; d0; d++, p-=9) { + char *s = fmt_u(*d, buf+9); + while (s>buf) *--s='0'; + out(f, s, MIN(9,p)); + } + pad(f, '0', p+9, 9, 0); + } else { + if (z<=a) z=a+1; + for (d=a; d=0; d++) { + char *s = fmt_u(*d, buf+9); + if (s==buf+9) *--s='0'; + if (d!=a) while (s>buf) *--s='0'; + else { + out(f, s++, 1); + if (p>0||(fl&ALT_FORM)) out(f, ".", 1); + } + out(f, s, MIN(buf+9-s, p)); + p -= buf+9-s; + } + pad(f, '0', p+18, 18, 0); + out(f, estr, ebuf-estr); + } + + pad(f, ' ', w, pl+l, fl^LEFT_ADJ); + + return MAX(w, pl+l); +} + +static int getint(char **s) { + int i; + for (i=0; isdigit(**s); (*s)++) { + if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1; + else i = 10*i + (**s-'0'); + } + return i; +} + +static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type) +{ + char *a, *z, *s=(char *)fmt; + unsigned l10n=0, fl; + int w, p, xp; + union arg arg; + int argpos; + unsigned st, ps; + int cnt=0, l=0; + size_t i; + char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4]; + const char *prefix; + int t, pl; + wchar_t wc[2], *ws; + char mb[4]; +#ifdef LOSCFG_FS_VFS + struct winsize wsz; + + if (f && (f->write == __stdout_write) && !ioctl(f->fd, TIOCGWINSZ, &wsz)) { + f->lbf = '\n'; + f->write = __stdio_write; + f->wpos = f->wbase = f->buf; + f->wend = f->buf + f->buf_size; + } +#endif + for (;;) { + /* This error is only specified for snprintf, but since it's + * unspecified for other forms, do the same. Stop immediately + * on overflow; otherwise %n could produce wrong results. */ + if (l > INT_MAX - cnt) goto overflow; + + /* Update output count, end loop when fmt is exhausted */ + cnt += l; + if (!*s) break; + + /* Handle literal text and %% format specifiers */ + for (a=s; *s && *s!='%'; s++); + for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2); + if (z-a > INT_MAX-cnt) goto overflow; + l = z-a; + if (f) out(f, a, l); + if (l) continue; + + if (isdigit(s[1]) && s[2]=='$') { + l10n=1; + argpos = s[1]-'0'; + s+=3; + } else { + argpos = -1; + s++; + } + + /* Read modifier flags */ + for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<(*s-' '))); s++) + fl |= 1U<<(*s-' '); + + /* Read field width */ + if (*s=='*') { + if (isdigit(s[1]) && s[2]=='$') { + l10n=1; + nl_type[s[1]-'0'] = INT; + w = nl_arg[s[1]-'0'].i; + s+=3; + } else if (!l10n) { + w = f ? va_arg(*ap, int) : 0; + s++; + } else goto inval; + if (w<0) fl|=LEFT_ADJ, w=-w; + } else if ((w=getint(&s))<0) goto overflow; + + /* Read precision */ + if (*s=='.' && s[1]=='*') { + if (isdigit(s[2]) && s[3]=='$') { + nl_type[s[2]-'0'] = INT; + p = nl_arg[s[2]-'0'].i; + s+=4; + } else if (!l10n) { + p = f ? va_arg(*ap, int) : 0; + s+=2; + } else goto inval; + xp = (p>=0); + } else if (*s=='.') { + s++; + p = getint(&s); + xp = 1; + } else { + p = -1; + xp = 0; + } + + /* Format specifier state machine */ + st=0; + do { + if (OOB(*s)) goto inval; + ps=st; + st=states[st]S(*s++); + } while (st-1=0) goto inval; + } else { + if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; + else if (f) pop_arg(&arg, st, ap); + else return 0; + } + + if (!f) continue; + + z = buf + sizeof(buf); + prefix = "-+ 0X0x"; + pl = 0; + t = s[-1]; + + /* Transform ls,lc -> S,C */ + if (ps && (t&15)==3) t&=~32; + + /* - and 0 flags are mutually exclusive */ + if (fl & LEFT_ADJ) fl &= ~ZERO_PAD; + + switch(t) { + case 'n': + switch(ps) { + case BARE: *(int *)arg.p = cnt; break; + case LPRE: *(long *)arg.p = cnt; break; + case LLPRE: *(long long *)arg.p = cnt; break; + case HPRE: *(unsigned short *)arg.p = cnt; break; + case HHPRE: *(unsigned char *)arg.p = cnt; break; + case ZTPRE: *(size_t *)arg.p = cnt; break; + case JPRE: *(uintmax_t *)arg.p = cnt; break; + } + continue; + case 'p': + p = MAX(p, 2*sizeof(void*)); + t = 'x'; + fl |= ALT_FORM; + case 'x': case 'X': + a = fmt_x(arg.i, z, t&32); + if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2; + if (0) { + case 'o': + a = fmt_o(arg.i, z); + if ((fl&ALT_FORM) && pINTMAX_MAX) { + arg.i=-arg.i; + } else if (fl & MARK_POS) { + prefix++; + } else if (fl & PAD_POS) { + prefix+=2; + } else pl=0; + case 'u': + a = fmt_u(arg.i, z); + } + if (xp && p<0) goto overflow; + if (xp) fl &= ~ZERO_PAD; + if (!arg.i && !p) { + a=z; + break; + } + p = MAX(p, z-a + !arg.i); + break; + case 'c': + *(a=z-(p=1))=arg.i; + fl &= ~ZERO_PAD; + break; + case 'm': + if (1) a = strerror(errno); else + case 's': + a = arg.p ? arg.p : "(null)"; + z = a + strnlen(a, p<0 ? INT_MAX : p); + if (p<0 && *z) goto overflow; + p = z-a; + fl &= ~ZERO_PAD; + break; + case 'C': + wc[0] = arg.i; + wc[1] = 0; + arg.p = wc; + p = -1; + case 'S': + ws = arg.p; + for (i=l=0; i

=0 && l<=p-i; i+=l); + if (l<0) return -1; + if (i > INT_MAX) goto overflow; + p = i; + pad(f, ' ', w, p, fl); + ws = arg.p; + for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l) + out(f, mb, l); + pad(f, ' ', w, p, fl^LEFT_ADJ); + l = w>p ? w : p; + continue; + case 'e': case 'f': case 'g': case 'a': + case 'E': case 'F': case 'G': case 'A': + if (xp && p<0) goto overflow; + l = fmt_fp(f, arg.f, w, p, fl, t); + if (l<0) goto overflow; + continue; + } + + if (p < z-a) p = z-a; + if (p > INT_MAX-pl) goto overflow; + if (w < pl+p) w = pl+p; + if (w > INT_MAX-cnt) goto overflow; + + pad(f, ' ', w, pl+p, fl); + out(f, prefix, pl); + pad(f, '0', w, pl+p, fl^ZERO_PAD); + pad(f, '0', p, z-a, 0); + out(f, a, z-a); + pad(f, ' ', w, pl+p, fl^LEFT_ADJ); + + l = w; + } + + if (f) return cnt; + if (!l10n) return 0; + + for (i=1; i<=NL_ARGMAX && nl_type[i]; i++) + pop_arg(nl_arg+i, nl_type[i], ap); + for (; i<=NL_ARGMAX && !nl_type[i]; i++); + if (i<=NL_ARGMAX) goto inval; + return 1; + +inval: + errno = EINVAL; + return -1; +overflow: + errno = EOVERFLOW; + return -1; +} + +int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) +{ + va_list ap2; + int nl_type[NL_ARGMAX+1] = {0}; + union arg nl_arg[NL_ARGMAX+1]; + unsigned char internal_buf[80], *saved_buf = 0; + int olderr; + int ret; + + /* the copy allows passing va_list* even if va_list is an array */ + va_copy(ap2, ap); + if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { + va_end(ap2); + return -1; + } + + FLOCK(f); + olderr = f->flags & F_ERR; + if (f->mode < 1) f->flags &= ~F_ERR; + if (!f->buf_size) { + saved_buf = f->buf; + f->buf = internal_buf; + f->buf_size = sizeof internal_buf; + f->wpos = f->wbase = f->wend = 0; + } + if (!f->wend && __towrite(f)) ret = -1; + else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); + if (saved_buf) { + f->write(f, 0, 0); + if (!f->wpos) ret = -1; + f->buf = saved_buf; + f->buf_size = 0; + f->wpos = f->wbase = f->wend = 0; + } + if (f->flags & F_ERR) ret = -1; + f->flags |= olderr; + FUNLOCK(f); + va_end(ap2); + return ret; +} diff --git a/porting/liteos_m/kernel/src/stdio/vprintf.c b/porting/liteos_m/kernel/src/stdio/vprintf.c new file mode 100755 index 00000000..30d2bffa --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vprintf.c @@ -0,0 +1,6 @@ +#include + +int vprintf(const char *restrict fmt, va_list ap) +{ + return vfprintf(stdout, fmt, ap); +} diff --git a/porting/liteos_m/kernel/src/stdio/vsnprintf.c b/porting/liteos_m/kernel/src/stdio/vsnprintf.c new file mode 100755 index 00000000..7d81a4c0 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vsnprintf.c @@ -0,0 +1,57 @@ +#include "stdio_impl.h" +#include +#include +#include +#include +#include + +struct cookie { + char *s; + size_t n; +}; + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static size_t sn_write(FILE *f, const unsigned char *s, size_t l) +{ + struct cookie *c = f->cookie; + size_t k = MIN(c->n, f->wpos - f->wbase); + if (k) { + memcpy(c->s, f->wbase, k); + c->s += k; + c->n -= k; + } + k = MIN(c->n, l); + if (k) { + memcpy(c->s, s, k); + c->s += k; + c->n -= k; + } + *c->s = 0; + f->wpos = f->wbase = f->buf; + /* pretend to succeed, even if we discarded extra data */ + return l; +} + +int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) +{ + unsigned char buf[1]; + char dummy[1]; + struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 }; + pthread_mutex_t locallock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + FILE f = { + .lbf = EOF, + .write = sn_write, + .lock = &locallock, + .buf = buf, + .cookie = &c, + }; + + if (n > INT_MAX) { + errno = EOVERFLOW; + return -1; + } + + *c.s = 0; + return vfprintf(&f, fmt, ap); +} diff --git a/porting/liteos_m/kernel/src/stdio/vsprintf.c b/porting/liteos_m/kernel/src/stdio/vsprintf.c new file mode 100755 index 00000000..c57349d4 --- /dev/null +++ b/porting/liteos_m/kernel/src/stdio/vsprintf.c @@ -0,0 +1,7 @@ +#include +#include + +int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) +{ + return vsnprintf(s, INT_MAX, fmt, ap); +} diff --git a/porting/liteos_m/kernel/src/string/strnlen.c b/porting/liteos_m/kernel/src/string/strnlen.c new file mode 100755 index 00000000..6442eb79 --- /dev/null +++ b/porting/liteos_m/kernel/src/string/strnlen.c @@ -0,0 +1,7 @@ +#include + +size_t strnlen(const char *s, size_t n) +{ + const char *p = memchr(s, 0, n); + return p ? p-s : n; +} diff --git a/porting/liteos_m/kernel/src/time/asctime.c b/porting/liteos_m/kernel/src/time/asctime.c new file mode 100755 index 00000000..1febe544 --- /dev/null +++ b/porting/liteos_m/kernel/src/time/asctime.c @@ -0,0 +1,7 @@ +#include + +char *asctime(const struct tm *tm) +{ + static char buf[26]; + return __asctime_r(tm, buf); +} diff --git a/porting/liteos_m/kernel/src/time/asctime_r.c b/porting/liteos_m/kernel/src/time/asctime_r.c new file mode 100755 index 00000000..fce9a819 --- /dev/null +++ b/porting/liteos_m/kernel/src/time/asctime_r.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "locale_impl.h" +//#include "atomic.h" + +char *__asctime_r(const struct tm *restrict tm, char *restrict buf) +{ + if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", + __nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE), + __nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE), + tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec, + 1900 + tm->tm_year) >= 26) + { + /* ISO C requires us to use the above format string, + * even if it will not fit in the buffer. Thus asctime_r + * is _supposed_ to crash if the fields in tm are too large. + * We follow this behavior and crash "gracefully" to warn + * application developers that they may not be so lucky + * on other implementations (e.g. stack smashing..). + */ + //a_crash(); + } + return buf; +} + +weak_alias(__asctime_r, asctime_r); diff --git a/porting/liteos_m/kernel/src/time/ctime.c b/porting/liteos_m/kernel/src/time/ctime.c new file mode 100755 index 00000000..36029315 --- /dev/null +++ b/porting/liteos_m/kernel/src/time/ctime.c @@ -0,0 +1,8 @@ +#include + +char *ctime(const time_t *t) +{ + struct tm *tm = localtime(t); + if (!tm) return 0; + return asctime(tm); +} -- GitLab