diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/LIB.status | 7 | ||||
| -rw-r--r-- | libc/Makefile | 1 | ||||
| -rw-r--r-- | libc/include/stdio.h | 50 | ||||
| -rw-r--r-- | libc/src/xprintf.c | 94 | ||||
| -rwxr-xr-x | libc/src/xscanf.c | 4 | ||||
| -rw-r--r-- | libc/src/yscanf.c | 55 | 
6 files changed, 106 insertions, 105 deletions
| diff --git a/libc/LIB.status b/libc/LIB.status index b2b573a..7ef0748 100644 --- a/libc/LIB.status +++ b/libc/LIB.status @@ -78,10 +78,9 @@ fdopen     - missing  setbuf     - missing  setvbuf    - missing -*printf    - ok (f, s, vf, v, vs, sn, vsn, vas, as) -*dprintf   - missing -*scanf     - missing (f, s, vf, v, vs) -*getc      - missing +*printf    - ok, v-versions inlined (f, s, d, sn, as + x) +*scanf     - ok, v-versions inlined (f, s, d + x) +*getc      - ok, inlined (f, .)  getchar    - missing  *putc      - missing  putchar    - missing diff --git a/libc/Makefile b/libc/Makefile index 18f3d54..15b75a6 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -33,6 +33,7 @@ src/malloc.c \  \  src/xprintf.c \  src/xscanf.c \ +src/yscanf.c \  include $(ROOTDIR)/target-rules.mk diff --git a/libc/include/stdio.h b/libc/include/stdio.h index ee6226f..a99fd42 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -14,18 +14,37 @@ struct _FILE {  };  typedef struct _FILE FILE; +extern FILE * stdin, * stdout, * stderr; -int printf(const char * format, ...); -int fprintf(FILE *stream, const char * format, ...); -int sprintf(char * str, const char * format, ...); -int snprintf(char * str, size_t size, const char * format, ...); -int asprintf(char ** strp, const char * format, ...); - -int vprintf(const char * format, va_list ap); -int vfprintf(FILE *stream, const char * format, va_list ap); +int vdprintf(int fd, const char * format, va_list ap);  int vsprintf(char * str, const char * format, va_list ap);  int vsnprintf(char * str, size_t size, const char * format, va_list ap);  int vasprintf(char ** strp, const char * format, va_list ap); +int vxprintf(void (*func)(const char *, int, void *), void * arg, const char * format, va_list ap); +static inline int vfprintf(FILE * stream, const char * format, va_list ap) { return vdprintf(stream->fd, format, ap); } +static inline int vprintf(const char * format, va_list ap) { return vfprintf(stdout, format, ap); } + +static inline int dprintf(int fd, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vdprintf(fd, format, ap); va_end(ap); return r; } +static inline int sprintf(char * str, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vsprintf(str, format, ap); va_end(ap); return r; } +static inline int snprintf(char * str, size_t size, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vsnprintf(str, size, format, ap); va_end(ap); return r; } +static inline int asprintf(char ** strp, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vasprintf(strp, format, ap); va_end(ap); return r; } +static inline int xprintf(void (*func)(const char *, int, void *), void * arg, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vxprintf(func, arg, format, ap); va_end(ap); return r; } +static inline int fprintf(FILE * stream, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vfprintf(stream, format, ap); va_end(ap); return r; } +static inline int printf(const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vprintf(format, ap); va_end(ap); return r; } + +int vdscanf(int fd, const char * format, va_list ap); +int vsscanf(const char * str, const char * format, va_list ap); +int vxscanf(int (*xgetc)(void *), void (*xungetc)(void *, int), void * opaque, const char * format, va_list args); +static inline int vfscanf(FILE * stream, const char * format, va_list ap) { return vdscanf(stream->fd, format, ap); } +static inline int vscanf(const char * format, va_list ap) { return vfscanf(stdin, format, ap); } + +static inline int dscanf(int fd, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vdscanf(fd, format, ap); va_end(ap); return r; } +static inline int sscanf(const char * str, const char * format, ...)  { va_list ap; int r; va_start(ap, format); r = vsscanf(str, format, ap); va_end(ap); return r; } +static inline int xscanf(int (*xgetc)(void *), void (*xungetc)(void *, int), void * opaque, const char *format, ...) { va_list ap; int r; va_start(ap, format); r = vxscanf(xgetc, xungetc, opaque, format, ap); va_end(ap); return r; } +static inline int fscanf(FILE * stream, const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vfscanf(stream, format, ap); va_end(ap); return r; } +static inline int scanf(const char * format, ...) { va_list ap; int r; va_start(ap, format); r = vscanf(format, ap); va_end(ap); return r; } + +  void __sinit(struct _reent *); @@ -150,6 +169,19 @@ static inline size_t fwrite(const void * _ptr, size_t size, size_t nmemb, FILE *      return nmemb;  } -extern FILE * stdin, * stdout, * stderr; +static inline int fgetc(FILE * stream) { +    uint8_t v; + +    if (!stream) { +        _impure_ptr->_errno = EINVAL; +        return -1; +    } +     +    if (read(stream->fd, &v, 1) != 1) +        return EOF; +    return v; +} + +static inline int getc() { return fgetc(stdin); }  #endif diff --git a/libc/src/xprintf.c b/libc/src/xprintf.c index 30659f7..269d77c 100644 --- a/libc/src/xprintf.c +++ b/libc/src/xprintf.c @@ -213,7 +213,7 @@ static int getdigit(long double *val, int *cnt){  ** seems to make a big difference in determining how fast this beast  ** will run.  */ -static int vxprintf(func,arg,format,ap) +int vxprintf(func,arg,format,ap)    void (*func)(const char*,int,void*);    void *arg;    const char *format; @@ -665,20 +665,6 @@ static int vxprintf(func,arg,format,ap)  } /* End of function */  /* -** This non-standard function is still occasionally useful.... -*/ -int xprintf( -  void (*func)(char*,int,void*), -  void *arg, -  const char *format, -  ... -){ -  va_list ap; -  va_start(ap,format); -  return vxprintf(func,arg,format,ap); -} - -/*  ** Now for string-print, also as found in any standard library.  ** Add to this the snprint function which stops added characters  ** to the string at a given length. @@ -713,19 +699,6 @@ static void sout(txt,amt,arg)    ((struct s_strargument*)arg)->next = head;  } -int sprintf(char *buf, const char *fmt, ...){ -  int rc; -  va_list ap; -  struct s_strargument arg; - -  va_start(ap,fmt); -  arg.next = buf; -  arg.last = 0; -  *arg.next = 0; -  rc = vxprintf(sout,&arg,fmt,ap); -  va_end(ap); -  return rc; -}  int vsprintf(char *buf,const char *fmt,va_list ap){    struct s_strargument arg;    arg.next = buf; @@ -733,19 +706,6 @@ int vsprintf(char *buf,const char *fmt,va_list ap){    *buf = 0;    return vxprintf(sout,&arg,fmt,ap);  } -int snprintf(char *buf, size_t n, const char *fmt, ...){ -  int rc; -  va_list ap; -  struct s_strargument arg; - -  va_start(ap,fmt); -  arg.next = buf; -  arg.last = &arg.next[n-1]; -  *arg.next = 0; -  rc = vxprintf(sout,&arg,fmt,ap); -  va_end(ap); -  return rc; -}  int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap){    struct s_strargument arg;    arg.next = buf; @@ -799,31 +759,6 @@ static void mout(zNewText,nNewChar,arg)  ** We changed the name to TclMPrint() to conform with the Tcl private  ** routine naming conventions.  */ -int asprintf(char ** out, const char *zFormat, ...){ -  va_list ap; -  struct sgMprintf sMprintf; -  char *zNew; -  char zBuf[200]; -  int r; - -  va_start(ap,zFormat); -  sMprintf.nChar = 0; -  sMprintf.nAlloc = sizeof(zBuf); -  sMprintf.zText = zBuf; -  sMprintf.zBase = zBuf; -  r = vxprintf(mout,&sMprintf,zFormat,ap); -  va_end(ap); -  if( sMprintf.zText==sMprintf.zBase ){ -    zNew = malloc( sMprintf.nChar+1 ); -    if( zNew ) strcpy(zNew,zBuf); -  }else{ -    zNew = realloc(sMprintf.zText,sMprintf.nChar+1); -  } -   -  *out = zNew; - -  return r; -}  /* This is the varargs version of mprintf.    ** @@ -860,31 +795,10 @@ static void fout(zNewText,nNewChar,arg)    int nNewChar;    void *arg;  { -  fwrite(zNewText,1,nNewChar,(FILE*)arg); +  write(*(int*)arg,zNewText,nNewChar);  }  /* The public interface routines */ -int fprintf(FILE *pOut, const char *zFormat, ...){ -  va_list ap; -  int retc; - -  va_start(ap,zFormat);   -  retc = vxprintf(fout,pOut,zFormat,ap); -  va_end(ap); -  return retc; -} -int vfprintf(FILE *pOut, const char *zFormat, va_list ap){ -  return vxprintf(fout,pOut,zFormat,ap); -} -int printf(const char *zFormat, ...){ -  va_list ap; -  int retc; - -  va_start(ap,zFormat); -  retc = vxprintf(fout,stdout,zFormat,ap); -  va_end(ap); -  return retc; -} -int vprintf(const char *zFormat, va_list ap){ -  return vxprintf(fout,stdout,zFormat,ap); +int vdprintf(int fd, const char *zFormat, va_list ap){ +  return vxprintf(fout,&fd,zFormat,ap);  } diff --git a/libc/src/xscanf.c b/libc/src/xscanf.c index ad6f190..d121722 100755 --- a/libc/src/xscanf.c +++ b/libc/src/xscanf.c @@ -11,7 +11,7 @@   * VAL(a)       leads to 1 if a is true and valid   */  #define NEXT(c) ((c)=xgetc(opaque),size++,incount++) -#define PREV(c) do{if((c)!=EOF)xungetc((c),opaque);size--;incount--;}while(0) +#define PREV(c) do{if((c)!=EOF)xungetc(opaque,(c));size--;incount--;}while(0)  #define VAL(a)  ((a)&&size<=width)  #ifdef NOFLOATINGPOINT @@ -30,7 +30,7 @@ static const unsigned char undef[3][sizeof(double)]= /* Undefined numeric values  };  #endif -int vxscanf(int (*xgetc)(void *),void (*xungetc)(int,void*),void *opaque,const char *format,va_list args) +int vxscanf(int (*xgetc)(void *),void (*xungetc)(void*,int),void *opaque,const char *format,va_list args)  {    size_t blocks=0,incount=0;    int c=0; diff --git a/libc/src/yscanf.c b/libc/src/yscanf.c new file mode 100644 index 0000000..3d2a488 --- /dev/null +++ b/libc/src/yscanf.c @@ -0,0 +1,55 @@ +#include "stdio.h" + +struct opaque_t { +    union { +        const char * p; +        int fd; +    }; +    uint8_t bsize; +    char backbuffer[3]; +}; + +static int str_getc(void * _opaque) { +    struct opaque_t * opaque = (struct opaque_t *) _opaque; +    int r; + +    if (opaque->bsize) +        return opaque->backbuffer[--(opaque->bsize)]; +     +    r = *(opaque->p++); +     +    return r ? r : EOF; +} + +static int file_getc(void * _opaque) { +    struct opaque_t * opaque = (struct opaque_t *) _opaque; +    uint8_t v; + +    if (opaque->bsize) +        return opaque->backbuffer[--(opaque->bsize)]; +     +    if (read(opaque->fd, &v, 1) != 1) +        return EOF; +    return v; +} + +static void scanf_ungetc(void * _opaque, int c) { +    struct opaque_t * opaque = (struct opaque_t *) _opaque; +     +    if (opaque->bsize < sizeof(opaque->backbuffer)) +        opaque->backbuffer[opaque->bsize++] = c; +} + +int vsscanf(const char * str, const char * format, va_list ap) { +    struct opaque_t opaque; +    opaque.p = str; +    opaque.bsize = 0; +    return vxscanf(str_getc, scanf_ungetc, &opaque, format, ap); +} + +int vdscanf(int fd, const char * format, va_list ap) { +    struct opaque_t opaque; +    opaque.fd = fd; +    opaque.bsize = 0; +    return vxscanf(file_getc, scanf_ungetc, &opaque, format, ap); +} | 
