提交 d4ad1a7a 编写于 作者: S silen

feat: L0 arm-qemu剥离工具链

Change-Id: Ieb45066f200d0da1d28367ec4fac2e9c33378dc5
Signed-off-by: Nsilen <wuyunjie@huawei.com>
上级 42b36311
......@@ -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 = [
......
#include <math.h>
#include <stdint.h>
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;
}
#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
#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)
};
#define bittab __fsmu8
#include <stdint.h>
#include <features.h>
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"
#include <stdlib.h>
#include <wchar.h>
#include <errno.h>
#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;
}
#include <stdlib.h>
#include <wchar.h>
#include <errno.h>
#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;
}
#include <stdlib.h>
#include <wchar.h>
int wctomb(char *s, wchar_t wc)
{
if (!s) return 0;
return wcrtomb(s, wc, 0);
}
#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;
}
#include <stdio.h>
#include "getc.h"
int fgetc(FILE *f)
{
return do_getc(f);
}
#include <stdio.h>
#include "putc.h"
int fputc(int c, FILE *f)
{
return do_putc(c, f);
}
#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);
}
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int remove(const char *path)
{
int r = unlink(path);
if (r==-EISDIR) r = rmdir(path);
return r;
}
#include <stdio.h>
#include <stdarg.h>
int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
{
return 0;
}
#include "stdio_impl.h"
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
#include <inttypes.h>
#include <math.h>
#include <float.h>
#include <sys/ioctl.h>
/* 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<<sh)+carry;
*d = x % 1000000000;
carry = x / 1000000000;
}
if (carry) *--a = carry;
while (z>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<z; d++) {
uint32_t rm = *d & ((1<<sh)-1);
*d = (*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<z) for (i=10, e=9*(r-a); *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<i/2) small=0x0.8p0;
else if (x==i/2 && d+1==z) small=0x1.0p0;
else small=0x1.8p0;
if (pl && *prefix=='-') round*=-1, small*=-1;
*d -= x;
/* Decide whether to round by probing round+small */
if (round+small != round) {
*d = *d + i;
while (*d > 999999999) {
*d--=0;
if (d<a) *--a=0;
(*d)++;
}
for (i=10, e=9*(r-a); *a>=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 (; d<z && p>0; 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<z && p>=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<STOP);
if (!st) goto inval;
/* Check validity of argument type (nl/normal) */
if (st==NOARG) {
if (argpos>=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) && p<z-a+1) p=z-a+1;
} if (0) {
case 'd': case 'i':
pl=1;
if (arg.i>INTMAX_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<p && *ws && (l=wctomb(mb, *ws++))>=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;
}
#include <stdio.h>
int vprintf(const char *restrict fmt, va_list ap)
{
return vfprintf(stdout, fmt, ap);
}
#include "stdio_impl.h"
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <pthread.h>
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);
}
#include <stdio.h>
#include <limits.h>
int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
{
return vsnprintf(s, INT_MAX, fmt, ap);
}
#include <string.h>
size_t strnlen(const char *s, size_t n)
{
const char *p = memchr(s, 0, n);
return p ? p-s : n;
}
#include <time.h>
char *asctime(const struct tm *tm)
{
static char buf[26];
return __asctime_r(tm, buf);
}
#include <time.h>
#include <stdio.h>
#include <langinfo.h>
#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);
#include <time.h>
char *ctime(const time_t *t)
{
struct tm *tm = localtime(t);
if (!tm) return 0;
return asctime(tm);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册