summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-02-05 13:05:37 -0800
committerPixel <pixel@nobis-crew.org>2011-02-05 13:05:37 -0800
commit078b4ccf0b65d655d81e9f4fc6e1284773e1dda4 (patch)
treedadfbf7c2ae6d81d48bb402da57721592a3a7d45
parentb6378c65dbad497cab13c3551e89b9bbbef2602b (diff)
Re-structured the *scanf and *printf functions.
-rw-r--r--libc/LIB.status7
-rw-r--r--libc/Makefile1
-rw-r--r--libc/include/stdio.h50
-rw-r--r--libc/src/xprintf.c94
-rwxr-xr-xlibc/src/xscanf.c4
-rw-r--r--libc/src/yscanf.c55
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);
+}