From 4cd6a4a5d7e49d54d53dcf4a6f3393d50bd88e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwenol=C3=A9=20Beauchesne?= Date: Wed, 4 Jun 2003 18:44:09 +0000 Subject: Import dietlibc 0.22 + other fixes for AMD64 --- mdk-stage1/dietlibc/lib/__v_scanf.c | 391 ++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 mdk-stage1/dietlibc/lib/__v_scanf.c (limited to 'mdk-stage1/dietlibc/lib/__v_scanf.c') diff --git a/mdk-stage1/dietlibc/lib/__v_scanf.c b/mdk-stage1/dietlibc/lib/__v_scanf.c new file mode 100644 index 000000000..6db51db59 --- /dev/null +++ b/mdk-stage1/dietlibc/lib/__v_scanf.c @@ -0,0 +1,391 @@ +#include "dietfeatures.h" +#include +#include +#include +#include +#include +#include + +#include "dietstdio.h" +#include "dietwarning.h" + +#define A_GETC(fn) (++consumed,(fn)->getch((fn)->data)) +#define A_PUTC(c,fn) (--consumed,(fn)->putch((c),(fn)->data)) + +int __v_scanf(struct arg_scanf* fn, const unsigned char *format, va_list arg_ptr) +{ + unsigned int ch; /* format act. char */ + int n=0; + + /* arg_ptr tmps */ +#ifdef WANT_FLOATING_POINT_IN_SCANF + double *pd; + float *pf; +#endif +#ifdef WANT_LONGLONG_SCANF + long long *pll; +#endif + long *pl; + short *ph; + int *pi; + char *s; + + unsigned int consumed=0; + + /* get one char */ + int tpch= A_GETC(fn); + + //while ((tpch!=-1)&&(*format)) + while (*format) + { +// const unsigned char *prev_fmt=format; + ch=*format++; + switch (ch) { + /* end of format string ?!? */ + case 0: return 0; + + /* skip spaces ... */ + case ' ': + case '\f': + case '\t': + case '\v': + case '\n': + case '\r': + while((*format)&&(isspace(*format))) ++format; + while(isspace(tpch)) tpch=A_GETC(fn); + break; + + /* format string ... */ + case '%': + { + unsigned int _div=0; + int width=-1; + char flag_width=0; + char flag_discard=0; + char flag_half=0; + char flag_long=0; + char flag_longlong=0; + +in_scan: + ch=*format++; + if(ch!='n' && tpch==-1) goto err_out; + switch (ch) { + /* end of format string ?!? */ + case 0: return 0; + + /* check for % */ + case '%': + if ((unsigned char)tpch != ch) goto err_out; + tpch=A_GETC(fn); + break; + + /* FLAGS */ + case '*': + flag_discard=1; + goto in_scan; + case 'h': + flag_half=1; + goto in_scan; + case 'l': + if (flag_long) flag_longlong=1; + flag_long=1; + goto in_scan; + case 'q': + case 'L': + flag_longlong=1; + goto in_scan; + + /* WIDTH */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + width=strtol(format-1,&s,10); + format=s; + flag_width=1; + goto in_scan; + + /* scan for integer / strtol reimplementation ... */ + case 'p': + case 'X': + case 'x': + _div+=6; + case 'd': + _div+=2; + case 'o': + _div+=8; + case 'u': + case 'i': + { +#ifdef WANT_LONGLONG_SCANF + unsigned long long v=0; +#else + unsigned long v=0; +#endif + unsigned int consumedsofar=consumed; + int neg=0; + while(isspace(tpch)) tpch=A_GETC(fn); + if (tpch=='-') { + tpch=A_GETC(fn); + neg=1; + } + + if (tpch=='+') tpch=A_GETC(fn); + + if (!flag_width) { + if ((_div==16) && (tpch=='0')) goto scan_hex; + if (!_div) { + _div=10; + if (tpch=='0') { + _div=8; +scan_hex: + tpch=A_GETC(fn); + if ((tpch|32)=='x') { + tpch=A_GETC(fn); + _div=16; + } + } + } + } + while ((width)&&(tpch!=-1)) { + register unsigned long c=tpch&0xff; +#ifdef WANT_LONGLONG_SCANF + register unsigned long long d=c|0x20; +#else + register unsigned long d=c|0x20; +#endif + c=(d>='a'?d-'a'+10:c<='9'?c-'0':0xff); + if (c>=_div) break; + d=v*_div; +#ifdef WANT_LONGLONG_SCANF + v=(d=-((unsigned long long)LLONG_MIN)) { + l=(neg)?LLONG_MIN:LLONG_MAX; + } + else { + if (neg) v*=-1; + } +#else + register long l=v; + if (v>=-((unsigned long)LONG_MIN)) { + l=(neg)?LONG_MIN:LONG_MAX; + } + else { + if (neg) v*=-1; + } +#endif + } + if (!flag_discard) { +#ifdef WANT_LONGLONG_SCANF + if (flag_longlong) { + pll=(long long *)va_arg(arg_ptr,long long*); + *pll=v; + } else +#endif + if (flag_long) { + pl=(long *)va_arg(arg_ptr,long*); + *pl=v; + } else if (flag_half) { + ph=(short*)va_arg(arg_ptr,short*); + *ph=v; + } else { + pi=(int *)va_arg(arg_ptr,int*); + *pi=v; + } + if(consumedsofar=0) && (cset[tpch]^flag_not)) { + if (!flag_discard) *s=tpch; + if (tpch) ++s; else break; + --width; + tpch=A_GETC(fn); + } + if (!flag_discard) *s=0; + ++format; + } + break; +#endif + default: + goto err_out; + } + } + break; + + /* check if equal format string... */ + default: + if ((unsigned char)tpch != ch) goto err_out; + tpch=A_GETC(fn); + break; + } + } +err_out: + if (tpch<0 && n==0) return EOF; + A_PUTC(tpch,fn); + return n; +} + +link_warning("__v_scanf","warning: the scanf functions add several kilobytes of bloat."); -- cgit v1.2.1